Je suis en train d'essayer de télécharger des fichiers sur s3 à l'aide de Boto3, de rendre public ce fichier téléchargé et de le renvoyer sous forme d'URL.
class UtilResource(BaseZMPResource):
class Meta(BaseZMPResource.Meta):
queryset = Configuration.objects.none()
resource_name = 'util_resource'
allowed_methods = ['get']
def post_list(self, request, **kwargs):
fileToUpload = request.FILES
# write code to upload to amazone s3
# see: https://boto3.readthedocs.org/en/latest/reference/services/s3.html
self.session = Session(aws_access_key_id=settings.AWS_KEY_ID,
aws_secret_access_key=settings.AWS_ACCESS_KEY,
region_name=settings.AWS_REGION)
client = self.session.client('s3')
client.upload_file('zango-static','fileToUpload')
url = "some/test/url"
return self.create_response(request, {
'url': url // return's public url of uploaded file
})
J'ai cherché dans toute la documentation mais je n'ai trouvé aucun lien décrivant comment faire. Quelqu'un peut-il expliquer ou fournir une ressource où je peux trouver l'âme?
Je suis dans la même situation .. Impossible de trouver quoi que ce soit dans la documentation Boto3 au-delà de generate_presigned_url, ce qui n'est pas ce dont j'ai besoin dans mon cas car j'ai des objets S3 lisibles en public.
Le meilleur que j'ai trouvé est:
bucket_location = boto3.client('s3').get_bucket_location(Bucket=s3_bucket_name)
object_url = "https://s3-{0}.amazonaws.com/{1}/{2}".format(
bucket_location['LocationConstraint'],
s3_bucket_name,
key_name)
Vous pouvez essayer de publier sur la liste des problèmes de boto3 github pour une meilleure solution.
J'ai eu le même problème… .. En supposant que vous connaissiez le nom du compartiment dans lequel vous souhaitez stocker vos données, vous pouvez ensuite utiliser les éléments suivants:
import boto3
from boto3.s3.transfer import S3Transfer
credentials = {
'aws_access_key_id': aws_access_key_id,
'aws_secret_access_key': aws_secret_access_key
}
client = boto3.client('s3', 'us-west-2', **credentials)
transfer = S3Transfer(client)
transfer.upload_file('/tmp/myfile', bucket, key,
extra_args={'ACL': 'public-read'})
file_url = '%s/%s/%s' % (client.meta.endpoint_url, bucket, key)
La meilleure solution que j'ai trouvée est toujours d'utiliser le generate_presigned_url
, mais le Client.Config.signature_version
doit être défini sur botocore.UNSIGNED
.
Ce qui suit renvoie le lien public sans les éléments de signature.
config.signature_version = botocore.UNSIGNED
boto3.client('s3', config=config).generate_presigned_url('get_object', ExpiresIn=0, Params={'Bucket': bucket, 'Key': key})
Les discussions pertinentes sur le référentiel boto3 sont:
Quelqu'un qui souhaite créer une URL directe pour un objet accessible au public afin d'éviter d'utiliser generate_presigned_url
pour une raison quelconque,
Veuillez construire l'URL avec urllib.parse.quote_plus
en tenant compte des espaces et des problèmes de caractères spéciaux.
2018-11-26 16:34:48.351890+09:00.jpg
veuillez noter les espaces et ':' https://s3.my_region.amazonaws.com/my_bucket_name/2018-11-26+16%3A34%3A48.351890%2B09%3A00.jpg
Le code ci-dessous était OK pour moi
import boto3
s3_client = boto3.client
bucket_location = s3_client.get_bucket_location(Bucket='my_bucket_name')
url = "https://s3.{0}.amazonaws.com/{1}/{2}".format(bucket_location['LocationConstraint'], 'my_bucket_name', quote_plus('2018-11-26 16:34:48.351890+09:00.jpg')
print(url)