From 454a41fe94b08ca93ae04b9b580cf2ff51e2fa75 Mon Sep 17 00:00:00 2001 From: Virendra Rajput Date: Sun, 31 Mar 2013 21:23:16 +0530 Subject: [PATCH 01/20] added the missing slash in "getMentionsTimeline" was unable to fetch mentions because of the missing slash and the missing '.json' --- twython/twitter_endpoints.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/twython/twitter_endpoints.py b/twython/twitter_endpoints.py index 03c418a..5f79e66 100644 --- a/twython/twitter_endpoints.py +++ b/twython/twitter_endpoints.py @@ -21,7 +21,7 @@ base_url = 'http://api.twitter.com/{{version}}' api_table = { # Timelines 'getMentionsTimeline': { - 'url': 'statuses/mentions_timeline', + 'url': '/statuses/mentions_timeline.json', 'method': 'GET', }, 'getUserTimeline': { From a6afb2cf5ce1a2f6c5750f0b4dd43ea260acf8c7 Mon Sep 17 00:00:00 2001 From: Mike Helmick Date: Sun, 31 Mar 2013 12:38:07 -0400 Subject: [PATCH 02/20] Version bump! --- setup.py | 2 +- twython/twython.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 94d4006..e6d49c9 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup from setuptools import find_packages __author__ = 'Ryan McGrath ' -__version__ = '2.6.0' +__version__ = '2.6.1' setup( # Basic package information. diff --git a/twython/twython.py b/twython/twython.py index 29b7418..93c5c42 100644 --- a/twython/twython.py +++ b/twython/twython.py @@ -7,7 +7,7 @@ """ __author__ = "Ryan McGrath " -__version__ = "2.6.0" +__version__ = "2.6.1" import urllib import re From 7d1ffefc45a7f29877034c0fe2a95ab00a26d5ac Mon Sep 17 00:00:00 2001 From: Mike Helmick Date: Thu, 4 Apr 2013 14:44:05 -0400 Subject: [PATCH 03/20] Fixes #158, #159, #160 --- twython/twython.py | 40 ++++++++++++++++------------------------ 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/twython/twython.py b/twython/twython.py index 93c5c42..09b2783 100644 --- a/twython/twython.py +++ b/twython/twython.py @@ -99,7 +99,6 @@ class Twython(object): self.api_url = 'https://api.twitter.com/%s' self.request_token_url = self.api_url % 'oauth/request_token' self.access_token_url = self.api_url % 'oauth/access_token' - self.authorize_url = self.api_url % 'oauth/authorize' self.authenticate_url = self.api_url % 'oauth/authenticate' # Enforce unicode on keys and secrets @@ -265,8 +264,11 @@ class Twython(object): return self._last_call['headers'][header] return self._last_call - def get_authentication_tokens(self): + def get_authentication_tokens(self, force_login=False, screen_name=''): """Returns an authorization URL for a user to hit. + + :param force_login: (optional) Forces the user to enter their credentials to ensure the correct users account is authorized. + :param app_secret: (optional) If forced_login is set OR user is not currently logged in, Prefills the username input box of the OAuth login screen with the given value """ request_args = {} if self.callback_url: @@ -287,6 +289,12 @@ class Twython(object): 'oauth_token': request_tokens['oauth_token'], } + if force_login: + auth_url_params.update({ + 'force_login': force_login, + 'screen_name': screen_name + }) + # Use old-style callback argument if server didn't accept new-style if self.callback_url and not oauth_callback_confirmed: auth_url_params['oauth_callback'] = self.callback_url @@ -453,28 +461,12 @@ class Twython(object): ########################################################################### def getProfileImageUrl(self, username, size='normal', version='1'): - """Gets the URL for the user's profile image. - - :param username: (required) Username, self explanatory. - :param size: (optional) Default 'normal' (48px by 48px) - bigger - 73px by 73px - mini - 24px by 24px - original - undefined, be careful -- images may be - large in bytes and/or size. - :param version: (optional) A number, default 1 because that's the - only API version for Twitter that supports this call - """ - endpoint = 'users/profile_image/%s' % username - url = self.api_url % version + '/' + endpoint - - response = self.client.get(url, params={'size': size}, allow_redirects=False) - image_url = response.headers.get('location') - - if response.status_code in (301, 302, 303, 307) and image_url is not None: - return image_url - else: - raise TwythonError('getProfileImageUrl() threw an error.', - error_code=response.status_code) + warnings.warn( + "This function has been deprecated. Twitter API v1.1 will not have a dedicated endpoint \ + for this functionality.", + DeprecationWarning, + stacklevel=2 + ) @staticmethod def stream(data, callback): From fffedd4588a73c85032c09227af6c6e2ca5857c7 Mon Sep 17 00:00:00 2001 From: Mike Helmick Date: Thu, 4 Apr 2013 14:52:32 -0400 Subject: [PATCH 04/20] Version bump --- setup.py | 2 +- twython/twython.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index e6d49c9..a6bf312 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup from setuptools import find_packages __author__ = 'Ryan McGrath ' -__version__ = '2.6.1' +__version__ = '2.7.0' setup( # Basic package information. diff --git a/twython/twython.py b/twython/twython.py index 09b2783..cddf739 100644 --- a/twython/twython.py +++ b/twython/twython.py @@ -7,7 +7,7 @@ """ __author__ = "Ryan McGrath " -__version__ = "2.6.1" +__version__ = "2.7.0" import urllib import re From e65790d7170c97c120dd6037102358c276907f45 Mon Sep 17 00:00:00 2001 From: Mike Helmick Date: Thu, 4 Apr 2013 14:52:54 -0400 Subject: [PATCH 05/20] New showOwnedLists method Returns the lists owned by the specified Twitter user. Private lists will only be shown if the authenticated user is also the owner of the lists. --- twython/twitter_endpoints.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/twython/twitter_endpoints.py b/twython/twitter_endpoints.py index 5f79e66..ff78779 100644 --- a/twython/twitter_endpoints.py +++ b/twython/twitter_endpoints.py @@ -320,6 +320,10 @@ api_table = { 'url': '/lists/members/destroy_all.json', 'method': 'POST' }, + 'showOwnedLists': { + 'url': '/lists/ownerships.json', + 'method': 'GET' + }, # Saved Searches From 99a6dccbce2fea77689475b18b411f49cc97d076 Mon Sep 17 00:00:00 2001 From: Paul Date: Fri, 5 Apr 2013 00:12:54 +0200 Subject: [PATCH 06/20] added oauth_verifier arg --- twython/twython.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/twython/twython.py b/twython/twython.py index cddf739..cd724a3 100644 --- a/twython/twython.py +++ b/twython/twython.py @@ -81,7 +81,7 @@ class TwythonRateLimitError(TwythonError): class Twython(object): - def __init__(self, app_key=None, app_secret=None, oauth_token=None, oauth_token_secret=None, \ + def __init__(self, app_key=None, app_secret=None, oauth_token=None, oauth_token_secret=None, oauth_verifier=None, \ headers=None, callback_url=None, twitter_token=None, twitter_secret=None, proxies=None, version='1.1'): """Instantiates an instance of Twython. Takes optional parameters for authentication and such (see below). @@ -110,6 +110,8 @@ class Twython(object): self.callback_url = callback_url + self.oauth_verifier = oauth_verifier + # If there's headers, set them, otherwise be an embarassing parent for their own good. self.headers = headers or {'User-Agent': 'Twython v' + __version__} @@ -306,7 +308,7 @@ class Twython(object): def get_authorized_tokens(self): """Returns authorized tokens after they go through the auth_url phase. """ - response = self.client.get(self.access_token_url) + response = self.client.get(self.access_token_url,params={'oauth_verifier' : self.oauth_verifier}) authorized_tokens = dict(parse_qsl(response.content)) if not authorized_tokens: raise TwythonError('Unable to decode authorized tokens.') From 26b3a232d0be46ce17920bca287260ec8eca43bc Mon Sep 17 00:00:00 2001 From: hansenrum Date: Fri, 5 Apr 2013 00:25:23 +0200 Subject: [PATCH 07/20] oauth_verifier fix --- twython/twython.py | 1 - 1 file changed, 1 deletion(-) diff --git a/twython/twython.py b/twython/twython.py index cd724a3..e9f701c 100644 --- a/twython/twython.py +++ b/twython/twython.py @@ -109,7 +109,6 @@ class Twython(object): self.oauth_token_secret = oauth_token_secret and u'%s' % oauth_token_secret self.callback_url = callback_url - self.oauth_verifier = oauth_verifier # If there's headers, set them, otherwise be an embarassing parent for their own good. From 1eb1bd080d88e35b13de355926e64a14ebe767a7 Mon Sep 17 00:00:00 2001 From: hansenrum Date: Fri, 5 Apr 2013 18:36:58 +0200 Subject: [PATCH 08/20] moved oauth_verifier from init to method --- twython/twython.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/twython/twython.py b/twython/twython.py index e9f701c..2e27ee5 100644 --- a/twython/twython.py +++ b/twython/twython.py @@ -81,7 +81,7 @@ class TwythonRateLimitError(TwythonError): class Twython(object): - def __init__(self, app_key=None, app_secret=None, oauth_token=None, oauth_token_secret=None, oauth_verifier=None, \ + def __init__(self, app_key=None, app_secret=None, oauth_token=None, oauth_token_secret=None, \ headers=None, callback_url=None, twitter_token=None, twitter_secret=None, proxies=None, version='1.1'): """Instantiates an instance of Twython. Takes optional parameters for authentication and such (see below). @@ -109,7 +109,6 @@ class Twython(object): self.oauth_token_secret = oauth_token_secret and u'%s' % oauth_token_secret self.callback_url = callback_url - self.oauth_verifier = oauth_verifier # If there's headers, set them, otherwise be an embarassing parent for their own good. self.headers = headers or {'User-Agent': 'Twython v' + __version__} @@ -304,10 +303,10 @@ class Twython(object): return request_tokens - def get_authorized_tokens(self): + def get_authorized_tokens(self, oauth_verifier): """Returns authorized tokens after they go through the auth_url phase. """ - response = self.client.get(self.access_token_url,params={'oauth_verifier' : self.oauth_verifier}) + response = self.client.get(self.access_token_url, params={'oauth_verifier' : oauth_verifier}) authorized_tokens = dict(parse_qsl(response.content)) if not authorized_tokens: raise TwythonError('Unable to decode authorized tokens.') From abaa3e558a75d225a31d5ad1df93a459361334f9 Mon Sep 17 00:00:00 2001 From: Mike Helmick Date: Mon, 8 Apr 2013 11:49:12 -0400 Subject: [PATCH 09/20] oauth_verifier required, remove simplejson dependency, update endpoint * Update `updateProfileBannerImage` to use the v1.1 endpoint * Added `getProfileBannerSizes` method using the GET /users/profile_banner.json endpoint * Fixed a couple of endpoints using variable in the url: * destroyDirectMessage, createBlock, destroyBlock no longer use id in their urls, this shouldn't break anything though. (t.destroyDirectMessage(id=123) should still work) * `oauth_verifier` is now **required** when calling `get_authorized_tokens` * Updated docs - removed getProfileImageUrl docs since it is deprecated. Noted since `Twython` 2.7.0 that users should focus on migrating to v1.1 endpoints since Twitter is deprecating v1 endpoints in May!, --- README.md | 18 +++++------------- README.rst | 17 +++++------------ setup.py | 2 +- twython/twitter_endpoints.py | 12 ++++++++---- twython/twython.py | 24 ++++++++---------------- 5 files changed, 27 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index c3fcca5..cbf80d1 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Features - Twitter lists - Timelines - User avatar URL - - and anything found in [the docs](https://dev.twitter.com/docs/api) + - and anything found in [the docs](https://dev.twitter.com/docs/api/1.1) * Image Uploading! - **Update user status with an image** - Change user avatar @@ -57,7 +57,7 @@ from twython import Twython ''' oauth_token and oauth_token_secret come from the previous step -if needed, store those in a session variable or something +if needed, store those in a session variable or something. oauth_verifier from the previous call is now required to pass to get_authorized_tokens ''' t = Twython(app_key=app_key, @@ -65,7 +65,7 @@ t = Twython(app_key=app_key, oauth_token=oauth_token, oauth_token_secret=oauth_token_secret) -auth_tokens = t.get_authorized_tokens() +auth_tokens = t.get_authorized_tokens(oauth_verifier) print auth_tokens ``` @@ -90,16 +90,6 @@ t = Twython(app_key=app_key, print t.getHomeTimeline() ``` -###### Get a user avatar url *(no authentication needed)* - -```python -from twython import Twython - -t = Twython() -print t.getProfileImageUrl('ryanmcgrath', size='bigger') -print t.getProfileImageUrl('mikehelmick') -``` - ###### Streaming API *Usage is as follows; it's designed to be open-ended enough that you can adapt it to higher-level (read: Twitter must give you access) streams.* @@ -122,6 +112,8 @@ Twython.stream({ Notes ----- +Twython (as of 2.7.0) is currently in the process of ONLY supporting Twitter v1.1 endpoints and deprecating all v1 endpoints! Please see the **[Twitter v1.1 API Documentation](https://dev.twitter.com/docs/api/1.1)** to help migrate your API calls! + As of Twython 2.0.0, we have changed routes for functions to abide by the **[Twitter Spring 2012 clean up](https://dev.twitter.com/docs/deprecations/spring-2012)** Please make changes to your code accordingly. Development of Twython (specifically, 1.3) diff --git a/README.rst b/README.rst index 1bb6677..02cfa0a 100644 --- a/README.rst +++ b/README.rst @@ -10,7 +10,7 @@ Features - Twitter lists - Timelines - User avatar URL - - and anything found in `the docs `_ + - and anything found in `the docs `_ * Image Uploading! - **Update user status with an image** - Change user avatar @@ -58,7 +58,7 @@ Handling the callback ''' oauth_token and oauth_token_secret come from the previous step - if needed, store those in a session variable or something + if needed, store those in a session variable or something. oauth_verifier from the previous call is now required to pass to get_authorized_tokens ''' from twython import Twython @@ -67,7 +67,7 @@ Handling the callback oauth_token=oauth_token, oauth_token_secret=oauth_token_secret) - auth_tokens = t.get_authorized_tokens() + auth_tokens = t.get_authorized_tokens(oauth_verifier) print auth_tokens *Function definitions (i.e. getHomeTimeline()) can be found by reading over twython/twitter_endpoints.py* @@ -90,15 +90,6 @@ Getting a user home timeline # Returns an dict of the user home timeline print t.getHomeTimeline() -Get a user avatar url *(no authentication needed)* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -:: - - from twython import Twython - - t = Twython() - print t.getProfileImageUrl('ryanmcgrath', size='bigger') - print t.getProfileImageUrl('mikehelmick') Streaming API ~~~~~~~~~~~~~ @@ -124,6 +115,8 @@ streams.* Notes ----- +* Twython (as of 2.7.0) is currently in the process of ONLY supporting Twitter v1.1 endpoints and deprecating all v1 endpoints! Please see the `Twitter API Documentation `_ to help migrate your API calls! + * As of Twython 2.0.0, we have changed routes for functions to abide by the `Twitter Spring 2012 clean up `_ Please make changes to your code accordingly. diff --git a/setup.py b/setup.py index a6bf312..d8f6863 100644 --- a/setup.py +++ b/setup.py @@ -14,7 +14,7 @@ setup( include_package_data=True, # Package dependencies. - install_requires=['simplejson', 'requests>=1.0.0, <2.0.0', 'requests_oauthlib==0.3.0'], + install_requires=['requests>=1.0.0, <2.0.0', 'requests_oauthlib==0.3.0'], # Metadata for PyPI. author='Ryan McGrath', diff --git a/twython/twitter_endpoints.py b/twython/twitter_endpoints.py index ff78779..d946b25 100644 --- a/twython/twitter_endpoints.py +++ b/twython/twitter_endpoints.py @@ -9,7 +9,7 @@ will be replaced with the keyword that gets passed in to the function at call time. i.e, in this case, if I pass version = 47 to any function, {{version}} will be replaced - with 47, instead of defaulting to 1 (said defaulting takes place at conversion time). + with 47, instead of defaulting to 1.1 (said defaulting takes place at conversion time). This map is organized the order functions are documented at: https://dev.twitter.com/docs/api/1.1 @@ -87,7 +87,7 @@ api_table = { 'method': 'GET', }, 'destroyDirectMessage': { - 'url': '/direct_messages/destroy/{{id}}.json', + 'url': '/direct_messages/destroy.json', 'method': 'POST', }, 'sendDirectMessage': { @@ -183,11 +183,11 @@ api_table = { 'method': 'GET', }, 'createBlock': { - 'url': '/blocks/create/{{id}}.json', + 'url': '/blocks/create.json', 'method': 'POST', }, 'destroyBlock': { - 'url': '/blocks/destroy/{{id}}.json', + 'url': '/blocks/destroy.json', 'method': 'POST', }, 'lookupUser': { @@ -215,6 +215,10 @@ api_table = { 'method': 'POST', }, # See twython.py for update_profile_banner + 'getProfileBannerSizes': { + 'url': '/users/profile_banner.json', + 'method': 'GET', + }, # Suggested Users diff --git a/twython/twython.py b/twython/twython.py index 2e27ee5..b189d3f 100644 --- a/twython/twython.py +++ b/twython/twython.py @@ -26,17 +26,9 @@ except ImportError: from twitter_endpoints import base_url, api_table, twitter_http_status_codes try: - import simplejson + import simplejson as json except ImportError: - try: - # Python 2.6 and up - import json as simplejson - except ImportError: - try: - from django.utils import simplejson - except: - # Seriously wtf is wrong with you if you get this Exception. - raise Exception("Twython requires the simplejson library (or Python 2.6) to work. http://www.undefined.org/python/") + import json class TwythonError(Exception): @@ -194,7 +186,7 @@ class Twython(object): # why? twitter will return invalid json with an error code in the headers json_error = False try: - content = simplejson.loads(content) + content = content.json() except ValueError: json_error = True content = {} @@ -437,13 +429,13 @@ class Twython(object): **params - You may pass items that are taken in this doc (https://dev.twitter.com/docs/api/1.1/post/statuses/update_with_media) """ - subdomain = 'upload' if version == '1' else 'api' - url = 'https://%s.twitter.com/%s/statuses/update_with_media.json' % (subdomain, version) + + url = 'https://api.twitter.com/%s/statuses/update_with_media.json' % version return self._media_update(url, {'media': (file_, open(file_, 'rb'))}, **params) - def updateProfileBannerImage(self, file_, version=1, **params): + def updateProfileBannerImage(self, file_, version='1.1', **params): """Updates the users profile banner :param file_: (required) A string to the location of the file @@ -453,7 +445,7 @@ class Twython(object): **params - You may pass items that are taken in this doc (https://dev.twitter.com/docs/api/1/post/account/update_profile_banner) """ - url = 'https://api.twitter.com/%d/account/update_profile_banner.json' % version + url = 'https://api.twitter.com/%s/account/update_profile_banner.json' % version return self._media_update(url, {'banner': (file_, open(file_, 'rb'))}, **params) @@ -518,7 +510,7 @@ class Twython(object): for line in stream.iter_lines(): if line: try: - callback(simplejson.loads(line)) + callback(json.loads(line)) except ValueError: raise TwythonError('Response was not valid JSON, unable to decode.') From 4a181d3ac14ef41abff46cec9298044787791d8b Mon Sep 17 00:00:00 2001 From: Mike Helmick Date: Mon, 8 Apr 2013 11:51:34 -0400 Subject: [PATCH 10/20] Version bump! --- setup.py | 2 +- twython/twython.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index d8f6863..ceb205f 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup from setuptools import find_packages __author__ = 'Ryan McGrath ' -__version__ = '2.7.0' +__version__ = '2.7.1' setup( # Basic package information. diff --git a/twython/twython.py b/twython/twython.py index b189d3f..aff9967 100644 --- a/twython/twython.py +++ b/twython/twython.py @@ -7,7 +7,7 @@ """ __author__ = "Ryan McGrath " -__version__ = "2.7.0" +__version__ = "2.7.1" import urllib import re From 6a3539882caf500e1287c0f71d107a4db1a45862 Mon Sep 17 00:00:00 2001 From: Virendra Rajput Date: Mon, 8 Apr 2013 22:59:27 +0530 Subject: [PATCH 11/20] Update twython.py if unicode object is detected, convert it to json using simplejson/json --- twython/twython.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/twython/twython.py b/twython/twython.py index aff9967..afd968b 100644 --- a/twython/twython.py +++ b/twython/twython.py @@ -186,7 +186,12 @@ class Twython(object): # why? twitter will return invalid json with an error code in the headers json_error = False try: - content = content.json() + try: + # try to get json + content = content.json() + except AttributeError: + # if unicode detected + content = json.loads(content) except ValueError: json_error = True content = {} From 10dbe11b565aaa824d3ebc5d0c787072e6b9cbc6 Mon Sep 17 00:00:00 2001 From: Mike Helmick Date: Mon, 8 Apr 2013 16:40:59 -0400 Subject: [PATCH 12/20] Version bump and update contributors! --- README.md | 1 + README.rst | 1 + setup.py | 2 +- twython/twython.py | 2 +- 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cbf80d1..b5f5d82 100644 --- a/README.md +++ b/README.md @@ -187,3 +187,4 @@ me and let me know (or just issue a pull request on GitHub, and leave a note abo - **[terrycojones](https://github.com/terrycojones)**, Error cleanup and Exception processing in 2.3.0. - **[Leandro Ferreira](https://github.com/leandroferreira)**, Fix for double-encoding of search queries in 2.3.0. - **[Chris Brown](https://github.com/chbrown)**, Updated to use v1.1 endpoints over v1 +- **[Virendra Rajput](https://github.com/bkvirendra)**, Fixed unicode (json) encoding in twython.py 2.7.2. diff --git a/README.rst b/README.rst index 02cfa0a..cca5a26 100644 --- a/README.rst +++ b/README.rst @@ -194,3 +194,4 @@ me and let me know (or just issue a pull request on GitHub, and leave a note abo - `terrycojones `_, Error cleanup and Exception processing in 2.3.0. - `Leandro Ferreira `_, Fix for double-encoding of search queries in 2.3.0. - `Chris Brown `_, Updated to use v1.1 endpoints over v1 +- `Virendra Rajput `_, Fixed unicode (json) encoding in twython.py 2.7.2. diff --git a/setup.py b/setup.py index ceb205f..198584c 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup from setuptools import find_packages __author__ = 'Ryan McGrath ' -__version__ = '2.7.1' +__version__ = '2.7.2' setup( # Basic package information. diff --git a/twython/twython.py b/twython/twython.py index afd968b..b3c50b0 100644 --- a/twython/twython.py +++ b/twython/twython.py @@ -7,7 +7,7 @@ """ __author__ = "Ryan McGrath " -__version__ = "2.7.1" +__version__ = "2.7.2" import urllib import re From 8dfb076f11ef9806c9dfa34b97c1a90a2b75751e Mon Sep 17 00:00:00 2001 From: Mike Helmick Date: Wed, 10 Apr 2013 23:08:43 -0400 Subject: [PATCH 13/20] Update authors --- README.md | 1 + README.rst | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index b5f5d82..c1119d2 100644 --- a/README.md +++ b/README.md @@ -188,3 +188,4 @@ me and let me know (or just issue a pull request on GitHub, and leave a note abo - **[Leandro Ferreira](https://github.com/leandroferreira)**, Fix for double-encoding of search queries in 2.3.0. - **[Chris Brown](https://github.com/chbrown)**, Updated to use v1.1 endpoints over v1 - **[Virendra Rajput](https://github.com/bkvirendra)**, Fixed unicode (json) encoding in twython.py 2.7.2. +- **[Paul Solbach](https://github.com/hansenrum)**, fixed requirement for oauth_verifier diff --git a/README.rst b/README.rst index cca5a26..5267099 100644 --- a/README.rst +++ b/README.rst @@ -195,3 +195,4 @@ me and let me know (or just issue a pull request on GitHub, and leave a note abo - `Leandro Ferreira `_, Fix for double-encoding of search queries in 2.3.0. - `Chris Brown `_, Updated to use v1.1 endpoints over v1 - `Virendra Rajput `_, Fixed unicode (json) encoding in twython.py 2.7.2. +- `Paul Solbach `_, fixed requirement for oauth_verifier From 12eb1610c895357da49b759bb4bea2f1f44097ce Mon Sep 17 00:00:00 2001 From: Greg Nofi Date: Thu, 11 Apr 2013 19:42:16 -0400 Subject: [PATCH 14/20] Use built-in Exception attributes for storing and retrieving error message. Keeping msg as a property so it's backwards compatible. Note that this only fixes Python 2.x --- twython/twython.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/twython/twython.py b/twython/twython.py index b3c50b0..aca83fd 100644 --- a/twython/twython.py +++ b/twython/twython.py @@ -42,17 +42,18 @@ class TwythonError(Exception): from twython import TwythonError, TwythonAPILimit, TwythonAuthError """ def __init__(self, msg, error_code=None, retry_after=None): - self.msg = msg self.error_code = error_code if error_code is not None and error_code in twitter_http_status_codes: - self.msg = '%s: %s -- %s' % \ - (twitter_http_status_codes[error_code][0], - twitter_http_status_codes[error_code][1], - self.msg) + msg = '%s: %s -- %s' % (twitter_http_status_codes[error_code][0], + twitter_http_status_codes[error_code][1], + msg) - def __str__(self): - return repr(self.msg) + super(TwythonError, self).__init__(msg) + + @property + def msg(self): + return self.args[0] class TwythonAuthError(TwythonError): @@ -67,9 +68,9 @@ class TwythonRateLimitError(TwythonError): retry_wait_seconds is the number of seconds to wait before trying again. """ def __init__(self, msg, error_code, retry_after=None): - TwythonError.__init__(self, msg, error_code=error_code) if isinstance(retry_after, int): - self.msg = '%s (Retry after %d seconds)' % (msg, retry_after) + msg = '%s (Retry after %d seconds)' % (msg, retry_after) + TwythonError.__init__(self, msg, error_code=error_code) class Twython(object): From 7469f8bc739fa28fde7644bd2743bb8bc5511841 Mon Sep 17 00:00:00 2001 From: Mike Helmick Date: Fri, 12 Apr 2013 11:17:40 -0400 Subject: [PATCH 15/20] Fixes #175, #177 * Auth Errors are thrown in the correct spots * Error messages are a lot cleaner than before and correspond with error codes on https://dev.twitter.com/docs/error-codes-responses --- twython/twitter_endpoints.py | 5 ++++- twython/twython.py | 40 +++++++++++++++++++++--------------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/twython/twitter_endpoints.py b/twython/twitter_endpoints.py index d946b25..1c0d8a0 100644 --- a/twython/twitter_endpoints.py +++ b/twython/twitter_endpoints.py @@ -404,8 +404,11 @@ twitter_http_status_codes = { 403: ('Forbidden', 'The request is understood, but it has been refused. An accompanying error message will explain why. This code is used when requests are being denied due to update limits.'), 404: ('Not Found', 'The URI requested is invalid or the resource requested, such as a user, does not exists.'), 406: ('Not Acceptable', 'Returned by the Search API when an invalid format is specified in the request.'), - 420: ('Enhance Your Calm', 'Returned by the Search and Trends API when you are being rate limited.'), + 410: ('Gone', 'This resource is gone. Used to indicate that an API endpoint has been turned off.'), + 422: ('Unprocessable Entity', 'Returned when an image uploaded to POST account/update_profile_banner is unable to be processed.'), + 429: ('Too Many Requests', 'Returned in API v1.1 when a request cannot be served due to the application\'s rate limit having been exhausted for the resource.'), 500: ('Internal Server Error', 'Something is broken. Please post to the group so the Twitter team can investigate.'), 502: ('Bad Gateway', 'Twitter is down or being upgraded.'), 503: ('Service Unavailable', 'The Twitter servers are up, but overloaded with requests. Try again later.'), + 504: ('Gateway Timeout', 'The Twitter servers are up, but the request couldn\'t be serviced due to some failure within our stack. Try again later.'), } diff --git a/twython/twython.py b/twython/twython.py index aca83fd..07be9a9 100644 --- a/twython/twython.py +++ b/twython/twython.py @@ -39,15 +39,15 @@ class TwythonError(Exception): Note: To use these, the syntax has changed as of Twython 1.3. To catch these, you need to explicitly import them into your code, e.g: - from twython import TwythonError, TwythonAPILimit, TwythonAuthError + from twython import TwythonError, TwythonRateLimitError, TwythonAuthError """ def __init__(self, msg, error_code=None, retry_after=None): self.error_code = error_code if error_code is not None and error_code in twitter_http_status_codes: - msg = '%s: %s -- %s' % (twitter_http_status_codes[error_code][0], - twitter_http_status_codes[error_code][1], - msg) + msg = 'Twitter API returned a %s (%s), %s' % (error_code, + twitter_http_status_codes[error_code][0], + msg) super(TwythonError, self).__init__(msg) @@ -74,8 +74,8 @@ class TwythonRateLimitError(TwythonError): class Twython(object): - def __init__(self, app_key=None, app_secret=None, oauth_token=None, oauth_token_secret=None, \ - headers=None, callback_url=None, twitter_token=None, twitter_secret=None, proxies=None, version='1.1'): + def __init__(self, app_key=None, app_secret=None, oauth_token=None, oauth_token_secret=None, + headers=None, callback_url=None, twitter_token=None, twitter_secret=None, proxies=None, version='1.1'): """Instantiates an instance of Twython. Takes optional parameters for authentication and such (see below). :param app_key: (optional) Your applications key @@ -199,14 +199,21 @@ class Twython(object): if response.status_code > 304: # If there is no error message, use a default. - error_msg = content.get( - 'error', 'An error occurred processing your request.') - self._last_call['api_error'] = error_msg + errors = content.get('errors', + [{'message': 'An error occurred processing your request.'}]) + error_message = errors[0]['message'] + self._last_call['api_error'] = error_message - #Twitter API 1.1 , always return 429 when rate limit is exceeded - exceptionType = TwythonRateLimitError if response.status_code == 429 else TwythonError + ExceptionType = TwythonError + if response.status_code == 429: + # Twitter API 1.1, always return 429 when rate limit is exceeded + ExceptionType = TwythonRateLimitError + elif response.status_code == 401 or 'Bad Authentication data' in error_message: + # Twitter API 1.1, returns a 401 Unauthorized or + # a 400 "Bad Authentication data" for invalid/expired app keys/user tokens + ExceptionType = TwythonAuthError - raise exceptionType(error_msg, + raise ExceptionType(error_message, error_code=response.status_code, retry_after=response.headers.get('retry-after')) @@ -273,9 +280,10 @@ class Twython(object): request_args['oauth_callback'] = self.callback_url response = self.client.get(self.request_token_url, params=request_args) - - if response.status_code != 200: - raise TwythonAuthError("Seems something couldn't be verified with your OAuth junk. Error: %s, Message: %s" % (response.status_code, response.content)) + if response.status_code == 401: + raise TwythonAuthError(response.content, error_code=response.status_code) + elif response.status_code != 200: + raise TwythonError(response.content, error_code=response.status_code) request_tokens = dict(parse_qsl(response.content)) if not request_tokens: @@ -304,7 +312,7 @@ class Twython(object): def get_authorized_tokens(self, oauth_verifier): """Returns authorized tokens after they go through the auth_url phase. """ - response = self.client.get(self.access_token_url, params={'oauth_verifier' : oauth_verifier}) + response = self.client.get(self.access_token_url, params={'oauth_verifier': oauth_verifier}) authorized_tokens = dict(parse_qsl(response.content)) if not authorized_tokens: raise TwythonError('Unable to decode authorized tokens.') From 969c0f5e72344e814f52959935f75e24f0ddcd87 Mon Sep 17 00:00:00 2001 From: Mike Helmick Date: Fri, 12 Apr 2013 11:28:58 -0400 Subject: [PATCH 16/20] Move AUTHORS into their own file remove README md as well, see how the rst looks --- AUTHORS.rst | 39 +++++++++++++++++++++++++++++++++++++++ README.md | 34 ---------------------------------- README.rst | 35 ----------------------------------- 3 files changed, 39 insertions(+), 69 deletions(-) create mode 100644 AUTHORS.rst diff --git a/AUTHORS.rst b/AUTHORS.rst new file mode 100644 index 0000000..34f03b8 --- /dev/null +++ b/AUTHORS.rst @@ -0,0 +1,39 @@ +Special Thanks +-------------- +This is a list of all those who have contributed code to Twython in some way, shape, or form. I think it's +exhaustive, but I could be wrong - if you think your name should be here and it's not, please contact +me and let me know (or just issue a pull request on GitHub, and leave a note about it so I can just accept it ;). + +Development Lead +```````````````` + +- Ryan Mcgrath + + +Patches and Suggestions +```````````````````````` + +- `Mike Helmick `_, multiple fixes and proper ``requests`` integration. Too much to list here. +- `kracekumar `_, early ``requests`` work and various fixes. +- `Erik Scheffers `_, various fixes regarding OAuth callback URLs. +- `Jordan Bouvier `_, various fixes regarding OAuth callback URLs. +- `Dick Brouwer `_, fixes for OAuth Verifier in ``get_authorized_tokens``. +- `hades `_, Fixes to various initial OAuth issues and keeping ``Twython3k`` up-to-date. +- `Alex Sutton `_, fix for parameter substitution regular expression (catch underscores!). +- `Levgen Pyvovarov `_, Various argument fixes, cyrillic text support. +- `Mark Liu `_, Missing parameter fix for ``addListMember``. +- `Randall Degges `_, PEP-8 fixes, MANIFEST.in, installer fixes. +- `Idris Mokhtarzada `_, Fixes for various example code pieces. +- `Jonathan Elsas `_, Fix for original Streaming API stub causing import errors. +- `LuqueDaniel `_, Extended example code where necessary. +- `Mesar Hameed `_, Commit to swap ``__getattr__`` trick for a more debuggable solution. +- `Remy DeCausemaker `_, PEP-8 contributions. +- `mckellister `_ Twitter Spring 2012 Clean Up fixes to ``Exception`` raised by Twython (Rate Limits, etc). +- `Tatz Tsuchiya `_, Fix for ``lambda`` scoping in key injection phase. +- `Mohammed ALDOUB `_, Fixes for ``http/https`` access endpoints. +- `Fumiaki Kinoshita `_, Re-added Proxy support for 2.3.0. +- `Terry Jones `_, Error cleanup and Exception processing in 2.3.0. +- `Leandro Ferreira `_, Fix for double-encoding of search queries in 2.3.0. +- `Chris Brown `_, Updated to use v1.1 endpoints over v1 +- `Virendra Rajput `_, Fixed unicode (json) encoding in twython.py 2.7.2. +- `Paul Solbach `_, fixed requirement for oauth_verifier \ No newline at end of file diff --git a/README.md b/README.md index c1119d2..aa41a4c 100644 --- a/README.md +++ b/README.md @@ -114,8 +114,6 @@ Notes ----- Twython (as of 2.7.0) is currently in the process of ONLY supporting Twitter v1.1 endpoints and deprecating all v1 endpoints! Please see the **[Twitter v1.1 API Documentation](https://dev.twitter.com/docs/api/1.1)** to help migrate your API calls! -As of Twython 2.0.0, we have changed routes for functions to abide by the **[Twitter Spring 2012 clean up](https://dev.twitter.com/docs/deprecations/spring-2012)** Please make changes to your code accordingly. - Development of Twython (specifically, 1.3) ------------------------------------------ As of version 1.3, Twython has been extensively overhauled. Most API endpoint definitions are stored @@ -157,35 +155,3 @@ Twython is released under an MIT License - see the LICENSE file for more informa Want to help? ------------- Twython is useful, but ultimately only as useful as the people using it (say that ten times fast!). If you'd like to help, write example code, contribute patches, document things on the wiki, tweet about it. Your help is always appreciated! - - -Special Thanks to... ------------------------------------------------------------------------------------------------------ -This is a list of all those who have contributed code to Twython in some way, shape, or form. I think it's -exhaustive, but I could be wrong - if you think your name should be here and it's not, please contact -me and let me know (or just issue a pull request on GitHub, and leave a note about it so I can just accept it ;)). - -- **[Mike Helmick (michaelhelmick)](https://github.com/michaelhelmick)**, multiple fixes and proper `requests` integration. -- **[kracekumar](https://github.com/kracekumar)**, early `requests` work and various fixes. -- **[Erik Scheffers (eriks5)](https://github.com/eriks5)**, various fixes regarding OAuth callback URLs. -- **[Jordan Bouvier (jbouvier)](https://github.com/jbouvier)**, various fixes regarding OAuth callback URLs. -- **[Dick Brouwer (dikbrouwer)](https://github.com/dikbrouwer)**, fixes for OAuth Verifier in `get_authorized_tokens`. -- **[hades](https://github.com/hades)**, Fixes to various initial OAuth issues and updates to `Twython3k` to stay current. -- **[Alex Sutton (alexdsutton)](https://github.com/alexsdutton/twython/)**, fix for parameter substitution regular expression (catch underscores!). -- **[Levgen Pyvovarov (bsn)](https://github.com/bsn)**, Various argument fixes, cyrillic text support. -- **[Mark Liu (mliu7)](https://github.com/mliu7)**, Missing parameter fix for `addListMember`. -- **[Randall Degges (rdegges)](https://github.com/rdegges)**, PEP-8 fixes, MANIFEST.in, installer fixes. -- **[Idris Mokhtarzada (idris)](https://github.com/idris)**, Fixes for various example code pieces. -- **[Jonathan Elsas (jelsas)](https://github.com/jelsas)**, Fix for original Streaming API stub causing import errors. -- **[LuqueDaniel](https://github.com/LuqueDaniel)**, Extended example code where necessary. -- **[Mesar Hameed (mhameed)](https://github.com/mhameed)**, Commit to swap `__getattr__` trick for a more debuggable solution. -- **[Remy DeCausemaker (decause)](https://github.com/decause)**, PEP-8 contributions. -- **[mckellister](https://github.com/mckellister)**, Fixes to `Exception`s raised by Twython (Rate Limits, etc). -- **[tatz_tsuchiya](http://d.hatena.ne.jp/tatz_tsuchiya/20120115/1326623451)**, Fix for `lambda` scoping in key injection phase. -- **[Voulnet (Mohammed ALDOUB)](https://github.com/Voulnet)**, Fixes for `http`/`https` access endpoints -- **[fumieval](https://github.com/fumieval)**, Re-added Proxy support for 2.3.0. -- **[terrycojones](https://github.com/terrycojones)**, Error cleanup and Exception processing in 2.3.0. -- **[Leandro Ferreira](https://github.com/leandroferreira)**, Fix for double-encoding of search queries in 2.3.0. -- **[Chris Brown](https://github.com/chbrown)**, Updated to use v1.1 endpoints over v1 -- **[Virendra Rajput](https://github.com/bkvirendra)**, Fixed unicode (json) encoding in twython.py 2.7.2. -- **[Paul Solbach](https://github.com/hansenrum)**, fixed requirement for oauth_verifier diff --git a/README.rst b/README.rst index 5267099..f39d2b7 100644 --- a/README.rst +++ b/README.rst @@ -117,9 +117,6 @@ Notes ----- * Twython (as of 2.7.0) is currently in the process of ONLY supporting Twitter v1.1 endpoints and deprecating all v1 endpoints! Please see the `Twitter API Documentation `_ to help migrate your API calls! -* As of Twython 2.0.0, we have changed routes for functions to abide by the `Twitter Spring 2012 clean up `_ Please make changes to your code accordingly. - - Twython && Django ----------------- If you're using Twython with Django, there's a sample project showcasing OAuth and such **[that can be found here](https://github.com/ryanmcgrath/twython-django)**. Feel free to peruse! @@ -164,35 +161,3 @@ You can also follow me on Twitter - `@ryanmcgrath `_, multiple fixes and proper ``requests`` integration. Too much to list here. -- `kracekumar `_, early ``requests`` work and various fixes. -- `Erik Scheffers (eriks5) `_, various fixes regarding OAuth callback URLs. -- `Jordan Bouvier (jbouvier) `_, various fixes regarding OAuth callback URLs. -- `Dick Brouwer (dikbrouwer) `_, fixes for OAuth Verifier in ``get_authorized_tokens``. -- `hades `_, Fixes to various initial OAuth issues and updates to ``Twython3k`` to stay current. -- `Alex Sutton (alexdsutton) `_, fix for parameter substitution regular expression (catch underscores!). -- `Levgen Pyvovarov (bsn) `_, Various argument fixes, cyrillic text support. -- `Mark Liu (mliu7) `_, Missing parameter fix for ``addListMember``. -- `Randall Degges (rdegges) `_, PEP-8 fixes, MANIFEST.in, installer fixes. -- `Idris Mokhtarzada (idris) `_, Fixes for various example code pieces. -- `Jonathan Elsas (jelsas) `_, Fix for original Streaming API stub causing import errors. -- `LuqueDaniel `_, Extended example code where necessary. -- `Mesar Hameed (mhameed) `_, Commit to swap ``__getattr__`` trick for a more debuggable solution. -- `Remy DeCausemaker (decause) `_, PEP-8 contributions. -- `[mckellister](https://github.com/mckellister) `_, Fixes to ``Exception`` raised by Twython (Rate Limits, etc). -- `tatz_tsuchiya `_, Fix for ``lambda`` scoping in key injection phase. -- `Voulnet (Mohammed ALDOUB) `_, Fixes for ``http/https`` access endpoints. -- `fumieval `_, Re-added Proxy support for 2.3.0. -- `terrycojones `_, Error cleanup and Exception processing in 2.3.0. -- `Leandro Ferreira `_, Fix for double-encoding of search queries in 2.3.0. -- `Chris Brown `_, Updated to use v1.1 endpoints over v1 -- `Virendra Rajput `_, Fixed unicode (json) encoding in twython.py 2.7.2. -- `Paul Solbach `_, fixed requirement for oauth_verifier From d228e04bc098866fa680e84eab4cf8c72c40f5b3 Mon Sep 17 00:00:00 2001 From: Mike Helmick Date: Fri, 12 Apr 2013 11:40:05 -0400 Subject: [PATCH 17/20] Version bump! --- setup.py | 2 +- twython/twython.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 198584c..249035c 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup from setuptools import find_packages __author__ = 'Ryan McGrath ' -__version__ = '2.7.2' +__version__ = '2.7.3' setup( # Basic package information. diff --git a/twython/twython.py b/twython/twython.py index 07be9a9..bf66740 100644 --- a/twython/twython.py +++ b/twython/twython.py @@ -7,7 +7,7 @@ """ __author__ = "Ryan McGrath " -__version__ = "2.7.2" +__version__ = "2.7.3" import urllib import re From 023b29b202f8aa9b2027a6baa62378d38024b4c8 Mon Sep 17 00:00:00 2001 From: Adrien Tronche Date: Sun, 14 Apr 2013 00:16:28 -0300 Subject: [PATCH 18/20] Small correction in comments Headers have changed and a - is now needed between rate and limit. --- twython/twython.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/twython/twython.py b/twython/twython.py index bf66740..853e6bd 100644 --- a/twython/twython.py +++ b/twython/twython.py @@ -258,10 +258,10 @@ class Twython(object): This will return None if the header is not present Most useful for the following header information: - x-ratelimit-limit - x-ratelimit-remaining - x-ratelimit-class - x-ratelimit-reset + x-rate-limit-limit + x-rate-limit-remaining + x-rate-limit-class + x-rate-limit-reset """ if self._last_call is None: raise TwythonError('This function must be called after an API call. It delivers header information.') From 6d1c439a8920e808dd7a3099c81ff9ef2eef1257 Mon Sep 17 00:00:00 2001 From: Mike Helmick Date: Mon, 15 Apr 2013 16:12:02 -0400 Subject: [PATCH 19/20] Move Exceptions to own file --- twython/__init__.py | 2 +- twython/exceptions.py | 48 +++++++++++++++++++++++++++++++++++++++++++ twython/twython.py | 45 ++-------------------------------------- 3 files changed, 51 insertions(+), 44 deletions(-) create mode 100644 twython/exceptions.py diff --git a/twython/__init__.py b/twython/__init__.py index 26a3860..97be55a 100644 --- a/twython/__init__.py +++ b/twython/__init__.py @@ -1,2 +1,2 @@ from twython import Twython -from twython import TwythonError, TwythonRateLimitError, TwythonAuthError +from .exceptions import TwythonError, TwythonRateLimitError, TwythonAuthError diff --git a/twython/exceptions.py b/twython/exceptions.py new file mode 100644 index 0000000..7c939af --- /dev/null +++ b/twython/exceptions.py @@ -0,0 +1,48 @@ +from twitter_endpoints import twitter_http_status_codes + + +class TwythonError(Exception): + """ + Generic error class, catch-all for most Twython issues. + Special cases are handled by TwythonAuthError & TwythonRateLimitError. + + Note: Syntax has changed as of Twython 1.3. To catch these, + you need to explicitly import them into your code, e.g: + + from twython import ( + TwythonError, TwythonRateLimitError, TwythonAuthError + ) + """ + def __init__(self, msg, error_code=None, retry_after=None): + self.error_code = error_code + + if error_code is not None and error_code in twitter_http_status_codes: + msg = 'Twitter API returned a %s (%s), %s' % \ + (error_code, + twitter_http_status_codes[error_code][0], + msg) + + super(TwythonError, self).__init__(msg) + + @property + def msg(self): + return self.args[0] + + +class TwythonAuthError(TwythonError): + """ Raised when you try to access a protected resource and it fails due to + some issue with your authentication. + """ + pass + + +class TwythonRateLimitError(TwythonError): + """ Raised when you've hit a rate limit. + + The amount of seconds to retry your request in will be appended + to the message. + """ + def __init__(self, msg, error_code, retry_after=None): + if isinstance(retry_after, int): + msg = '%s (Retry after %d seconds)' % (msg, retry_after) + TwythonError.__init__(self, msg, error_code=error_code) diff --git a/twython/twython.py b/twython/twython.py index bf66740..415b145 100644 --- a/twython/twython.py +++ b/twython/twython.py @@ -23,7 +23,8 @@ except ImportError: # Twython maps keyword based arguments to Twitter API endpoints. The endpoints # table is a file with a dictionary of every API endpoint that Twython supports. -from twitter_endpoints import base_url, api_table, twitter_http_status_codes +from twitter_endpoints import base_url, api_table +from .exceptions import TwythonError, TwythonAuthError, TwythonRateLimitError try: import simplejson as json @@ -31,48 +32,6 @@ except ImportError: import json -class TwythonError(Exception): - """ - Generic error class, catch-all for most Twython issues. - Special cases are handled by TwythonAPILimit and TwythonAuthError. - - Note: To use these, the syntax has changed as of Twython 1.3. To catch these, - you need to explicitly import them into your code, e.g: - - from twython import TwythonError, TwythonRateLimitError, TwythonAuthError - """ - def __init__(self, msg, error_code=None, retry_after=None): - self.error_code = error_code - - if error_code is not None and error_code in twitter_http_status_codes: - msg = 'Twitter API returned a %s (%s), %s' % (error_code, - twitter_http_status_codes[error_code][0], - msg) - - super(TwythonError, self).__init__(msg) - - @property - def msg(self): - return self.args[0] - - -class TwythonAuthError(TwythonError): - """ Raised when you try to access a protected resource and it fails due to - some issue with your authentication. - """ - pass - - -class TwythonRateLimitError(TwythonError): - """ Raised when you've hit a rate limit. - retry_wait_seconds is the number of seconds to wait before trying again. - """ - def __init__(self, msg, error_code, retry_after=None): - if isinstance(retry_after, int): - msg = '%s (Retry after %d seconds)' % (msg, retry_after) - TwythonError.__init__(self, msg, error_code=error_code) - - class Twython(object): def __init__(self, app_key=None, app_secret=None, oauth_token=None, oauth_token_secret=None, headers=None, callback_url=None, twitter_token=None, twitter_secret=None, proxies=None, version='1.1'): From 80c74880b1a5370d6fde4299f9fb547ed89e44be Mon Sep 17 00:00:00 2001 From: Mike Helmick Date: Mon, 15 Apr 2013 16:15:52 -0400 Subject: [PATCH 20/20] Update authors --- AUTHORS.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/AUTHORS.rst b/AUTHORS.rst index 34f03b8..dff2a73 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -36,4 +36,5 @@ Patches and Suggestions - `Leandro Ferreira `_, Fix for double-encoding of search queries in 2.3.0. - `Chris Brown `_, Updated to use v1.1 endpoints over v1 - `Virendra Rajput `_, Fixed unicode (json) encoding in twython.py 2.7.2. -- `Paul Solbach `_, fixed requirement for oauth_verifier \ No newline at end of file +- `Paul Solbach `_, fixed requirement for oauth_verifier +- `Greg Nofi `_, fixed using built-in Exception attributes for storing & retrieving error message