Redesign de a-propos

This commit is contained in:
Colin Maudry
2026-06-25 01:19:36 +02:00
parent 06fad7ec2d
commit b4f7e94800
13 changed files with 378 additions and 200 deletions
+17
View File
@@ -138,6 +138,23 @@ p.version > a {
font-weight: 600;
}
.account-nav .nav-link {
color: inherit;
padding-left: 10px;
border-left: 3px solid transparent;
border-radius: 0;
}
.account-nav .nav-link:hover {
background-color: rgba(255, 240, 240, 0.9);
}
.account-nav .nav-link.active {
color: #d9230f;
font-weight: 600;
border-left-color: #d9230f;
background-color: transparent;
}
#announcements {
margin: 25px 40px 0 60px;
font-size: 90%;
+1 -1
View File
@@ -161,7 +161,7 @@ def get_sources_tables(source_path) -> html.Div:
style_cell_conditional=[
{
"if": {"column_id": ["nom", "organisation"]},
"minWidth": "350px",
"minWidth": "220px",
"textAlign": "left",
"overflow": "hidden",
"lineHeight": "14px",
+67
View File
@@ -0,0 +1,67 @@
import dash_bootstrap_components as dbc
from dash import Input, Output, State, callback, html
SECTIONS = [
{"key": "presentation", "label": "Présentation", "href": "/a-propos/presentation"},
{
"key": "donnees-brutes",
"label": "Données brutes",
"href": "/a-propos/donnees-brutes",
},
{"key": "contact", "label": "Contact", "href": "/a-propos/contact"},
{"key": "contribuer", "label": "Contribuer", "href": "/a-propos/contribuer"},
{"key": "explorer", "label": "Explorer le projet", "href": "/a-propos/explorer"},
{"key": "qualite", "label": "Qualité des données", "href": "/a-propos/qualite"},
{"key": "sources", "label": "Sources de données", "href": "/a-propos/sources"},
{
"key": "mentions-legales",
"label": "Mentions légales",
"href": "/a-propos/mentions-legales",
},
]
def _nav(active: str):
links = [
dbc.NavLink(s["label"], href=s["href"], active=(s["key"] == active))
for s in SECTIONS
]
return dbc.Nav(links, vertical=True, class_name="account-nav")
def apropos_shell(active: str, contenu):
sidebar = dbc.Col(
html.Div([html.H5("À propos", className="mb-3"), _nav(active)]),
md=3,
className="d-none d-md-block",
)
mobile = html.Div(
[
dbc.Button(
"☰ Sections",
id="apropos-offcanvas-open",
color="secondary",
outline=True,
className="mb-3",
),
dbc.Offcanvas(
_nav(active),
id="apropos-offcanvas",
title="À propos",
is_open=False,
),
],
className="d-md-none",
)
content = dbc.Col([mobile, contenu], md=9)
return dbc.Container(dbc.Row([sidebar, content]), className="py-4")
@callback(
Output("apropos-offcanvas", "is_open"),
Input("apropos-offcanvas-open", "n_clicks"),
State("apropos-offcanvas", "is_open"),
prevent_initial_call=True,
)
def _toggle_apropos_offcanvas(_n, is_open):
return not is_open
+22 -199
View File
@@ -1,12 +1,7 @@
import os
from dash import Input, Output, callback, dcc, html, register_page
from dash import dcc, html, register_page
from src.figures import get_sources_tables
from src.utils.seo import META_CONTENT
NAME = "À propos"
register_page(
__name__,
path="/a-propos",
@@ -17,201 +12,29 @@ register_page(
order=5,
)
layout = html.Div(
className="container",
children=[
html.H2(NAME),
html.Div(
className="a-propos-container",
children=[
# Main Content Column
html.Div(
className="a-propos-content",
children=[
dcc.Markdown(
"""Outil d'exploration libre et gratuit des données de marchés publics, développé par Colin Maudry.
_HASH_MAP = {
"#donnees-brutes": "/a-propos/donnees-brutes",
"#api-privee": "/a-propos/api-privee",
"#contact": "/a-propos/contact",
"#contribuer": "/a-propos/contribuer",
"#explorer": "/a-propos/explorer",
"#qualite-exhausitivite": "/a-propos/qualite",
"#sources": "/a-propos/sources",
"#mentions-legales": "/a-propos/mentions-legales",
"#publication": "/a-propos/mentions-legales",
"#audience": "/a-propos/mentions-legales",
"#attributions": "/a-propos/mentions-legales",
"#liste_marches": "/a-propos/mentions-legales",
}
Ce projet vise à démocratiser l'accès aux données des marchés publics et à un outil performant et gratuit. Si vous le trouvez utile
j'aimerais beaucoup échanger avec vous pour comprendre vos cas d'usages et vos besoins. Cet outil ne peut rester performant que si je comprends les problèmes qu'il peut aider à résoudre. Ce projet ne peut rester gratuit que grâce au financement du développement de nouvelles fonctionnalités.
En effet, le potentiel des données d'attribution de marchés et des données qui peuvent les enrichir est très loin d'être exploité par
les fonctionnalités actuelles de decp.info. Il est ainsi possible de rajouter
def layout(**_):
return html.Div(dcc.Location(id="apropos-redirect-loc"))
- de nombreuses visualisations de données (cartes, graphiques, tableaux) sur des thématiques variées (vivacité de la concurrence, secteurs d'activité, insertion par l'activité économique (IAE), distance acheteur-titulaire...)
- des alertes par email si des marchés correspondant à certains critères
- ...et toutes les fonctionnalités auxquelles vous pourrez penser
"""
),
html.H4("Consommer les données brutes", id="donnees-brutes"),
dcc.Markdown(
"""
Vous pouvez consommer les données qui alimentent decp.info
- en les téléchargeant [sur data.gouv.fr](https://www.data.gouv.fr/datasets/donnees-essentielles-de-la-commande-publique-consolidees-format-tabulaire) (Parquet, CSV), pensez à lire la description du jeu de données
- en interrogeant l'[API REST ouverte](https://www.data.gouv.fr/datasets/donnees-essentielles-de-la-commande-publique-consolidees-format-tabulaire#user-content-api-rest)
"""
),
html.H4("API privée", id="api-privee"),
dcc.Markdown(
"""
Une API HTTP est disponible pour accéder aux mêmes données par programme.
Documentation interactive : [Swagger UI](/api/v1/swagger).
L'accès se fait sur token. Pour en obtenir un, contactez
[colin@maudry.com](mailto:colin@maudry.com).
"""
),
html.H4("Contact", id="contact"),
dcc.Markdown(
"""
- Email : [colin@colmo.tech](mailto:colin@colmo.tech)
- Bluesky : [@col1m.bsky.social](https://bsky.app/profile/col1m.bsky.social)
- Mastodon : [col1m@mamot.fr](https://mamot.fr/@col1m)
- LinkedIn : [colinmaudry](https://www.linkedin.com/in/colinmaudry/)
"""
),
html.H4("Pour contribuer", id="contribuer"),
dcc.Markdown(
"""
- via l'achat d'une prestation de service (devis, prestation, facture), vous pouvez financer le développement de [fonctionnalités prévues](https://github.com/ColinMaudry/decp.info/issues), ou d'autres !
- ma société accepte aussi les dons (pas de réduction d'impôt possible)
- écrivez-moi et on discute !
"""
),
html.H4("Pour explorer le projet", id="explorer"),
dcc.Markdown(
"""
- ✉️ [inscription à la liste de diffusion](https://6254d9a3.sibforms.com/serve/MUIFAEonUVkoSVrdgey18CTgLyI16xw4yeu-M-YOUzhWE_AgfQfbgkyT7GvA_RYLro9MfuRqkzQxSvu7-uzbMSv2a2ZQPsliM7wtiiqIL8kR2zOvl6m11fb5qjcOxMAYsLiY_YBi3P7NY95CTJ8vRY4CpsDclF2iLooOElKkTgIgi5nePe7zAIrgiYM5v2EuALlGJZMEG9vBP-Cu) (annonces des mises à jour et évènements, maximum une fois par mois)
- 💾 [données consolidées en Open Data](https://www.data.gouv.fr/datasets/donnees-essentielles-de-la-commande-publique-consolidees-format-tabulaire/)
- 🗞️ [mon blog](https://colin.maudry.com)
- 📔 [wiki du projet](https://github.com/ColinMaudry/decp-processing/wiki)
- 🚰 code source
- [de decp.info](https://github.com/ColinMaudry/decp.info)
- [du traitement des données](https://github.com/ColinMaudry/decp-processing)
"""
),
html.H4(
"Qualité et exhaustivité des données",
id="qualite-exhausitivite",
),
dcc.Markdown(
"""Les données visibles sur ce site proviennent exclusivement de la publication de données ouvertes par les acheteurs publics ou en leur nom, régie par [l'arrêté du 22 décembre 2022](https://www.legifrance.gouv.fr/jorf/id/JORFTEXT000046850496). Leur qualité est donc principalement liée à la qualité de leur saisie par les agents publics, parfois peu aidé·es par la qualité des outils à leur disposition. Je pense que l'analyse de marchés individuels et le comptage de marchés sur des critères autres que financiers sont plutôt fiables. En revanche, certains montants de marché estimés à des valeurs farfelues ([1 euro](https://decp.info/marches/432766947000192025S01301), [1 milliard](https://decp.info/marches/2459004280001320210000000271)) faussent les calculs par aggrégation (sommes, moyennes, médianes) et donc la production de statistiques financières fiables. Acheteurs, acheteuses : s'il vous plaît, essayez d'estimer les montants des marchés publics attribués de manière plus précise.
Quant à l'exhaustivité, je consolide toutes les sources de données exploitables que j'ai pu identifier (voir [ci-dessous](/bin.usr-is-merged/)). Je tiens à souligner la belle continuité de la publication par la DGFiP des données des marchés publics remontées via le [protocole PES](https://www.collectivites-locales.gouv.fr/finances-locales/le-protocole-dechange-standard-pes). Merci à leurs équipes."""
),
html.H4("Sources de données ", id="sources"),
get_sources_tables(os.getenv("SOURCE_STATS_CSV_PATH")),
html.H4("Mentions légales", id="mentions-legales"),
html.H5("Publication", id="publication"),
dcc.Markdown(
"""
Site Web développé et édité par [SAS Colmo](https://annuaire-entreprises.data.gouv.fr/entreprise/colmo-989393350), 989 393 350 RCS Rennes au capital de 3 000 euros.
Siège social : 1 carrefour Jouaust, 35000 Rennes
Hébergement : serveur situé en France et administré par Scaleway, 8 rue de la Ville lEvêque, 75008 Paris
"""
),
html.H5("Suivi d'audience", id="audience"),
dcc.Markdown(
"""
Ce site dépose un petit fichier texte (un « cookie ») sur votre ordinateur lorsque vous le consultez ([Wikipédia](https://fr.wikipedia.org/wiki/Cookie_(informatique))). Cela me permet de mesurer le nombre de visites, de distinguer les nouveaux visiteurs des utilisateurs réguliers et ainsi de communiquer sur l'impact de decp.info.
**Ce site naffiche pas de bannière de consentement aux cookies, pourquoi ?**
Cest vrai, vous navez pas eu à cliquer sur un bloc qui recouvre la moitié de la page pour dire que vous êtes daccord avec le dépôt de cookies.
Rien dexceptionnel, je respecte simplement la loi, qui dit que certains outils de suivi daudience, correctement configurés pour respecter la vie privée, sont exemptés dautorisation préalable.
Jutilise pour cela [Matomo](https://matomo.org/), un outil [libre](https://matomo.org/free-software/), paramétré pour être en conformité avec [la recommandation « Cookies »](https://www.cnil.fr/fr/solutions-pour-les-cookies-de-mesure-daudience) de la CNIL. Cela signifie que votre adresse IP, par exemple, est anonymisée avant d’être enregistrée. Il mest donc impossible dassocier vos visites sur ce site à votre personne.
J'enregistre également les données suivantes, de manière anonyme, afin de mieux comprendre comment vous utilisez le site et l'améliorer :
- recherches sur la page d'accueil
- filtres appliqués aux données
"""
),
html.H5("Attributions", id="attributions"),
dcc.Markdown("""
Les polices de caractères sont distribuées par [Bunny fonts](https://fonts.bunny.net), une alternative européenne et qualitative à Google Fonts.
- la police de caractère [Inter](https://fonts.bunny.net/family/inter), principale police de ce site, a été créée par The Inter Project Authors ([source](https://github.com/rsms/inter))
- la police de caractère [Fira Code](https://fonts.bunny.net/family/fira-code), la police à largeure fixe, a été créée par The Fira Code Project Authors (https://github.com/tonsky/FiraCode)
"""),
html.H4(
"Liste des marchés par département", id="liste_marches"
),
dcc.Markdown(
"""
- [Marchés par département](/departements)
"""
),
],
),
# Table of Contents Column
html.Div(
className="a-propos-toc",
children=[
html.Div(
[
html.A(
"Consommer les données brutes",
href="#donnees-brutes",
className="toc-link",
),
html.A(
"API privée",
href="#api-privee",
className="toc-link",
),
html.A(
"Contact", href="#contact", className="toc-link"
),
html.A(
"Pour contribuer",
href="#contribuer",
className="toc-link",
),
html.A(
"Pour explorer le projet",
href="#explorer",
className="toc-link",
),
html.A(
"Qualité et exhaustivité des données",
href="#qualite-exhausitivite",
className="toc-link",
),
html.A(
"Sources de données",
href="#sources",
className="toc-link",
),
html.A(
"Mentions légales",
href="#mentions-legales",
className="toc-link",
),
html.A(
"Publication",
href="#publication",
className="toc-link toc-level-2",
),
html.A(
"Suivi d'audience",
href="#audience",
className="toc-link toc-level-2",
),
html.A(
"Attributions",
href="#attributions",
className="toc-link toc-level-2",
),
]
),
],
),
],
),
],
@callback(
Output("apropos-redirect-loc", "href"),
Input("apropos-redirect-loc", "hash"),
)
def _redirect(hash_val):
return _HASH_MAP.get(hash_val or "", "/a-propos/presentation")
View File
+29
View File
@@ -0,0 +1,29 @@
from dash import dcc, html, register_page
from src.pages._apropos_shell import apropos_shell
from src.utils.seo import META_CONTENT
register_page(
__name__,
path="/a-propos/contact",
title="Contact | À propos | decp.info",
description="Contactez Colin Maudry, développeur de decp.info.",
image_url=META_CONTENT["image_url"],
)
def layout(**_):
contenu = html.Div(
[
html.H2("Contact"),
dcc.Markdown(
"""
- Email : [colin@colmo.tech](mailto:colin@colmo.tech)
- Bluesky : [@col1m.bsky.social](https://bsky.app/profile/col1m.bsky.social)
- Mastodon : [col1m@mamot.fr](https://mamot.fr/@col1m)
- LinkedIn : [colinmaudry](https://www.linkedin.com/in/colinmaudry/)
"""
),
]
)
return apropos_shell("contact", contenu)
+28
View File
@@ -0,0 +1,28 @@
from dash import dcc, html, register_page
from src.pages._apropos_shell import apropos_shell
from src.utils.seo import META_CONTENT
register_page(
__name__,
path="/a-propos/contribuer",
title="Contribuer | À propos | decp.info",
description="Comment contribuer au projet decp.info.",
image_url=META_CONTENT["image_url"],
)
def layout(**_):
contenu = html.Div(
[
html.H2("Pour contribuer"),
dcc.Markdown(
"""
- via l'achat d'une prestation de service (devis, prestation, facture), vous pouvez financer le développement de [fonctionnalités prévues](https://github.com/ColinMaudry/decp.info/issues), ou d'autres !
- ma société accepte aussi les dons (pas de réduction d'impôt possible)
- écrivez-moi et on discute !
"""
),
]
)
return apropos_shell("contribuer", contenu)
+28
View File
@@ -0,0 +1,28 @@
from dash import dcc, html, register_page
from src.pages._apropos_shell import apropos_shell
from src.utils.seo import META_CONTENT
register_page(
__name__,
path="/a-propos/donnees-brutes",
title="Données brutes | À propos | decp.info",
description="Téléchargez ou interrogez les données brutes qui alimentent decp.info.",
image_url=META_CONTENT["image_url"],
)
def layout(**_):
contenu = html.Div(
[
html.H2("Consommer les données brutes"),
dcc.Markdown(
"""
Vous pouvez consommer les données qui alimentent decp.info en les téléchargeant [sur data.gouv.fr](https://www.data.gouv.fr/datasets/donnees-essentielles-de-la-commande-publique-consolidees-format-tabulaire) (Parquet, CSV), pensez à lire la description du jeu de données
Une API REST tabulaire (JSON) est également disponible par abonnement mensuel pour accéder aux mêmes données et alimenter une application.
Documentation interactive : [Swagger UI](/api/v1/swagger). Si cela vous intéresse, [contactez-moi](/a-propos/contact)."""
),
]
)
return apropos_shell("donnees-brutes", contenu)
+32
View File
@@ -0,0 +1,32 @@
from dash import dcc, html, register_page
from src.pages._apropos_shell import apropos_shell
from src.utils.seo import META_CONTENT
register_page(
__name__,
path="/a-propos/explorer",
title="Explorer le projet | À propos | decp.info",
description="Ressources pour explorer le projet decp.info : données, code source, blog.",
image_url=META_CONTENT["image_url"],
)
def layout(**_):
contenu = html.Div(
[
html.H2("Pour explorer le projet"),
dcc.Markdown(
"""
- ✉️ [inscription à la liste de diffusion](https://6254d9a3.sibforms.com/serve/MUIFAEonUVkoSVrdgey18CTgLyI16xw4yeu-M-YOUzhWE_AgfQfbgkyT7GvA_RYLro9MfuRqkzQxSvu7-uzbMSv2a2ZQPsliM7wtiiqIL8kR2zOvl6m11fb5qjcOxMAYsLiY_YBi3P7NY95CTJ8vRY4CpsDclF2iLooOElKkTgIgi5nePe7zAIrgiYM5v2EuALlGJZMEG9vBP-Cu) (annonces des mises à jour et évènements, maximum une fois par mois)
- 💾 [données consolidées en Open Data](https://www.data.gouv.fr/datasets/donnees-essentielles-de-la-commande-publique-consolidees-format-tabulaire/)
- 🗞️ [mon blog](https://colin.maudry.com)
- 📔 [wiki du projet](https://github.com/ColinMaudry/decp-processing/wiki)
- 🚰 code source
- [de decp.info](https://github.com/ColinMaudry/decp.info)
- [du traitement des données](https://github.com/ColinMaudry/decp-processing)
"""
),
]
)
return apropos_shell("explorer", contenu)
+61
View File
@@ -0,0 +1,61 @@
from dash import dcc, html, register_page
from src.pages._apropos_shell import apropos_shell
from src.utils.seo import META_CONTENT
register_page(
__name__,
path="/a-propos/mentions-legales",
title="Mentions légales | À propos | decp.info",
description="Mentions légales de decp.info : éditeur, hébergement, suivi d'audience, attributions.",
image_url=META_CONTENT["image_url"],
)
def layout(**_):
contenu = html.Div(
[
html.H2("Mentions légales"),
html.H4("Publication", id="publication"),
dcc.Markdown(
"""
Site Web développé et édité par [SAS Colmo](https://annuaire-entreprises.data.gouv.fr/entreprise/colmo-989393350), 989 393 350 RCS Rennes au capital de 3 000 euros.
Siège social : 1 carrefour Jouaust, 35000 Rennes
Hébergement : serveur situé en France et administré par Scaleway, 8 rue de la Ville l'Evêque, 75008 Paris
"""
),
html.H4("Suivi d'audience", id="audience"),
dcc.Markdown(
"""
Ce site dépose un petit fichier texte (un « cookie ») sur votre ordinateur lorsque vous le consultez ([Wikipédia](https://fr.wikipedia.org/wiki/Cookie_(informatique))). Cela me permet de mesurer le nombre de visites, de distinguer les nouveaux visiteurs des utilisateurs réguliers et ainsi de communiquer sur l'impact de decp.info.
**Ce site n'affiche pas de bannière de consentement aux cookies, pourquoi ?**
C'est vrai, vous n'avez pas eu à cliquer sur un bloc qui recouvre la moitié de la page pour dire que vous êtes d'accord avec le dépôt de cookies.
Rien d'exceptionnel, je respecte simplement la loi, qui dit que certains outils de suivi d'audience, correctement configurés pour respecter la vie privée, sont exemptés d'autorisation préalable.
J'utilise pour cela [Matomo](https://matomo.org/), un outil [libre](https://matomo.org/free-software/), paramétré pour être en conformité avec [la recommandation « Cookies »](https://www.cnil.fr/fr/solutions-pour-les-cookies-de-mesure-daudience) de la CNIL. Cela signifie que votre adresse IP, par exemple, est anonymisée avant d'être enregistrée. Il m'est donc impossible d'associer vos visites sur ce site à votre personne.
J'enregistre également les données suivantes, de manière anonyme, afin de mieux comprendre comment vous utilisez le site et l'améliorer :
- recherches sur la page d'accueil
- filtres appliqués aux données
"""
),
html.H4("Attributions", id="attributions"),
dcc.Markdown(
"""
Les polices de caractères sont distribuées par [Bunny fonts](https://fonts.bunny.net), une alternative européenne et qualitative à Google Fonts.
- la police de caractère [Inter](https://fonts.bunny.net/family/inter), principale police de ce site, a été créée par The Inter Project Authors ([source](https://github.com/rsms/inter))
- la police de caractère [Fira Code](https://fonts.bunny.net/family/fira-code), la police à largeure fixe, a été créée par The Fira Code Project Authors (https://github.com/tonsky/FiraCode)
"""
),
html.H4("Marchés par département", id="liste_marches"),
dcc.Markdown("- [Marchés par département](/departements)"),
]
)
return apropos_shell("mentions-legales", contenu)
+35
View File
@@ -0,0 +1,35 @@
from dash import dcc, html, register_page
from src.pages._apropos_shell import apropos_shell
from src.utils.seo import META_CONTENT
register_page(
__name__,
path="/a-propos/presentation",
title="Présentation | À propos | decp.info",
description="En savoir plus sur decp.info, l'outil d'exploration des données essentielles de la commande publique.",
image_url=META_CONTENT["image_url"],
)
def layout(**_):
contenu = html.Div(
[
html.H2("Présentation"),
dcc.Markdown(
"""Outil d'exploration libre et gratuit des données de marchés publics, développé par Colin Maudry.
Ce projet vise à démocratiser l'accès aux données des marchés publics et à un outil performant et gratuit. Si vous le trouvez utile
j'aimerais beaucoup échanger avec vous pour comprendre vos cas d'usages et vos besoins. Cet outil ne peut rester performant que si je comprends les problèmes qu'il peut aider à résoudre. Ce projet ne peut rester gratuit que grâce au financement du développement de nouvelles fonctionnalités.
En effet, le potentiel des données d'attribution de marchés et des données qui peuvent les enrichir est très loin d'être exploité par
les fonctionnalités actuelles de decp.info. Il est ainsi possible de rajouter
- de nombreuses visualisations de données (cartes, graphiques, tableaux) sur des thématiques variées (vivacité de la concurrence, secteurs d'activité, insertion par l'activité économique (IAE), distance acheteur-titulaire...)
- des alertes par email si des marchés correspondant à certains critères
- ...et toutes les fonctionnalités auxquelles vous pourrez penser
"""
),
]
)
return apropos_shell("presentation", contenu)
+33
View File
@@ -0,0 +1,33 @@
from dash import dcc, html, register_page
from src.pages._apropos_shell import apropos_shell
from src.utils.seo import META_CONTENT
register_page(
__name__,
path="/a-propos/qualite",
title="Qualité des données | À propos | decp.info",
description="Informations sur la qualité et l'exhaustivité des données de marchés publics sur decp.info.",
image_url=META_CONTENT["image_url"],
)
def layout(**_):
contenu = html.Div(
[
html.H2("Qualité et exhaustivité des données"),
dcc.Markdown(
"""Les données visibles sur ce site proviennent exclusivement de la publication de données
ouvertes par les acheteurs publics ou en leur nom, régie par
[l'arrêté du 22 décembre 2022](https://www.legifrance.gouv.fr/jorf/id/JORFTEXT000046850496). Leur
qualité est donc principalement liée à la qualité de leur saisie par les agents publics, parfois
peu aidé·es par la qualité des outils à leur disposition.
Je pense que l'analyse de marchés
individuels et le comptage de marchés sur des critères autres que financiers sont plutôt fiables. En revanche, certains montants de marché estimés à des valeurs farfelues ([1 euro](https://decp.info/marches/432766947000192025S01301), [1 milliard](https://decp.info/marches/2459004280001320210000000271)) faussent les calculs par aggrégation (sommes, moyennes, médianes) et donc la production de statistiques financières fiables. Acheteurs, acheteuses : s'il vous plaît, essayez d'estimer les montants des marchés publics attribués de manière plus précise.
Quant à l'exhaustivité, je consolide toutes les sources de données exploitables que j'ai pu identifier (voir [Sources de données](/a-propos/sources)). Je tiens à souligner la belle continuité de la publication par la DGFiP des données des marchés publics remontées via le [protocole PES](https://www.collectivites-locales.gouv.fr/finances-locales/le-protocole-dechange-standard-pes). Merci à leurs équipes."""
),
]
)
return apropos_shell("qualite", contenu)
+25
View File
@@ -0,0 +1,25 @@
import os
from dash import html, register_page
from src.figures import get_sources_tables
from src.pages._apropos_shell import apropos_shell
from src.utils.seo import META_CONTENT
register_page(
__name__,
path="/a-propos/sources",
title="Sources de données | À propos | decp.info",
description="Sources de données utilisées par decp.info pour consolider les marchés publics français.",
image_url=META_CONTENT["image_url"],
)
def layout(**_):
contenu = html.Div(
[
html.H2("Sources de données"),
get_sources_tables(os.getenv("SOURCE_STATS_CSV_PATH")),
]
)
return apropos_shell("sources", contenu)