2017-07-23 5 views
1

J'utilise le framework Falcon et Pillow pour télécharger une photo de profil d'un contact vers S3, puis redimensionner cette image pour une vignette, puis télécharger cette image.Télécharger l'image miniature en S3 en utilisant Boto3

J'ai examiné d'autres réponses, mais certaines d'entre elles nécessitent bucket write access activated et d'autres utilisent la fonctionnalité default_storage de django que je n'ai pas.

client = boto3.client('s3', 
    aws_access_key_id=os.environ.get('AWS_ACCESS_KEY_ID'), 
    aws_secret_access_key=os.environ.get('AWS_SECRET_ACCESS_KEY') 
) 


class UploadResource(object): 

    def on_post(self, req, res): 
     #gathering file from SPA 
     contact_id = req.get_param('id') 
     filename = req.get_param('file').filename 
     file = req.get_param('file').file 
     salt = ''.join(chr(random.randint(97, 122)) for i in range(20)) 
     filename = salt + '-' + filename 
     filename_thumb = salt + '-thumb-' + filename 

     #uploading normal sized image 
     client.upload_fileobj(file, 'contacts-cloud-images', filename) 

     #pull down image again and resize 
     img = Image.open(requests.get(image_url, stream=True).raw) 
     img.thumbnail((50,50)) 
     print(img.format, img.size) 

     #save it to BytesIO container 
     io = BytesIO() 
     img.save(io, img.format) 

     #upload value of BytesIO container 
---> client.upload_fileobj(io.getvalue(), 'contacts-cloud-images', filename_thumb) 

je reçois l'erreur suivante de la ligne avec la flèche (---->):

ValueError: Fileobj must implement read

Répondre

1

L'erreur signifie client.upload_fileobj attend un objet de type fichier qui implémente une méthode read, mais vous est de lui passer le contenu de l'objet de type fichier (io.getvalue()) au lieu de l'objet de type fichier lui-même (io)

Ceci est un lien à la documentation de upload_fileobj

Note non liée Important: Une chose importante à noter est que vous nommant la variable qui contient votre tampon io. io est également le nom d'un module de la bibliothèque standard, et vous l'écrasez. Cela devrait être un non-non absolu. Malgré la portée locale de votre variable, je vous recommande de le renommer en quelque chose de signifiant, comme file_content ou image_content.

+0

Il est maintenant dit sur S3 que le fichier téléchargé est '0B'. Je ne suis pas sûr de ce qui est arrivé qui a causé le fichier ne contient aucune donnée dans le code ci-dessus. J'ai fini par télécharger l'objet 'io' au lieu d'utiliser la méthode' getvalue() '. (Je l'ai renommé aussi, merci pour cela.) – qarthandso

+0

Je vérifie que la ligne 'print (img.format, img.size)' imprime une valeur différente de zéro pour la taille. Pour clarifier, boto3 ne télécharge pas l'objet comme un fichier, il télécharge le contenu du fichier, mais il est construit de telle sorte que vous devez lui passer l'objet comme un fichier –

+0

Je vais aussi souligner que je ne voyez pas image_url défini n'importe où. Cependant, il est difficile de penser que c'est la cause du problème, puisque requests.get soulèverait une erreur si image_url ne contient pas une URL valide, et Image.open déclenchera une erreur si le corps de la requête ne contient pas une image valide –