Sube un archivo a Amazon S3 con Boto3
Usa upload_file() de Boto3 para enviar un archivo local a un bucket privado de S3
existente. Esta guía te proporciona un comando que recibe un destino explícito, espera a que termine
la subida y finaliza con un estado de error si falla el archivo o la transferencia. Las credenciales
y los permisos del bucket permanecen en tu configuración de AWS.
La subida administrada de Boto3 se encarga de las transferencias multiparte de archivos grandes. Tú proporcionas un nombre de archivo, un nombre de bucket y una clave de objeto; no necesitas dividir el archivo por tu cuenta.
Prepara tu entorno
Los siguientes comandos usan Bash y Python 3.12 con venv y
pip en Linux. El ejemplo usa Boto3 1.43.100. Antes de ejecutarlo, necesitas:
- Un bucket de S3 privado y de uso general existente, su región de AWS y un prefijo en el que
puedas escribir, como
incoming/. Mantén habilitado S3 Block Public Access. - Un perfil de AWS autenticado. En una estación de trabajo, usa las credenciales temporales de tu
organización, como un perfil de IAM Identity Center.
Completa primero esa configuración; para un perfil existente llamado
uploads, renueva su sesión conaws sso login --profile uploadsmediante AWS CLI v2. No incluyas claves de acceso en el script. - Permiso para realizar
s3:PutObjecten los objetos de destino, por ejemplo,arn:aws:s3:::your-bucket-name/incoming/*. Permites3:AbortMultipartUploaden ese ámbito para limpiar las subidas multiparte fallidas. Consulta los permisos de operaciones multiparte de AWS. El script no enumera ni descarga objetos, por lo que no necesitas3:ListBucketnis3:GetObject.
Crea un directorio nuevo y un entorno de Python aislado. La cadena && se
detiene si falla un paso; si boto3-upload ya existe, elige otro nombre de directorio
antes de continuar.
mkdir boto3-upload &&
cd boto3-upload &&
python3 -m venv .venv &&
.venv/bin/python -m pip install 'boto3==1.43.100'
Continúa desde boto3-upload una vez que la instalación finalice correctamente. El
siguiente comando supone que usas el perfil uploads y
us-east-1; reemplázalos por tu perfil y la región del bucket.
La cadena de credenciales de Boto3 también puede
usar un rol de IAM asociado en AWS. En ese entorno, omite AWS_PROFILE en lugar de
copiar las credenciales de la estación de trabajo al servidor. Las credenciales del entorno pueden
tener prioridad sobre un perfil, así que elimina de tu shell las credenciales obsoletas que lo
sobrescriban si Boto3 selecciona la identidad equivocada.
Guarda el comando de subida
Guarda este programa completo como upload.py en el nuevo directorio. Acepta un
solo archivo regular, incluso si está vacío, y rechaza una ruta inexistente o un directorio antes
de crear un cliente de S3.
import argparse
import sys
from pathlib import Path
import boto3
from boto3.exceptions import S3UploadFailedError
from botocore.exceptions import BotoCoreError, ClientError
def main():
parser = argparse.ArgumentParser(description="Upload one file to S3.")
parser.add_argument("file", type=Path, help="Local file to upload")
parser.add_argument("bucket", help="Existing S3 bucket name")
parser.add_argument("key", help="Full destination object key")
args = parser.parse_args()
if not args.bucket or not args.key:
parser.error("bucket and key must not be empty")
try:
if not args.file.is_file():
parser.error("file must be an existing regular file")
s3 = boto3.client("s3")
s3.upload_file(str(args.file), args.bucket, args.key)
except (S3UploadFailedError, BotoCoreError, ClientError, OSError) as error:
print(f"Upload failed ({type(error).__name__}).", file=sys.stderr)
return 1
print(f"Uploaded to s3://{args.bucket}/{args.key}")
return 0
if __name__ == "__main__":
sys.exit(main())
La implementación de la subida
devuelve None si se completa correctamente y lanza una excepción si falla.
No evalúes su valor de retorno como una condición booleana. El programa imprime el mensaje de éxito
solo después de que termina la llamada y captura tanto los fallos de transferencia administrada
como los errores de nivel inferior del SDK o del sistema de archivos. Informa del tipo de excepción
sin volcar la respuesta completa del servicio.
El cliente usa HTTPS con verificación de certificados de forma predeterminada. Mantén esos valores predeterminados para AWS y elimina cualquier configuración personalizada del endpoint que haya quedado de las pruebas locales. El cifrado en reposo y los permisos de acceso son configuraciones independientes que se explican más adelante.
Ejecútalo con una clave de objeto explícita
Elige un archivo local y su destino antes de ejecutar el comando. Aquí, ./report.pdf
es un archivo existente que colocas en boto3-upload; puedes sustituirlo por otra
ruta. Reemplaza your-bucket-name por el nombre de tu bucket, sin el prefijo
s3://.
AWS_PROFILE=uploads AWS_DEFAULT_REGION=us-east-1 \
.venv/bin/python upload.py './report.pdf' 'your-bucket-name' 'incoming/report.pdf'
La clave es el nombre completo dentro del bucket. S3 no la deduce de la ruta local ni añade el nombre
del archivo a incoming/. Escribe entre comillas las rutas y claves que contengan
espacios; si el nombre de un archivo local empieza con un guion, incluye su prefijo
./.
Para el destino que se muestra arriba, la salida cuando la subida se completa correctamente es:
Uploaded to s3://your-bucket-name/incoming/report.pdf
Volver a ejecutar este comando escribe de nuevo en la misma clave sin pedir confirmación. En un bucket sin control de versiones, eso reemplaza el objeto existente. Con el control de versiones habilitado, S3 conserva una nueva versión. Usa una clave distinta si necesitas conservar subidas separadas. Consulta el comportamiento de sobrescritura y control de versiones de AWS.
Para un programador de tareas u otro script, usa el estado del proceso: 0
significa que la subida terminó, 1 indica un fallo de subida capturado y
2 indica argumentos no válidos o una entrada que no existe o no es un
archivo. El archivo local permanece en su lugar. Un fallo de conexión puede dejar incierto el
resultado remoto si S3 aceptó una solicitud antes de que se perdiera la respuesta; comprueba el
destino antes de reintentar si una versión duplicada supondría un problema. Mantén el archivo de
origen sin cambios mientras lo subes.
Usa la configuración de cifrado del bucket
Amazon S3 cifra todos los objetos nuevos en reposo. SSE-S3, que usa AES256, es la opción predeterminada inicial del bucket y no tiene cargos adicionales de cifrado. Un administrador puede seleccionar otra opción predeterminada, como SSE-KMS. Como este programa no envía ninguna configuración que anule el cifrado predeterminado, S3 usa el valor predeterminado configurado en el bucket.
Para SSE-KMS, la identidad que realiza la subida necesita kms:GenerateDataKey en la clave;
las subidas multiparte también necesitan kms:Decrypt. La clave debe estar en la
región del bucket y su política debe permitir el uso previsto. AWS documenta estos
permisos y requisitos de KMS.
Una política de bucket que exija encabezados de cifrado explícitos puede rechazar este script
incluso cuando el cifrado predeterminado del bucket esté configurado. Antes de usar este ejemplo,
pregunta al propietario del bucket si se permiten subidas basadas en los valores predeterminados;
no debilites esa política para que se acepte una subida.
Deja el control de acceso en manos del propietario del bucket
Omitir una ACL no convierte cualquier bucket en privado. Usa el bucket privado y la identidad con
ámbito limitado que preparaste antes. Los buckets nuevos tienen habilitada de forma predeterminada
la configuración que exige que los objetos pertenezcan al propietario del bucket, lo que desactiva
las ACL. Añadir ACL='private' a una subida de ese tipo puede causar
AccessControlListNotSupported; administra el acceso mediante políticas y mantén Block Public Access
habilitado, como se describe en la guía de seguridad de S3 de AWS.
Pide al propietario del bucket que mantenga las reglas aplicables a todo el bucket, incluido cualquier requisito de denegar solicitudes que no usen HTTPS. El programa de subida no debería instalar una nueva política de bucket cada vez que envía un archivo.
Diagnostica una subida fallida
- Entrada no válida, estado
2: comprueba la ruta con respecto a tu directorio actual. Un directorio no es un archivo que se pueda subir; este comando no lo recorre de forma recursiva. NoCredentialsErroro una sesión caducada: selecciona el perfil previsto y renueva su sesión. Si el comando solo funciona en tu shell interactivo, confirma que el programador de tareas o el servicio tenga su propia identidad configurada.S3UploadFailedError: comprueba con el propietario el nombre del bucket, el prefijo exacto de la clave, el permiso de subida y cualquier denegación de la política del bucket. Para SSE-KMS, comprueba también los permisos de la clave. Esta excepción puede encapsular varios errores del servicio; su tipo por sí solo no demuestra que se haya denegado el acceso.EndpointConnectionErroru otro error de conexión: comprueba la red, la región, el proxy y la configuración del endpoint. No desactives la verificación de certificados para eludir un error de TLS.PermissionErroru otroOSError: comprueba que el proceso pueda leer el archivo y que este no se haya movido ni eliminado durante la subida.
Transfer Acceleration, las reglas de ciclo de vida y las notificaciones de eventos son decisiones independientes de administración del bucket. En particular, establecer una configuración de notificaciones de S3 reemplaza la configuración existente; añadir un activador de Lambda debe formar parte de un cambio de infraestructura revisado que conserve los destinos existentes. Asegúrate de que el comando de subida de un solo archivo funcione con la identidad y el prefijo previstos antes de integrarlo en una tarea programada.
