cassionAnalyse de données

Retour à la leçonLeçon 5 sur 8Sortir les données

Interroger le système au lieu d'exporter à la main

Le même diaporama que les téléchargements, rendu sous forme de page. Lancez le diaporama pour le présenter en plein écran — les flèches ou un clic avancent d'une diapositive, Échap quitte.

Diapositives · PDFDiapositives · PowerPoint

  1. Diapositive 1 / 24

    Ce que couvre cette leçon

    • L'export mensuel est le problème
    • Deux points d'accès, deux questions
    • Adresser le cube
    • La forme de la réponse
    • Les quatre choses à régler d'abord
    • Tirez aussi les métadonnées
    • La suite
    Notes du présentateur
    Deux points d'accès qui répondent à des questions différentes, la syntaxe de dimensions qui adresse un cube, et les quatre choses à régler avant tout — authentification, pagination, limites de débit, et le fait que les tables analytiques sont périmées tant que personne ne les reconstruit.
  2. Diapositive 2 / 24

    L'export mensuel est le problème

    • Quelqu'un ouvre l'interface, choisit les unités d'organisation, les périodes, les éléments de données, clique sur exporter, et envoie un tableur par courriel.
    Notes du présentateur
    Quelqu'un ouvre l'interface, choisit les unités d'organisation, les périodes, les éléments de données, clique sur exporter, et envoie un tableur par courriel. Le mois suivant, quelqu'un recommence, légèrement différemment, et personne ne sait dire comment. C'est ce processus que cette leçon remplace. Non parce que l'interface est mauvaise — c'est ainsi que la plupart des gens devraient employer DHIS2 — mais parce qu'une analyse qui commence par un fichier bâti à la main n'est pas reproductible, et la reproduire était tout l'objet du module 2.
  3. Diapositive 3 / 24

    Deux points d'accès, deux questions

    Point d'accèsRenvoieÀ employer pour
    /api/dataValueSetsLes valeurs brutes stockées, telles que saisiesReproduire le registre ; tout ce qui exige de voir ce qui a été tapé
    /api/analyticsDes valeurs agrégées et calculéesIndicateurs, totaux remontés dans la hiérarchie, tout ce que le système calcule
    Notes du présentateur
    La chose la plus utile à savoir sur l'API est qu'il existe deux façons de sortir des données et qu'elles répondent à des questions différentes.
  4. Diapositive 4 / 24

    Deux points d'accès, deux questions

    • dataValueSets donne la vérité telle que stockée — une ligne par élément de données, unité d'organisation, période et…
    • analytics donne la réponse que le système afficherait sur un tableau de bord — agrégée dans la hiérarchie,…
    • Tirez les deux quand ils sont censés concorder — Là où ils divergent, l'écart est une règle d'agrégation dont vous…
    Notes du présentateur
    La différence compte plus qu'il n'y paraît. dataValueSets donne la vérité telle que stockée — une ligne par élément de données, unité d'organisation, période et combinaison d'options de catégories. Aucune agrégation, aucune arithmétique d'indicateur, aucun remplissage. C'est ce qu'il vous faut quand l'analyse doit être défendable jusqu'à la saisie. analytics donne la réponse que le système afficherait sur un tableau de bord — agrégée dans la hiérarchie, indicateurs évalués, opérateurs d'agrégation appliqués. C'est ce qu'il vous faut quand il vous faut le même chiffre que celui que regarde le ministère. Tirez les deux quand ils sont censés concorder. Là où ils divergent, l'écart est une règle d'agrégation dont vous n'avez pas tenu compte, et la trouver vaut une après-midi.
  5. Diapositive 5 / 24

    Adresser le cube — Exemple

    GET /api/analytics.json
      ?dimension=dx:PENTA3_UID;BCG_UID
      &dimension=ou:LEVEL-4;DISTRICT_UID
      &dimension=pe:202401;202402;202403
      &displayProperty=NAME
    Notes du présentateur
    Les requêtes analytics sont dimensionnelles. Vous demandez une tranche de cube, et chaque dimension porte un nom.
  6. Diapositive 6 / 24

    Adresser le cube

    • dx — dimension de données : éléments de données, indicateurs, opérandes.
    • ou — unités d'organisation. LEVEL-4 désigne toutes les unités du niveau 4 ; y adjoindre l'UID d'un district…
    • pe — périodes, explicites (202401) ou relatives (LAST_12_MONTHS).
    • Préférez les périodes explicites aux relatives dans un script — LAST_12_MONTHS renvoie une fenêtre différente chaque…
    Notes du présentateur
    Préférez les périodes explicites aux relatives dans un script. LAST_12_MONTHS renvoie une fenêtre différente chaque mois, ce qui est commode pour un tableau de bord et fatal pour la reproductibilité. Calculez la fenêtre dans votre code, puis demandez-la nommément, pour que la requête elle-même consigne ce qui a été demandé.
  7. Diapositive 7 / 24

    Adresser le cube — En Python

    import requests
    
    BASE = "https://play.dhis2.org/40/api"
    
    def analytics(dx, ou, pe, session):
        response = session.get(
            f"{BASE}/analytics.json",
            params={
                "dimension": [f"dx:{';'.join(dx)}", f"ou:{ou}", f"pe:{';'.join(pe)}"],
                "displayProperty": "NAME",
                "skipMeta": "false",
            },
            timeout=120,
        )
        response.raise_for_status()
        return response.json()
  8. Diapositive 8 / 24

    Adresser le cube — En R

    library(httr2)
    
    analytics <- function(dx, ou, pe) {
      request("https://play.dhis2.org/40/api/analytics.json") |>
        req_url_query(
          dimension = paste0("dx:", paste(dx, collapse = ";")),
          dimension = paste0("ou:", ou),
          dimension = paste0("pe:", paste(pe, collapse = ";")),
          displayProperty = "NAME",
          .multi = "explode"
        ) |>
        req_perform() |>
        resp_body_json()
    }
    Notes du présentateur
    skipMeta=false est délibéré. Le bloc de métadonnées porte les noms derrière chaque UID de la réponse, et sans lui vous avez un tableau d'identifiants que personne ne peut lire.
  9. Diapositive 9 / 24

    La forme de la réponse — En Python

    def to_frame(payload):
        import pandas as pd
    
        columns = [h["name"] for h in payload["headers"]]
        frame = pd.DataFrame(payload["rows"], columns=columns)
    
        names = {uid: item["name"]
                 for uid, item in payload["metaData"]["items"].items()}
        for column in ("dx", "ou", "pe"):
            if column in frame:
                frame[f"{column}_name"] = frame[column].map(names)
        return frame
    Notes du présentateur
    analytics renvoie un bloc d'en-têtes, un tableau de lignes et un dictionnaire de métadonnées. Transformez-le en tableau immédiatement et joignez les noms.
  10. Diapositive 10 / 24

    La forme de la réponse — En R

    to_frame <- function(payload) {
      cols <- vapply(payload$headers, \(h) h$name, character(1))
      rows <- do.call(rbind, lapply(payload$rows, \(r) unlist(r)))
      as.data.frame(rows, stringsAsFactors = FALSE) |> setNames(cols)
    }
  11. Diapositive 11 / 24

    La forme de la réponse

    • Conservez les UID en plus des noms — Les noms changent ; les UID non
    Notes du présentateur
    Conservez les UID en plus des noms. Les noms changent ; les UID non. Un script qui joint sur un nom casse à la première correction orthographique, et il casse en silence, en renvoyant moins de lignes.
  12. Diapositive 12 / 24

    Les quatre choses à régler d'abord

    • L'authentification — Employez un jeton d'accès personnel là où l'instance le permet, l'authentification de base sinon,…
    Notes du présentateur
    L'authentification. Employez un jeton d'accès personnel là où l'instance le permet, l'authentification de base sinon, et ne mettez jamais l'un ni l'autre dans le script. Une variable d'environnement ou un fichier d'identifiants hors du dépôt, toujours.
  13. Diapositive 13 / 24

    Les quatre choses à régler d'abord — En Python

    import os
    
    session = requests.Session()
    session.headers["Authorization"] = f"ApiToken {os.environ['DHIS2_TOKEN']}"
  14. Diapositive 14 / 24

    Les quatre choses à régler d'abord — En R

    req_headers(request(url), Authorization = paste("ApiToken", Sys.getenv("DHIS2_TOKEN")))
  15. Diapositive 15 / 24

    Les quatre choses à régler d'abord

    • La pagination — Les points d'accès de métadonnées paginent par défaut à 50
    Notes du présentateur
    Un dépôt d'analyse contenant un identifiant valide pour un système d'information sanitaire national est un incident grave, et cela s'est produit assez souvent pour que ce soit la première chose qu'un relecteur doive chercher. La pagination. Les points d'accès de métadonnées paginent par défaut à 50. Les points d'accès de données renverront volontiers des millions de lignes et expireront avant.
  16. Diapositive 16 / 24

    Les quatre choses à régler d'abord — En Python

    def paged(url, session, page_size=1000):
        page = 1
        while True:
            payload = session.get(url, params={"page": page, "pageSize": page_size},
                                  timeout=120).json()
            yield payload
            pager = payload.get("pager", {})
            if page >= pager.get("pageCount", 1):
                return
            page += 1
  17. Diapositive 17 / 24

    Les quatre choses à régler d'abord — En R

    # Same idea: loop until page == pageCount, and never assume one request is all of it.
  18. Diapositive 18 / 24

    Les quatre choses à régler d'abord

    • Le débit et la taille — Demandez un district et une année à la fois, non le pays et cinq années
    • Les tables analytiques sont périmées — C'est celle qui surprend
    Notes du présentateur
    Le débit et la taille. Demandez un district et une année à la fois, non le pays et cinq années. Une requête qui répond en huit secondes vaut mieux qu'une qui expire à quatre-vingt-dix, et la boucle fait trois lignes. Soyez un bon citoyen d'un serveur où travaillent aussi des agents de saisie. Les tables analytiques sont périmées. C'est celle qui surprend. analytics lit des tables pré-agrégées reconstruites selon un calendrier, en général nocturne. Une donnée saisie aujourd'hui n'est pas dans analytics tant que les tables n'ont pas tourné. dataValueSets la voit immédiatement. Les deux points d'accès peuvent donc légitimement diverger, et la bonne réaction n'est pas d'ouvrir un ticket. Vérifiez la dernière exécution.
  19. Diapositive 19 / 24

    Les quatre choses à régler d'abord — En Python

    info = session.get(f"{BASE}/system/info", timeout=60).json()
    print(info.get("lastAnalyticsTableSuccess"))
  20. Diapositive 20 / 24

    Les quatre choses à régler d'abord — En R

    resp <- request(paste0(base, "/system/info")) |> req_perform() |> resp_body_json()
    resp$lastAnalyticsTableSuccess
  21. Diapositive 21 / 24

    Les quatre choses à régler d'abord

    • Consignez cet horodatage avec chaque extraction — C'est la différence entre « les chiffres ont changé » et « les…
    Notes du présentateur
    Consignez cet horodatage avec chaque extraction. C'est la différence entre « les chiffres ont changé » et « les chiffres ont changé parce que les tables analytiques n'avaient pas tourné quand j'ai tiré ».
  22. Diapositive 22 / 24

    Tirez aussi les métadonnées — Exemple

    /api/dataElements.json?fields=id,name,aggregationType,categoryCombo[id,name]
    /api/organisationUnits.json?fields=id,name,level,parent[id]&paging=false
    /api/dataSets.json?fields=id,name,periodType,organisationUnits~size
    /api/indicators.json?fields=id,name,numerator,denominator,indicatorType[name]
    Notes du présentateur
    Tout ce que la leçon 1 réclamait est un point d'accès. Quatre requêtes. Elles vous donnent l'opérateur d'agrégation, la hiérarchie figée, le dénominateur des rapports attendus et les définitions d'indicateurs — soit toutes les questions que les leçons précédentes disaient qu'il faudrait poser à un collègue. Enregistrez-les à côté des données, et la leçon suivante rend cela automatique.
  23. Diapositive 23 / 24

    La suite

    • Vous savez poser une question au système.
    Notes du présentateur
    Vous savez poser une question au système. La leçon suivante rend cette interrogation reproductible — un script, une fenêtre énoncée, les métadonnées tirées en même temps, et un manifeste qui consigne exactement ce qui a été demandé et quand.
  24. Diapositive 24 / 24

    La suite

    Lire la leçon complète, avec le code exécutable Retour à la leçon