Solución:
Encontré algo de tiempo para experimentar con esto y esto es lo que encontré.
>>> import boto
>>> c =boto.connect_s3()
>>> fp = open('myfiletoupload.txt')
>>> content_length = len(fp.read())
>>> c.generate_url(300, 'PUT', 'test-1332789015', 'foobar', headers={'Content-Length': str(content_length)}, force_http=True)
'http://test-1332789015.s3.amazonaws.com/foobar?Signature=oUARG45mR95utXsiQYRJNiCI4x4%3D&Expires=1333731456&AWSAccessKeyId=AKIAJOTCCJRP4C3NSMYA&Content-Length=16'
Luego pude usar curl para PONER el archivo a esa url de esta manera:
$ curl --request PUT --upload-file myfiletoupload.txt "http://test-1332789015.s3.amazonaws.com/foobar?Signature=oUARG45mR95utXsiQYRJNiCI4x4%3D&Expires=1333731456&AWSAccessKeyId=AKIAJOTCCJRP4C3NSMYA&Content-Length=16"
Esto dio como resultado que el archivo se cargara en el depósito. Entonces, parece que es posible. Es posible que desee ver si puede calcular el valor content-md5 e incluirlo en los encabezados, pero luego también debe averiguar cómo hacer que curl envíe ese encabezado. Además, debería poder hacer que esto funcione a través de HTTPS en lugar de HTTP, pero no lo he intentado.
Así es como se ve en boto3 (probado con la versión 1.2.3).
Primero, cree una URL pre-firmada con s3.generate_presigned_url
método:
>>> import boto3
>>> s3 = boto3.client('s3')
>>> s3.generate_presigned_url('put_object', Params={'Bucket':'YourBucket', 'Key':'YourKey'}, ExpiresIn=3600, HttpMethod='PUT')
u'https://s3-ap-northeast-1.amazonaws.com/YourBucket/YourKey?AWSAccessKeyId=AKIAXXXXXXXXXXXXXXXX&Expires=1451061671&Signature=%2FtyAyCd5vrp13p%2FqLdoPkox7yTM%3D'
PONER a S3 con una URL predefinida
$ curl
--request PUT
--upload-file path/to/file
"https://s3-ap-northeast-1.amazonaws.com/YourBucket/YourKey?AWSAccessKeyId=AKIAXXXXXXXXXXXXXXXX&Expires=1451061671&Signature=%2FtyAyCd5vrp13p%2FqLdoPkox7yTM%3D"
Todas las demás respuestas asumen que el archivo se cargará con curl
, que realmente no es conveniente en la mayoría de los scripts de Python. A continuación, se genera una URL firmada previamente con boto3
y el archivo se carga con el requests
Biblioteca:
session = boto3.Session(aws_access_key_id="XXX", aws_secret_access_key="XXX")
s3client = session.client('s3')
url = s3client.generate_presigned_url('put_object', Params={'Bucket': 'mybucket', 'Key': 'mykey'})
requests.put(url, data=open("/path/to/file").read())