Django Tweepy 无法访问 Amazon S3 文件
Django Tweepy can't access Amazon S3 file
我正在使用 Tweepy,一个推文 python 库,django-storages
和 boto
。我有一个自定义的 manage.py
命令可以在本地正常工作,它从文件系统获取图像并发布该图像。但是,如果我将存储更改为 Amazon S3,我将无法访问该文件。它给了我这个错误:
raise TweepError('Unable to access file: %s' % e.strerror)
我尝试在存储桶中制作图像 "public"。没用。这是代码(它在没有 S3 的情况下工作):
filename = model_object.image.file.url
media_ids = api.media_upload(filename=filename) # ERROR
params = {'status': tweet_text, 'media_ids': [media_ids.media_id_string]}
api.update_status(**params)
这一行:
model_object.image.file.url
给我完整的 url 我想发推的图片,像这样:
我还尝试手动构建 url,因为它是存储在我的存储桶中的 public 图像,如下所示:
filename = "https://criptolibertad.s3.amazonaws.com/OrillaLibertaria/195.jpg"
但是没用。
¿为什么我会收到 Unable to access file
错误?
tweepy 的源代码如下所示:
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) # ERROR
kwargs.update({'headers': headers, 'post_data': post_data})
def _pack_image(filename, max_size, form_field="image", f=None):
"""Pack image from file into multipart-formdata post body"""
# image must be less than 700kb in size
if f is None:
try:
if os.path.getsize(filename) > (max_size * 1024):
raise TweepError('File is too big, must be less than %skb.' % max_size)
except os.error as e:
raise TweepError('Unable to access file: %s' % e.strerror)
看起来 Tweepy
无法从 Amazon S3 存储桶中获取图像,但我该如何让它工作?任何建议都会有所帮助。
当 tweepy 尝试在 _pack_image
中获取文件大小时出现问题:
if os.path.getsize(filename) > (max_size * 1024):
函数os.path.getsize
假设它在磁盘上有一个文件路径;但是,在您的情况下,它被赋予 URL。自然地,在磁盘上找不到该文件并引发 os.error
。例如:
# The following raises OSError on my machine
os.path.getsize('https://criptolibertad.s3.amazonaws.com/OrillaLibertaria/195.jpg')
你可以做的是获取文件内容,暂时保存在本地,然后推特:
import tempfile
with tempfile.NamedTemporaryFile(delete=True) as f:
name = model_object.image.file.name
f.write(model_object.image.read())
media_ids = api.media_upload(filename=name, f=f)
params = dict(status='test media', media_ids=[media_ids.media_id_string])
api.update_status(**params)
为了您的方便,我在这里发布了一个完整的示例:https://github.com/izzysoftware/so38134984
我正在使用 Tweepy,一个推文 python 库,django-storages
和 boto
。我有一个自定义的 manage.py
命令可以在本地正常工作,它从文件系统获取图像并发布该图像。但是,如果我将存储更改为 Amazon S3,我将无法访问该文件。它给了我这个错误:
raise TweepError('Unable to access file: %s' % e.strerror)
我尝试在存储桶中制作图像 "public"。没用。这是代码(它在没有 S3 的情况下工作):
filename = model_object.image.file.url
media_ids = api.media_upload(filename=filename) # ERROR
params = {'status': tweet_text, 'media_ids': [media_ids.media_id_string]}
api.update_status(**params)
这一行:
model_object.image.file.url
给我完整的 url 我想发推的图片,像这样:
我还尝试手动构建 url,因为它是存储在我的存储桶中的 public 图像,如下所示:
filename = "https://criptolibertad.s3.amazonaws.com/OrillaLibertaria/195.jpg"
但是没用。
¿为什么我会收到 Unable to access file
错误?
tweepy 的源代码如下所示:
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) # ERROR
kwargs.update({'headers': headers, 'post_data': post_data})
def _pack_image(filename, max_size, form_field="image", f=None):
"""Pack image from file into multipart-formdata post body"""
# image must be less than 700kb in size
if f is None:
try:
if os.path.getsize(filename) > (max_size * 1024):
raise TweepError('File is too big, must be less than %skb.' % max_size)
except os.error as e:
raise TweepError('Unable to access file: %s' % e.strerror)
看起来 Tweepy
无法从 Amazon S3 存储桶中获取图像,但我该如何让它工作?任何建议都会有所帮助。
当 tweepy 尝试在 _pack_image
中获取文件大小时出现问题:
if os.path.getsize(filename) > (max_size * 1024):
函数os.path.getsize
假设它在磁盘上有一个文件路径;但是,在您的情况下,它被赋予 URL。自然地,在磁盘上找不到该文件并引发 os.error
。例如:
# The following raises OSError on my machine
os.path.getsize('https://criptolibertad.s3.amazonaws.com/OrillaLibertaria/195.jpg')
你可以做的是获取文件内容,暂时保存在本地,然后推特:
import tempfile
with tempfile.NamedTemporaryFile(delete=True) as f:
name = model_object.image.file.name
f.write(model_object.image.read())
media_ids = api.media_upload(filename=name, f=f)
params = dict(status='test media', media_ids=[media_ids.media_id_string])
api.update_status(**params)
为了您的方便,我在这里发布了一个完整的示例:https://github.com/izzysoftware/so38134984