Skip to content

Pilotage : Chiffres clés dynamiques dans le tableau de bord - #4589

Merged
rsebille merged 3 commits into
masterfrom
rsebille/c2/kpi-in-dashboard
Mar 10, 2025
Merged

Pilotage : Chiffres clés dynamiques dans le tableau de bord#4589
rsebille merged 3 commits into
masterfrom
rsebille/c2/kpi-in-dashboard

Conversation

@rsebille

Copy link
Copy Markdown
Contributor

🤔 Pourquoi ?

[Chiffres clés dynamiques TB privés] - Institutions : intégrer les chiffres clés dynamiques et à jour sur la page statistique privée des emplois

🍰 Comment ?

Récupération des données via l'API Metabase, elles sont ensuite stockées dans le cache (un redis avec une expiration très longue)

🏝️ Comment tester

  • Se connecter avec un compte institution lié à l'IAE

[Optionnel] Pour avoir des données :

  1. Configurer METABASE_API_KEY
  2. Lancer ./manage.py metabase_data fetch --wet-run

💻 Captures d'écran

image

@rsebille rsebille added 1-recette-jetable [Payé à l’heure] Crée une recette jetable sur CC ajouté Ajouté dans le changelog. labels Aug 21, 2024
@rsebille rsebille self-assigned this Aug 21, 2024
@github-actions

Copy link
Copy Markdown

🥁 La recette jetable est prête ! 👉 Je veux tester cette PR !

@rsebille
rsebille force-pushed the rsebille/c2/kpi-in-dashboard branch from 134df89 to 2c65d14 Compare August 29, 2024 08:32
@rsebille
rsebille force-pushed the rsebille/c2/kpi-in-dashboard branch from 2c65d14 to 141745d Compare September 3, 2024 14:06
@rsebille
rsebille marked this pull request as ready for review September 3, 2024 14:06

@hellodeloo hellodeloo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Je t'ai pushé un petit commit d'ajustement ui 😘

@hellodeloo

Copy link
Copy Markdown
Contributor

@rsebille si t'es chaud, y'a le même besoin sur pilotage qui attend que j'ai le temps et que j'en sois capable ;)

@hellodeloo
hellodeloo self-requested a review September 3, 2024 16:28

@hellodeloo hellodeloo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Comment thread clevercloud/cron.json Outdated
Comment thread itou/utils/apis/metabase.py Outdated
@rsebille
rsebille force-pushed the rsebille/c2/kpi-in-dashboard branch 3 times, most recently from a942fb7 to 4695868 Compare September 4, 2024 15:13
Comment thread itou/templates/dashboard/includes/stats_kpi_labor_inspector_iae.html Outdated
Comment thread itou/templates/dashboard/includes/stats_kpi_labor_inspector_iae.html Outdated
Comment thread itou/templates/dashboard/includes/stats_kpi_labor_inspector_iae.html Outdated
Comment thread itou/templates/dashboard/includes/stats_kpi_labor_inspector_iae.html Outdated
Comment thread itou/www/stats/utils.py
Comment thread itou/metabase/models.py
Comment thread itou/metabase/management/commands/metabase_data.py
Comment thread itou/metabase/management/commands/metabase_data.py Outdated

@rsebille rsebille left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PI, la PR passe en stand by pour le moment car il y a un problème métier avec les deux derniers indicateurs donc j’attends la décision sur le sujet : soit suppression, soit remplacement

Comment thread itou/templates/dashboard/includes/stats_kpi_labor_inspector_iae.html Outdated
Comment thread itou/metabase/management/commands/metabase_data.py Outdated
@rsebille
rsebille force-pushed the rsebille/c2/kpi-in-dashboard branch 2 times, most recently from 9cd5095 to 83990c8 Compare September 11, 2024 13:36
@rsebille rsebille removed the 1-recette-jetable [Payé à l’heure] Crée une recette jetable sur CC label Oct 15, 2024
@rsebille
rsebille marked this pull request as draft October 15, 2024 13:00
@rsebille
rsebille force-pushed the rsebille/c2/kpi-in-dashboard branch 2 times, most recently from eb9d130 to 7a5a314 Compare November 20, 2024 16:59
@rsebille
rsebille force-pushed the rsebille/c2/kpi-in-dashboard branch 2 times, most recently from 155bb71 to 15f688c Compare November 21, 2024 15:48
@rsebille
rsebille force-pushed the rsebille/c2/kpi-in-dashboard branch from cc614a2 to eb3326a Compare December 19, 2024 10:05
@rsebille
rsebille marked this pull request as ready for review December 19, 2024 10:09
@rsebille

Copy link
Copy Markdown
Contributor Author

Je réouvre la PR maintenant que les chiffres affichés sont OK et validés

Comment thread itou/utils/apis/metabase.py Outdated
Comment thread tests/utils/apis/test_metabase.py Outdated
@rsebille
rsebille force-pushed the rsebille/c2/kpi-in-dashboard branch 3 times, most recently from 92ed9da to d6f9603 Compare December 26, 2024 14:46
Comment thread tests/utils/apis/test_metabase.py Outdated
Comment thread itou/utils/apis/metabase.py Outdated
Comment thread itou/utils/apis/metabase.py Outdated
"region": [17676],
},
},
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tous ces entiers/ids en dur 🙈

Comment thread itou/utils/apis/metabase.py Outdated
*filters,
]

def fetch_card_results(self, card, filters=None, group_by=None, *, single_value=False):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

J'ai l'impression qu'on appelle uniquement cette fonction avec single_value=True , a-t-on besoin de single_value=False ? 👀

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dans notre utilisation actuel non car on ne va chercher que des chiffres agrégés, mais autant le gérer dés à présent plutôt que devoir se replonger dans l'API metabase à un autre moment, non ?

Comment thread itou/utils/apis/metabase.py Outdated
raise RuntimeError(f"{field_id=} was not found in columns metadata")

@staticmethod
def transform_metabase_results(results, group_by=None, *, single_value=False):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Peut-être qu'un commentaire détaillant les structures possibles de results aiderait à la compréhension 😬

@rsebille
rsebille force-pushed the rsebille/c2/kpi-in-dashboard branch from d6f9603 to 53062f5 Compare January 7, 2025 14:43
Comment thread tests/utils/apis/test_metabase.py Outdated
Comment on lines +86 to +89
assert Client.transform_metabase_results(data_results, group_by=["Col 2"], single_value=True) == {
1: 1.0,
2: 2.0,
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Je trouve la combinaison des group_by & single_value assez peu intuitive: ce n'est pas clair pourquoi on récupère la valeur de Col 3 (et non celle de Col 1 par exemple, ou ce qu'il se passe si on récupérait encore plus de colonne.

Peut-être que pour clarifier, il faudrait enlever la partie single_value de transform_metabase_results et faire la transformation spécifique à single_value dans fetch_card_results directement ?
Après le retour de l'API est assez peu clair et https://www.metabase.com/docs/latest/api/card ne fournit pas la réponse 😬

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Je trouve la combinaison des group_by & single_value assez peu intuitive: ce n'est pas clair pourquoi on récupère la valeur de Col 3 (et non celle de Col 1 par exemple, ou ce qu'il se passe si on récupérait encore plus de colonne.

Oui mais en principe si tu donnes single_value=True alors il n'est sensé y avoir qu'1 seul élément autre que la clé donc ça me choque pas que dans le cas où tu en donnes plus ça tombe dans un cas indéfini et laissé au choix de l'implémentation. C'est ce qui ce passe ici, on utilise .popitem() donc on prend la dernière valeur récupérée, et ça colle aussi au fait que l'API retourne toujours les champs group_by premier donc que la valeur est a la fin.

Peut-être que pour clarifier, il faudrait enlever la partie single_value de transform_metabase_results et faire la transformation spécifique à single_value dans fetch_card_results directement ? Après le retour de l'API est assez peu clair et https://www.metabase.com/docs/latest/api/card ne fournit pas la réponse 😬

Oui, la doc de l'API c'est juste une liste d'endpoint donc c'est de la pure ingénierie inverse d'où le fait que tout ne soit pas super clair et que ça tâtonne :).
fetch_card_results est déjà assez poilu donc je sais pas si ça serais mieux, ou peut-être dans une fonction à part, mais pas sûr 🤔.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Disons que sans le cas particulier du group_by/single_value , transform_metabase_results devient très simple et sort une liste de dictionnaire clef valeur.
Alors qu'actuellement la partie du group_by est assez indigeste et semble se baser sur plein de non-dits sur le format a priori qu'on reçoit et qui (j'imagine) dépendent de l'endpoint utilisé d'où IMHO l'intérêt de déplacer cette partie à coté de l'appel au endpoint.

Ainsi dans fetch_card_results on aurait pour la carte seule:

data = self._client.post(f"/card/{card}/query").raise_for_status().json()
[single_metadata_result] = self.transform_metabase_results(data["data"])
return single_metadata_result["la bonne colonne - dont le nom est ptet récupérable dans data ?"]

et pour le dataset:

data = self._client.post("/dataset", json=card_query).raise_for_status().json()
metadata_results = self.transform_metabase_results(data["data"])
# insérer ici du code intelligible ^.^

@rsebille
rsebille force-pushed the rsebille/c2/kpi-in-dashboard branch from 53062f5 to ea1b073 Compare February 25, 2025 14:43
@rsebille rsebille removed the 1-recette-jetable [Payé à l’heure] Crée une recette jetable sur CC label Feb 25, 2025
@rsebille
rsebille force-pushed the rsebille/c2/kpi-in-dashboard branch from ea1b073 to 56922e9 Compare February 25, 2025 17:45
@rsebille

Copy link
Copy Markdown
Contributor Author

Gros changement au niveau du client API, je passe par l'export en JSON pour les deux endpoints donc plus besoin de recoller les noms à la main, ce qui par extension m'a fait supprimer .transform_metabase_results() ;).
Et ils ont fait une MAJ de leur doc API, elle donne un peu plus d'information maintenant.

@rsebille
rsebille force-pushed the rsebille/c2/kpi-in-dashboard branch 2 times, most recently from 1dff31c to 79e923d Compare February 25, 2025 18:10

@xavfernandez xavfernandez left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C'est effectivement plus digeste 👍

Comment thread itou/utils/apis/metabase.py Outdated
return {"database": database, "type": "query", "query": query, "parameters": []}

def fetch_dataset_results(self, dataset_query):
# /!\ MB (hardcoded) limit to the first 2000 rows when "viewing", "download" has a 1_000_000 rows limits

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Je ne vois pas de lien entre ce commentaire et le code ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oui c'est pas clair je vais compléter, en fait il y a un endpoint /dataset qui permet d'explorer les résultats d'une requête mais ça limite à 2_000 lignes car c'est pour faire joujou dans l'interface, alors que /dataset/<format> est pour exporter les données et est donc limité à 1_000_000 lignes cette fois.

Comment on lines +425 to +420
if limit:
query["limit"] = limit

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On est d'accord que ce n'est jamais utilisé dans le code (tout comme select & table) ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oui c'est inutilisé, mais vu que je suis tombé dessus et que ça complexifiais pas trop le code je me suis que c'était pas plus mal d'inclure tout ceux que j'avais trouvé pour "documenter".
Et select ou table vont me servir coté pilotage très très bientôt :).

@rsebille
rsebille force-pushed the rsebille/c2/kpi-in-dashboard branch from 79e923d to cde6ebd Compare March 4, 2025 11:15
# - `/dataset` limit to 2_000 rows as it is used to preview query results
# - `/dataset/{export-format}` limit to 1_000_000 rows as it is used to download queries results
data = self._client.post("/dataset/json", data={"query": json.dumps(query)}).raise_for_status().json()
if type(data) is not list: # `/dataset/json` return a list of rows if successful otherwise it's a dict

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙈

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oui... Metabase sort beaucoup de chose en cas d'erreur donc par précaution j'ai préféré ne pas faire totalement passe-plat.

@rsebille
rsebille force-pushed the rsebille/c2/kpi-in-dashboard branch from cde6ebd to d451e02 Compare March 4, 2025 13:47
@rsebille
rsebille added this pull request to the merge queue Mar 10, 2025
Merged via the queue into master with commit 4ef4134 Mar 10, 2025
@rsebille
rsebille deleted the rsebille/c2/kpi-in-dashboard branch March 10, 2025 09:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ajouté Ajouté dans le changelog. pilotage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants