diff --git a/README.md b/README.md index 6847e48..2209fce 100755 --- a/README.md +++ b/README.md @@ -28,125 +28,210 @@ Yahoo! Query Language Documentation and Support * YQL Open Table (Classes and Metaclasses) Generator * Response prettyfier -### Installation +mYQL +========= + +mYQL is a Python wrapper of the Yahoo Query Language. + +Yahoo! Query Language Documentation and Support +=============================================== + +* [Yahoo! Query Language](http://developer.yahoo.com/yql/) +* [Yahoo! Developer Network](http://developer.yahoo.com) +* [Yahoo! Application Platform](http://developer.yahoo.com/yap/) +* [Yahoo! Social APIs](http://developer.yahoo.com/social/) +* [Yahoo! Query Language Console](https://developer.yahoo.com/yql/console/) + +Installation +============ ```shell $ pip install myql ``` -#### Examples --------------- +Quick Start +=========== + +```python +>>> import myql +>>> yql = myql.MYQL() +>>> yql.diagnostics = True # To turn diagnostics on +``` + +####Disable access to community tables -* ___rawQuery___ +```python +>>> rep = yql.rawQuery('desc yahoo.finance.quotes ') +>>> rep.json() +{u'query': {u'count': 1, u'lang': u'en-US', u'results': {u'table': {u'src': u'http://www.datatables.org/yahoo/finance/yahoo.finance.quotes.xml', u'hash': u'061616a1c033ae89aaf2cbe83790b979', u'name': u'yahoo.finance.quotes', u'request': {u'select': {u'key': {u'required': u'true', u'type': u'xs:string', u'name': u'symbol'}}}, u'meta': {u'sampleQuery': u'\n\t\t\tselect * from yahoo.finance.quotes where symbol in ("YHOO","AAPL","GOOG","MSFT")\n\t\t'}, u'security': u'ANY'}}, u'created': u'2014-08-24T11:26:48Z'}} +>>> +>>> yql.community= True # Setting up access to community +>>> yql = myql.MYQL() +>>> rep = yql.rawQuery('desc yahoo.finance.quotes ') +>>> rep.json() +{u'error': {u'lang': u'en-US', u'description': u'No definition found for Table yahoo.finance.quotes'}} + +``` +or ```python >>> import myql ->>> from myql.utils import pretty_json, pretty_xml ->>> yql = myql.MYQL(format='json') ->>> response = yql.rawQuery("select name, woeid from geo.states where place='Congo' limit 2") +>>> yql = myql.MYQL(community=False) +>>> # do your magic +``` + +####Changing response format (xml or json) + +The response format is by default ***json***. + +```python +>>> import myql +>>> yql = myql.MYQL(format='xml', community=True) +>>> rep = yql.rawQuery('select name, woeid from geo.states where place="Congo"') +>>> rep.text +u'\nCuvette-Ouest Department55998384Cuvette Department2344968Plateaux District2344973Sangha2344974Lekoumou2344970Pool Department2344975Likouala Department2344971Niari Department2344972Brazzaville2344976Bouenza Department2344967Kouilou2344969\n\n' +>>> rep = yql.rawQuery('select name, woeid from geo.states where place="Congo"', format='json') +>>> rep.json() +{u'query': {u'count': 11, u'lang': u'en-US', u'results': {u'place': [{u'woeid': u'55998384', u'name': u'Cuvette-Ouest Department'}, {u'woeid': u'2344968', u'name': u'Cuvette Department'}, {u'woeid': u'2344973', u'name': u'Plateaux District'}, {u'woeid': u'2344974', u'name': u'Sangha'}, {u'woeid': u'2344970', u'name': u'Lekoumou'}, {u'woeid': u'2344975', u'name': u'Pool Department'}, {u'woeid': u'2344971', u'name': u'Likouala Department'}, {u'woeid': u'2344972', u'name': u'Niari Department'}, {u'woeid': u'2344976', u'name': u'Brazzaville'}, {u'woeid': u'2344967', u'name': u'Bouenza Department'}, {u'woeid': u'2344969', u'name': u'Kouilou'}]}, u'created': u'2014-08-27T04:52:38Z'}} +>>> +``` + + +Methods +------- + +####use(yql_table_url,name=yql_table_name) +Changes the data provider + +```python +>>> yql.use('http://www.josuebrunel.org//users.xml', name='myusers') +``` + +####desc(tablename) +Returns table description + +```python +>>> response = yql.desc('weather.forecast') +>>> response.json() +{u'query': {u'count': 1, u'lang': u'en-US', u'results': {u'table': {u'request': {u'select': [{u'key': [{u'required': u'true', u'type': u'xs:string', u'name': u'location'}, {u'type': u'xs:string', u'name': u'u'}]}, {u'key': [{u'required': u'true', u'type': u'xs:string', u'name': u'woeid'}, {u'type': u'xs:string', u'name': u'u'}]}]}, u'security': u'ANY', u'meta': {u'documentationURL': u'http://developer.yahoo.com/weather/', u'sampleQuery': u'select * from weather.forecast where woeid=2502265', u'description': u'Weather forecast table', u'author': u'Yahoo! Inc'}, u'hash': u'aae78b1462a6a8fbc748aec4cf292767', u'name': u'weather.forecast'}}, u'created': u'2014-08-16T19:31:51Z'}} +>>> +``` + +####rawQuery(query) + +Allows you to directly type your query + +```python +>>> response = yql.rawQuery("select * from geo.countries where place='North America'") +>>> # deal with the response +``` + +####select(table, fields, limit).where(filters, ...) + +Select a table i.e *weather.forecast*. +If *table* not provided, it will use the default table. If there's no such thing as a default table, it will raise a *NoTableSelectedError* + +***NB*** : A simple select doesn't return any data. Use ***GET*** instead. + +```python +>>> response = yql.select('geo.countries', [name, code, woeid]).where(['name', '=', 'Canada']) +>>> response.json() +{u'query': {u'count': 1, u'lang': u'en-US', u'results': {u'place': {u'woeid': u'23424775', u'name': u'Canada'}}, u'created': u'2014-08-16T19:04:08Z'}} +>>> ... +>>> rep = yql.select('geo.countries', ['name', 'woeid'], 2).where(['place', '=', 'Africa']) +>>> rep.json() +{u'query': {u'count': 2, u'lang': u'en-US', u'results': {u'place': [{u'woeid': u'23424740', u'name': u'Algeria'}, {u'woeid': u'23424745', u'name': u'Angola'}]}, u'created': u'2014-08-17T10:52:49Z'}} +>>> +>>> rep = yql.select('geo.countries', ['name', 'woeid'], 2).where(['place', 'in', ('Africa', 'Europe')]) +>>> rep.json() +{u'query': {u'count': 2, u'lang': u'en-US', u'results': {u'place': [{u'woeid': u'23424740', u'name': u'Algeria'}, {u'woeid': u'23424745', u'name': u'Angola'}]}, u'created': u'2014-08-17T11:22:49Z'}} +>>> +``` + +####get(table, fields, limit) +Same as ***SELECT***, but instead returns data. + +**REMINDER** : Some tables require a **where clause**, therefore ***GET*** won't work on those tables, use *select(...).where(...)* instead . + +```python +>>> yql.get('geo.countries', ['name', 'woeid'], 1) +>>> rep.json() +{u'query': {u'count': 1, u'lang': u'en-US', u'results': {u'place': {u'woeid': u'23424966', u'name': u'Sao Tome and Principe'}}, u'created': u'2014-08-17T10:32:25Z'}} +>>> +``` + +####insert(table, (field1, field2, ..., fieldN),(value1, value2, ..., valueN)) +Insert values into a table. Arguments 2 and 3 may be **tuples** or **list**. + +```python +>>> from myql.utils import pretty_json +>>> response = yql.insert('yql.storage.admin',('value',),('http://josuebrunel.org',)) >>> print(pretty_json(response.content)) { "query": { - "count": 2, - "created": "2015-06-03T04:51:23Z", - "lang": "en-US", + "count": 1, + "created": "2015-05-14T13:25:56Z", + "lang": "en-US", "results": { - "place": [ - { - "name": "Cuvette-Ouest Department", - "woeid": "55998384" - }, - { - "name": "Cuvette Department", - "woeid": "2344968" - } - ] + "inserted": { + "execute": "store://KkkC5xDw4v32IcWWSQ4YRe", + "select": "store://Zc5LHXcmYM7XBfSbo9tzFL", + "update": "store://Rqb5fbQyDvrfHJiClWnZ6q" + } } } } ->>> - ``` -* ___get(table, item=[], limit=None)___ +####update(table,[field1, ..., fieldN],[value1, ..., ...valueN]).where(filters, ...) +Update fields values. This method __is always followed by ***where()***__. Arguments 2 and 3 may be **tuples** or **list**. ```python ->>> response = yql.get('geo.countries',['name,woeid'],3) +>>> from myql.utils import pretty_json +>>> response = yql.update('yql.storage',('value',),('https://josuebrunel.org',)).where(['name','=','store://Rqb5fbQyDvrfHJiClWnZ6q']) >>> print(pretty_json(response.content)) { "query": { - "count": 3, - "created": "2015-06-03T05:07:47Z", - "lang": "en-US", + "count": 1, + "created": "2015-05-14T13:32:52Z", + "lang": "en-US", "results": { - "place": [ - { - "name": "Sao Tome and Principe", - "woeid": "23424966" - }, - { - "name": "Ghana", - "woeid": "23424824" - }, - { - "name": "Togo", - "woeid": "23424965" - } - ] + "success": "Updated store://KkkC5xDw4v32IcWWSQ4YRe" } } } ->>> - ``` -* ___select(table,item=[],limit=None).were(condition)___ - +####delete(table).where(filters, ...) +Delete records ```python ->>> yql.format = 'xml' ->>> response = yql.select('weather.forecast',['units','atmosphere']).where(['woeid','in',('select woeid from geo.places(1) where text="Paris,Fr"',)]) # IN requires tuple ->>> print(pretty_xml(response.content)) - - - - - - - - - - - - - - - - - - - - - - - +>>> from myql.utils import pretty_json +>>> response = self.yql.delete('yql.storage').where(['name','=','store://Rqb5fbQyDvrfHJiClWnZ6q']) +>>> print(pretty_json(response.content)) +{ + "query": { + "count": 1, + "created": "2015-05-14T13:38:28Z", + "lang": "en-US", + "results": { + "success": "store://Rqb5fbQyDvrfHJiClWnZ6q deleted" + } + } +} + ``` -* ___Using OAUTH___ +Using OAuth to fetch protected resources +========================================= ```python - +>>> from myql.contrib.auth import YOAuth +>>> oauth = YOAuth(None, None, from_file='credentials.json') # only consumer_key and consumer_secret are required. +>>> from myql import MYQL +>>> yql = MYQL(format='xml', oauth=oauth) +>>> response = yql.getGUID('josue_brunel') # Deal with the response ``` -### Documentation - -Full Documentation is [here](http://myql.readthedocs.org/en/latest/) - -### Contribute - -* Report issue -* Star and Fork the repository -* Submit pull requests -* Above all, have fun playing with data :wink: #### Release Notes diff --git a/README.rst b/README.rst index b51099e..fd727b2 100644 --- a/README.rst +++ b/README.rst @@ -1,7 +1,36 @@ +`mYQL `__ +================================================= + +|Build Status| |Documentation Status| |Latest Version| |Downloads| +|Py\_Versions| |Implementations| |Join the chat at +https://gitter.im/josuebrunel/myql| |Code Issues| + +mYQL is a Python wrapper of the Yahoo Query Language. **`Full +Documentation `__** + +Yahoo! Query Language Documentation and Support +=============================================== + +- Yahoo! Query Language - http://developer.yahoo.com/yql/ +- Yahoo! Developer Network: http://developer.yahoo.com +- Yahoo! Application Platform - http://developer.yahoo.com/yap/ +- Yahoo! Social APIs - http://developer.yahoo.com/social/ +- Yahoo! QUery Language Console + https://developer.yahoo.com/yql/console/ + +Features +~~~~~~~~ + +- Simple YQL Query +- Authenticated YQL Query ( OAuth ) +- StockScraper +- YQL Open Table (Classes and Metaclasses) Generator +- Response prettyfier + mYQL ==== -mYQL is a Python wrapper of the Yahoo Query Language. Read the full Documentation `http://myql.readthedocs.org/en/latest/` +mYQL is a Python wrapper of the Yahoo Query Language. Yahoo! Query Language Documentation and Support =============================================== @@ -13,51 +42,43 @@ Yahoo! Query Language Documentation and Support - `Yahoo! Query Language Console `__ -Features -======== - -* Simple YQL Query -* Authenticated YQL Query ( OAuth ) -* StockScraper -* YQL Open Table (Classes and Metaclasses) Generator - Installation ============ -:: +.. code:: shell $ pip install myql Quick Start =========== -:: +.. code:: python >>> import myql >>> yql = myql.MYQL() >>> yql.diagnostics = True # To turn diagnostics on -Access to community tables -^^^^^^^^^^^^^^^^^^^^^^^^^^ +Disable access to community tables +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -:: +.. code:: python - >>> yql = myql.MYQL() >>> rep = yql.rawQuery('desc yahoo.finance.quotes ') >>> rep.json() - {u'error': {u'lang': u'en-US', u'description': u'No definition found for Table yahoo.finance.quotes'}} + {u'query': {u'count': 1, u'lang': u'en-US', u'results': {u'table': {u'src': u'http://www.datatables.org/yahoo/finance/yahoo.finance.quotes.xml', u'hash': u'061616a1c033ae89aaf2cbe83790b979', u'name': u'yahoo.finance.quotes', u'request': {u'select': {u'key': {u'required': u'true', u'type': u'xs:string', u'name': u'symbol'}}}, u'meta': {u'sampleQuery': u'\n\t\t\tselect * from yahoo.finance.quotes where symbol in ("YHOO","AAPL","GOOG","MSFT")\n\t\t'}, u'security': u'ANY'}}, u'created': u'2014-08-24T11:26:48Z'}} + >>> >>> yql.community= True # Setting up access to community + >>> yql = myql.MYQL() >>> rep = yql.rawQuery('desc yahoo.finance.quotes ') >>> rep.json() - {u'query': {u'count': 1, u'lang': u'en-US', u'results': {u'table': {u'src': u'http://www.datatables.org/yahoo/finance/yahoo.finance.quotes.xml', u'hash': u'061616a1c033ae89aaf2cbe83790b979', u'name': u'yahoo.finance.quotes', u'request': {u'select': {u'key': {u'required': u'true', u'type': u'xs:string', u'name': u'symbol'}}}, u'meta': {u'sampleQuery': u'\n\t\t\tselect * from yahoo.finance.quotes where symbol in ("YHOO","AAPL","GOOG","MSFT")\n\t\t'}, u'security': u'ANY'}}, u'created': u'2014-08-24T11:26:48Z'}} - >>> + {u'error': {u'lang': u'en-US', u'description': u'No definition found for Table yahoo.finance.quotes'}} or -:: +.. code:: python >>> import myql - >>> yql = myql.MYQL(community=True) + >>> yql = myql.MYQL(community=False) >>> # do your magic Changing response format (xml or json) @@ -65,7 +86,7 @@ Changing response format (xml or json) The response format is by default ***json***. -:: +.. code:: python >>> import myql >>> yql = myql.MYQL(format='xml', community=True) @@ -85,7 +106,7 @@ use(yql\_table\_url,name=yql\_table\_name) Changes the data provider -:: +.. code:: python >>> yql.use('http://www.josuebrunel.org//users.xml', name='myusers') @@ -94,7 +115,7 @@ desc(tablename) Returns table description -:: +.. code:: python >>> response = yql.desc('weather.forecast') >>> response.json() @@ -106,7 +127,7 @@ rawQuery(query) Allows you to directly type your query -:: +.. code:: python >>> response = yql.rawQuery("select * from geo.countries where place='North America'") >>> # deal with the response @@ -121,7 +142,7 @@ will raise a *NoTableSelectedError* ***NB*** : A simple select doesn't return any data. Use ***GET*** instead. -:: +.. code:: python >>> response = yql.select('geo.countries', [name, code, woeid]).where(['name', '=', 'Canada']) >>> response.json() @@ -145,7 +166,7 @@ Same as ***SELECT***, but instead returns data. ***GET*** won't work on those tables, use *select(...).where(...)* instead . -:: +.. code:: python >>> yql.get('geo.countries', ['name', 'woeid'], 1) >>> rep.json() @@ -158,10 +179,11 @@ insert(table, (field1, field2, ..., fieldN),(value1, value2, ..., valueN)) Insert values into a table. Arguments 2 and 3 may be **tuples** or **list**. -:: +.. code:: python + >>> from myql.utils import pretty_json >>> response = yql.insert('yql.storage.admin',('value',),('http://josuebrunel.org',)) - >>> response.json() # result prettyfied just for the example + >>> print(pretty_json(response.content)) { "query": { "count": 1, @@ -183,10 +205,11 @@ update(table,[field1, ..., fieldN],[value1, ..., ...valueN]).where(filters, ...) Update fields values. This method **is always followed by ***where()*****. Arguments 2 and 3 may be **tuples** or **list**. -:: +.. code:: python + >>> from myql.utils import pretty_json >>> response = yql.update('yql.storage',('value',),('https://josuebrunel.org',)).where(['name','=','store://Rqb5fbQyDvrfHJiClWnZ6q']) - >>> response.json() # result prettyfied just for the example + >>> print(pretty_json(response.content)) { "query": { "count": 1, @@ -203,10 +226,11 @@ delete(table).where(filters, ...) Delete records -:: +.. code:: python + >>> from myql.utils import pretty_json >>> response = self.yql.delete('yql.storage').where(['name','=','store://Rqb5fbQyDvrfHJiClWnZ6q']) - >>> response.json() # result prettyfied just for the example + >>> print(pretty_json(response.content)) { "query": { "count": 1, @@ -221,7 +245,7 @@ Delete records Using OAuth to fetch protected resources ======================================== -:: +.. code:: python >>> from myql.contrib.auth import YOAuth >>> oauth = YOAuth(None, None, from_file='credentials.json') # only consumer_key and consumer_secret are required. @@ -229,12 +253,84 @@ Using OAuth to fetch protected resources >>> yql = MYQL(format='xml', oauth=oauth) >>> response = yql.getGUID('josue_brunel') # Deal with the response -` `__\ Next - --------------- - -Built with `MkDocs `__ using a -`theme `__ provided by `Read -the Docs `__. +Release Notes +^^^^^^^^^^^^^ + +##### 1.2.3 +----------- + +- Fixed issue related to date in StockRetriver.get\_historical\_info + `#107 `__ +- Fixed issue with **IN** condition in **where** clause + `#106 `__ +- Fix definition of raw\_input for python3 + `#105 `__ + +##### 1.2.2 +----------- + +- **Python3** support OK + `#71 `__ +- **PyPy/PyPy3** support OK +- Fixed issue with **IN** condition in **where** clause +- Fixed issue when passing an empty list/tuple (**[]/()**) in a + **where** clause besides first argument +- Import of + ***`StockParser `__*** from + Gurchet Rai OK + `#68 `__ +- Insert, Update, Delete methods added + `#67 `__ +- Dummy *try/except* removed from main module +- Fixed **Invalid OAuth Signature** when using a refreshed token + `#64 `__ +- Fixed misused of ***MYQL.use(...)*** + `#76 `__ +- Fixed format issue + `#82 `__ +- Added useful functions in utils + `#81 `__ +- Default access to community tables +- Response prettyfier : *pretty\_json, pretty\_xml* + +##### v 1.2.1 +------------- + +- Multiple requests while using OAuth fixed + +##### 1.2.0 +----------- + +- OpenTable classes +- Access to resources requiring authentication + +##### 0.5.6 +----------- + +- fetch data +- access to community data +- select data format (xml/json) +- change data source +- filter data +- fix handling of default response format on the fly +- fix limit on ***select(...).where(...)*** when no limit value is + passed +- fix limit on ***get(...)*** + +.. |Build Status| image:: https://travis-ci.org/josuebrunel/myql.svg?branch=master + :target: https://travis-ci.org/josuebrunel/myql +.. |Documentation Status| image:: https://readthedocs.org/projects/myql/badge/?version=latest + :target: https://myql.readthedocs.org +.. |Latest Version| image:: https://pypip.in/version/myql/badge.svg + :target: https://pypi.python.org/pypi/myql/ +.. |Downloads| image:: https://pypip.in/download/myql/badge.svg + :target: https://pypi.python.org/pypi/myql +.. |Py\_Versions| image:: https://pypip.in/py_versions/myql/badge.svg + :target: https://pypi.python.org/pypi/myql +.. |Implementations| image:: https://pypip.in/implementation/myql/badge.svg + :target: https://pypi.python.org/pypi/myql +.. |Join the chat at https://gitter.im/josuebrunel/myql| image:: https://badges.gitter.im/Join%20Chat.svg + :target: https://gitter.im/josuebrunel/myql?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge +.. |Code Issues| image:: https://www.quantifiedcode.com/project/gh:josuebrunel:myql/badge.svg + :target: https://www.quantifiedcode.com/app/project/gh:josuebrunel:myql -GitHub `« Previous <>`__ `Next » `__