2016-06-30 4 views
2

Я использую Tweedy, чириканскую библиотеку питонов, django-storages и boto. У меня есть пользовательская команда manage.py, которая работает корректно локально, она получает изображение из файловой системы и твиты этого изображения. Однако, если я изменяю хранилище на Amazon S3, я не могу получить доступ к файлу. Это дает мне эту ошибку:Django Tweepy не может получить доступ к файлу Amazon S3

raise TweepError('Unable to access file: %s' % e.strerror) 

Я попытался сделать изображения в ведре «общедоступными». Не работает. Это код (работает без 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 изображения Я хочу, чтобы чирикать, что-то вроде этого:

https://criptolibertad.s3.amazonaws.com/OrillaLibertaria/195.jpg?Signature=xxxExpires=1467645897&AWSAccessKeyId=yyy

Я также попытался создать URL-адрес вручную, так как это общедоступное изображение, хранящееся в моем ковше, например:

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, но как я могу заставить его работать? Любые советы помогут.

+0

url - это метод, а не атрибут. –

+0

@BurhanKhalid, как я могу его назвать? Если я делаю 'model_object.image.file.url()' Я получаю ошибку: ''Объект S3BotoStorageFile' не имеет атрибута 'url'' – alejoss

+0

' model_object.image.url() ' –

ответ

2

Проблема возникает, когда 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

+0

Спасибо за ваш ответ bro. У меня проблема. Я проработал пару часов, чтобы выполнить эту работу. Мой код теперь такой же, как у вас, однако я все равно получаю сообщение об ошибке «Невозможно получить доступ к файлу». Вы можете увидеть весь мой проект на этом репо, и здесь указаны точные строки: https://github.com/Alejoss/CrHisoka/blob/master/hisoka/management/commands/tweet.py. Почему я получаю сообщение об ошибке? Я понятия не имею. Но я подозреваю, что 'f' является' None' после 'f.write (model_object.image.read())'. Есть идеи? – alejoss

+0

Я не думаю, что f может быть ничем; может, он пуст? Ваш код выглядит солидно, я попытаюсь проверить его позже сегодня вечером и попробовать. Вы можете проверить, что у вашего пользователя aws есть s3 perms, как требуется – tutuDajuju

+0

Мне удалось использовать ваш код для загрузки медиа и твитов, см. Подробности в PR здесь: https://github.com/Alejoss/CrHisoka/pull/1 , – tutuDajuju