leximpact / leximpact-server

Simuler l'impact des réformes socio-fiscales en moins d'une minute
https://leximpact.an.fr
GNU Affero General Public License v3.0
4 stars 0 forks source link

The repository has now been moved to https://git.leximpact.dev/leximpact/leximpact-server/

Pour consulter la dernière version du projet, merci de vous rendre sur https://git.leximpact.dev/leximpact/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.

[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.

Leximpact est constitué de deux parties :

Installation

Pour Docker voir docker/README.md.

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

Plateformes supportées :

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>

Installez un environnement virtuel

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

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 :tada: Vous êtes prêt·e à installer LexImpact-Server !

Installez 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é !

Lancez l'API Web LexImpact

Fichier de configuration .env

ℹ️ 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 fonctionnalités (i.e. les endpoints auth et simpop), il devrait être possible de faire tourner Leximpact-server sans base de données ni 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, les champs y apparaissant sont :

Variable optionnelle :

Base de données et migrations

Pour créer la base de données, et exécuter toutes les migrations, 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 !

Mode agrégats de population

Par défaut, seul de résultats à partir de cas-types sont présents dans l'API.

Dans le cas où une base de données représentant la population française (non incluse dans la bibliothèque) est présente sur l'ordinateur d'exécution, des agrégats d'impact (budgétaire, redistributif...) seront inclus dans les réponses de l'API.

Pour ce faire, modifiez le fichier suivant :

# Simulation_engine/simulate_pop_from_reform.py
version_beta_sans_graph_pop = False  # Au lieu de True par défaut

Note : les instructions supra vous sont fournies à caractère indicatif, l'équipe de développement LexImpact ne disposant pas à ce stade de véritable jeu de données.

🎉 Félicitations, vous-êtes en train de réformer le système socio-fiscal français !

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

Endpoints de l'API Web - Impôt sur le revenu

L'API Web dispose des itinéraires suivants :

Parmi ces itinéraires, deux nécessitent une vérification de l'identité de l'appelant :

Itinéraire par défaut ou /

/metadata/description_cas_types

/auth/login

/calculate/compare

En version 1.1.0 de la spécification de l'API Web, la structure de la réforme étend les possibilités d'amendement du quotient familial et cela est défini par un nouveau champ calculNombreParts.

Elle reproduit presque la structure d'OpenFisca-France. Si un paramètre est omis, il est remplacé par la version par défaut d'OpenFisca-France (donc le code de loi existant). Le champ calculNombreParts est optionnel, mais s'il figure, tous ses champs doivent y figurer, et les élément du tableau associés aux quatre situations familiales doivent faire la même longueur :

"reforme" : {
    "impot_revenu" :{
        "bareme" :{
            "seuils": [9964, 25659, 73369, 157806],
            "taux": [0.14, 0.3, 0.41, 0.45]
        },
        "decote" : {"seuil_celib": 777, "seuil_couple": 1286, "taux": 0.4525},
        "plafond_qf":{
            "abat_dom":{
                "taux_GuadMarReu" : 0.3,
                "plaf_GuadMarReu" : 2450,
                "taux_GuyMay" : 0.4,
                "plaf_GuyMay" : 4050
            },
            "maries_ou_pacses" : 1567,
            "celib_enf" : 3697,
            "celib" : 936,
            "reduc_postplafond" : 1562,
            "reduc_postplafond_veuf": 1745,
            "reduction_ss_condition_revenus" :{
                "seuil_maj_enf": 3797, 
                "seuil1": 18985,
                "seuil2":21037,
                "taux":0
            }
        },
        "calculNombreParts": {
            "partsSelonNombrePAC": [
                {
                    "veuf": 1,
                    "mariesOuPacses": 2,
                    "celibataire": 1,
                    "divorce": 1
                },
                {
                    "veuf": 2.5,
                    "mariesOuPacses": 2.5,
                    "celibataire": 1.5,
                    "divorce": 1.5
                },
                {
                    "veuf": 3,
                    "mariesOuPacses": 3,
                    "celibataire": 2,
                    "divorce": 2
                },
                {
                    "veuf": 4,
                    "mariesOuPacses": 4,
                    "celibataire": 3,
                    "divorce": 3
                }
            ],
            "partsParPACAuDela": 1,
            "partsParPACChargePartagee": {
                "zeroChargePrincipale": {
                    "deuxPremiers": 0.25,
                    "suivants": 0.5
                },
                "unChargePrincipale": {
                    "premier": 0.25,
                    "suivants": 0.5
                },
                "deuxOuPlusChargePrincipale": {
                    "suivants": 0.5
                }
            },
            "bonusParentIsole": {
                "auMoinsUnChargePrincipale": 0.5,
                "zeroChargePrincipaleUnPartage": 0.25,
                "zeroChargeprincipaleDeuxOuPlusPartage": 0.5
            }
        }
    }
}

PAC désigne personne à charge.

/calculate/simpop

Endpoints de l'API Web - Dotations aux collectivités locales

L'API Web traite également d'une thématique isolée de l'impôt sur le revenu : les dotations de l'État aux collectivités locales.

/dotations

Base de données

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 remplir les différentes fonctions suivantes :

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 est déposée et régulièrement updatée par le SSI de l'AN dans le serveur ssian@eig.etalab.gouv.fr

    .\scalingo -a leximpact-server --region osc-fr1 run --file users.csv bash
    pip install tables
    python ./repo/preload.py
   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. 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