Envoyer un fichier vers Amazon S3 avec Boto3
Utilisez upload_file() de Boto3 pour envoyer un fichier local vers un bucket S3 privé existant. Ce guide
vous fournit une commande qui prend une destination explicite, attend la fin de l’envoi et se termine
avec un code d’échec lorsque le fichier ou le transfert échoue. Les identifiants et les autorisations
du bucket restent dans votre configuration AWS.
L’envoi géré de Boto3 prend en charge les transferts multipartie des fichiers volumineux. Vous fournissez un nom de fichier, un nom de bucket et une clé d’objet ; vous n’avez pas besoin de découper le fichier vous-même.
Préparer votre environnement
Les commandes ci-dessous utilisent Bash et Python 3.12 avec venv et pip sous Linux. L’exemple utilise
Boto3 1.43.100. Avant de l’exécuter, il vous faut :
- Un bucket S3 privé à usage général existant, sa région AWS et un préfixe dans lequel vous avez
le droit d’écrire, tel que
incoming/. Laissez S3 Block Public Access activé. - Un profil AWS authentifié. Sur un poste de travail, utilisez les identifiants temporaires de votre
organisation, par exemple un profil IAM Identity Center.
Terminez d’abord cette configuration ; pour un profil existant nommé
uploads, renouvelez sa session avecaws sso login --profile uploadsà l’aide d’AWS CLI v2. Ne placez pas de clés d’accès dans le script. - L’autorisation d’effectuer
s3:PutObjectsur les objets de destination, par exemplearn:aws:s3:::your-bucket-name/incoming/*. Autorisezs3:AbortMultipartUploadsur ce même périmètre pour nettoyer les envois multipartie en échec. Consultez les autorisations multipartie d’AWS. Le script ne liste ni ne télécharge d’objets ; il n’a donc pas besoin des3:ListBucketni des3:GetObject.
Créez un nouveau répertoire et un environnement Python isolé. La chaîne && s’arrête si une étape
échoue ; si boto3-upload existe déjà, choisissez un autre nom de répertoire avant de continuer.
mkdir boto3-upload &&
cd boto3-upload &&
python3 -m venv .venv &&
.venv/bin/python -m pip install 'boto3==1.43.100'
Une fois l’installation réussie, poursuivez depuis boto3-upload. La commande ci-dessous suppose le
profil uploads et us-east-1 ; remplacez-les par votre profil et la région du bucket.
La chaîne d’identifiants de Boto3 peut aussi
utiliser un rôle IAM attaché sur AWS. Dans cet environnement, omettez AWS_PROFILE au lieu de copier
les identifiants du poste de travail sur le serveur. Les identifiants définis dans l’environnement
peuvent être prioritaires sur un profil ; si Boto3 sélectionne la mauvaise identité, supprimez donc
de votre shell les remplacements d’identifiants obsolètes.
Enregistrer la commande d’envoi
Enregistrez ce programme complet sous upload.py dans le nouveau répertoire. Il accepte un seul fichier
ordinaire, y compris un fichier vide, et rejette un chemin inexistant ou un répertoire avant de créer
un client 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())
L’implémentation de l’envoi
renvoie None en cas de succès et lève une exception en cas d’échec. Ne testez pas sa valeur de
retour dans une condition booléenne. Le programme n’affiche le succès qu’une fois l’appel terminé, et
intercepte à la fois les échecs du transfert géré et les erreurs de plus bas niveau du SDK ou du
système de fichiers. Il indique le type d’exception sans afficher la réponse complète du service.
Le client utilise HTTPS avec vérification des certificats par défaut. Conservez ces valeurs par défaut pour AWS et supprimez tout remplacement de point de terminaison personnalisé laissé par des tests locaux. Le chiffrement au repos et les autorisations d’accès sont des paramètres distincts, traités ci-dessous.
Exécuter la commande avec une clé d’objet explicite
Choisissez un fichier local et sa destination avant d’exécuter la commande. Ici, ./report.pdf est un
fichier existant que vous placez dans boto3-upload ; vous pouvez indiquer un autre chemin. Remplacez
your-bucket-name par le nom de votre bucket, sans préfixe s3://.
AWS_PROFILE=uploads AWS_DEFAULT_REGION=us-east-1 \
.venv/bin/python upload.py './report.pdf' 'your-bucket-name' 'incoming/report.pdf'
La clé est le nom complet dans le bucket. S3 ne la déduit pas du chemin local et n’ajoute pas le nom
du fichier à incoming/. Mettez entre guillemets les chemins et les clés qui contiennent des espaces ;
pour un nom de fichier local commençant par un tiret, incluez son préfixe ./.
Pour la destination indiquée ci-dessus, la sortie en cas de succès est :
Uploaded to s3://your-bucket-name/incoming/report.pdf
Relancer cette commande réécrit la même clé sans demander de confirmation. Dans un bucket sans gestion des versions, l’objet existant est alors remplacé. Si la gestion des versions est activée, S3 conserve une nouvelle version. Utilisez une clé différente si vous devez conserver des envois distincts. Consultez la documentation AWS sur le comportement d’écrasement et de gestion des versions.
Pour un planificateur ou un autre script, utilisez le code de sortie du processus : 0 signifie que
l’envoi s’est terminé, 1 signale un échec d’envoi intercepté et 2 indique des arguments
invalides ou une entrée absente ou qui n’est pas un fichier. Le fichier local reste en place. Un échec
de connexion peut laisser le résultat distant incertain si S3 a accepté une requête avant que la
réponse ne soit perdue ; vérifiez la destination avant de réessayer si une version en double poserait
problème. Ne modifiez pas le fichier source pendant son envoi.
Utiliser les paramètres de chiffrement du bucket
Amazon S3 chiffre au repos tous les nouveaux objets. SSE-S3, qui utilise AES256, est le chiffrement par défaut initial des buckets et n’entraîne aucun coût de chiffrement supplémentaire. Un administrateur peut choisir un autre chiffrement par défaut, comme SSE-KMS. Comme ce programme n’envoie aucune option de chiffrement qui remplacerait la valeur par défaut, S3 applique le chiffrement par défaut configuré pour le bucket.
Avec SSE-KMS, l’identité qui effectue l’envoi a besoin de kms:GenerateDataKey sur la clé ; les envois multipartie
nécessitent aussi kms:Decrypt. La clé doit se trouver dans la région du bucket, et sa stratégie de clé
doit autoriser l’usage prévu. AWS documente ces autorisations et exigences KMS.
Une stratégie de bucket qui exige des en-têtes de chiffrement explicites peut rejeter ce script même
lorsque le chiffrement par défaut du bucket est configuré. Avant d’utiliser cet exemple, demandez au
propriétaire du bucket si les envois reposant sur le chiffrement par défaut sont autorisés ;
n’assouplissez pas cette stratégie pour faire passer un envoi.
Laisser le contrôle d’accès au propriétaire du bucket
Omettre une ACL ne rend pas privé un bucket quelconque. Utilisez le bucket privé et l’identité aux
droits restreints préparés plus tôt. Les nouveaux buckets utilisent par défaut le paramètre qui impose
le propriétaire du bucket (bucket owner enforced), ce qui désactive les ACL. Ajouter ACL='private' à un
tel envoi peut provoquer AccessControlListNotSupported ;
gérez l’accès au moyen de stratégies et laissez Block Public Access activé, comme le décrivent les
recommandations de sécurité S3 d’AWS.
Laissez le propriétaire du bucket gérer les règles qui s’appliquent à l’ensemble du bucket, y compris toute exigence de refus des requêtes non HTTPS. Le programme d’envoi ne devrait pas installer une nouvelle stratégie de bucket à chaque fichier envoyé.
Diagnostiquer un envoi en échec
- Entrée invalide, code
2: vérifiez le chemin par rapport à votre répertoire courant. Un répertoire n’est pas un fichier pouvant être envoyé ; cette commande ne le parcourt pas récursivement. NoCredentialsErrorou session expirée : sélectionnez le profil prévu et renouvelez sa connexion. Si la commande ne fonctionne que dans votre shell interactif, vérifiez que le planificateur ou le service dispose de sa propre identité configurée.S3UploadFailedError: vérifiez le nom du bucket, le préfixe de clé exact, l’autorisation d’envoi et, avec le propriétaire, tout refus lié à une stratégie de bucket. Avec SSE-KMS, vérifiez aussi les autorisations de la clé. Cette exception peut encapsuler plusieurs erreurs de service ; son type seul ne prouve pas que l’accès a été refusé.EndpointConnectionErrorou autre erreur de connexion : vérifiez la configuration du réseau, de la région, du proxy et du point de terminaison. Ne désactivez pas la vérification des certificats pour contourner une erreur TLS.PermissionErrorou autreOSError: vérifiez que le processus peut lire le fichier et que celui-ci n’a pas été déplacé ou supprimé pendant l’envoi.
Transfer Acceleration, les règles de cycle de vie et les notifications d’événements relèvent de décisions distinctes de gestion du bucket. En particulier, définir une configuration de notification S3 remplace la configuration existante ; l’ajout d’un déclencheur Lambda doit passer par une modification d’infrastructure revue, qui préserve les destinations existantes. Faites fonctionner la commande pour un seul fichier avec l’identité et le préfixe prévus avant de l’intégrer à une tâche planifiée.
