Updating a lot of docstrings, EndpointMixin replaces api_table dict
[ci skip]
This commit is contained in:
parent
9c6fe0d6b8
commit
ff7e3fab94
5 changed files with 858 additions and 450 deletions
160
twython/api.py
160
twython/api.py
|
|
@ -1,28 +1,38 @@
|
|||
import re
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
twython.api
|
||||
~~~~~~~~~~~
|
||||
|
||||
This module contains functionality for access to core Twitter API calls,
|
||||
Twitter Authentication, and miscellaneous methods that are useful when
|
||||
dealing with the Twitter API
|
||||
"""
|
||||
|
||||
import requests
|
||||
from requests_oauthlib import OAuth1
|
||||
|
||||
from . import __version__
|
||||
from .compat import json, urlencode, parse_qsl, quote_plus, str, is_py2
|
||||
from .endpoints import api_table
|
||||
from .endpoints import EndpointsMixin
|
||||
from .exceptions import TwythonError, TwythonAuthError, TwythonRateLimitError
|
||||
from .helpers import _transparent_params
|
||||
|
||||
|
||||
class Twython(object):
|
||||
class Twython(EndpointsMixin, object):
|
||||
def __init__(self, app_key=None, app_secret=None, oauth_token=None,
|
||||
oauth_token_secret=None, headers=None, proxies=None,
|
||||
api_version='1.1', ssl_verify=True):
|
||||
"""Instantiates an instance of Twython. Takes optional parameters for authentication and such (see below).
|
||||
|
||||
:param app_key: (optional) Your applications key
|
||||
:param app_secret: (optional) Your applications secret key
|
||||
:param oauth_token: (optional) Used with oauth_token_secret to make authenticated calls
|
||||
:param oauth_token_secret: (optional) Used with oauth_token to make authenticated calls
|
||||
:param headers: (optional) Custom headers to send along with the request
|
||||
:param proxies: (optional) A dictionary of proxies, for example {"http":"proxy.example.org:8080", "https":"proxy.example.org:8081"}.
|
||||
:param ssl_verify: (optional) Turns off ssl verification when False. Useful if you have development server issues.
|
||||
:param app_key: (optional) Your applications key
|
||||
:param app_secret: (optional) Your applications secret key
|
||||
:param oauth_token: (optional) Used with oauth_token_secret to make authenticated calls
|
||||
:param oauth_token_secret: (optional) Used with oauth_token to make authenticated calls
|
||||
:param headers: (optional) Custom headers to send along with the request
|
||||
:param proxies: (optional) A dictionary of proxies, for example {"http":"proxy.example.org:8080", "https":"proxy.example.org:8081"}.
|
||||
:param ssl_verify: (optional) Turns off ssl verification when False. Useful if you have development server issues.
|
||||
|
||||
"""
|
||||
|
||||
# API urls, OAuth urls and API version; needed for hitting that there API.
|
||||
|
|
@ -62,32 +72,11 @@ class Twython(object):
|
|||
|
||||
self._last_call = None
|
||||
|
||||
def _setFunc(key):
|
||||
'''Register functions, attaching them to the Twython instance'''
|
||||
return lambda **kwargs: self._constructFunc(key, **kwargs)
|
||||
|
||||
# Loop through all our Twitter API endpoints made available in endpoints.py
|
||||
for key in api_table.keys():
|
||||
self.__dict__[key] = _setFunc(key)
|
||||
|
||||
def __repr__(self):
|
||||
return '<Twython: %s>' % (self.app_key)
|
||||
|
||||
def _constructFunc(self, api_call, **kwargs):
|
||||
# Go through and replace any {{mustaches}} that are in our API url.
|
||||
fn = api_table[api_call]
|
||||
url = re.sub(
|
||||
'\{\{(?P<m>[a-zA-Z_]+)\}\}',
|
||||
lambda m: "%s" % kwargs.get(m.group(1)),
|
||||
self.api_url % self.api_version + fn['url']
|
||||
)
|
||||
|
||||
return self._request(url, method=fn['method'], params=kwargs)
|
||||
|
||||
def _request(self, url, method='GET', params=None, api_call=None):
|
||||
'''Internal response generator, no sense in repeating the same
|
||||
code twice, right? ;)
|
||||
'''
|
||||
"""Internal request method"""
|
||||
method = method.lower()
|
||||
params = params or {}
|
||||
|
||||
|
|
@ -153,14 +142,21 @@ class Twython(object):
|
|||
|
||||
return content
|
||||
|
||||
'''
|
||||
# Dynamic Request Methods
|
||||
Just in case Twitter releases something in their API
|
||||
and a developer wants to implement it on their app, but
|
||||
we haven't gotten around to putting it in Twython yet. :)
|
||||
'''
|
||||
|
||||
def request(self, endpoint, method='GET', params=None, version='1.1'):
|
||||
"""Return dict of response received from Twitter's API
|
||||
|
||||
:param endpoint: (required) Full url or Twitter API endpoint (e.g. search/tweets)
|
||||
:type endpoint: string
|
||||
:param method: (optional) Method of accessing data, either GET or POST. (default GET)
|
||||
:type method: string
|
||||
:param params: (optional) Dict of parameters (if any) accepted the by Twitter API endpoint you are trying to access (default None)
|
||||
:type params: dict or None
|
||||
:param version: (optional) Twitter API version to access (default 1.1)
|
||||
:type version: string
|
||||
|
||||
:rtype: dict
|
||||
"""
|
||||
|
||||
# In case they want to pass a full Twitter URL
|
||||
# i.e. https://api.twitter.com/1.1/search/tweets.json
|
||||
if endpoint.startswith('http://') or endpoint.startswith('https://'):
|
||||
|
|
@ -173,25 +169,25 @@ class Twython(object):
|
|||
return content
|
||||
|
||||
def get(self, endpoint, params=None, version='1.1'):
|
||||
"""Shortcut for GET requests via :class:`request`"""
|
||||
return self.request(endpoint, params=params, version=version)
|
||||
|
||||
def post(self, endpoint, params=None, version='1.1'):
|
||||
"""Shortcut for POST requests via :class:`request`"""
|
||||
return self.request(endpoint, 'POST', params=params, version=version)
|
||||
|
||||
# End Dynamic Request Methods
|
||||
|
||||
def get_lastfunction_header(self, header):
|
||||
"""Returns the header in the last function
|
||||
This must be called after an API call, as it returns header based
|
||||
information.
|
||||
"""Returns a specific header from the last API call
|
||||
This will return None if the header is not present
|
||||
|
||||
This will return None if the header is not present
|
||||
:param header: (required) The name of the header you want to get the value of
|
||||
|
||||
Most useful for the following header information:
|
||||
x-rate-limit-limit,
|
||||
x-rate-limit-remaining,
|
||||
x-rate-limit-class,
|
||||
x-rate-limit-reset
|
||||
|
||||
Most useful for the following header information:
|
||||
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.')
|
||||
|
|
@ -202,11 +198,12 @@ class Twython(object):
|
|||
return None
|
||||
|
||||
def get_authentication_tokens(self, callback_url=None, force_login=False, screen_name=''):
|
||||
"""Returns a dict including an authorization URL (auth_url) to direct a user to
|
||||
"""Returns a dict including an authorization URL, ``auth_url``, to direct a user to
|
||||
|
||||
:param callback_url: (optional) Url the user is returned to after they authorize your app (web clients only)
|
||||
: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
|
||||
:param callback_url: (optional) Url the user is returned to after they authorize your app (web clients only)
|
||||
: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
|
||||
:rtype: dict
|
||||
"""
|
||||
callback_url = callback_url or self.callback_url
|
||||
request_args = {}
|
||||
|
|
@ -244,9 +241,11 @@ class Twython(object):
|
|||
return request_tokens
|
||||
|
||||
def get_authorized_tokens(self, oauth_verifier):
|
||||
"""Returns authorized tokens after they go through the auth_url phase.
|
||||
"""Returns a dict of authorized tokens after they go through the :class:`get_authentication_tokens` phase.
|
||||
|
||||
:param oauth_verifier: (required) The oauth_verifier (or a.k.a PIN for non web apps) retrieved from the callback url querystring
|
||||
:rtype: dict
|
||||
|
||||
:param oauth_verifier: (required) The oauth_verifier (or a.k.a PIN for non web apps) retrieved from the callback url querystring
|
||||
"""
|
||||
response = self.client.get(self.access_token_url, params={'oauth_verifier': oauth_verifier})
|
||||
authorized_tokens = dict(parse_qsl(response.content.decode('utf-8')))
|
||||
|
|
@ -262,7 +261,24 @@ class Twython(object):
|
|||
# ------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@staticmethod
|
||||
def construct_api_url(base_url, params=None):
|
||||
def construct_api_url(api_url, **params):
|
||||
"""Construct a Twitter API url, encoded, with parameters
|
||||
|
||||
:param api_url: URL of the Twitter API endpoint you are attempting to construct
|
||||
:param \*\*params: Parameters that are accepted by Twitter for the endpoint you're requesting
|
||||
:rtype: string
|
||||
|
||||
Usage::
|
||||
|
||||
>>> from twython import Twython
|
||||
>>> twitter = Twython()
|
||||
|
||||
>>> api_url = 'https://api.twitter.com/1.1/search/tweets.json'
|
||||
>>> constructed_url = twitter.construct_api_url(api_url, q='python', result_type='popular')
|
||||
>>> print constructed_url
|
||||
https://api.twitter.com/1.1/search/tweets.json?q=python&result_type=popular
|
||||
|
||||
"""
|
||||
querystring = []
|
||||
params, _ = _transparent_params(params or {})
|
||||
params = requests.utils.to_key_val_list(params)
|
||||
|
|
@ -270,18 +286,28 @@ class Twython(object):
|
|||
querystring.append(
|
||||
'%s=%s' % (Twython.encode(k), quote_plus(Twython.encode(v)))
|
||||
)
|
||||
return '%s?%s' % (base_url, '&'.join(querystring))
|
||||
return '%s?%s' % (api_url, '&'.join(querystring))
|
||||
|
||||
def search_gen(self, search_query, **kwargs):
|
||||
def search_gen(self, search_query, **params):
|
||||
"""Returns a generator of tweets that match a specified query.
|
||||
|
||||
Documentation: https://dev.twitter.com/docs/api/1.1/get/search/tweets
|
||||
Documentation: https://dev.twitter.com/docs/api/1.1/get/search/tweets
|
||||
|
||||
:param search_query: Query you intend to search Twitter for
|
||||
:param \*\*params: Extra parameters to send with your search request
|
||||
:rtype: generator
|
||||
|
||||
Usage::
|
||||
|
||||
>>> from twython import Twython
|
||||
>>> twitter = Twython(APP_KEY, APP_SECRET, OAUTH_TOKEN, OAUTH_TOKEN_SECRET)
|
||||
|
||||
>>> search = twitter.search_gen('python')
|
||||
>>> for result in search:
|
||||
>>> print result
|
||||
|
||||
e.g search = x.search_gen('python')
|
||||
for result in search:
|
||||
print result
|
||||
"""
|
||||
content = self.search(q=search_query, **kwargs)
|
||||
content = self.search(q=search_query, **params)
|
||||
|
||||
if not content.get('statuses'):
|
||||
raise StopIteration
|
||||
|
|
@ -290,12 +316,12 @@ class Twython(object):
|
|||
yield tweet
|
||||
|
||||
try:
|
||||
if not 'since_id' in kwargs:
|
||||
kwargs['since_id'] = (int(content['statuses'][0]['id_str']) + 1)
|
||||
if not 'since_id' in params:
|
||||
params['since_id'] = (int(content['statuses'][0]['id_str']) + 1)
|
||||
except (TypeError, ValueError):
|
||||
raise TwythonError('Unable to generate next page of search results, `page` is not a number.')
|
||||
|
||||
for tweet in self.search_gen(search_query, **kwargs):
|
||||
for tweet in self.search_gen(search_query, **params):
|
||||
yield tweet
|
||||
|
||||
@staticmethod
|
||||
|
|
|
|||
1088
twython/endpoints.py
1088
twython/endpoints.py
File diff suppressed because it is too large
Load diff
|
|
@ -1,23 +1,20 @@
|
|||
from .endpoints import twitter_http_status_codes
|
||||
from .endpoints import TWITTER_HTTP_STATUS_CODE
|
||||
|
||||
|
||||
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
|
||||
|
||||
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:
|
||||
if error_code is not None and error_code in TWITTER_HTTP_STATUS_CODE:
|
||||
msg = 'Twitter API returned a %s (%s), %s' % \
|
||||
(error_code,
|
||||
twitter_http_status_codes[error_code][0],
|
||||
TWITTER_HTTP_STATUS_CODE[error_code][0],
|
||||
msg)
|
||||
|
||||
super(TwythonError, self).__init__(msg)
|
||||
|
|
@ -29,7 +26,9 @@ class TwythonError(Exception):
|
|||
|
||||
class TwythonAuthError(TwythonError):
|
||||
"""Raised when you try to access a protected resource and it fails due to
|
||||
some issue with your authentication."""
|
||||
some issue with your authentication.
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
|
|
@ -37,7 +36,9 @@ 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."""
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
from .. import __version__
|
||||
from ..compat import json, is_py3
|
||||
from ..exceptions import TwythonStreamError
|
||||
from .types import TwythonStreamerTypes
|
||||
|
||||
import requests
|
||||
|
|
@ -112,7 +111,8 @@ class TwythonStreamer(object):
|
|||
See https://dev.twitter.com/docs/streaming-apis/messages for messages
|
||||
sent along in stream responses.
|
||||
|
||||
:param data: dict of data recieved from the stream
|
||||
:param data: data recieved from the stream
|
||||
:type data: dict
|
||||
"""
|
||||
|
||||
if 'delete' in data:
|
||||
|
|
@ -129,7 +129,10 @@ class TwythonStreamer(object):
|
|||
want it handled.
|
||||
|
||||
:param status_code: Non-200 status code sent from stream
|
||||
:type status_code: int
|
||||
|
||||
:param data: Error message sent from stream
|
||||
:type data: dict
|
||||
"""
|
||||
return
|
||||
|
||||
|
|
@ -141,8 +144,8 @@ class TwythonStreamer(object):
|
|||
|
||||
Twitter docs for deletion notices: http://spen.se/8qujd
|
||||
|
||||
:param data: dict of data from the 'delete' key recieved from
|
||||
the stream
|
||||
:param data: data from the 'delete' key recieved from the stream
|
||||
:type data: dict
|
||||
"""
|
||||
return
|
||||
|
||||
|
|
@ -154,8 +157,8 @@ class TwythonStreamer(object):
|
|||
|
||||
Twitter docs for limit notices: http://spen.se/hzt0b
|
||||
|
||||
:param data: dict of data from the 'limit' key recieved from
|
||||
the stream
|
||||
:param data: data from the 'limit' key recieved from the stream
|
||||
:type data: dict
|
||||
"""
|
||||
return
|
||||
|
||||
|
|
@ -167,13 +170,15 @@ class TwythonStreamer(object):
|
|||
|
||||
Twitter docs for disconnect notices: http://spen.se/xb6mm
|
||||
|
||||
:param data: dict of data from the 'disconnect' key recieved from
|
||||
the stream
|
||||
:param data: data from the 'disconnect' key recieved from the stream
|
||||
:type data: dict
|
||||
"""
|
||||
return
|
||||
|
||||
def on_timeout(self):
|
||||
""" Called when the request has timed out """
|
||||
return
|
||||
|
||||
def disconnect(self):
|
||||
"""Used to disconnect the streaming client manually"""
|
||||
self.connected = False
|
||||
|
|
|
|||
|
|
@ -1,9 +1,20 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
twython.streaming.types
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This module contains classes and methods for :class:`TwythonStreamer` to mak
|
||||
"""
|
||||
|
||||
|
||||
class TwythonStreamerTypes(object):
|
||||
"""Class for different stream endpoints
|
||||
|
||||
Not all streaming endpoints have nested endpoints.
|
||||
User Streams and Site Streams are single streams with no nested endpoints
|
||||
Status Streams include filter, sample and firehose endpoints
|
||||
|
||||
"""
|
||||
def __init__(self, streamer):
|
||||
self.streamer = streamer
|
||||
|
|
@ -36,6 +47,7 @@ class TwythonStreamerTypesStatuses(object):
|
|||
Available so TwythonStreamer.statuses.filter() is available.
|
||||
Just a bit cleaner than TwythonStreamer.statuses_filter(),
|
||||
statuses_sample(), etc. all being single methods in TwythonStreamer
|
||||
|
||||
"""
|
||||
def __init__(self, streamer):
|
||||
self.streamer = streamer
|
||||
|
|
@ -43,6 +55,8 @@ class TwythonStreamerTypesStatuses(object):
|
|||
def filter(self, **params):
|
||||
"""Stream statuses/filter
|
||||
|
||||
:param \*\*params: Paramters to send with your stream request
|
||||
|
||||
Accepted params found at:
|
||||
https://dev.twitter.com/docs/api/1.1/post/statuses/filter
|
||||
"""
|
||||
|
|
@ -53,6 +67,8 @@ class TwythonStreamerTypesStatuses(object):
|
|||
def sample(self, **params):
|
||||
"""Stream statuses/sample
|
||||
|
||||
:param \*\*params: Paramters to send with your stream request
|
||||
|
||||
Accepted params found at:
|
||||
https://dev.twitter.com/docs/api/1.1/get/statuses/sample
|
||||
"""
|
||||
|
|
@ -63,6 +79,8 @@ class TwythonStreamerTypesStatuses(object):
|
|||
def firehose(self, **params):
|
||||
"""Stream statuses/firehose
|
||||
|
||||
:param \*\*params: Paramters to send with your stream request
|
||||
|
||||
Accepted params found at:
|
||||
https://dev.twitter.com/docs/api/1.1/get/statuses/firehose
|
||||
"""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue