Making twython work (again?) in Python 3

- Added a ``HISTORY.rst`` to start tracking history of changes
- Updated ``twitter_endpoints.py`` to ``endpoints.py`` for cleanliness
- Removed twython3k directory, no longer needed
- Added ``compat.py`` for compatability with Python 2.6 and greater
- Added some ascii art, moved description of Twython and ``__author__`` to ``__init__.py``
- Added ``version.py`` to store the current Twython version, instead of repeating it twice -- it also had to go into it's own file because of dependencies of ``requests`` and ``requests-oauthlib``, install would fail because those libraries weren't installed yet (on fresh install of Twython)
- Removed ``find_packages()`` from ``setup.py``, only one package -- we can
just define it
- added quick publish method for Ryan and I: ``python setup.py publish`` is faster to type and easier to remember than ``python setup.py sdist upload``
- Removed ``base_url`` from ``endpoints.py`` because we're just repeating it in
``Twython.__init__``
- ``Twython.get_authentication_tokens()`` now takes ``callback_url`` argument rather than passing the ``callback_url`` through ``Twython.__init__``, ``callback_url`` is only used in the ``get_authentication_tokens`` method and nowhere else (kept in init though for backwards compatability)
- Updated README to better reflect current Twython codebase
- Added ``warnings.simplefilter('default')`` line in ``twython.py`` for Python 2.7 and greater to display Deprecation Warnings in console
- Added Deprecation Warnings for usage of ``twitter_token``, ``twitter_secret`` and ``callback_url`` in ``Twython.__init__``
- Headers now always include the User-Agent as Twython vXX unless User-Agent is overwritten
- Removed senseless TwythonError thrown if method is not GET or POST, who cares -- if the user passes something other than GET or POST just let Twitter return the error that they messed up
- Removed conversion to unicode of (int, bool) params passed to a requests. ``requests`` isn't greedy about variables that can't be converted to unicode anymore
This commit is contained in:
Mike Helmick 2013-04-17 18:59:11 -04:00
parent 8ecc55b5ad
commit bb019d3a57
16 changed files with 306 additions and 1000 deletions

411
twython/endpoints.py Normal file
View file

@ -0,0 +1,411 @@
"""
A huge map of every Twitter API endpoint to a function definition in Twython.
Parameters that need to be embedded in the URL are treated with mustaches, e.g:
{{version}}, etc
When creating new endpoint definitions, keep in mind that the name of the mustache
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.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
"""
api_table = {
# Timelines
'getMentionsTimeline': {
'url': '/statuses/mentions_timeline.json',
'method': 'GET',
},
'getUserTimeline': {
'url': '/statuses/user_timeline.json',
'method': 'GET',
},
'getHomeTimeline': {
'url': '/statuses/home_timeline.json',
'method': 'GET',
},
'retweetedOfMe': {
'url': '/statuses/retweets_of_me.json',
'method': 'GET',
},
# Tweets
'getRetweets': {
'url': '/statuses/retweets/{{id}}.json',
'method': 'GET',
},
'showStatus': {
'url': '/statuses/show/{{id}}.json',
'method': 'GET',
},
'destroyStatus': {
'url': '/statuses/destroy/{{id}}.json',
'method': 'POST',
},
'updateStatus': {
'url': '/statuses/update.json',
'method': 'POST',
},
'retweet': {
'url': '/statuses/retweet/{{id}}.json',
'method': 'POST',
},
# See twython.py for update_status_with_media
'getOembedTweet': {
'url': '/statuses/oembed.json',
'method': 'GET',
},
# Search
'search': {
'url': '/search/tweets.json',
'method': 'GET',
},
# Direct Messages
'getDirectMessages': {
'url': '/direct_messages.json',
'method': 'GET',
},
'getSentMessages': {
'url': '/direct_messages/sent.json',
'method': 'GET',
},
'getDirectMessage': {
'url': '/direct_messages/show.json',
'method': 'GET',
},
'destroyDirectMessage': {
'url': '/direct_messages/destroy.json',
'method': 'POST',
},
'sendDirectMessage': {
'url': '/direct_messages/new.json',
'method': 'POST',
},
# Friends & Followers
'getUserIdsOfBlockedRetweets': {
'url': '/friendships/no_retweets/ids.json',
'method': 'GET',
},
'getFriendsIDs': {
'url': '/friends/ids.json',
'method': 'GET',
},
'getFollowersIDs': {
'url': '/followers/ids.json',
'method': 'GET',
},
'lookupFriendships': {
'url': '/friendships/lookup.json',
'method': 'GET',
},
'getIncomingFriendshipIDs': {
'url': '/friendships/incoming.json',
'method': 'GET',
},
'getOutgoingFriendshipIDs': {
'url': '/friendships/outgoing.json',
'method': 'GET',
},
'createFriendship': {
'url': '/friendships/create.json',
'method': 'POST',
},
'destroyFriendship': {
'url': '/friendships/destroy.json',
'method': 'POST',
},
'updateFriendship': {
'url': '/friendships/update.json',
'method': 'POST',
},
'showFriendship': {
'url': '/friendships/show.json',
'method': 'GET',
},
'getFriendsList': {
'url': '/friends/list.json',
'method': 'GET',
},
'getFollowersList': {
'url': '/followers/list.json',
'method': 'GET',
},
# Users
'getAccountSettings': {
'url': '/account/settings.json',
'method': 'GET',
},
'verifyCredentials': {
'url': '/account/verify_credentials.json',
'method': 'GET',
},
'updateAccountSettings': {
'url': '/account/settings.json',
'method': 'POST',
},
'updateDeliveryService': {
'url': '/account/update_delivery_device.json',
'method': 'POST',
},
'updateProfile': {
'url': '/account/update_profile.json',
'method': 'POST',
},
# See twython.py for update_profile_background_image
'updateProfileColors': {
'url': '/account/update_profile_colors.json',
'method': 'POST',
},
# See twython.py for update_profile_image
'listBlocks': {
'url': '/blocks/list.json',
'method': 'GET',
},
'listBlockIds': {
'url': '/blocks/ids.json',
'method': 'GET',
},
'createBlock': {
'url': '/blocks/create.json',
'method': 'POST',
},
'destroyBlock': {
'url': '/blocks/destroy.json',
'method': 'POST',
},
'lookupUser': {
'url': '/users/lookup.json',
'method': 'GET',
},
'showUser': {
'url': '/users/show.json',
'method': 'GET',
},
'searchUsers': {
'url': '/users/search.json',
'method': 'GET',
},
'getContributees': {
'url': '/users/contributees.json',
'method': 'GET',
},
'getContributors': {
'url': '/users/contributors.json',
'method': 'GET',
},
'removeProfileBanner': {
'url': '/account/remove_profile_banner.json',
'method': 'POST',
},
# See twython.py for update_profile_banner
'getProfileBannerSizes': {
'url': '/users/profile_banner.json',
'method': 'GET',
},
# Suggested Users
'getUserSuggestionsBySlug': {
'url': '/users/suggestions/{{slug}}.json',
'method': 'GET',
},
'getUserSuggestions': {
'url': '/users/suggestions.json',
'method': 'GET',
},
'getUserSuggestionsStatusesBySlug': {
'url': '/users/suggestions/{{slug}}/members.json',
'method': 'GET',
},
# Favorites
'getFavorites': {
'url': '/favorites/list.json',
'method': 'GET',
},
'destroyFavorite': {
'url': '/favorites/destroy.json',
'method': 'POST',
},
'createFavorite': {
'url': '/favorites/create.json',
'method': 'POST',
},
# Lists
'showLists': {
'url': '/lists/list.json',
'method': 'GET',
},
'getListStatuses': {
'url': '/lists/statuses.json',
'method': 'GET'
},
'deleteListMember': {
'url': '/lists/members/destroy.json',
'method': 'POST',
},
'getListMemberships': {
'url': '/lists/memberships.json',
'method': 'GET',
},
'getListSubscribers': {
'url': '/lists/subscribers.json',
'method': 'GET',
},
'subscribeToList': {
'url': '/lists/subscribers/create.json',
'method': 'POST',
},
'isListSubscriber': {
'url': '/lists/subscribers/show.json',
'method': 'GET',
},
'unsubscribeFromList': {
'url': '/lists/subscribers/destroy.json',
'method': 'POST',
},
'createListMembers': {
'url': '/lists/members/create_all.json',
'method': 'POST'
},
'isListMember': {
'url': '/lists/members/show.json',
'method': 'GET',
},
'getListMembers': {
'url': '/lists/members.json',
'method': 'GET',
},
'addListMember': {
'url': '/lists/members/create.json',
'method': 'POST',
},
'deleteList': {
'url': '/lists/destroy.json',
'method': 'POST',
},
'updateList': {
'url': '/lists/update.json',
'method': 'POST',
},
'createList': {
'url': '/lists/create.json',
'method': 'POST',
},
'getSpecificList': {
'url': '/lists/show.json',
'method': 'GET',
},
'getListSubscriptions': {
'url': '/lists/subscriptions.json',
'method': 'GET',
},
'deleteListMembers': {
'url': '/lists/members/destroy_all.json',
'method': 'POST'
},
'showOwnedLists': {
'url': '/lists/ownerships.json',
'method': 'GET'
},
# Saved Searches
'getSavedSearches': {
'url': '/saved_searches/list.json',
'method': 'GET',
},
'showSavedSearch': {
'url': '/saved_searches/show/{{id}}.json',
'method': 'GET',
},
'createSavedSearch': {
'url': '/saved_searches/create.json',
'method': 'POST',
},
'destroySavedSearch': {
'url': '/saved_searches/destroy/{{id}}.json',
'method': 'POST',
},
# Places & Geo
'getGeoInfo': {
'url': '/geo/id/{{place_id}}.json',
'method': 'GET',
},
'reverseGeocode': {
'url': '/geo/reverse_geocode.json',
'method': 'GET',
},
'searchGeo': {
'url': '/geo/search.json',
'method': 'GET',
},
'getSimilarPlaces': {
'url': '/geo/similar_places.json',
'method': 'GET',
},
'createPlace': {
'url': '/geo/place.json',
'method': 'POST',
},
# Trends
'getPlaceTrends': {
'url': '/trends/place.json',
'method': 'GET',
},
'getAvailableTrends': {
'url': '/trends/available.json',
'method': 'GET',
},
'getClosestTrends': {
'url': '/trends/closest.json',
'method': 'GET',
},
# Spam Reporting
'reportSpam': {
'url': '/users/report_spam.json',
'method': 'POST',
},
}
# from https://dev.twitter.com/docs/error-codes-responses
twitter_http_status_codes = {
200: ('OK', 'Success!'),
304: ('Not Modified', 'There was no new data to return.'),
400: ('Bad Request', 'The request was invalid. An accompanying error message will explain why. This is the status code will be returned during rate limiting.'),
401: ('Unauthorized', 'Authentication credentials were missing or incorrect.'),
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.'),
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.'),
}