# Bleus budgétaires de l'État : base locale PAP / RAP et emplois

Chaîne de collecte et d'extraction des documents budgétaires de l'État (projets annuels de
performances annexés aux PLF, rapports annuels de performances annexés aux lois de règlement),
avec extraction des plafonds d'emplois (ETPT) et des schémas d'emplois (ETP). Elle alimente le
minisite budget-etat.urgence-marseille.fr.

Toute la configuration est dans `config.yml` : années, périmètre, dossiers, politesse réseau,
valeurs connues pour les contrôles.

## Arborescence

```
config.yml              paramètres
requirements.txt        dépendances Python (venv .venv)
manifeste.csv           un document par ligne : annee, type_doc, mission, programme, url,
                        chemin_local, taille, sha256, date_telechargement, statut, puis colonnes
                        de travail (niveau, code_mission, titre, nom_fichier_origine, page_source...)
emplois_long.csv        extraction des tableaux d'emplois (format long, page et fichier source)
pdf/                    lien vers le fonds eg-transparency ETAT/BUDGET :
                        pdf/<annee>/<PAP|RAP>/<code>_<mission>.pdf et .../programmes/<code>_<prog>_<titre>.pdf
html/                   extraits HTML par programme (justification au premier euro, etc.)
opendata/               fichiers bruts (brut/<annee>/), sources.csv, credits_long.csv, etpt_long.csv,
                        nomenclature_programmes.csv
journal/                journaux d'exécution, erreurs.csv, introuvables.csv, extraction_anomalies.csv,
                        controles.csv, lignes_douteuses.csv
travail/                état de reprise de l'inventaire, pages HTML visitées, profil Chrome
scripts/                la chaîne (voir ci-dessous)
RAPPORT.md              rapport final généré
```

## Relancer

Les étapes sont idempotentes et reprennent où elles en étaient.

```
cd /srv/donut/scripts/budget-etat
export DISPLAY=:99                      # écran virtuel Xvfb (conteneur donut-xvfb)
.venv/bin/python scripts/build.py inventaire      # pages budget.gouv.fr -> manifeste.csv
.venv/bin/python scripts/build.py telecharger     # fichiers du périmètre -> pdf/ et html/
.venv/bin/python scripts/build.py opendata        # jeux ODS -> opendata/*.csv
.venv/bin/python scripts/build.py extraire        # PDF -> emplois_long.csv
.venv/bin/python scripts/build.py controles       # cohérence + valeurs connues
.venv/bin/python scripts/build.py rapport         # RAPPORT.md
.venv/bin/python scripts/build.py publier         # copie des données vers le minisite
.venv/bin/python scripts/build.py tout            # tout à la suite
```

Options utiles : `inventaire --annees 2026,2027`, `inventaire --refaire`, `telecharger --niveau mission`,
`telecharger --verifier` (recalcule tailles et empreintes, retente les introuvables),
`extraire_emplois.py --fichier chemin.pdf --annee 2026 --type-doc PAP --mission EC` pour tester un PDF.

Pourquoi un navigateur : budget.gouv.fr est protégé par un pare-feu Imperva/Incapsula qui bloque les
clients HTTP simples (curl, requests). Les pages et les fichiers sont donc lus depuis un vrai Chrome
piloté par nodriver sur l'écran virtuel Xvfb :99 (même recette que le scraper registre-numerique.fr).
Une requête toutes les 2 à 3 secondes ; en cas de blocage temporaire, pause de deux minutes puis reprise.

## Ajouter une année

1. Dans `config.yml`, ajouter l'exercice à `annees.pap` (PLF) ou `annees.rap` (PLR, PLRG).
2. Dans `scripts/opendata.py`, ajouter les jeux ODS de l'année au catalogue `SOURCES` (chercher
   sur data.economie.gouv.fr : « PLF 20XX », « LFI 20XX », « PLRG 20XX ») et, si la structure est
   nouvelle, un adaptateur dans `opendata_harmoniser.py`.
3. Relancer `build.py inventaire`, puis `telecharger`, `opendata`, `extraire`, `controles`, `rapport`,
   `publier`.
4. Si les PDF de l'année ont une nouvelle mise en page de tableau, l'extraction produit des lignes
   `a_verifier` : compléter le dictionnaire `COLONNES` de `extraire_emplois.py` après lecture du PDF.

## Sources

- budget.gouv.fr, rubrique Documentation, documents budgétaires par exercice (2019 et suivants) et
  application d'archives du Forum de la performance (`/documents-budgetaires/`, 1996 à 2018).
- data.economie.gouv.fr (API Opendatasoft) : données du PLF et des annexes PAP, LFI, PLR et PLRG.
- Repli possible : Assemblée nationale (dossiers législatifs des PLF, PAP par mission en PDF).

## Limites connues

- Les plafonds d'emplois par programme ne sont ouverts que jusqu'à la LFI 2023 ; après, seuls
  les PDF les donnent.
- Les colonnes des tableaux sont reconnues par la position des nombres sous l'en-tête lu dans le
  PDF (les anciennes mises en page laissent les cellules à zéro vides), puis traduites en
  indicateurs par mots-clés. Faute d'en-tête lisible, un repli par nombre de colonnes s'applique
  aux mises en page connues ; une mise en page inédite donne des lignes `a_verifier`, jamais une
  valeur inventée.
- Les récapitulations des emplois par programme (page de synthèse de la mission) n'existent que
  dans les PAP ; elles donnent aussi les emplois des opérateurs (sous et hors plafond).
- Un seul navigateur à la fois sur budget.gouv.fr : deux Chrome en parallèle (inventaire et
  téléchargement) ont déclenché le pare-feu le 8 octobre 2026 (pages incomplètes, HTTP 403) ;
  la pause de deux minutes puis la reprise ont suffi. L'application d'archives 2017-2018 sert
  ses fichiers lentement (30 à 40 s par bleu).
- Les missions disparues avant 2019 (« Égalité des territoires et logement », « Politique des
  territoires ») reçoivent les codes de convention ET et PT, qui ne sont pas des codes Farandole.
- Les libellés de missions et de programmes changent d'une année à l'autre ; les codes servent de clés
  (missions à deux lettres : EC = Enseignement scolaire, programmes à trois chiffres).
- Les récapitulations de mission sont arrondies à l'unité dans les PDF.
- Le ZIP de tous les PAP 2026 (74 Mo) est inventorié mais non téléchargé (chaque PAP l'est séparément).
- Pas de tiret cadratin dans les textes rédigés, conformément à la consigne.
