MapleStatsMCP

Statistique Canada · Notes tirées du code

Comment le MCP interroge Statistique Canada

Statistique Canada n'a pas une API, mais plusieurs. Voici comment MapleStats MCP trouve un tableau, passe d'une coordonnée à un vecteur, découpe un grand tableau avec SDMX et pondère un fichier de microdonnées, et ce que les services en direct m'ont appris en chemin.

Plusieurs services, une seule entrée

Commençons par la liste. Le Service de données Web (WDS) sert les tableaux et les séries chronologiques en JSON. Une API REST SDMX sert les mêmes tableaux en SDMX-ML. Le service de données de référence (RDaaS) contient les classifications comme le SCIAN. Le Profil du recensement de 2021 a sa propre API SDMX sur un autre hôte, celui de 2016 une API JSON distincte, et les profils de 2001 à 2016 n'existent qu'en téléchargement en bloc. Les fichiers de microdonnées à grande diffusion (FMGD) sont des archives ZIP. Viennent ensuite les flux Atom du Quotidien, le catalogue Données, le répertoire des enquêtes, un service de géographie du recensement et les flux d'indicateurs de la page d'accueil de Statistique Canada.

Chacun a ses identifiants, ses façons d'échouer et sa propre idée de ce qu'est un corps de requête. Un agent ne devrait pas avoir à apprendre tout cela avant de répondre à une question sur les prix. MapleStats regroupe ces services en 61 outils, et l'agent ne les voit pas non plus sous forme de liste. Le serveur présente trois outils au client : plan_query, search_tools et call_tool. Chaque outil de Statistique Canada se trouve par une requête en langage courant à search_tools et s'exécute par call_tool. La première requête d'une question sur Statistique Canada n'est donc pas une requête à Statistique Canada :

Requêtesearch_tools
{
  "query": "chercher un tableau Statistique Canada"
}
Réponse : noms seulementclassement au moment de la génération
[
  "statcan_sdg_search_indicators",
  "wds_search_cubes",
  "statcan_daily_get_releases",
  "statcan_surveys_search_surveys",
  "statcan_pumf_tabulate"
]

Le classement vient de l'index BM25 du serveur, construit sur le nom et la docstring de chaque outil ; c'est le même index que la recherche de ce site. wds_search_cubes figure parmi les résultats, et c'est par lui que commence la chasse au tableau.

D'une question à un tableau

Chaque tableau de Statistique Canada a un identifiant de produit, le PID. C'est le numéro du tableau sans ses traits d'union : le tableau 18-10-0004-01 a le PID 18100004, puisque les deux derniers chiffres, qui désignent une vue du tableau, sont facultatifs. La ressource docs://statcan/addressing fournie par le serveur détaille les dix chiffres : deux pour le sujet, deux pour le type de produit, quatre pour le numéro séquentiel et deux pour la vue.

wds_search_cubes transforme des mots en PID, et il est moins savant qu'il n'y paraît. Il télécharge getAllCubesListLite, la liste de tous les tableaux du WDS, la garde en cache une heure et cherche la requête comme sous-chaîne de chaque titre, français et anglais. Voici la recherche du tableau derrière le graphique de l'IPC dans les études de cas :

Requêtecall_tool
{
  "name": "wds_search_cubes",
  "arguments": {"query": "consumer price index", "limit": 5}
}
Réponse, abrégéestatcan.wds.CubeSummaryList
{
  "cubes": [
    // 1 de plus
    {
      "product_id": 18100004,
      "cansim_id": "326-0020",
      "cube_title_fr": "Indice des prix à la consommation mensuel, non désaisonnalisé",
      "release_time": "2026-09-14T12:30:00Z"
    },
    {
      "product_id": 18100005,
      "cansim_id": "326-0021",
      "cube_title_fr": "Indice des prix à la consommation, moyenne annuelle, non désaisonnalisé",
      "release_time": "2026-01-19T13:30:00Z"
    }
    // 2 de plus
  ],
  "total_count": 5,
  "provenance": {
    "url": "https://www150.statcan.gc.ca/t1/wds/rest/getAllCubesListLite",
    "coverage": "top 5 matches of 8271 cubes searched"
    // + 8 autres champs
  }
}

Une correspondance de sous-chaîne est un outil grossier. « consumer price index » trouve les tableaux de l'IPC parce que leur titre le dit ; une question formulée autrement que les titres de Statistique Canada peut les manquer, et l'agent doit alors réessayer avec les mots de Statistique Canada. La provenance indique l'étendue de la recherche, et chaque résultat porte cansim_id, le numéro du tableau dans l'ancien système CANSIM, à côté de release_time, la dernière diffusion du tableau.

Coordonnées et vecteurs

Un tableau de Statistique Canada est un cube. Chaque dimension a un arbre de membres, et un membre de chaque dimension désigne une série. wds_get_cube_metadata renvoie les dimensions. Le tableau de l'IPC en a deux : Géographie, avec 30 membres, et Produits et groupes de produits, avec 359.

Requêtecall_tool
{
  "name": "wds_get_cube_metadata",
  "arguments": {"product_id": 18100004}
}
Réponse, abrégéestatcan.wds.CubeMetadata
{
  "product_id": 18100004,
  "cube_title_fr": "Indice des prix à la consommation mensuel, non désaisonnalisé",
  "n_series": 2139,
  "dimensions": [
    {
      "dimension_position_id": 1,
      "dimension_name_fr": "Géographie",
      "members": [
        {"member_id": 2, "parent_member_id": null, "member_name_fr": "Canada"},
        {"member_id": 3, "parent_member_id": 2, "member_name_fr": "Terre-Neuve-et-Labrador"}
        // 28 autres membres
      ]
    },
    {
      "dimension_position_id": 2,
      "dimension_name_fr": "Produits et groupes de produits",
      "members": [
        {"member_id": 2, "parent_member_id": null, "member_name_fr": "Ensemble"},
        {"member_id": 3, "parent_member_id": 2, "member_name_fr": "Aliments"}
        // 357 autres membres
      ]
    }
  ]
  // + 13 autres champs
}

Les identifiants de membres se répètent d'une dimension à l'autre : dans les deux, le membre 2 est la racine de l'arbre, celui qui n'a pas de parent (Canada, et Ensemble). Et toutes les combinaisons n'existent pas. 30 géographies fois 359 produits donneraient 10 770 séries ; le tableau en compte 2 139. Une coordonnée n'est donc pas un choix libre : elle doit désigner une série que Statistique Canada publie.

Une coordonnée aligne un identifiant de membre par dimension, dans l'ordre des dimensions, séparés par des points. Le WDS exige toujours exactement dix positions, avec des zéros pour les dimensions que le tableau n'a pas. Le client complète la coordonnée : demander 2.2 envoie 2.2.0.0.0.0.0.0.0.0. En retour vient le vecteur, un identifiant stable pour une série, le numéro « V » hérité de CANSIM.

Requêtecall_tool
{
  "name": "wds_get_series_info_from_cube_pid_coord",
  "arguments": {"product_id": 18100004, "coordinate": "2.2"}
}
Réponse, abrégéestatcan.wds.SeriesInfo
{
  "product_id": 18100004,
  "coordinate": "2.2.0.0.0.0.0.0.0.0",
  "vector_id": 41690973,
  "provenance": {
    "url": "https://www150.statcan.gc.ca/t1/wds/rest/getSeriesInfoFromCubePidCoord"
    // + 9 autres champs
  }
}

Avec le vecteur, les données ne sont plus qu'à un appel. Celui-ci est la requête derrière le graphique de l'IPC des études de cas : les 84 derniers mois de v41690973.

Requêtecall_tool
{
  "name": "wds_get_data_from_vectors",
  "arguments": {"vector_ids": [41690973], "latest_n": 84}
}
Réponse, abrégéestatcan.wds.VectorData
[
  {
    "product_id": 18100004,
    "coordinate": "2.2.0.0.0.0.0.0.0.0",
    "vector_id": 41690973,
    "observations": [
      // 83 mois précédents
      {
        "ref_period": "2026-08-01",
        "value": 169.8,
        "decimals": 1,
        "scalar_factor_code": 0,
        "symbol_code": 0,
        "status_code": 0,
        "security_level_code": 0,
        "release_time": "2026-09-14T08:30:00Z"
      }
    ],
    "provenance": {
      "url": "https://www150.statcan.gc.ca/t1/wds/rest/getDataFromVectorsAndLatestNPeriods"
      // + 9 autres champs
    }
  }
]

Une valeur ne voyage jamais seule. Chaque observation porte les codes qui disent comment la lire :

scalar_factor_code
La puissance de dix dans laquelle la valeur est exprimée : 0 pour les unités, 3 pour les milliers, 6 pour les millions. Pour l'IPC, c'est 0.
decimals
Le nombre de décimales que Statistique Canada publie. La valeur est déjà arrondie par Statistique Canada.
symbol_code, status_code
Les symboles et les indicateurs d'état que Statistique Canada associe à une valeur, sous forme de codes. wds_get_code_sets les décode, tout comme les facteurs scalaires, les fréquences et les unités de mesure.
release_time
L'horodatage de diffusion que le WDS donne au point de données. Ce n'est pas toujours la première publication : août 2026 porte le 14 septembre 2026, mais septembre 2019, le mois le plus ancien de cet enregistrement, porte le 15 septembre 2021.

Vient ensuite la règle qui me tient le plus à cœur : le serveur n'applique jamais le facteur scalaire. value est exactement ce que le WDS a envoyé. Le code le dit deux fois, dans la docstring du schéma (« deliberately NOT applied ... WDS never auto-applies it either ») et en tête de liste dans docs://statcan/gotchas. Une valeur en milliers reste en milliers, avec son code à côté. La mise à l'échelle tient en une ligne, apply_scalar_factor(value, code) multiplie par dix à la puissance du code, mais cette ligne revient à qui utilise le chiffre, là où elle reste visible. Ce que l'outil renvoie correspond à ce que le WDS renvoie, chiffre pour chiffre.

Quand le WDS ne suffit pas : SDMX

Le WDS raisonne en séries : donnez-lui des vecteurs ou des coordonnées, il renvoie leurs observations. Quand une question porte sur toute une tranche d'un grand tableau, chaque géographie détaillée ou chaque profession, procéder série par série oblige à trouver d'abord chaque coordonnée, et télécharger le tableau complet revient à prendre bien plus que ce que la question demande. L'API SDMX de Statistique Canada découpe plutôt côté serveur. Une clé nomme les membres voulus, dimension par dimension, et une position vide sert de joker.

La clé est la coordonnée sans ses zéros de remplissage : une position par dimension autre que le temps. sdmx_get_vector_data la construit seul à partir d'un vecteur. Il cherche la coordonnée du vecteur par le WDS, lit la structure SDMX du tableau pour compter ses dimensions et coupe la coordonnée à cette longueur : v41690973 devient la clé 2.2.

Requêtecall_tool
{
  "name": "sdmx_get_vector_data",
  "arguments": {"vector_id": 41690973, "last_n_observations": 3}
}
Réponse, abrégéestatcan.sdmx.SdmxData
{
  "dataflow_id": "DF_18100004",
  "key": "2.2",
  "series": [
    {
      "series_key": {
        "Geography": "2",
        "Products_and_product_groups": "2"
      },
      "vector_id": 41690973,
      "scalar_factor": 0,
      "decimals": 1,
      "dguid": "2016A000011124",
      "uom_code": "17",
      "observations": [
        {"period": "2026-06", "value": 169.0},
        {"period": "2026-07", "value": 169.9},
        {"period": "2026-08", "value": 169.8}
      ]
    }
  ],
  "row_count": 3,
  "provenance": {
    "url": "https://www150.statcan.gc.ca/t1/wds/sdmx/statcan/rest/data/DF_18100004/2.2"
    // + 9 autres champs
  }
}

Trois particularités de cette API sont inscrites dans le client.

Elle répond en XML

Demandez du JSON avec format=jsondata ou un en-tête Accept, et le point d'accès SDMX de Statistique Canada renvoie tout de même du SDMX-ML, pour les données comme pour la structure. Le fichier de constantes note que c'est confirmé en direct, à l'encontre d'une documentation de référence qui supposait du SDMX-JSON. Le client lit donc le XML lui-même, avec defusedxml plutôt que l'analyseur de la bibliothèque standard.

Les jokers échantillonnent les grandes dimensions

Laissez vide une dimension de plus d'une trentaine de codes, et la réponse est un échantillon clairsemé et imprévisible de ses codes, pas leur totalité. sdmx_get_key_for_dimension construit plutôt la version complète. Il lit la liste de codes de la dimension dans la structure, garde les codes terminaux (ceux qui ne sont parents d'aucun autre) et les joint par des + en une clé OR explicite, à insérer dans la clé à cette position.

Une combinaison est refusée

lastNObservations combiné à startPeriod ou à endPeriod reçoit HTTP 406. Le client refuse cette combinaison avant d'envoyer quoi que ce soit, et si un 406 revient malgré tout, l'erreur nomme la cause habituelle au lieu de transmettre le statut nu.

Microdonnées, poids et répliques

Les tableaux sont des agrégats. Un fichier de microdonnées à grande diffusion, ce sont les enregistrements eux-mêmes, une ligne par répondant, avec des poids qui font représenter la population par l'échantillon. Statistique Canada distribue les FMGD dans des ZIP, et les dictionnaires qu'ils contiennent prennent plusieurs formes : dictionnaires CSV, fichiers Stata .dct et .do, fichiers d'étiquettes SPSS et fichiers SAS.

Les API de tableaux ne voient pas du tout les FMGD. Le seul endroit où les découvrir est le catalogue Données de Statistique Canada, que statcan_reference_search_data interroge. Une fois le fichier trouvé, statcan_pumf_get_codebook lit son dictionnaire à l'intérieur du ZIP par des requêtes HTTP partielles : on connaît les variables et les poids avant de télécharger le fichier de données. statcan_pumf_tabulate fait ensuite les calculs sur le serveur, avec DuckDB. Son premier appel télécharge le fichier dans un cache local, et les appels suivants le réutilisent.

Voici l'appel derrière le graphique du baccalauréat des études de cas : le fichier des particuliers du recensement de 2021, les adultes de 25 à 64 ans (groupes d'âge 9 à 16), et la part de chaque plus haut diplôme dans chaque province, sans les codes « non disponible » et « sans objet ».

Requêtecall_tool
{
  "name": "statcan_pumf_tabulate",
  "arguments": {
    "url": "https://www150.statcan.gc.ca/n1/pub/98m0001x/2023001/cen21_ind_98m0001x_part_rec21.zip",
    "rows": [
      "PR",
      "HDGREE"
    ],
    "statistic": "share",
    "filters": {
      "AGEGRP": ["9", "10", "11", "12", "13", "14", "15", "16"],
      "HDGREE": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13"]
    }
  }
}
Réponse, abrégéestatcan_pumf.WeightedTable
{
  "data_file": "data_donnees_2021_ind_v2.csv",
  "statistic": "share",
  "weight": "WEIGHT",
  "unweighted_n": 525504,
  "weighted_total": 19463104.06541252,
  "cells": [
    {
      "groups": [
        {"variable": "PR", "code": "10", "label": "newfoundland and labrador"},
        {"variable": "HDGREE", "code": "9", "label": "bachelor's degree"}
      ],
      "estimate": 13.305555555555555,
      "standard_error": 0.42801216439502804,
      "cv": 0.032167928848060565,
      "unweighted_n": 958,
      "low_count": false
    }
    // 142 autres cellules
  ]
  // + url, value_variable, filters, truncated, variance_method, notes, provenance
}
Les cellules du baccalauréat pour les 5 premières provinces de la réponse, arrondies.
Provinceestimatestandard_errorcvunweighted_nlow_count
Terre-Neuve-et-Labrador13,310,430,032958false
Île-du-Prince-Édouard18,151,000,055366false
Nouvelle-Écosse20,080,340,0172 721false
Nouveau-Brunswick16,670,330,0201 779false
Québec18,150,110,00621 670false

Deux choses décident de la justesse d'un tel tableau. La première est le poids. Par défaut, l'outil prend le poids principal du dictionnaire, ici WEIGHT, et il vérifie les étiquettes et la largeur des champs en plus des noms, car les noms trompent : dans la CSWC, WTQ_05 est une question sur le travail de nuit, et dans l'ESCC, DOHWT est un indicateur d'inclusion pour la taille et le poids. Les vrais poids sont des champs numériques larges : une largeur connue de moins de quatre colonnes écarte donc une variable. La seconde est l'échantillon sous chaque cellule. Chaque cellule indique son effectif non pondéré, et par défaut celles de moins de 30 répondants sont marquées low_count.

Viennent ensuite les erreurs-types. Le fichier du recensement contient 16 poids de réplication, de WT1 à WT16. L'outil calcule l'estimation une fois avec le poids principal et une fois avec chaque réplique, additionne les écarts au carré des 16 estimations répliquées à leur moyenne, divise par 35 et prend la racine carrée. Ce 35 n'est pas une coquille. C'est la recette du guide de l'utilisateur, un ajustement de Fay sur 16 groupes, et le commentaire qui le précède dans tabulate.py en montre le calcul : (240/35) × (1/240). Statistique Canada signale que cette méthode surestime l'erreur des petites estimations.

Chaque méthode est reprise du guide de l'utilisateur de l'enquête, avec la section citée, et un fichier n'en reçoit une qu'après lecture de son guide, « never by analogy with another survey », selon le commentaire qui précède la liste. 3 fichiers en ont une pour l'instant :

Fichiers de microdonnées avec une méthode d'erreur-type
FichierPoidsRépliquesErreur-type
Recensement de 2021, fichier des particuliers (98M0001X)WEIGHTWT1–WT16 16Groupes aléatoires : écarts au carré à la moyenne des répliques, divisés par 35
Enquête sur la couverture de l'assurance-emploi, 2024 (89M0025X)WTPMWRPM1–WRPM1000 1 000Bootstrap : écarts au carré à l'estimation sur l'échantillon complet, divisés par 1 000
CSWC, 2024-2025 (14-25-0001)CSWCWTBSW1–BSW1000 1 000Bootstrap : écarts au carré à l'estimation sur l'échantillon complet, divisés par 1 000

Pour tout autre FMGD, le résultat ne donne pas d'erreur-type, explique pourquoi et nomme les poids de réplication ou le fichier bootstrap trouvés. Les poids bootstrap des FMGD sont perturbés pour protéger la confidentialité : leurs erreurs-types sont comparables à celles de Statistique Canada, sans être identiques. Deux études de cas utilisent ainsi le fichier du recensement de 2021 : le baccalauréat par province et le faible revenu d'une génération d'immigration à l'autre.

Ce qui nous a joué des tours

La plupart de ces pièges ont été trouvés en appelant les services en direct, pas en lisant la documentation. Le code consigne comment chacun a été confirmé, à côté du correctif, pour qu'une modification ultérieure ne le défasse pas en silence.

shared/http.py

La connexion qui restait pendue

De simples connexions httpx vers statcan.gc.ca expiraient, sans bruit. La cause n'est pas dans ce code : un élément du réseau de Statistique Canada, un pare-feu applicatif ou un CDN, bloque les négociations TLS dont l'extension ALPN n'offre que http/1.1, soit exactement ce qu'httpx offre par défaut. Le diagnostic a reproduit le blocage avec un socket ssl brut limité à cette seule valeur, puis l'a vu disparaître dès que h2 est revenu dans la liste. Le correctif tient en un argument, http2=True. Cet argument porte maintenant un commentaire qui demande à la personne suivante de ne pas le supprimer, h2 est une dépendance épinglée pour cette raison, et les scripts Python qu'écrit reproduce_code le règlent aussi.

statcan/wds/client.py

Le verrou de nuit

De minuit à 8 h 30, heure de l'Est, pendant que Statistique Canada met ses données à jour, certaines méthodes du WDS répondent HTTP 409. C'est un horaire, pas une panne, et aucune nouvelle tentative ne vient à bout d'un horaire : la couche commune de nouvelles tentatives exclut donc 409 des statuts qu'elle réessaie (429, 500, 502, 503 et 504). Les clients WDS et SDMX en font une erreur DataLocked qui dit de réessayer après 8 h 30.

statcan/wds/client.py

Un statut, trois sens

Le WDS répond à une requête bien formée qui vise un objet inexistant, un productId inconnu par exemple, par HTTP 406 et non 404. Il répond aussi 406 quand une date est trop courte : les intervalles de périodes de référence exigent des dates complètes AAAA-MM-JJ, et ceux de diffusion AAAA-MM-JJTHH:MM. Enfin, getBulkVectorDataByRange veut un corps fait d'un seul objet plat, là où toutes les autres méthodes POST du WDS prennent une liste ; envoyez-lui une liste, et c'est encore un 406. Le client fait d'un 406 du WDS une erreur InvalidInput qui invite l'agent à vérifier ses identifiants.

shared/json_utils.py

Null n'est pas une liste vide

dict.get(key, []) n'utilise sa valeur par défaut que si la clé est absente. Certains cubes du WDS envoient plutôt surveyCode et subjectCode avec un null explicite, et un null là où le schéma attend une liste échoue à la validation. list_or_empty(obj, key) vaut obj.get(key) or [], ce qui couvre les deux cas, et c'est désormais la règle pour tout champ de type liste tiré d'une API externe. Les codes numériques des observations sont traités de la même façon, pour la même raison : int(None) lève une exception, alors decimals et les autres codes sont lus avec or 0.

statcan/reference/client.py

La recherche qui ignorait son mot-clé

Les catalogues Référence, Analyse et Données de Statistique Canada partagent un même moteur de recherche Drupal. Interrogé à froid avec un mot-clé, il renvoie tous les documents du catalogue, sans filtre, à moins que la session n'ait d'abord visité la page de base et ne porte le témoin que cette visite dépose. La preuve : un curl brut avec un fichier de témoins, la même URL et la même chaîne de requête, et un résultat différent selon la seule question de savoir si la page de base est venue d'abord. Le client prépare donc la session une fois par catalogue et par langue. Mais les sessions expirent, et une session expirée échoue de la même manière silencieuse ; chaque réponse est donc vérifiée. Si la boîte de recherche de la page revient vide malgré un mot-clé, le client prépare de nouveau la session et réessaie une fois, puis lève une erreur plutôt que de présenter tout le catalogue comme résultat.

AGENTS.md

Deux sur trente-deux

La première version du module Statistique Canada n'appelait que 2 de ses 32 outils sur l'API réelle quand on l'a jugée terminée. Les autres passaient des tests écrits d'après des données fictives. Un passage ultérieur a appelé les 32 en direct et trouvé 9 autres bogues : des noms de champs erronés pour 4 des 10 catégories de getCodeSets, des notes supposées être des chaînes qui sont en fait des objets, deux méthodes du WDS qui exigent un corps de requête d'une autre forme, deux autres aux exigences de dates inverses de celles supposées, un point d'accès du RDaaS qui renvoie une liste là où l'on attendait un dictionnaire, et des réponses 404 et 406 qui s'échappaient en erreurs HTTP brutes au lieu d'erreurs typées. Les données fictives ne pouvaient rien en détecter, puisqu'elles reposaient sur les mêmes hypothèses erronées que le code. La règle depuis : avant qu'un client soit terminé, un script jetable appelle chacune de ses fonctions sur l'API réelle, et la suite de tests échoue pour tout module sans test de fumée en direct.

D'un appel à un script

La réponse d'un agent ne vaut que la vérification qu'on peut faire sans lui. reproduce_code prend le nom d'un outil et ses arguments, et écrit un script R, Python, Stata ou Julia qui récupère les mêmes données directement chez Statistique Canada. Ce que fait le script dépend de l'appel :

Ce qu'écrit reproduce_code pour chaque type d'appel
AppelScript
Un appel wds_ ou sdmx_ avec un product_idTélécharge le tableau complet en CSV, à filtrer selon les lignes renvoyées par l'outil ; en R, get_cansim() de cansim.
wds_get_data_from_vectorsEnvoie la même requête WDS pour ces vecteurs ; en R, get_cansim_vector() de cansim.
sdmx_get_vector_dataRécupère le même vecteur par le WDS, qui le sert en JSON.
Un appel statcan_pumf_ avec l'url d'un ZIPTélécharge le même ZIP, avec des notes sur la variable de poids et sur la lecture des fichiers à largeur fixe à l'aide des fichiers Stata, SPSS ou SAS qu'il contient. Le tableau pondéré lui-même est calculé par le serveur.
statcan_census_tables_get_downloads2016 : le CSV du tableau complet et, en R, le fichier Beyond 20/20 lu avec canivt. 2006 et 2011 : R seulement, avec canivt.
statcan_indicators_get_indicatorsTélécharge le même flux et reprend les filtres de l'outil.
Le Quotidien, et les catalogues de documents et d'analysesAucun script : ils renvoient des documents, pas des données.
Tout autre outil de Statistique CanadaL'outil s'exécute une fois pendant que ses requêtes sont enregistrées, et le script reprend exactement la requête de données.

Pour l'appel de l'IPC ci-dessus, le script R obtient les données en un seul appel à cansim, et le script Python reprend la requête WDS, http2=True compris. Aucun des deux n'enfreint la règle du facteur scalaire : les deux gardent value tel que le WDS l'a envoyé et placent la valeur mise à l'échelle dans une colonne à part, val_norm de cansim en R et value_normalized en Python. Extraits des scripts enregistrés :

Python

with httpx.Client(
    http2=True,
    follow_redirects=True,
    timeout=300,
    headers={"User-Agent": "Mozilla/5.0 (compatible; research script)"},
) as client:
    response = client.post('https://www150.statcan.gc.ca/t1/wds/rest/getDataFromVectorsAndLatestNPeriods', json=[{'vectorId': 41690973, 'latestN': 84}])
response.raise_for_status()
raw_path.write_bytes(response.content)

# …

# scalarFactorCode is the value's power of ten; refPer is the reference date.

data = data.with_columns(
    (pl.col("value") * 10 ** pl.col("scalarFactorCode")).alias("value_normalized"),
    pl.col("refPer").str.to_date(strict=False).alias("ref_date"),
)

R

data <- get_cansim_vector(c("v41690973"))

# …

# cansim adds val_norm (the value times its scalar factor) and a Date column.

data <- data |>
  filter(!is.na(val_norm))

Tout le reste, en bref

Classifications. Le RDaaS contient le SCIAN, la Classification géographique type et les autres : structure, arbres de catégories, termes de l'index, exclusions et concordances qui font passer les codes d'une version à la suivante. Il a une lacune à connaître. Interrogé sur l'arbre des catégories du SCIAN actuel, 2022.1.0, il répond par un corps vide, alors que toutes les versions antérieures essayées renvoient l'arbre complet. L'outil le signale et renvoie à la concordance de 2017 à 2022, dont les codes cibles sont ceux du SCIAN actuel. Les termes de l'index ne passent au français que par un en-tête Accept-Language, que le client envoie.

Le recensement. Le Profil du recensement de 2021 est une API SDMX sur son propre hôte : on trouve une géographie, de la province à l'aire de diffusion, et l'une de 2 631 caractéristiques, puis on obtient les valeurs. Lui aussi choisit sa langue par un en-tête Accept-Language plutôt que par un paramètre. Le profil de 2016 a une API JSON distincte, et les profils de 2001 à 2016 sont des téléchargements en bloc CSV ou TAB, dont les outils d'archives donnent les liens directs. La géographie du recensement vient d'un service ArcGIS REST qui fournit les limites et les DGUID, et qui répond à toute erreur par HTTP 200 avec un objet d'erreur.

Diffusions. Le Quotidien vient de ses flux Atom, les 100 derniers jours par sujet, et du fichier JSON derrière le calendrier des diffusions, qui remonte au 14 mars 2012. wds_get_changed_cube_list liste les tableaux modifiés à une date donnée, et statcan_delta_get_file_link trouve le ZIP de mise à jour d'un jour ouvrable.

La liste complète des familles, avec le préfixe et le nombre d'outils de chacune, comptés dans le registre au moment de générer cette page :

Tableaux et séries chronologiques

Recensement

Microdonnées

Classifications

Indicateurs

Diffusions, catalogues et méthodes

Pour aller plus loin