Metadata-Version: 2.4
Name: leximpact-dotations-back
Version: 8.0.0
Summary: Simulating annual State grants to the French administrative divisions
License: AGPL-3.0-or-later
License-File: LICENSE
Author: LexImpact
Author-email: leximpact@assemblee-nationale.fr
Requires-Python: >=3.11,<3.12
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Legal Industry
Classifier: Intended Audience :: Other Audience
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Requires-Dist: fastapi[standard] (>=0.117.0,<0.118.0)
Requires-Dist: openfisca-france-dotations-locales (>=7.0.0,<8.0.0)
Requires-Dist: pandas (>=2.2.2,<3.0.0)
Requires-Dist: python-dotenv (>=1.1.1,<2.0.0)
Project-URL: Repository, https://git.leximpact.dev/leximpact/simulateur-dotations-communes/leximpact-dotations-back
Description-Content-Type: text/markdown

# leximpact-dotations-back

Ce dépôt est dédié aux calculs des dotations de l'État aux territoires. Il propose une API web répondant en particulier aux besoins de l'interface définie dans le dépôt [leximpact-dotations-ui](https://git.leximpact.dev/leximpact/simulateur-dotations-communes/leximpact-dotations-ui).

## Pré-requis

Ce dépôt requiert le [langage Python](https://www.python.org) dans sa version `3.11`. Il utilise le gestionnaire de dépendances et de paquetage [Poetry](https://python-poetry.org).

### Gestion de versions de Python multiples avec `pyenv`

Si votre environnement local dispose déjà d'autres versions de Python, vous pouvez définir une version Python propre à ce dépôt avec [pyenv](https://github.com/pyenv/pyenv).  

Les commandes sont alors `pyenv install 3.11` suivie de `pyenv local 3.11`.

Pour relier la version du langage choisie à l'environnement isolé que créera Poetry, exécuter la commande suivante dans un terminal Shell : 
```shell
poetry env use python3.11
```

## Installer `leximpact-dotations-back`

Initialiser la configuration en copiant le modèle de fichier `.env` :

```shell
# dans le répertoire racine du dépôt
# (celui où se trouve ce fichier README.md)
cp .env.example .env
```

Vérifier que la version de Python associée à Poetry est bien la version attendue :

```shell
poetry run python --version
# résultat attendu : Python 3.11.x
```

Pour installer les dépendances de ce dépôt, exécuter la commande suivante dans un terminal Shell :

```shell
poetry install
```

Ceci créera un environnement virtuel.  
Si l'on souhaite voir l'environnement actif, celui-ci est indiqué parmi les environnements existants. Cette commande permet de les lister :
```shell
poetry env list
```

## Exécuter `leximpact-dotations-back` en local

Exécuter `leximpact-dotations-back` revient à exécuter son API web grâce à la commande suivante :
```shell
# mode développement
poetry run fastapi dev leximpact_dotations_back/main.py

# mode production
poetry run fastapi run leximpact_dotations_back/main.py
```

L'API est alors disponible à l'adresse locale suivante : `http://127.0.0.1:8000`
Sa documentation est automatiquement générée et accessible à l'adresse : `http://127.0.0.1:8000/docs`

## Exécuter les tests

Pour vérifier les résultats des tests unitaires, exécuter la commande suivante :
```shell
poetry run pytest
```

Il est possible d'afficher les résultats de `print` avec l'option `-s`. Exemple sur un fichier de test :
```shell
poetry run pytest tests/2022/test_criteres_2022_2024.py -s
```

Par ailleurs, les traces de `leximpact_dotations_back` sont gérées avec la librairie [logging](https://docs.python.org/3.11/library/logging.html). Si l'on souhaite les afficher durant l'exécution des tests, exécuterles alors cette commande (ici pour les messages de niveau `DEBUG`) :
```shell
poetry run pytest --log-cli-level=DEBUG
```

Pour les tests d'API web, se référer au [README_API](./README_API.md).

## Ajuster le style du code

Vérifier le style du code avec [flake8](https://flake8.pycqa.org) : 
```shell
poetry run flake8
```

Ou vérifier le style du code que vous avez ajouté avec : 
```shell
poetry run flake8 `git ls-files | grep "\.py"`
```

Et le corriger automatiquement dans le répertoire courant et récursivement dans son contenu avec : 
```shell
poetry run autopep8 .
```

La récursivité de cette commande n'est effective que lorsqu'elle est configuée pour [autopep8](https://pypi.org/project/autopep8/) dans le fichier `pyproject.toml`.

## Données

La Direction générale des collectivités locales (DGCL), publie en donnée ouverte les critères de répartition des dotations. Ces données évoluent annuellement.

### Données DGCL de 2023 à 2026

#### À partir de 2026

On transcrit le fichier XLSX de critères de répartition DGCL en CSV par la voie d'un script afin d'éviter les arrondis 
de valeur de tableurs (détecté sur LibreOffice qui exporte les valeurs telles qu'elles sont affichées et les affiche arrondies).

Par exemple, pour le calcul des dotations de l'année 2026, `leximpact-dotations-back` utilise le fichier `criteres_repartition_2026.csv`. Celui-ci est obtenu selon les étapes suivantes :

1. le fichier des critères pour la catégorie des communes `criteres_repartition_csv.php.xlsx` est téléchargé sur le [site officiel](http://www.dotations-dgcl.interieur.gouv.fr/consultation/criteres_repartition.php),
2. le fichier est renommé pour indiquer l'année, par exemple en `criteres_repartition_csv_2026.xlsx` (il ne sera pas mis sous GIT car ce serait inutilement lourd pour un format qui empêche la comparaison des modifications),
3. la feuille `Critères de répartition` est exportée par la voie du script `data/raw/xlsx_to_raw_csv.py` vers le CSV brut :

   ```shell
   poetry run python data/raw/xlsx_to_raw_csv.py \
     data/raw/criteres_repartition_csv_2026.xlsx \
     data/raw/criteres_repartition_2026_raw.csv
   ```

   Le nom de la feuille peut être précisé si nécessaire avec `--sheet` :

   ```shell
   poetry run python data/raw/xlsx_to_raw_csv.py \
     source.xlsx cible_raw.csv \
     --sheet "Critères de répartition"
   ```

4. le CSV brut est nettoyé pour produire le fichier final :

   ```shell
   poetry run python data/raw/data_cleanup.py 2026
   ```

Pour une autre année, adapter simplement l'année dans les noms de fichiers et dans la commande de nettoyage.

> Le convertisseur XLSX `data/raw/xlsx_to_raw_csv.py` n'ajoute aucune dépendance : il utilise uniquement la bibliothèque standard Python. 
> Un fichier XLSX étant une archive OOXML, le script lit directement :
>
> - `workbook.xml` pour trouver la feuille demandée ;
> - `sharedStrings.xml` pour les textes ;
> - `styles.xml` pour reconnaître les pourcentages et les identifiants à zéros initiaux ;
> - la valeur sous-jacente `<v>` de chaque cellule dans le XML de la feuille.
> Le script conserve aussi les conventions attendues par `data_cleanup.py` : pourcentages exprimés en points avec le suffixe `%`,
> encodage UTF-8, séparateur virgule et codes formatés avec leurs zéros initiaux.

#### De 2023 à 2025

Par exemple, pour le calcul des dotations de l'année 2024, `leximpact-dotations-back` utilise le fichier `criteres_repartition_2024.csv`. Celui-ci est obtenu selon les étapes suivantes : 
1. le fichier des critères pour la catégorie des communes `criteres_repartition_csv.php.xlsx` est téléchargé sur le [site officiel](http://www.dotations-dgcl.interieur.gouv.fr/consultation/criteres_repartition.php),
2. le fichier est renommé pour indiquer l'année en `criteres_repartition_csv_2024.php.xlsx` 
3. puis ce fichier `.xlsx` est ouvert dans un tableur (LibreOffice), 
4. dans l'onglet `Critères de répartition`, si l'on est sous LibreOffice, formater les cellules 
    pour conserver la précision des valeurs numérique (Clic Droit + Formater des cellules).  
    Sous un autre tableur, vérifier la non perte d'information au CSV obtenu à l'étape suivante.
    > ⚠️ Raisons du traitement manuel du format :  
    > Lors de l’export CSV depuis `LibreOffice`, on constate que les valeurs numériques sont exportées telles qu’elles sont affichées dans le tableur, 
    et non avec leur précision complète.  
    > Par exemple, si une cellule contient la valeur `13,7072898550724` mais est affichée sans décimales, la valeur exportée dans le CSV sera `14,0`.  
    > Si l'on veut exporter `13,7072898550724`, il est donc nécessaire de changer le format de la cellule (Clic Droit + Formater des cellules).  
    > C'est le cas par exemple pour le fichier criteres de 2025, colonne `Résidences secondaires de l'année N`.  
5. l'onglet `Critères de répartition` est sauvegardé en tant que `.csv` sous `data/raw/criteres_repartition_2024_raw.csv` (UTF-8 pour l'encodage, virgule pour les délimitations, double guillemet pour les chaînes de caractères)
6. `criteres_repartition_2024_raw.csv` est ensuite lu pour produire le fichier final `criteres_repartition_2024.csv` grâce à la commande suivante :
    ```shell
    poetry run python data/raw/data_cleanup.py 2024
    ```

De même pour 2023 (respectivement 2025) où l'on remplace `2024` par `2023` (respectivement `2025`).

### Données INSEE 2026

Pour l'initialisation du calcul sur la DCN on emploie les données de l'INSEE.

À partir de 2026, on emploie la table des évènements sur les communes depuis 1943.

Cette table est obtenue du [COG millésime 2026](https://www.insee.fr/fr/information/8740222) > `Évènements sur les communes` > Téléchargement du CSV.

On obtient alors `v_mvt_commune_2026.csv` que l'on renomme en `insee_mvt_commune_1943.csv`.

Pour identifier la date du COG pris en compte, on se fie alors à la date de mise à jour du CSV sur GIT et au commentaire de commit associé.

> Avant 2026 :
> On employait la liste des communes depuis 1943.
> Cette table était obtenue du [COG millésime 2025](https://www.insee.fr/fr/information/8377162) (ou antérieur) > `Communes depuis 1943` > Téléchargement du CSV.
> On obtenait alors `v_commune_depuis_1943.csv` que l'on renommait en `insee_commune_depuis_1943.csv`.


**ℹ️ Note spécifique indiquée par le producteur des données :**

"Le [décret n°2025-34 du 8 janvier 2025](https://www.legifrance.gouv.fr/jorf/id/JORFTEXT000050962940) portant changement du nom de sept communes est entré en vigueur le 11 janvier 2025.
Ces modifications, postérieures au 1er janvier 2025, ne figurent pas dans cette édition du Code officiel géographique. Elles seront intégrées au millésime 2026."

