Necesito recuperar una URL de objeto público directamente después de cargar un archivo, esto para poder almacenarlo en una base de datos. Este es mi código de carga:
s3 = boto3.resource('s3') s3bucket.upload_file(filepath, objectname, ExtraArgs={'StorageClass': 'STANDARD_IA'})
No estoy buscando una URL prefirmada, solo la URL que siempre será accesible públicamente a través de https.
Cualquier ayuda apreciada.
No hay una forma simple, pero puede construir la URL desde la región donde se encuentra el depósito ( get_bucket_location
), el nombre del depósito y la clave de almacenamiento:
bucket_name = "my-aws-bucket" key = "upload-file" s3 = boto3.resource('s3') bucket = s3.Bucket(bucket_name) bucket.upload_file("upload.txt", key) location = boto3.client('s3').get_bucket_location(Bucket=bucket_name)['LocationConstraint'] url = "https://s3-%s.amazonaws.com/%s/%s" % (location, bucket_name, key)
Desde 2010, puede usar una URL S3 de estilo alojado virtualmente, es decir, no es necesario meterse con las URL específicas de la región:
url = f'https://{bucket}.s3.amazonaws.com/{key}'
Con clave citada:
url = f'''https://{bucket}.s3.amazonaws.com/{urllib.parse.quote(key, safe="~()*!.'")}'''
Además, la compatibilidad con el modelo de estilo de ruta (URL específicas de la región) continúa para los depósitos creados el 30 de septiembre de 2020 o antes. Los depósitos creados después de esa fecha deben referenciarse mediante el modelo alojado virtual .
Véase también esta entrada de blog .
La concatenación de la clave sin procesar fallará para algunos caracteres especiales en la clave (por ejemplo, '+'), debe citarlos:
url = "https://s3-%s.amazonaws.com/%s/%s" % ( location, bucket_name, urllib.parse.quote(key, safe="~()*!.'"), )
O puedes llamar:
my_config = Config(signature_version = botocore.UNSIGNED) url = boto3.client("s3", config=my_config).generate_presigned_url( "get_object", ExpiresIn=0, Params={"Bucket": bucket_name, "Key": key} )
... como se describe aquí .