Merge pull request #396 from akarambir/upload-video-endpoint

Add chunked video upload functionality
This commit is contained in:
Mike Helmick 2015-10-06 15:29:51 -04:00
commit c59de5c1df
3 changed files with 83 additions and 3 deletions

View file

@ -35,6 +35,22 @@ Documentation:
* https://dev.twitter.com/rest/reference/post/statuses/update
* https://dev.twitter.com/rest/reference/post/media/upload
Updating Status with Video
--------------------------
This uploads a video as a media object and associates it with a status update.
.. code-block:: python
video = open('/path/to/file/video.mp4', 'rb')
response = twitter.upload_video(media=video, media_type='video/mp4')
twitter.update_status(status='Checkout this cool video!', media_ids=[response['media_id']])
Documentation:
* https://dev.twitter.com/rest/reference/post/statuses/update
* https://dev.twitter.com/rest/reference/post/media/upload
Posting a Status with an Editing Image
--------------------------------------

View file

@ -194,6 +194,9 @@ class Twython(EndpointsMixin, object):
retry_after=response.headers.get('X-Rate-Limit-Reset'))
try:
if response.status_code == 204:
content = response.content
else:
content = response.json()
except ValueError:
raise TwythonError('Response was not valid JSON. \

View file

@ -14,7 +14,12 @@ This map is organized the order functions are documented at:
https://dev.twitter.com/docs/api/1.1
"""
import os
import warnings
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
from .advisory import TwythonDeprecationWarning
@ -139,6 +144,62 @@ class EndpointsMixin(object):
"""
return self.post('https://upload.twitter.com/1.1/media/upload.json', params=params)
def upload_video(self, media, media_type, size=None):
"""Uploads video file to Twitter servers in chunks. The file will be available to be attached
to a status for 60 minutes. To attach to a update, pass a list of returned media ids
to the 'update_status' method using the 'media_ids' param.
Upload happens in 3 stages:
- INIT call with size of media to be uploaded(in bytes). If this is more than 15mb, twitter will return error.
- APPEND calls each with media chunk. This returns a 204(No Content) if chunk is received.
- FINALIZE call to complete media upload. This returns media_id to be used with status update.
Twitter media upload api expects each chunk to be not more than 5mb. We are sending chunk of 1mb each.
Docs:
https://dev.twitter.com/rest/public/uploading-media#chunkedupload
"""
upload_url = 'https://upload.twitter.com/1.1/media/upload.json'
if not size:
media.seek(0, os.SEEK_END)
size = media.tell()
media.seek(0)
# Stage 1: INIT call
params = {
'command': 'INIT',
'media_type': media_type,
'total_bytes': size
}
response_init = self.post(upload_url, params=params)
media_id = response_init['media_id']
# Stage 2: APPEND calls with 1mb chunks
segment_index = 0
while True:
data = media.read(1*1024*1024)
if not data:
break
media_chunk = StringIO()
media_chunk.write(data)
media_chunk.seek(0)
params = {
'command': 'APPEND',
'media_id': media_id,
'segment_index': segment_index,
'media': media_chunk,
}
self.post(upload_url, params=params)
segment_index += 1
# Stage 3: FINALIZE call to complete upload
params = {
'command': 'FINALIZE',
'media_id': media_id
}
return self.post(upload_url, params=params)
def get_oembed_tweet(self, **params):
"""Returns information allowing the creation of an embedded
representation of a Tweet on third party sites.