Plateforme ELT serverless sur Google Cloud pour les données Vélib' Métropole : ingestion haute fréquence, stockage colonnaire, transformation analytique, infrastructure versionnée.
Construire un entrepôt analytique alimenté en quasi-temps réel, permettant de répondre à des questions métier sur le réseau Vélib' :
- Dynamique des trajets (durée, distance, saisonnalité horaire)
- Santé du parc (batterie, blocages, trajets répétés courts)
- Patterns d'occupation des stations
- Cycle atelier des vélos
Un snapshot complet du parc est capturé toutes les 5 minutes (~1 400 stations, ~20 000 vélos), soit ~200 M de points d'observation par an.
flowchart TD
scheduler["Cloud Scheduler\n(cron */5min)"] --> workflows["Cloud Workflows"]
workflows --> extract["Cloud Run Job\nvelib-extract"]
workflows --> dbt["Cloud Run Job\nvelib-dbt"]
extract --> gcs["GCS landing\n(raw JSON)"]
gcs --> bq_raw["BigQuery raw"]
bq_raw --> bq_staging["staging"]
bq_staging --> bq_int["intermediate"]
bq_int --> bq_mart["mart"]
bq_mart --> bq_analytics["analytics"]
dbt -.-> bq_staging
Deux Cloud Run Jobs enchaînés par un Workflow, déclenchés toutes les 5 minutes par Cloud Scheduler. Extraction et chargement en Python, transformation en dbt. L'ensemble de l'infrastructure est décrit en Terraform.
| Couche | Outil | Rôle |
|---|---|---|
| Orchestration | Cloud Scheduler, Cloud Workflows | Déclenchement cron, enchaînement des étapes |
| Compute | Cloud Run Jobs | Exécution éphémère, facturation à la seconde |
| Stockage objet | Google Cloud Storage | Landing des payloads bruts |
| Data warehouse | BigQuery | Stockage colonnaire partitionné, moteur SQL |
| Transformation | dbt-core + dbt-bigquery | Modélisation, tests, lignage |
| Langage | Python 3.12 | Extraction et chargement |
| Dépendances | uv | Résolution et sync déterministes |
| Infrastructure | Terraform | IaC complet (GCP) |
| Packaging | Docker multi-stage | Image unique pour extract + dbt |
| Qualité | ruff, sqlfluff, pytest | Lint Python, lint SQL, tests unitaires |
velib-data-platform/
├── src/
│ ├── extract/ → Clients HTTP des sources de données (README)
│ ├── load/ → Chargement GCS et BigQuery (README)
│ ├── transform/ → Projet dbt (modèles, macros, tests) (README)
│ └── pipeline.py → Point d'entrée du job extract
├── terraform/ → Infrastructure Google Cloud (README)
├── tests/ → Tests Python
├── Dockerfile
├── docker-compose.yml
├── pyproject.toml
└── .sqlfluff
Chaque dossier principal dispose de sa propre documentation détaillée :
- src/extract/README.md — sources ingérées, design de l'extraction.
- src/load/README.md — stratégie de chargement BigQuery, partitionnement.
- src/transform/README.md — modélisation dbt (staging → mart → analytics), stratégies de matérialisation, logique de détection des trajets.
- terraform/README.md — ressources GCP provisionnées, comptes de service, IAM.
Séparation extract / load / transform. Chaque couche a un rôle unique et peut être relancée indépendamment. Le landing intermédiaire sur GCS garantit que le chargement BigQuery est rejouable sans re-solliciter les APIs amont.
Append-only au niveau raw. Les tables raw_velib.* ne subissent jamais de mutation : chaque run ajoute de nouvelles partitions journalières identifiées par ingested_at. La source de vérité est immuable, la reproductibilité est totale.
Matérialisations adaptées au grain. Les couches staging et intermediate utilisent un modèle incrémental avec partitionnement au jour, les marts agrégés sont reconstruits à chaque run pour garantir la cohérence des rankings et rollups. Le choix par modèle est détaillé dans src/transform/README.md.
Serverless partout. Aucun composant long-running. Le coût suit exactement l'usage, le scale-to-zero est transparent. Le pipeline reste dans le free tier GCP pour un usage personnel ou portfolio.
Infrastructure versionnée intégralement. Tout est décrit en Terraform, y compris les IAM, Secret Manager et Artifact Registry. Un projet GCP vierge peut être reprovisionné à partir du dépôt en une commande.
- Python 3.12, uv, Docker, gcloud CLI, Terraform ≥ 1.5
- Authentification GCP :
gcloud auth application-default login - Variables dans
.env:GCP_PROJECT,RAW_BUCKET_NAME, credentials sources
uv sync
uv run python -m src.pipelinecd src/transform
uv run dbt deps
uv run dbt build # run + testdocker build -t europe-west1-docker.pkg.dev/<project>/velib-platform/velib-pipeline:latest .
docker push europe-west1-docker.pkg.dev/<project>/velib-platform/velib-pipeline:latestcd terraform
terraform init
terraform applyuv run pytest
uv run sqlfluff lint src/transform/
cd src/transform && uv run dbt testProjet à visée pédagogique et démonstrative. Les données Vélib' Métropole sont diffusées sous licence ouverte par l'opérateur.