tva
← Insights

Construire un Entrepôt de Données Amazon avec FastAPI et TimescaleDB

La SP-API d'Amazon donne accès à un volume substantiel de données opérationnelles — commandes, stocks, règlements, publicité, performances du catalogue. Mais en réalité, les données n'ont de valeur que dans la forme où on peut les interroger. Les propres rapports d'Amazon sont éphémères, soumis à des limites de débit, et ne sont pas conçus pour les questions opérationnelles qui comptent le plus pour un vendeur gérant une activité multi-marchés. Vous pouvez voir ce qui s'est passé. Vous ne pouvez pas facilement demander ce qui se passe sur toutes les places de marché simultanément, ni quelle était la tendance de la demande au cours des quatre-vingt-dix derniers jours pour un ASIN spécifique dans une région de traitement spécifique.

Ce billet décrit l'architecture que nous utilisons pour un entrepôt de données Amazon : FastAPI comme couche API, TimescaleDB comme base de données temporelle, et Celery pour le pipeline asynchrone de rapports SP-API. L'objectif est un système où chaque donnée disponible via l'API Amazon est stockée dans une forme interrogeable que vous contrôlez, avec suffisamment de structure pour alimenter les prévisions de demande et l'analytique opérationnelle sans nécessiter une équipe d'ingénierie données pour le maintenir.

Pourquoi les Outils Natifs d'Amazon sont Insuffisants

Les rapports Seller Central couvrent la plupart des besoins opérationnels pour un seul marché avec un petit catalogue. Les lacunes deviennent apparentes à grande échelle. Les rapports sont générés à la demande et expirent. Il n'y a pas de couche de requêtes persistante — vous lancez un rapport, téléchargez un fichier, et le fichier est la donnée. Lancer le même rapport dans six mois vous donnera les données de dans six mois, pas celles d'aujourd'hui.

Cela signifie que toute analyse historique nécessite soit que quelqu'un ait téléchargé et stocké chaque rapport pertinent au bon intervalle, soit que vous reconstituiez l'historique à partir d'exports au niveau transaction — qui sont eux-mêmes soumis à des limites de débit, paginables par fenêtres limitées, et structurés pour la récupération d'enregistrements individuels plutôt que pour l'analyse en masse.

Le tableau de bord Business Reports d'Amazon fournit des données de tendances agrégées, mais la granularité et la fenêtre de rétention sont fixées par les décisions produit d'Amazon, non par vos besoins analytiques. La console publicitaire a son propre modèle de données qui ne se joint pas proprement aux données de traitement. Les données de règlement arrivent sur un cycle de deux semaines et nécessitent un parsing non trivial pour être réconciliées avec les données de commandes.

Un entrepôt personnalisé résout simultanément les problèmes de persistance et d'interrogeabilité. Vous possédez le stockage, vous définissez la rétention, et vous écrivez les requêtes qui répondent aux questions dont votre entreprise a réellement besoin — pas les questions pour lesquelles les tableaux de bord d'Amazon ont été conçus.

Choix Technologiques

Nous avons choisi TimescaleDB comme base principale parce que la plupart des données opérationnelles Amazon sont intrinsèquement des séries temporelles. Les commandes ont des horodatages. Les snapshots de stock sont ponctuels dans le temps. Les périodes de règlement ont des dates de début et de fin. Les dépenses et impressions publicitaires s'accumulent dans le temps. TimescaleDB est PostgreSQL avec des extensions hypertable qui rendent les requêtes sur des plages temporelles de grands ensembles de données substantiellement plus efficaces que le PostgreSQL standard, tout en maintenant une compatibilité SQL complète. Il n'y a pas de nouveau langage de requête à apprendre et pas de modèle opérationnel différant matériellement d'une installation Postgres standard.

FastAPI fournit la couche API entre les workers Celery qui extraient les données de la SP-API et les consommateurs internes qui interrogent l'entrepôt. Il gère l'authentification, la validation des requêtes et la sérialisation des réponses avec un minimum de code générique. Pour un service interne non exposé à l'internet public, la documentation OpenAPI automatique de FastAPI est particulièrement utile : elle fournit une définition d'interface interrogeable qui facilite l'écriture de nouveaux consommateurs sans avoir à faire de rétro-ingénierie du modèle de données depuis le schéma de base de données.

Celery gère le pipeline asynchrone de rapports SP-API. La génération de rapports SP-API est asynchrone par conception — vous demandez un rapport, attendez son statut, téléchargez le résultat quand il est prêt, et traitez le fichier. Cela correspond naturellement à une chaîne de tâches Celery : une tâche pour initier la demande de rapport, une tâche périodique pour surveiller le statut du rapport, une tâche pour télécharger et stocker le fichier brut, et une tâche pour parser et charger les données structurées dans TimescaleDB. Redis sert de broker Celery et de backend de résultats.

Modèle de Données

Les tables principales reflètent les domaines de données principaux de la SP-API. Le principe de conception est que chaque table doit répondre à une classe spécifique de questions opérationnelles sans nécessiter de jointures entre plusieurs types de rapports.

Orders est une hypertable partitionnée sur purchase_date. Chaque ligne représente un article de commande individuel plutôt qu'une commande entière, car l'analyse au niveau article — par ASIN, canal de traitement, place de marché — est la granularité analytique la plus courante. Les agrégats au niveau commande sont dérivés des enregistrements au niveau article. L'intervalle de partition de l'hypertable est réglé sur une semaine, ce qui offre de bonnes performances pour les requêtes sur des fenêtres glissantes utilisées dans les prévisions de demande.

Inventory snapshots stocke la sortie des rapports de stock au moment de leur extraction. L'inventaire FBA n'est pas un flux d'événements — c'est un état qui change en permanence et n'est pas entièrement reconstituable à partir des enregistrements de commandes seuls (les retours, ajustements et transferts affectent le stock sans commandes correspondantes). Nous extrayons des snapshots d'inventaire deux fois par jour et les stockons comme enregistrements ponctuels dans le temps. La fonctionnalité d'agrégats continus de TimescaleDB calcule des moyennes quotidiennes et hebdomadaires glissantes à partir de ces snapshots sans que la requête ait à parcourir l'historique complet des snapshots.

Settlements stocke les rapports de règlement parsés avec chaque ligne comme une ligne de table. Le modèle de données des règlements est l'un des défis de parsing les plus complexes dans l'écosystème SP-API — Amazon utilise des codes de type transaction différents selon les places de marché, et les lignes de frais utilisent des conventions de nommage qui ne sont pas entièrement cohérentes entre les régions. Nous maintenons une table de correspondance qui normalise les noms de types de frais entre marchés vers une taxonomie interne cohérente.

Catalog stocke un snapshot du catalogue produits — ASINs, titres, catégories, relations de variation — mis à jour hebdomadairement. Cette table est principalement une référence de consultation pour les autres tables et n'utilise pas de structure hypertable, car les données n'ont pas de caractéristiques temporelles significatives.

TimescaleDB en Pratique

Les hypertables sont la fonctionnalité centrale de TimescaleDB. Créer une hypertable à partir d'une table PostgreSQL standard nécessite une seule commande spécifiant la colonne temporelle et l'intervalle de partition. Ensuite, les requêtes SQL standard fonctionnent sans modification, et le planificateur de requêtes de TimescaleDB applique automatiquement l'exclusion de chunks — ignorant les partitions hors de la plage temporelle de la requête — pour rendre les requêtes bornées dans le temps rapides même sur de grands ensembles de données.

Les agrégats continus sont la deuxième fonctionnalité que nous utilisons intensivement. Un agrégat continu est une vue matérialisée que TimescaleDB met à jour de manière incrémentielle au fur et à mesure que de nouvelles données arrivent dans l'hypertable. Pour les prévisions de demande, nous maintenons des agrégats continus pour les totaux de ventes glissants sur 7, 30 et 90 jours par ASIN et place de marché. Ces agrégats sont mis à jour automatiquement selon un calendrier défini, et les requêtes contre eux portent sur des données précalculées plutôt que sur l'hypertable complète, ce qui rend l'analytique au niveau tableau de bord suffisamment rapide pour un usage interactif.

CREATE MATERIALIZED VIEW daily_sales_by_asin
WITH (timescaledb.continuous) AS
SELECT
  time_bucket('1 day', purchase_date) AS day,
  asin,
  marketplace_id,
  SUM(quantity_ordered) AS units_sold,
  SUM(item_price_amount) AS revenue
FROM order_items
GROUP BY day, asin, marketplace_id;

Cette vue est rafraîchie automatiquement par la politique en arrière-plan de TimescaleDB, que nous configurons pour s'exécuter toutes les heures. Les sommes glissantes sur 90 jours utilisées dans les prévisions sont calculées comme des requêtes de fonctions de fenêtre sur cette vue matérialisée, non sur la table des articles de commande bruts.

Le Pipeline Celery

Le pipeline de rapports SP-API s'exécute comme un ensemble de tâches Celery selon un calendrier géré par Celery Beat. Chaque type de rapport a son propre calendrier : les commandes sont extraites toutes les heures, les stocks deux fois par jour, les règlements sur un cycle de deux semaines qui reflète les périodes de règlement Amazon.

Le pipeline pour chaque type de rapport suit la même structure : une tâche planifiée initie une demande de rapport via la SP-API, en stockant l'identifiant de demande dans Redis. Une tâche de surveillance s'exécute toutes les quelques minutes, vérifie le statut du rapport via la SP-API, et quand le rapport est prêt, met en file d'attente une tâche de téléchargement. La tâche de téléchargement récupère le document du rapport, stocke le fichier brut sur disque, et met en file d'attente une tâche de traitement. La tâche de traitement parse le fichier et charge les enregistrements structurés dans TimescaleDB.

La déduplication est gérée à l'étape de traitement plutôt qu'au niveau base de données. La SP-API retourne occasionnellement des enregistrements dupliqués sur des fenêtres de rapports chevauchantes. Nous maintenons un hash des champs identifiants de chaque enregistrement et vérifions les enregistrements existants avant l'insertion, ce qui évite l'accumulation de lignes dupliquées dans l'entrepôt au fil du temps.

La gestion des erreurs suit une politique simple : les erreurs SP-API transitoires (réponses de limite de débit, indisponibilité temporaire du service) déclenchent une nouvelle tentative Celery avec recul exponentiel. Les erreurs persistantes — documents de rapport malformés, changements de schéma inattendus, échecs de parsing — sont consignées avec le contexte complet et arrêtent le traitement pour ce type de rapport sans affecter les autres pipelines. Nous révisons le journal d'erreurs lors de la revue opérationnelle hebdomadaire plutôt que de traiter ces situations comme des incidents urgents, sauf si elles affectent les données de réconciliation des règlements.

Fondation pour les Prévisions de Demande

L'entrepôt de données n'implémente pas directement les prévisions de demande. Il fournit la fondation de données qui rend les prévisions possibles : des données de ventes en séries temporelles propres à la granularité ASIN-marché-jour, avec suffisamment d'historique pour identifier les tendances saisonnières et calculer des estimations de tendance statistiquement significatives.

Les agrégats continus décrits ci-dessus produisent les signaux de demande glissants sur 7, 30 et 90 jours. Ces signaux alimentent des modèles de prévision simples — moyennes mobiles pondérées et extrapolation de tendance linéaire pour les produits stables, avec des facteurs d'ajustement manuels pour les produits à saisonnalité connue. Les modèles s'exécutent comme des endpoints FastAPI qui interrogent les agrégats continus et retournent des prévisions ponctuelles avec des intervalles de confiance.

Des approches de prévision plus sophistiquées deviennent réalisables une fois la fondation de données en place. Nous avons expérimenté le lissage exponentiel Holt-Winters pour les produits avec des cycles saisonniers marqués, et la régression simple sur des signaux externes (dépenses publicitaires, changements de prix) pour les produits où ces variables sont des moteurs de demande significatifs. Mais en réalité, l'amélioration de la précision des prévisions de ces approches plus complexes par rapport aux moyennes mobiles pondérées bien calibrées est modeste pour la plupart des produits — la qualité et la longueur de l'historique des données comptent plus que la complexité du modèle.

Ce que Cela Rend Possible

Les capacités spécifiques que l'entrepôt permet méritent d'être nommées, car elles représentent un changement qualitatif dans ce qui peut être fait opérationnellement plutôt qu'une simple amélioration incrémentale de la vitesse de reporting.

La planification des stocks cross-marchés devient gérable. Avec des données de vélocité des ventes au niveau ASIN-marché et l'inventaire FBA actuel de la table de snapshots, nous pouvons calculer les jours de stock pour chaque SKU sur chaque place de marché et générer automatiquement des recommandations de réapprovisionnement plutôt que de passer par une revue manuelle marché par marché.

La réconciliation des règlements devient auditable. Avec les données de commandes et de règlements stockées dans le même système, il devient possible de vérifier que chaque article commandé a été réglé au taux prévu — identifiant les écarts de frais, les remboursements incorrects ou les erreurs de règlement qui ne sont autrement visibles que pour les vendeurs qui rapprochent manuellement les lignes. Cette vérification s'exécute comme un rapport hebdomadaire sur l'entrepôt plutôt que de nécessiter un travail manuel.

L'attribution publicitaire devient possible au niveau ASIN. En joignant les données publicitaires aux données de commandes sur des identifiants partagés, nous pouvons calculer la contribution des dépenses publicitaires aux améliorations du classement organique dans le temps — une question à laquelle la console publicitaire d'Amazon ne répond pas directement, car elle montre les ventes attribuées à la publicité mais pas l'effet sur les ventes organiques en aval des changements de classement que la publicité a induits.


Autres Articles

Articles connexes