Commit 460acae6 authored by Florent Espanet's avatar Florent Espanet
Browse files

Add media/upload endpoint.

The media/upload endpoint is located on a different server :
upload.twitter.com.

It returns a unique result model called `Media` containing the
`media_id` and the image infos.

See also :

* [doc](https://dev.twitter.com/rest/reference/post/media/upload)
parent a192de35
......@@ -20,18 +20,21 @@ class API(object):
def __init__(self, auth_handler=None,
host='api.twitter.com', search_host='search.twitter.com',
cache=None, api_root='/1.1', search_root='',
retry_count=0, retry_delay=0, retry_errors=None, timeout=60,
parser=None, compression=False, wait_on_rate_limit=False,
upload_host='upload.twitter.com', cache=None, api_root='/1.1',
search_root='', upload_root='/1.1', retry_count=0,
retry_delay=0, retry_errors=None, timeout=60, parser=None,
compression=False, wait_on_rate_limit=False,
wait_on_rate_limit_notify=False, proxy=''):
""" Api instance Constructor
:param auth_handler:
:param host: url of the server of the rest api, default:'api.twitter.com'
:param search_host: url of the search server, default:'search.twitter.com'
:param upload_host: url of the upload server, default:'upload.twitter.com'
:param cache: Cache to query if a GET method is used, default:None
:param api_root: suffix of the api version, default:'/1.1'
:param search_root: suffix of the search version, default:''
:param upload_root: suffix of the upload version, default:'/1.1'
:param retry_count: number of allowed retries, default:0
:param retry_delay: delay in second between retries, default:0
:param retry_errors: default:None
......@@ -47,8 +50,10 @@ class API(object):
self.auth = auth_handler
self.host = host
self.search_host = search_host
self.upload_host = upload_host
self.api_root = api_root
self.search_root = search_root
self.upload_root = upload_root
self.cache = cache
self.compression = compression
self.retry_count = retry_count
......@@ -184,6 +189,24 @@ class API(object):
require_auth=True
)
def media_upload(self, filename, *args, **kwargs):
""" :reference: https://dev.twitter.com/rest/reference/post/media/upload
:allowed_param:
"""
f = kwargs.pop('file', None)
headers, post_data = API._pack_image(filename, 3072, form_field='media', f=f)
kwargs.update({'headers': headers, 'post_data': post_data})
return bind_api(
api=self,
path='/media/upload.json',
method='POST',
payload_type='media',
allowed_param=[],
require_auth=True,
upload_api=True
)(*args, **kwargs)
def update_with_media(self, filename, *args, **kwargs):
""" :reference: https://dev.twitter.com/rest/reference/post/statuses/update_with_media
:allowed_param:'status', 'possibly_sensitive', 'in_reply_to_status_id', 'lat', 'long', 'place_id', 'display_coordinates'
......
......@@ -33,6 +33,7 @@ def bind_api(**config):
method = config.get('method', 'GET')
require_auth = config.get('require_auth', False)
search_api = config.get('search_api', False)
upload_api = config.get('upload_api', False)
use_cache = config.get('use_cache', True)
session = requests.Session()
......@@ -61,6 +62,8 @@ def bind_api(**config):
# Pick correct URL root to use
if self.search_api:
self.api_root = api.search_root
elif self.upload_api:
self.api_root = api.upload_root
else:
self.api_root = api.api_root
......@@ -69,6 +72,8 @@ def bind_api(**config):
if self.search_api:
self.host = api.search_host
elif self.upload_api:
self.host = api.upload_host
else:
self.host = api.host
......@@ -181,7 +186,6 @@ def bind_api(**config):
auth=auth,
proxies=self.api.proxy)
except Exception as e:
raise TweepError('Failed to send request: %s' % e)
rem_calls = resp.headers.get('x-rate-limit-remaining')
if rem_calls is not None:
......
......@@ -458,6 +458,16 @@ class Place(Model):
return results
class Media(Model):
@classmethod
def parse(cls, api, json):
media = cls(api)
for k, v in json.items():
setattr(media, k, v)
return media
class ModelFactory(object):
"""
Used by parsers for creating instances
......@@ -475,6 +485,7 @@ class ModelFactory(object):
list = List
relation = Relation
relationship = Relationship
media = Media
json = JSONModel
ids = IDModel
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment