Client Python

Le client cartiflette publié sur PyPI lit en HTTPS les fichiers que le pipeline a écrits dans projet-cartiflette/production. Tout le traitement se fait avec DuckDB ; le résultat est converti en geopandas.GeoDataFrame à la fin (par défaut), ou rendu tel quel sous forme de relation DuckDB. Son code est dans python-package/cartiflette/, avec son propre pyproject.toml, son uv.lock et ses tests. Il n’importe rien du pipeline. Il demande Python 3.10 ou plus et DuckDB 1.5 ou plus.

La liste complète des fonctions est dans la référence de l’API, générée depuis les docstrings par quartodoc.

Utilisation

pip install cartiflette
from cartiflette import carti_download

# Départements, DROM rapprochés de la métropole (GeoDataFrame)
france = carti_download(
    values=["France"],
    borders="DEPARTEMENT",
    filter_by="FRANCE_ENTIERE_DROM_RAPPROCHES",
    simplification=50,
    year=2025,
)

# Communes de deux régions, gardées dans DuckDB pour continuer en SQL
communes = carti_download(
    values=["11", "84"],
    borders="COMMUNE",
    filter_by="REGION",
    year=2025,
    engine="duckdb",
)
communes.aggregate("INSEE_REG, sum(POPULATION)")

Moteur : engine

  • "geopandas" (défaut) : renvoie un GeoDataFrame. La lecture et le filtrage sont faits par DuckDB, la conversion n’a lieu qu’à la fin (to_geopandas).
  • "duckdb" : renvoie la relation DuckDB, pas encore évaluée, avec une colonne geometry de type GEOMETRY. Le paramètre con permet d’utiliser sa propre connexion (par exemple pour joindre le résultat à d’autres tables) ; par défaut, une connexion en mémoire est partagée par tous les appels.

Format : vectorfile_format

Les deux formats ne s’utilisent pas de la même façon :

  • GeoJSON : un fichier par valeur de filter_by, publié seulement pour les millésimes antérieurs à la refonte (2022) : le pipeline n’en produit plus, le GeoJSON des nouveaux millésimes est servi par l’API (04). Le client construit la liste des liens (geojson_urls, avec create_path_bucket) et DuckDB les lit ensemble (read_geojson, read_json).
  • GeoParquet : un seul fichier par niveau (create_path_consolidated), qui contient toute la France. Le client lit la métadonnée cartiflette:filter_columns pour savoir quelle colonne correspond à filter_by, puis ajoute un WHERE (read_parquet). DuckDB ne télécharge que les groupes de lignes utiles, grâce au tri du fichier, à ses statistiques et à ses filtres de Bloom : sur le fichier des communes 2025 (35 Mo), un département, un bassin de vie ou une zone d’emploi coûtent environ 2 Mo, une région 2 à 7 Mo. Une erreur est levée si une valeur n’existe pas ou si le niveau ne peut pas être filtré ainsi (ex. des régions par département).

Le GeoParquet est lu dès qu’il existe (à partir de 2025, et pour les années antérieures où il a été produit : parquet_available le vérifie par une requête HEAD, puis choose_format décide), même si vectorfile_format="geojson" est demandé : un avertissement l’indique. Il est aussi rapide que le GeoJSON pour une petite requête et bien plus rapide pour une grosse. Pour lire quand même le GeoJSON, passer force=True (un avertissement rappelle que le GeoParquet est plus rapide) : seulement pour les millésimes qui ont des fichiers GeoJSON (2022). À partir de 2025, ou pour un millésime republié par le pipeline actuel, il n’y en a pas (geojson_available le vérifie) : le GeoParquet est lu malgré force=True, avec un avertissement. Sans GeoParquet (ex. 2022 en production aujourd’hui), le GeoJSON est lu sans avertissement. Mesures depuis le SSPCloud, millésime 2025, simplification 50 :

Requête GeoParquet GeoJSON
Communes d’un département 0,2–0,3 s 0,1 s
Communes d’une région (84) 0,5 s 1,1 s
Départements, DROM rapprochés 0,4 s 0,8 s
Toutes les communes 2,2 s 16 s

Combinaisons disponibles

Elles correspondent à FILTERS dans cartiflette/pipeline.py. Chaque combinaison existe avec simplification 0 et 50, en crs=4326.

borders (polygones) filter_by (découpage)
COMMUNE, COMMUNE_ARRONDISSEMENT BASSIN_VIE, ZONE_EMPLOI, UNITE_URBAINE, AIRE_ATTRACTION_VILLES, DEPARTEMENT, REGION, TERRITOIRE, FRANCE_ENTIERE, FRANCE_ENTIERE_DROM_RAPPROCHES
DEPARTEMENT REGION, TERRITOIRE, FRANCE_ENTIERE, FRANCE_ENTIERE_DROM_RAPPROCHES
REGION, BASSIN_VIE, ZONE_EMPLOI, UNITE_URBAINE, AIRE_ATTRACTION_VILLES TERRITOIRE, FRANCE_ENTIERE, FRANCE_ENTIERE_DROM_RAPPROCHES

Valeurs de values selon le découpage : un code Insee ("75", "11"), le nom d’un territoire ("metropole", "guadeloupe"…) ou "France".

Formats et millésimes

  • À partir de 2025 : parquet seulement (alias accepté : geoparquet) ; le client lit le parquet même si geojson est demandé, force=True compris. Le GeoJSON de ces millésimes est servi par l’API (04).
  • Avant 2025 : geojson seulement en production pour 2022 (ancien pipeline) ; le client bascule seul sur le parquet si celui-ci est publié (2022 à 2024 peuvent être produits depuis les éditions IGN 3-x).
  • Codes de région : 1, "1" et "01" sont acceptés. Le client essaie REGION=01 (fichiers depuis 2025) puis REGION=1 (fichiers plus anciens), voir value_candidates.

Extensions DuckDB et proxy

Au premier appel, DuckDB télécharge ses extensions httpfs et spatial (depuis extensions.duckdb.org) et les garde dans ~/.duckdb. Derrière un proxy, définir la variable d’environnement https_proxy, transmise à DuckDB. Il n’y a plus de cache persistant des fichiers téléchargés : le GeoParquet ne rapatrie que ce qui est demandé.

Lire une sortie de test

Les paramètres bucket et path_within_bucket permettent de lire un autre emplacement que la production. C’est utile pour relire une exécution du pipeline écrite dans l’espace de test (voir Vérifier et faire évoluer) :

carti_download(values="11", borders="DEPARTEMENT", filter_by="REGION",
               year=2026, path_within_bucket="test/v0.3.0")

Développer le client

cd python-package/cartiflette
uv run pytest tests                   # tests `network` : lecture seule en production
uv run pytest tests -m "not network"  # hors ligne
  • create_path_consolidated doit rester identique à cartiflette/paths.py dans le pipeline (voir Les parties du projet). Les deux suites de tests fixent la même chaîne attendue. create_path_bucket n’existe plus que dans le client, pour lire les GeoJSON déjà publiés : ne pas le modifier.
  • Docstrings au format numpydoc : elles alimentent la référence de l’API.
  • Publication : monter version dans python-package/cartiflette/pyproject.toml, puis pousser un tag v*. Le workflow pypi.yml construit et publie le paquet (voir Versions, images et publication).

Construire cette documentation

La référence de l’API est générée par quartodoc, installé dans le groupe de dépendances docs du client. Il faut la régénérer avant de construire le site :

cd doc
uv run --project ../python-package/cartiflette --group docs quartodoc build
quarto render      # ou quarto preview

Les pages générées (doc/reference/, doc/objects.json) ne sont pas versionnées.

Publication

Le workflow .github/workflows/docs.yml publie sur GitHub Pages (https://inseefrlab.github.io/cartiflette/) un site unique :

  • à la racine, le site cartiflette-website (exemples, cas d’usage), dont les exemples Python sont exécutés avec le client de ce dépôt ;
  • sous doc/, ce site-ci.

Le lien « Documentation Python » de la barre de navigation du site principal est ajouté par un profil Quarto, doc/website/_quarto-cartiflette.yml, copié dans le dépôt cartiflette-website au moment du rendu. Le workflow tourne à chaque modification de doc/ ou du client sur main, à la main (workflow_dispatch), ou quand cartiflette-website envoie un événement repository_dispatch de type cartiflette-website. Sur une pull request, il vérifie seulement la construction.

Retour au sommet