Intégration API

S3 : HTTP 200, export non finalisé

Jérémy Chomel Dawap
  • Date éditoriale : 6 septembre 2025
  • Temps de lecture : 17 minutes
  1. Pour qui : un export volumineux dont la finalisation reste incertaine
  2. Lire le résultat de CompleteMultipartUpload jusqu’au bout
  3. Construire la demande finale avec les reçus du producteur
  4. Exercice : suivre quinze requêtes préparées par Botocore
  5. Erreurs fréquentes : appliquer le même retry à des refus différents
  6. Plan d’action : reprendre EXP-309 sans inventer son historique
  7. Conclusion : la finalisation doit porter un résultat interprété
Portrait de Jérémy Chomel

Le job d’export est vert, le journal indique HTTP 200, pourtant le document attendu n’apparaît pas dans le traitement partenaire. Sur Amazon S3, le risque est de clôturer la livraison sur les en-têtes avant de lire le résultat multipart complet. Le service peut commencer une réponse de succès, puis signaler une erreur dans son corps. Contrairement à ce que laisse penser le statut 200, cette tentative peut donc avoir échoué : le connecteur laisse alors la gestion attendre un fichier non finalisé.

Le scénario fictif EXP-309 suit une extraction CSV transmise en deux parties. Il sert à examiner trois décisions précises : interpréter la réponse de finalisation, conserver les reçus des parties réellement envoyées et décider quelle tentative peut être reprise. Recalculer l’export ou récupérer une liste distante ne suffit pas à reconstruire ces décisions. L’identité de l’envoi et la version du fichier doivent rester liées jusqu’au résultat examiné par le destinataire.

Nous avons exécuté un exercice original avec Botocore 1.43.114 : 72 contrôles observent quinze échanges à réponses préparées, sans connexion à AWS. Le véritable client prépare les requêtes, décode le XML et traite les erreurs. Ce laboratoire révèle ce que fait le SDK installé ; il ne prouve ni la conservation d’octets dans S3, ni les autorisations d’un compte, ni la validation d’un import ERP. Le jeu de données est entièrement fictif.

Notre prestation d’intégration AWS pour les échanges de fichiers métier peut partir de cette frontière entre transfert et finalisation. Dans un projet d’intégration API entre ERP et applications partenaires, nous recherchons l’opération qui manque réellement à la livraison. Vous allez voir quelles preuves conserver, quels refus interdisent un simple retry et pourquoi le compteur de parties transférées ne doit pas fermer le dossier documentaire.

Pour qui : un export volumineux dont la finalisation reste incertaine

Retrouver le client qui transforme la réponse S3 en statut métier

Le cas concerne une application qui utilise les opérations multipart de S3 pour déposer un fichier : préparation d’un envoi, transfert de parties, puis demande de composition. Cela peut être un export ERP, un document volumineux remis à un partenaire ou un fichier produit par un traitement asynchrone. Il faut identifier le composant qui décide « document disponible » : un client officiel, un adaptateur HTTP, un navigateur ou une passerelle qui résume la réponse.

Cette précision évite un mauvais correctif. Si un SDK officiel lève déjà une exception mais que l’adaptateur la remplace par un statut vert, modifier le découpage du fichier ne résoudra rien. Si le connecteur lit seulement les en-têtes d’une réponse HTTP, la perte d’information se situe plus tôt. Le diagnostic commence donc à l’endroit où le résultat natif devient une décision de clôture, avec la version du client et sa configuration de retry.

Séparer l’objet absent, l’ancien objet et le fichier refusé en aval

Un objet introuvable après finalisation n’est pas le même incident qu’un objet existant dont le contenu est ancien. Un fichier présent mais rejeté par le lecteur CSV ouvre encore un autre dossier. EXP-309 vise une nouvelle clé d’objet, avec une création conditionnelle ; il ne propose pas une méthode générale pour remplacer un document déjà publié. Si votre traitement écrase toujours le même nom, la politique de version et les producteurs concurrents doivent être qualifiés avant toute reprise.

Le coût caché apparaît quand le service métier demande plusieurs régénérations pour compenser une livraison qu’il ne sait pas retrouver. Les équipes manipulent alors des fichiers portant le même nom, avec des dates et des contenus différents. Le support doit pouvoir dire quelle extraction était attendue et quelle tentative lui correspond. Une nouvelle extraction peut être légitime, mais elle doit recevoir sa propre identité plutôt que réparer silencieusement l’histoire de la précédente.

Lire le résultat de CompleteMultipartUpload jusqu’au bout

Ne pas clôturer sur les seuls en-têtes de succès

La référence officielle de CompleteMultipartUpload décrit une réponse qui peut commencer en HTTP 200 pendant le traitement, puis contenir une erreur. Un client HTTP direct doit donc examiner le corps reçu complètement. Une métrique qui compte seulement les statuts 2xx peut annoncer un succès alors que l’opération n’a pas livré l’objet attendu. Le problème ne se règle pas en renommant cette métrique « succès métier ».

Dans notre réponse préparée, le corps contient un élément Error portant le code InternalError. Botocore 1.43.114 le reconnaît dans son traitement S3 et produit une exception dont les métadonnées indiquent un statut reclassé à 500. Le témoin conserve aussi le statut 200 fourni à l’entrée. Ces deux observations ne se contredisent pas : elles correspondent à la réponse préparée et à son interprétation par le client. Aucun serveur AWS n’a émis cette erreur pendant l’expérience.

Tracer l’exception sans masquer les relances du SDK

Les clients officiels peuvent traiter ces erreurs et appliquer leur politique de nouvelle tentative. Le témoin fixe le nombre total d’essais à un pour rendre chaque échange visible : il observe zéro retry implicite. Ce réglage sert au laboratoire, pas à recommander la suppression des relances en production. Votre diagnostic doit relever les paramètres effectifs, car une seule invocation applicative peut autrement représenter plusieurs requêtes vers le service.

La journalisation rapproche l’export EXP-309, l’UploadId concerné, l’opération, l’exception décodée et les tentatives autorisées. Une passerelle qui conserve uniquement la durée et le premier statut HTTP perd le signal nécessaire au support. Le monitoring doit distinguer un transfert accepté d’une composition confirmée. Le seuil d’alerte, convenu avec le destinataire, porte sur le temps entre le dernier reçu de partie et la finalisation confirmée. Un dépassement ouvre l’investigation du dossier ; il ne déclenche pas une nouvelle extraction. Ce signal faible reste utile même lorsque les graphiques de disponibilité demeurent verts.

Construire la demande finale avec les reçus du producteur

Conserver UploadId, PartNumber et ETag sans les réinventer

La vue d’ensemble du multipart S3 demande de conserver sa propre liste des numéros de parties et des ETag retournés pour préparer la finalisation. Cette liste appartient à une tentative identifiée par son UploadId. Notre proposition lui associe également la révision d’extraction et une empreinte locale du fichier source. Ces informations ont des fonctions différentes : la référence d’envoi désigne le transfert, tandis que la révision et l’empreinte rattachent ce transfert aux octets attendus.

Le témoin transmet 5 400 019 octets, découpés en une première partie de 5 242 880 octets et une dernière de 157 139 octets. La première respecte la taille minimale retenue pour cette configuration de bucket généraliste ; la dernière constitue la fin du fichier. Ce petit fichier sert à l’essai, sans fixer le seuil de passage au multipart de votre application. Le SDK renvoie les ETag fournis par nos réponses préparées. Nous les gardons comme des valeurs opaques : le mapping ne retire pas leurs guillemets et ne les remplace pas par une empreinte calculée sur la source.

La référence UploadPart précise qu’un nouvel envoi utilisant le même numéro remplace la partie précédente pour cet upload. Un reçu ne peut donc pas être conservé indéfiniment comme si ce numéro désignait toujours les mêmes octets. Le producteur doit lier le reçu à la tentative qui a accepté sa tranche. La demande finale du laboratoire reprend les deux reçus, triés par numéro, sans confondre cet ordre avec celui dans lequel le support les a retrouvés. Le payload XML de cette API REST contient les numéros de parties et les ETag que notre client soumet à la composition. Le fragment suivant reformate ce XML réellement observé.

<CompleteMultipartUpload xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  <Part>
    <PartNumber>1</PartNumber>
    <ETag>"opaque-part-one"</ETag>
  </Part>
  <Part>
    <PartNumber>2</PartNumber>
    <ETag>"opaque-part-two"</ETag>
  </Part>
</CompleteMultipartUpload>

Utiliser ListParts comme contrôle, pas comme plan de livraison

La pagination de ListParts doit être parcourue jusqu’à sa fin. Notre jeu d’essai force deux pages et vérifie que le marqueur natif de continuation passe dans la requête suivante. Le programme refuse une page tronquée qui n’offre pas de marqueur exploitable. Une première page rassurante ne permet pas de conclure qu’un envoi est complet ; il faut connaître la fin de la collection avant de rapprocher les parties du dossier source.

La règle locale proposée exige la même liste de numéros, de tailles et d’ETag que les reçus conservés. Elle bloque une partie absente, une partie étrangère et un ETag différent. Ce rapprochement ne transforme pas l’inventaire en preuve d’identité du fichier : une liste distante ne restitue ni l’intention du producteur ni sa révision d’export. Sans les reçus initiaux, la reprise doit traiter cette perte de preuve plutôt que fabriquer une composition à partir de tout ce qu’elle trouve.

Qualifier séparément le checksum et l’identité de la livraison

L’ETag d’un objet multipart ne doit pas être présenté comme son empreinte MD5 complète. Le contrôle d’intégrité documenté par AWS distingue notamment les checksums portant sur l’objet complet et les checksums composites. L’algorithme, le type et les champs fournis doivent correspondre au mode retenu. Comparer deux chaînes qui utilisent des conventions différentes peut créer une fausse alerte, ou donner une assurance injustifiée sur le fichier remis au partenaire.

Dans EXP-309, l’empreinte SHA-256 répond à une question locale : avons-nous encore les mêmes octets source avant de construire la demande ? Elle ne répond pas à la question distante : quels octets S3 a-t-il effectivement conservés ? La recette doit ajouter le mécanisme d’intégrité choisi et la lecture nécessaire à la livraison réelle. Même un fichier intègre peut appartenir à la mauvaise extraction ; la référence métier et la révision restent donc nécessaires à côté du contrôle des octets.

Exercice : suivre quinze requêtes préparées par Botocore

Observer le vrai client avant tout accès réseau

Le programme complet de finalisation multipart utilise Botocore 1.43.114 sous Python 3.14.8. Des gestionnaires d’événements before-send.s3 retournent les réponses préparées avant l’appel au transport HTTP. Le sérialiseur, le parseur et les gestionnaires d’erreurs S3 restent ceux du paquet installé. Il s’agit de quinze passages par ces événements, pas de quinze connexions ni d’un service S3 simulé avec sa persistance.

python3 -m venv .venv-s3
.venv-s3/bin/python -m pip install botocore==1.43.114
.venv-s3/bin/python -B multipart_completion_receipts.py
# checks_passed: 72
# prepared_before_send_invocations: 15
# real_http_requests: 0
# connection_attempts: 0

L’installation depuis le registre demande un accès réseau distinct. Pendant l’essai, les appels HTTP réels et les connexions instrumentées sont bloqués. Le client emploie une adresse .invalid et ne signe pas les requêtes. Le calcul automatique des checksums facultatifs est désactivé pour isoler l’observation ; l’empreinte SHA-256 de la source sert uniquement de liaison locale. Le programme ne démontre aucune vérification de checksum effectuée par AWS.

Lire les contre-exemples autant que la réponse acceptée

Les quinze échanges couvrent la création d’un upload, deux transferts, deux pages d’inventaire, une finalisation en erreur, une réponse de succès distinctement préparée et une lecture de propriétés. Trois finalisations refusées et quatre lectures d’inventaires anormaux complètent l’ensemble. Le succès fourni après l’erreur ne prouve pas qu’AWS accepterait une relance dans cette situation : le laboratoire fournit ces réponses séparément pour examiner le comportement du client, sans moteur de stockage entre les appels.

Cas du laboratoireObservation obtenue
HTTP 200 contenant ErrorException InternalError, statut client reclassé
Inventaire réparti sur deux pagesMarqueur repris dans la seconde requête
Reçus présentés dans l’ordre inverseParties soumises dans l’ordre numérique
ETag distant différentAucune demande finale supplémentaire
Source modifiée à taille égaleReprise refusée avant requête
Succès technique préparéAucune référence ERP publiée

Le programme compare aussi un fragment source à une substitution de même taille. Il montre pourquoi un contrôle de métadonnées n’observe pas les octets stockés à distance. De même, la réponse HEAD préparée permet de vérifier le décodage de la taille et de l’ETag, sans lire les lignes du CSV. Le seuil du témoin est explicite : zéro référence documentaire écrite dans l’état ERP fictif. L’acceptation fonctionnelle du fichier reste une étape à tester avec son véritable destinataire.

Erreurs fréquentes : appliquer le même retry à des refus différents

Examiner InvalidPart avant de renvoyer la même composition

La réponse préparée InvalidPart est conservée avec son statut 400. Le témoin ne l’assimile pas à une panne temporaire. Dans une investigation réelle, on rapproche l’UploadId, les reçus et les parties encore disponibles avant de soumettre une correction. Changer le numéro d’une partie ou recopier son ETag depuis une autre tentative n’est pas une réparation neutre : cela modifie le contenu de la demande qui doit produire le document.

Le contexte source doit être relu au même moment. Le contrôle local refuse une révision différente et un contenu de même taille dont l’empreinte a changé. Cela traite, par exemple, un job qui retrouve le chemin du CSV, alors que ce chemin contient désormais l’extraction suivante. Si les octets d’origine n’existent plus, la décision porte sur une nouvelle livraison à identifier. Elle ne consiste pas à continuer un upload ancien avec les parties d’un nouveau fichier.

Distinguer conflit de création et précondition refusée

Notre client envoie If-None-Match: * sur la finalisation d’une nouvelle clé. Les réponses préparées 409 ConditionalRequestConflict et 412 PreconditionFailed produisent deux exceptions distinctes. Le programme prouve leur décodage et la présence de l’en-tête, sans tester son application par S3. La procédure native de conflit conditionnel impose de réinitialiser l’envoi multipart et de retransmettre les parties après ce 409 ; elle ne se résume pas à répéter indéfiniment la même requête finale.

Une précondition refusée doit aussi faire examiner l’objet déjà présent et l’intention de création. Retirer l’en-tête pour faire passer le job pourrait transformer une création protégée en remplacement. Le runbook doit réserver cette décision à un responsable autorisé, avec une vérification du document qui existe et du dossier qui l’a publié. Le second signal faible est précisément une hausse de ces refus sur une clé supposée unique : elle peut révéler une collision de producteurs ou une politique de nommage devenue ambiguë.

La recette connectée exige aussi la signature AWS Signature Version 4 prévue pour ces écritures conditionnelles ; le client non signé du laboratoire ne la teste pas. Dans un bucket versionné, la condition porte sur la version courante, avec le cas particulier d’un marqueur de suppression. Enfin, un upload multipart en cours ne réserve pas à lui seul la clé contre un autre producteur. L’UploadId permet de suivre une tentative ; la politique de création décide comment cette tentative peut publier son objet.

Plan d’action : reprendre EXP-309 sans inventer son historique

Constituer le dossier de reprise avant de changer le connecteur

Le responsable de l’extraction retrouve la révision et les octets attendus. L’équipe AWS qualifie le bucket, la clé, l’identité technique et les opérations autorisées. L’intégrateur rapproche les reçus de transfert et le résultat de finalisation ; le destinataire précise ce qui autorise réellement l’import. Lorsque l’ERP est maintenu par un autre prestataire, Dawap coordonne cette investigation avec lui pour éviter qu’une régénération fonctionnelle soit confondue avec une réparation du transfert.

  1. Retrouver l’export demandé, sa révision et l’UploadId de la tentative à examiner.
  2. Contrôler le corps complet de finalisation, l’exception du client et les retries effectifs.
  3. Rapprocher les reçus du producteur avec toutes les pages de parties disponibles.
  4. Décider correction, nouvel envoi ou investigation de conflit selon le refus natif observé.
  5. Vérifier l’objet publié et sa prise en charge avant de diffuser sa référence documentaire.

La première recette provoque une erreur dans un HTTP 200, puis une perte de reçu et un changement de source entre deux tentatives. Les seuils d’admission viennent de ces cas : aucune finalisation construite depuis un inventaire incomplet, aucune reprise d’un upload attribué à une autre extraction et aucune clôture ERP sur un simple accusé HTTP. La recette connectée ajoute les producteurs concurrents, le timeout après traitement et le redémarrage du composant qui conserve les reçus. Le timeout laisse le résultat incertain : il faut retrouver la tentative avant de décider de la retransmission.

Faire durer les preuves et fermer les envois abandonnés

Dans le programme, source, reçus et décisions restent en mémoire. En production, leur persistance doit survivre au crash du job. Le contrat de reprise indique ce qui est enregistré avant et après chaque transfert, comment retrouver une tentative incertaine et où s’applique l’idempotence du traitement applicatif. Un rollback du connecteur doit pouvoir relire ces preuves ; il ne suffit pas de redéployer l’ancienne version si son format de reçus ne comprend plus les dossiers ouverts.

Les parties non finalisées ont aussi un coût de stockage à suivre. La procédure d’abandon d’un upload multipart doit tenir compte des transferts encore en cours ; leur arrêt n’est pas démontré par le seul envoi d’un abandon. Une politique de cycle de vie peut compléter ce nettoyage, avec son propre délai configuré. Le renouvellement d’un accès ou la relance d’un job ne remplace pas une décision explicite sur les envois devenus inutiles.

Les contrats restent propres à chaque fournisseur. La validation des blocs d’un export Azure Blob mobilise une liste et des règles de sélection différentes. La reprise d’un dépôt Google Drive après perte de réponse traite une autre identité de fichier. Ces comparaisons servent à choisir l’investigation adaptée, sans plaquer l’UploadId de S3 sur tous les échanges documentaires.

Conclusion : la finalisation doit porter un résultat interprété

EXP-309 rappelle une limite concrète d’un suivi fondé sur le statut HTTP : une réponse peut commencer par 200 sans aboutir à la finalisation attendue. Le client doit conserver son interprétation complète, tandis que les reçus relient la composition aux parties de la bonne extraction. Les 72 contrôles du laboratoire rendent ces frontières observables ; ils laissent à la recette AWS les preuves qui dépendent des droits, du stockage et des producteurs réels.

Avec notre accompagnement en intégration AWS reliée aux processus documentaires, un pilote peut cibler une extraction et un refus de finalisation réellement rencontrés. Nous examinons le client installé, les reçus conservés et la décision prise après l’exception, afin de corriger l’étape qui empêche le document d’être livré.

Dawap peut ensuite cadrer l’intégration API de cet export avec votre ERP et son destinataire. Le résultat recherché est un dossier que le support sait reprendre : une extraction connue, une tentative identifiable et une preuve de prise en charge à retrouver. L’extension à d’autres fichiers vient après cette recette, avec les responsabilités de reprise et le format des reçus explicités.

Portrait de Jérémy Chomel

Fiabiliser la livraison de vos exports S3

Dawap examine le client S3, les reçus de transfert et la finalisation pour définir une reprise exploitable avec vos équipes AWS, ERP et support.

Articles recommandés

Illustration de la reprise d’un export ERP Azure Blob entre blocs transférés et validation du fichier Intégration API Azure Blob : l’export n’est pas publié Lire l'article
  • 5 septembre 2025
  • Lecture ~18 minutes

Les blocs sont reçus dans Azure Blob, pourtant le nouvel export reste introuvable après un refus du lien signé. Retrouvez le manifeste source, les fragments disponibles et la requête de validation. Un exercice de 58 contrôles suit treize échanges préparés du SDK et met en évidence sa sélection de blocs, sans ouvrir de compte Azure.

Illustration des références documentaires et des transferts de fichiers entre applications métier Intégration API Google Drive : PDF en double Lire l'article
  • 3 septembre 2025
  • Lecture ~16 minutes

Le bon de livraison existe deux fois après un timeout du connecteur. Distinguez l’identifiant de fichier réservé de la session qui reçoit ses octets. Un exercice de 63 contrôles utilise le SDK Google avec 24 échanges préparés, observe les reprises à l’octet confirmé et conserve le conflit 409 comme une exception, sans connexion à Drive.

Illustration d’un inventaire documentaire Dropbox incomplet après la reprise du connecteur métier Intégration API Dropbox : des pièces disparaissent Lire l'article
  • 4 septembre 2025
  • Lecture ~16 minutes

Le plan reste dans Dropbox, mais le portail ne le propose plus après la relance du connecteur. Retrouvez la variante du refus et la page qui manque avant de retirer une pièce de l’inventaire actif. Notre expérience de 45 contrôles suit neuf échanges préparés du SDK, garde les références métier et refuse une reconstruction incomplète.

Illustration du trajet d’une pièce jointe entre réception n8n, stockage, worker et application de gestion Intégration API n8n : pièce jointe absente du worker Lire l'article
  • 13 août 2025
  • Lecture ~13 minutes

Le document est visible dans l’éditeur, mais son transfert ERP échoue selon le worker. Le diagnostic distingue référence, octets et preuve de rattachement. Une expérience locale de 28 contrôles montre les écarts de lecture, sans cluster n8n, appel distant ou écriture dans l’application de gestion destinataire.

Fiabiliser la livraison de vos exports S3

Dawap examine le client S3, les reçus de transfert et la finalisation pour définir une reprise exploitable avec vos équipes AWS, ERP et support.