Skip to content
Snippets Groups Projects
Select Git revision
  • Dorine-master-patch-77297
  • master default protected
  • base-2023
  • pipeline-2022
  • fix-params
  • check-dot-cn
  • dot_garantie_dsu_2022
  • plf-2022
  • benoit-cty-master-patch-87781
  • ci-manual-deploy
  • irpp-2021
  • migrate-to-prepare-data
  • docker
  • commune_fuzzy_search
  • doc-data
  • dotation-forfaitaire
  • test-cas-types
  • scalingo-emails
  • issue-beta-70
  • toggle_plf
  • integ protected
  • 1.3.0
  • 1.2.0
  • 1.0.0
24 results

leximpact-server

LexImpact-Server

[EN] Introduction

LexImpact allows civil servants, policy makers and citizens to simulate the ex ante impact of a reform to a country's tax-benefit system.

For more information on how LexImpact started, you can check out its history here:

[FR] Introduction

LexImpact permet aux administrations, aux parlementaires et à la société civile de simuler l'impact ex ante des réformes au système socio-fiscal.

Pour en savoir plus sur les débuts de LexImpact, vous pouvez consulter son histoire ici:

Contexte technique de leximpact-server

leximpact-server est le calculateur dédié aux simulations de l'interface d'impôt sur le revenu (IR) et de l'interface de dotations de LexImpact.

L'architecture mise en place est constituée de deux parties :

  • leximpact-server : interface en python utilisant le modèle de micro-simulation openfisca et contenant une API web répondant à des questions sur l'impact de modifications de la loi de finances (IR, dotations)
    • Optionnellement, une base de données PostgreSQL : base où sont stockées les données de population. Elle permet d'étendre les fonctionnalités de l'application IR en ajoutant aux calculs sur cas types, des estimations d'impact budgétaire.
  • leximpact-client : interface web communiquant avec l'API web et mettant à disposition des usagers un site web permettant de visulaliser les résultats des calculs de l'API.

Installation

Pour Docker voir docker/README.md.

Cette application requiert au minimum Python 3.7 (Python 3.8 fonctionne) et pip.

Plateformes supportées :

  • distributions GNU/Linux (en particulier Debian and Ubuntu) ;
  • Mac OS X ;
  • Windows;

Pour les autres OS : si vous pouvez exécuter Python et Numpy, l'installation de LexImpact-Server devrait fonctionner.

Pré-requis

Le serveur d'API nécessite libyaml, dhf5 et PostgreSQL, d'autres moteurs de bases de données peuvent théoriquement être utilisés sans modification.

Installation pour MacOS

brew install hdf5
brew install libyaml

Installation pour Ubuntu 20.04

apt-get -y install libyaml-dev libhdf5-serial-dev postgresql-client python3 make git python3-pip

Installation et configuration de PostgreSQL

apt install postgresql postgresql-contrib

On cree un user UNIX

adduser leximpact

On crée le même user dans la base avec le droit de creer une base :

sudo -u postgres createuser -d -P leximpact

On crée la base :

sudo -u leximpact createdb -T template0 -E utf8 -O leximpact leximpact

Ce sont ces informations qu'il faudra reprendre dans le fichier .env.

Optionnel : reverse proxy

Si vous souhaitez rendre accessible l'API depuis l'extérieur, vous pouvez utiliser la configuration nginx suivante :

nano /etc/nginx/conf.d/leximpactserver.conf
server {
    server_name <VOTRE NOM DE DOMAINE>;

    access_log /var/log/nginx/leximpactserver.log combined_time;

    location / {
        proxy_pass              http://localhost:5000/;
        proxy_set_header        Host                    $host;
        proxy_set_header        X-Real-IP               $remote_addr;
        proxy_set_header        X-Forwarded-Host        $host;
        proxy_set_header        X-Forwarded-Server      $host;
        proxy_set_header        X-Forwarded-For         $proxy_add_x_forwarded_for;
        proxy_set_header        X-Forwarded-Proto       $scheme;
        proxy_set_header        X-Real-IP               $remote_addr;
        client_max_body_size    16M;
    }
}

Optionnel : HTTPS

certbot --nginx -d <VOTRE NOM DE DOMAINE>

Installer un environnement virtuel

Nous recommandons l'utilisation d'un environnement virtuel (virtualenv) avec un gestionnaire de virtualenv tel que Pyenv.

  • Un virtualenv crée un environnement pour les besoins spécifiques du projet sur lequel vous travaillez.
  • Un gestionnaire de virtualenv, tel que Pyenv, vous permet de facilement créer, supprimer et naviguer entre différents projets.

Pour installer Pyenv (macOS), lancez une fenêtre de terminal et suivez ces instructions :

brew update
brew install pyenv
brew install pyenv-virtualenv
echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bash_profile
exec "$SHELL"

Créez un nouveau virtualenv nommé leximpact-server et configurez-le avec python 3.7 :

pyenv install 3.7.3
pyenv virtualenv 3.7.3 leximpact-server-3.7.3
pyenv activate leximpact-server-3.7.3

Le  virtualenv leximpact-server sera alors activé, c'est-à-dire que les commandes suivantes s'exécuteront directement dans l'environnement virtuel.

🎉 Bravo, vous êtes prêt·e à installer LexImpact-Server !

Installer LexImpact-Server

Pour installer LexImpact-Server, dans votre fenêtre de terminal :

make install

ou sous Windows

pip install --editable .[dev]

🎉 Félicitations LexImpact-Server est prêt à être utilisé !

Lancer l'API Web LexImpact

Configurer le fichier .env

Pour lancer LexImpact-Server, vous devez tout d'abord créer un fichier de configuration .env. Le fichier .env.example contient un exemple de fichier de configuration .env qui fonctionne par défaut, les champs y apparaissant sont :

  • DATABASE_* : décrit la configuration de la base de données, leximpact-server doit avoit un accès à une base de données postgres lui permettant de se comporter correctement. Ces variables ne sont pas nécessaires dans Scalingo car elles sont remplacées par une descriptions de la base de données automatiquement insérée par Scalingo dans les variables DATABASE_URL et SCALINGO_POSTGRESQL_URL.
  • JWT_* : Décrit les caractéristique du JSON Web Token. JWT_SECRET est une clef privée, JWT_AUDIENCE et JWT_ISSUER sont vérifiés quand le token est vérifié, mais peut être lu par quiconque a un token (car ces derniers ne sont pas chiffrés, mais juste signés par une clef privée) 
  • SMTP_* : données d'authentification pour l'envoie de mail, qui est utilisé pour envoyer les emails contenant les liens de connexion.
  • POPULATION_TABLE_PATH :  Les données de population prises en compte dans la simulation du budget de l'État. Peut contenir un nom de fichier (.csv ou .h5) ou un nom de table dans la base SQL. Cette source de données sera importée. Un exemple de fichier fonctionnnant comme source de données situé dans le dépôt est DCT.csv. Des fonctions pour calibrer une source de données en fonction des données existantes de la population française sont disponibles dans le fichier sous ./scripts (utilisés notamment dans le script TransformData.py
  • NAME_TABLE_BASE_RESULTS : Table SQL, générée par le script generate_default_results.csv, qui contient les résultats de la population pour les calculs réutilisés (i.e. code existant et PLF) utilisée pour économiser du temps de calcul.
  • RECETTES_ETAT_EURO : Valeur (entière) représentant le montant total de l'impôt attendu avec le code existant. Les résultats sur l'échantillon de population sont ajustés pour matcher cet ordre de grandeur pour le code existant. Si la valeur n'est pas spécifiée, aucun ajustement n'a lieu sur les résultats bruts de la simulation.
  • YEAR_COMPUTATION : Année de calcul : les revenus des cas-types et de la population seront supposés survenir l'année spécifiée, et seront donc taxés aux taux applicables cette année là.
  • PLF_PATH : Contient le chemin où l'on peut trouver un dictionnaire représentant la réforme. Un plf_path écrit au format "dossier.sousdossier.fichier.nom_dictionnaire" importera le dictionnaire portant le nom "nom_dictionnaire" dans le fichier "dossier/sousdossier/fichier.py" de l'arborescence. Cette variable fera planter le programme si elle contient des espaces ou le caractère ';', pour éviter toute fausse manipulation de l'utilisateur.

Variable optionnelle :

  • ASSETS_PATH : Par défaut, le folder /assets/ contient toutes les données publiques utiles au calcul des simulations. Il est toutefois possible pour l'usager de déclarer sa propre adresse de fichier dans cette variable d'environnement, qui doit être un chemin de répertoire valide.

Installer une base de données et configurer son contenu

Uniquement nécessaire dans le cas où les données sur la population sont utilisées (fonctionnalité simpop). En l'absence d'utilisation de ces données (i.e. les endpoints auth et simpop), il devrait être possible de faire tourner leximpact-server sans base de données ni fichier .env .

leximpact-server conserve l'ensemble des données qu'il utilise et qui ne sont pas ouvertes dans une base de données sécurisée en PostgreSQL. Cette partie décrit les différentes tables nécessaire au fonctionnement du site, et la manière de les créer.

Une base de données PostgreSQL doit être installée afin de stocker les données de population, d'améliorer les temps de calcul et d'assurer la sécurité des requêtes effectuées.

Pour créer la base de données, et exécuter toutes les migrations de contenu, dans votre fenêtre de terminal :

make migrate

Mode demo

Pour lancer LexImpact-Server, dans votre fenêtre de terminal :

make run

Pour s'assurer que tout marche bien :

./tests/server/stress/test.sh

🎉 Félicitations LexImpact-Server est en train de tourner !

Pour en savoir plus sur les endpoints de l'API Web IR et dotations, consulter ce README_API complémentaire.

Tables de la base de données

La base de données assure les différentes fonctions suivantes :

  • Stockage de la population (extrait de l'enquête ERFS-FPR adapté aux besoins de l'application IR)
  • Stockage de la liste des utilisateurs autorisés
  • Stockage des requêtes effectuées (pour éviter une surcharge provenant d'un utilisateur unique)
  • Stockage des résultats de base préprocessés pour économiser du temps de calcul (utile si la population est grande)

Elle contient des tables dédiées à ces différentes données.

users

Cette table contient les emails des usagers valides. Elle contient une colonne, "email", qui représente l'email de l'usager.

La liste des emails des députés est déposée et régulièrement updatée par le SSI de l'AN sur l'Open Data.

  • Etape 1 : Récupérer la liste des députés dans CircoData :
\copy (SELECT email FROM an_mailing) to users.csv csv header;

Il faut appeler le fichier users.csv pour que l'import fonctionne, car la table de destination s'appelle users.

  • Etape 1.5 (optionnelle): Une liste d'adresses supplémentaires est présente dans ce doc. Cette liste peut être concaténée au fichier créé à l'Etape 1

  • Etape 2 : uploader ce fichier et run le script preload.py dessus :

python ./repo/preload.py
  • Etape 3 : Si l'étape 1.5 n'a pas été exécutée, ou si des adresses sont rajoutées à la liste, il est possible de les inclure dans la base en copier-coller dans l'outil psql.
   INSERT INTO users values ('paul.poule@example.org', 'jean-marie.myriam@example.org');

requests

Contient la liste des requêtes simpop effectuées (timestamp et origine).

Description des colonnes :

nom colonne type Description
id Number Identifiant unique de la requête
email text (256) adresse email de l'usager
timestamp timestamp timestamp de la requête

Création / remplissage de la table : la table est créée automatiquement au lancement du serveur via alchemy, et son remplissage est automatique

suspended

Contient la liste des gens blacklistes avec date d'expiration du ban. Le blacklisting arrive quand les requêtes de simpop sont effectués en trop grand nombre, laissant supposer un objectif malveillant de la part de l'usager.

Description des colonnes :

nom colonne type Description
id Number Identifiant unique de la suspension
email text (256) adresse email de l'usager
end_suspension timestamp timestamp de fin de la suspension

Création / remplissage de la table : la table est créée automatiquement au lancement du serveur via alchemy, et son remplissage est automatique

data_erfs

Fichier contenant les données agrégées de la population française, construites, par exemple, à partir des données de l'ERFS FPR au format openfisca-france. C'est l'output de la phase transform_data (insérer lien vers la doc de la transformation des données). 

Le fichier est uploadé dans la base de données, par exemple via preload.py. Le nom de la table dans la base postgresql doit correspondre avec la variable d'environnement nommée POPULATION_TABLE_PATH.

base_results

Table contenant les résultats sur la population du code existant et du code

Remplie et créée en lançant le script ./scripts/generate_base_results.py via l'interface Scalingo. Le nom de la table doit correspondre avec la variable d'environnement nommée NAME_TABLE_BASE_RESULT

Extraction d'une table de la base

$ psql -U leximpact-user -h localhost -p 5479 leximpact_db_development
# \copy public.base_results_plf2022_20210923 (idfoy, avant, wprm) TO '/tmp/base_result_plf_2022.csv' CSV HEADER ENCODING 'UTF8';

Testing

Pour faire tourner les tests de LexImpact-Server, exécutez la commande suivante :

make test

Pour faire tourner les tests de performance de LexImpact-Server :

make stress-server

Puis, dans une nouvelle fenêtre, lancez :

make stress-test

Style

Ce dépôt adhère à un style de code précis, et on vous invite à le suivre pour que vos contributions soient intégrées au plus vite.

L'analyse de style est déjà exécutée avec make test. Pour le faire tourner de façon indépendante :

make check-style

Pour corriger les erreurs de style de façon automatique:

make format-style

Pour corriger les erreurs de style de façon automatique à chaque fois que vous faites un commit :

touch .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit

tee -a .git/hooks/pre-commit << END
#!/bin/sh
#
# Automatically format your code before committing.
exec make format-style
END

Activation & désactivation du PLF

leximpact-server permet de comparer une loi et un amendement défini par un usager mais aussi, une réforme de type Projet de Loi de Finances (PLF) pour l'IR et les dotations.

Pour activer ou désactiver le mode PLF, voir ce README_PLF complémentaire.