Comment ce chiffre est produit : Engagements de responsabilité (49.3)
Chaque étape, de la source primaire jusqu'au chiffre affiché sur la page Engagements de responsabilité (49.3). Les volumes sont lus dans la base au moment de l'affichage ; le code est celui qui tourne sur le serveur (version 4aabd6c).
Parcours des données
- 1. Fichiers sources3 fichiers publiés par l'Assemblée nationale et la DILA, téléchargés avec leur date de publication et contrôlés par leur empreinte MD5.
- 2. Données brutes versionnéesAN_DOSSIERS : 35 600 enregistrements courants (35 725 versions conservées).
- 3. Lecture et transformationengagements 49.3 lus dans les dossiers : 32retenus (15e à 17e législature) : 32dont textes budgétaires : 29Corrections justifiées : 0 (détail).
- 4. CalculMéthode I1 version 1 (définition), par législature, année parlementaire et session.
- 5. Résultats figés82 valeurs, calculées le 6 novembre 2026 (lot 400c1859), servies par l'API (/api/indicateurs/I1).
- 6. AffichageGraphiques et tableaux de la page Engagements de responsabilité (49.3), avec la source de chaque élément.
Fichiers sources
| Source | Fichier | Législature | Publié le | Collecté le | MD5 (publié / calculé) |
|---|---|---|---|---|---|
| AN_DOSSIERS | Dossiers_Legislatifs_XV.json.zip | 15 | 09/06/2022 | 06/11/2026 | 08f79aa683f73dbfe43b96c3eff0a64d08f79aa683f73dbfe43b96c3eff0a64d |
| AN_DOSSIERS | Dossiers_Legislatifs.json.zip | 16 | 28/06/2024 | 06/11/2026 | e7eb837f9ff3128e3dcbcdeddf6a12d4e7eb837f9ff3128e3dcbcdeddf6a12d4 |
| AN_DOSSIERS | Dossiers_Legislatifs.json.zip | 17 | 06/11/2026 | 06/11/2026 | c3f6a8e8a40d8fe716a8ceee5f5129e1c3f6a8e8a40d8fe716a8ceee5f5129e1 |
Code du calcul
Fonctions exécutées par le serveur pour produire ce chiffre, dans l'ordre : lecture des sources, puis calcul. Le texte est extrait du programme en cours d'exécution (version 4aabd6c).
Transformation.engagements_et_motions — donnees.transformation, lignes 432-513
def engagements_et_motions(self):
# Dossier du texte : dossier (hors procédure 13) qui contient un acte « …-DGVT » de même n° de texte.
hote = {}
for uid, (_, dp) in self.dossiers_json.items():
if (dp.get("procedureParlementaire") or {}).get("code") == an.PROCEDURE_ENGAGEMENT:
continue
for a in an.actes(dp.get("actesLegislatifs")):
if (a.get("codeActe") or "").endswith("-DGVT") and a.get("texteAssocie"):
hote[an.numero_texte(a["texteAssocie"])] = (uid, a["codeActe"].split("-")[0])
motions_brutes = [] # (motion json, dossier uid, engagement ou None, structurel ?)
engagements = []
for uid, (brut, dp) in self.dossiers_json.items():
if (dp.get("procedureParlementaire") or {}).get("code") != an.PROCEDURE_ENGAGEMENT:
continue
tous = an.actes(dp.get("actesLegislatifs"))
eng_actes = [a for a in tous if an.est_engagement_493(a)]
imbriquees = {}
for a in eng_actes:
jour = _jour(a["dateActe"])
texte_uid, lecture = hote.get(an.numero_texte(a.get("texteAssocie")), (None, ""))
dossier_texte = self.dos.get(texte_uid) if texte_uid else None
if dossier_texte is None:
self.rapport.alerte(f"Engagement {a['uid']} : dossier du texte introuvable")
e = Engagement493(
uid=a["uid"],
date=jour,
declaration=a.get("texteAssocie") or "",
dossier_engagement=self.dos[uid],
dossier_texte=dossier_texte,
lecture=lecture,
budgetaire=bool(
dossier_texte and dossier_texte.procedure_code in an.PROCEDURES_BUDGETAIRES
),
session=self.session(jour),
# Source : page du dossier d'engagement sur le site de l'Assemblée
**_trace(brut, a["uid"], an.url_dossier(dp["legislature"], uid)),
)
engagements.append(e)
for m in an.actes(a.get("actesLegislatifs")):
if m.get("codeActe") == an.ACTE_MOTION:
imbriquees[m["uid"]] = e
for m in tous:
if m.get("codeActe") != an.ACTE_MOTION:
continue
if m["uid"] in imbriquees:
motions_brutes.append((brut, m, uid, imbriquees[m["uid"]], ModeRattachement.STRUCTUREL))
elif eng_actes: # 15e : motion non imbriquée dans un dossier d'engagement
e = next(x for x in engagements if x.uid == eng_actes[0]["uid"])
motions_brutes.append((brut, m, uid, e, ModeRattachement.DOSSIER_DATE))
else:
motions_brutes.append((brut, m, uid, None, ModeRattachement.SANS_OBJET))
Engagement493.objects.bulk_create(engagements)
self.rapport.comptes["engagements_49_3"] = len(engagements)
motions = []
for brut, m, dossier_uid, eng, mode in motions_brutes:
vote = an.vote_de_motion(m)
ref = (vote.get("voteRefs") or {}).get("voteRef")
scrutin = self.scr.get(ref) if ref else None
motions.append(
MotionCensure(
identifiant=m.get("texteAssocie") or "",
dossier=self.dos[dossier_uid],
date_depot=_jour(m.get("dateActe")),
alinea=3 if eng else 2,
statut=MotionCensure.Statut.RETIREE
if m.get("dateRetrait")
else MotionCensure.Statut.NON_VOTEE,
engagement=eng,
mode_rattachement_engagement=mode,
scrutin=scrutin,
mode_rattachement_scrutin=ModeRattachement.VOTE_REF
if scrutin
else ModeRattachement.SANS_OBJET,
**_trace(brut, m["uid"], self.dos[dossier_uid].url_source),
)
)
self._rattacher_scrutins(motions)
MotionCensure.objects.bulk_create(motions)
self.rapport.comptes["motions"] = len(motions)
self.rapport.comptes["motions_votees"] = sum(m.statut == "votee" for m in motions)periodes — indicateurs.calcul, lignes 73-81
def periodes(jour: dt.date, legislature: int) -> list[tuple[str, str]]:
annee = annee_parlementaire(jour)
return [
(ResultatIndicateur.PeriodeType.LEGISLATURE, str(legislature)),
(ResultatIndicateur.PeriodeType.ANNEE_PARLEMENTAIRE, annee),
(ResultatIndicateur.PeriodeType.SESSION, f"{annee}/{type_session(jour)}"),
(ResultatIndicateur.PeriodeType.LEGISLATURE_ANNEE, f"{legislature}/{annee}"),
(ResultatIndicateur.PeriodeType.LEGISLATURE_SESSION, f"{legislature}/{annee}/{type_session(jour)}"),
]_compter — indicateurs.calcul, lignes 93-103
def _compter(elements, cle_legislature, cle_date, ventilations) -> dict:
"""{(periode_type, periode): Counter(ventilation)}"""
comptes = defaultdict(Counter)
for e in elements:
leg = cle_legislature(e)
if leg not in LEGISLATURES_JALON:
continue
for periode in periodes(cle_date(e), leg):
for v in ventilations(e):
comptes[periode][v] += 1
return comptescalculer() — bloc I1 — indicateurs.calcul
# I1 — engagements 49.3
engagements = list(Engagement493.objects.select_related("dossier_engagement"))
ajouter(
"I1",
_compter(
engagements,
lambda e: legs.a_la_date(e.date),
lambda e: e.date,
lambda e: ["total", "budgetaire" if e.budgetaire else "autres"],
),
)
textes = defaultdict(set)
for e in engagements:
leg = legs.a_la_date(e.date)
if leg in LEGISLATURES_JALON and e.dossier_texte_id:
for periode in periodes(e.date, leg):
textes[periode].add(e.dossier_texte_id)
for (ptype, periode), ids in textes.items():
resultats.append(
ResultatIndicateur(
definition=defs["I1"],
periode_type=ptype,
periode=periode,
ventilation="textes_distincts",
valeur=len(ids),
numerateur=len(ids),
lot=lot,
)
)