Faça upload de imagens e metadados para um bucket público do Amazon S3 com solicitações Python
-
21-12-2019 - |
Pergunta
Eu sei, existe a biblioteca boto para Python, no entanto, tudo que eu gostaria de fazer é enviar muitos arquivos de imagem, incluindo metadados, para um bucket S3 público.As imagens devem ir para vários subdiretórios dentro do intervalo.
Com cURL, isso deveria estar funcionando:
curl -v -F "key=test/test.jpg" -F "file=@test.jpg" http://my-public-bucket.s3.amazonaws.com/
Então, acho que isso deve ser possível apenas com solicitações urllib, urllib2 e/ou Python.Mas como?Sou totalmente novo no Amazon S3 ...e curvatura.
Além disso, qual é a melhor maneira de armazenar alguns metadados junto com as imagens?Um arquivo de string JSON adicional?
Solução
Sua string cURL se traduz aproximadamente no seguinte:
import requests
url = 'http://my-public-bucket.s3.amazonaws.com/'
files = {
'key': ('', 'test/test.jpg'),
'file': open('test.jpg', 'rb'),
}
r = requests.post(url, files=files)
A forma geral da sintaxe de multipart upload das solicitações é encontrada em esta resposta do StackOverflow.
Outras dicas
Usando boto
(versão 2.6.0) você faria assim:
import boto
connection = boto.connect_s3()
bucket = connection.get_bucket('mybucket')
key = bucket.new_key('myimage.jpg')
key.set_contents_from_filename('myimage.jpg')
key.set_metadata(...)
Certifique-se de ter as credenciais nas variáveis de ambiente AWS_ACCESS_KEY_ID
e AWS_SECRET_ACCESS_KEY
.
É isso.
Funciona apenas com solicitações Python:
import requests
r = requests.post('my_public_bucket', files={'file': open('/path/test.txt', 'rb')}, data={'key': 'test/test.txt'})
Para fazer upload para um URL assinado e solicitações, tive que fazer o seguinte:
with open('photo_1.jpg', 'rb') as content_file:
content = content_file.read()
result = requests.put(url=upload_url, headers={}, data=content)
Isso é ruim porque carrega tudo na memória, mas deve fazer você superar o obstáculo inicial.
Além disso, ao usar curl, tive que usar uma opção diferente:
curl -X PUT --upload-file photo_1.jpg <url>
Observação:Quando criei o URL em meu servidor com boto, configurei headers=None para que os cabeçalhos não fossem um problema.