<?xml version="1.0" encoding="UTF-8"?>
<rss  xmlns:atom="http://www.w3.org/2005/Atom" 
      xmlns:media="http://search.yahoo.com/mrss/" 
      xmlns:content="http://purl.org/rss/1.0/modules/content/" 
      xmlns:dc="http://purl.org/dc/elements/1.1/" 
      version="2.0">
<channel>
<title>SSPHub</title>
<link>https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog.html</link>
<atom:link href="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog.xml" rel="self" type="application/rss+xml"/>
<description>Articles, billets de blog écrits sur tout sujet en lien avec la data science. Cela peut couvrir des conférences, des nouveautés, des projets ...</description>
<generator>quarto-1.9.38</generator>
<lastBuildDate>Mon, 15 Jun 2026 00:00:00 GMT</lastBuildDate>
<item>
  <title>J’ai créé un bot sur Tchap banché à un LLM</title>
  <link>https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/bot_tchap/</link>
  <description><![CDATA[ 





<section id="quel-est-le-besoin" class="level1">
<h1>Quel est le besoin ?</h1>
<p>Dans l’équipe, on a un salon Tchap pour se dépanner sans déranger personne. C’est là qu’on pose les questions qu’on n’ose pas poser ailleurs. Et un jour, l’idée est venue d’y <strong>brancher un bot capable de répondre à nos questions</strong>, directement depuis Tchap, plutôt que d’attendre qu’un(e) gentil(le) collègue y réponde ou pose la question à un(e) autre collègue qui connaît la réponse. De quoi se dépanner sans déranger personne - et, accessoirement, briller en réunion d’équipe - si tant est qu’on capte dans la salle de réunion.</p>
<p>Et enfin, soyons honnêtes, c’était aussi en partie parce que c’était drôle d’essayer de mettre un bot sur Tchap.</p>
<p>Finalement, ce n’était pas si compliqué. On m’avait vendu que les bots Tchap étaient compliqués à mettre en place, et en fait je n’ai pas trouvé. Par ailleurs, se connecter à <a href="https://llm.lab.sspcloud.fr">llm.lab</a> est plutôt très simple. Le plus délicat a été de découvrir Tchap, d’orchestrer les deux et enfin la mise en production.</p>
<p>Après <em>une petite semaine de travail</em> (cf.&nbsp;détail plus bas pour ceux que cela intéresse), le bot est en place (cf.&nbsp;<a href="https://github.com/SSPHub/tchap_bot_llm">sa maison sur Github</a>) et fait aujourd’hui trois choses :</p>
<ul>
<li>il <strong>répond quand on dit coucou</strong>, histoire de vérifier qu’il est bien réveillé ;</li>
<li>il <strong>répond à vos questions</strong> en interrogeant un grand modèle de langage ;</li>
<li>et, pour le plaisir, il a une <strong>fonctionnalité mystère</strong> : il réagit à un mot-clé glissé dans la conversation. 🤫</li>
</ul>
</section>
<section id="comment-faire" class="level1">
<h1>Comment faire ?</h1>
<p>Le truc sympa avec Tchap, c’est sa <strong>philosophie ouverte</strong> - aux agents de l’État, en tout cas. Du coup, il y a pas mal de ressources en ligne ou directement sur la plateforme. Trois m’ont aidé à me lancer :</p>
<ul>
<li>le salon <a href="https://matrix.to/#/#BotsetIntgrationsTchapU2tHdMEN80D:agent.dinum.tchap.gouv.fr">Tchap - Bots et Intégrations</a>, où la communauté partage des questions et ses astuces ;</li>
<li>la <a href="https://aide.tchap.beta.gouv.fr/fr/article/documentation-technique-bot-et-integrations-tchap-1z3dfx/">doc technique officielle sur les bots et intégrations</a> ;</li>
<li>les <strong>webinaires en ligne</strong>, en particulier celui du MTES qui raconte comment ils ont automatisé leur bascule de Mattermost vers Tchap.</li>
</ul>
<p>La première découverte fut que <strong>dans Tchap, quasiment tout est automatisable</strong>. Le bot récupère exactement le nom et prénom du compte que vous lui donnez et puis il peut envoyer des messages, réagir, suivre un fil de discussion, inviter des gens …</p>
<p>Tout cela passe par des <strong>appels API</strong>, un peu comme sur Grist. A partir du moment où vous êtes un peu familier avec une API, c’est pas beaucoup plus compliqué de programmer un bot sur Tchap.</p>
<p>Matrix (la technologie derrière Tchap) repose sur un écosystème avec des bibliothèques et explications aussi accessibles, sans compter les outils internes à l’État listés dans les ressources ci-dessus. Après avoir regardé, mes besoins étaient au fond assez simples, je m’en suis tenu à un petit package public : <a href="https://pypi.org/project/simplematrixbotlib/"><code>simplematrixbotlib</code></a>, qui n’est lui-même qu’une surcouche bien pratique de <a href="https://matrix-nio.readthedocs.io/en/latest/#api-documentation"><code>matrix-nio</code></a>.</p>
<p>Je vais vous <strong>refaire le parcours pour créer facilement votre bot sur Tchap</strong>.</p>
</section>
<section id="première-étape-mettre-en-place-le-bot" class="level1">
<h1>Première étape : mettre en place le bot</h1>
<p>Petit avantage au démarrage : j’avais une <strong>boîte aux lettres fonctionnelle (BALF)</strong> sous la main, ce qui m’a permis de créer un compte Tchap tout neuf. Le bot n’emprunte donc pas mon identité. Si vous n’en avez pas, la bonne pratique indiqué dans les ressources de Tchap, c’est de créer une BALF et un compte Tchap rien que pour lui. Parce que sinon, <strong>rien ne différencie, vu de Tchap, un bot d’un utilisateur humain.</strong></p>
<p>Le plus dur au début, ça a été de me repérer dans l’univers Matrix / Tchap. Pour l’apprivoiser, on va <strong>retourner à la base des API</strong> avec quelques lignes de <code>bash</code> et <code>curl</code> et l’aide de la <a href="https://spec.matrix.org/latest/client-server-api/">documentation de Matrix</a> pour taper directement sur leurs API.</p>
<section id="authentification" class="level2">
<h2 class="anchored" data-anchor-id="authentification">Authentification</h2>
<p>Première mission : <strong>récupérer un jeton d’accès</strong>. Vous envoyez <strong>votre identifiant et mot de passe Tchap</strong> et l’API vous donne un token.</p>
<p>Le script ci-dessous tourne tel quel sur un Terminal, à condition d’avoir renseigné vos deux variables d’environnement <code>TCHAP_BOT_MATRIX_ID</code>, qui est votre <code>id</code> utilisateur de Tchap (quelque chose comme “<span class="citation" data-cites="votre-bot:agent.finances.tchap.gouv.fr">@votre-bot:agent.finances.tchap.gouv.fr</span>”), et <code>TCHAP_BOT_PWD</code> qui est le mot de passe que vous utilisez pour vous connecter au compte.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb1-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#!/usr/bin/env bash</span></span>
<span id="cb1-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Pré-requis : export TCHAP_BOT_MATRIX_ID="..." et export TCHAP_BOT_PWD="..."</span></span>
<span id="cb1-3"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">HOMESERVER</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://matrix.agent.finances.tchap.gouv.fr"</span></span>
<span id="cb1-4"></span>
<span id="cb1-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">curl</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-X</span> POST <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$HOMESERVER</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">/_matrix/client/v3/login"</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb1-6">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-H</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Content-Type: application/json"</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb1-7">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-d</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'{</span></span>
<span id="cb1-8"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">    "type": "m.login.password",</span></span>
<span id="cb1-9"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">    "password": "'"</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$TCHAP_BOT_PWD</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"'",</span></span>
<span id="cb1-10"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">    "identifier": { "type": "m.id.user", "user": "'"</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$TCHAP_BOT_MATRIX_ID</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"'" },</span></span>
<span id="cb1-11"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">    "device_id": "API"</span></span>
<span id="cb1-12"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  }'</span></span></code></pre></div></div>
<p>La requête vous renverra un joli token d’identification si cela marche.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb2-1"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"access_token"</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">:</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"mct_montokenanepasleaker"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"device_id"</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">:</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"API"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"user_id"</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">:</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"@votre-bot:agent.finances.tchap.gouv.fr"</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>Ce n’était qu’une première étape pour vérifier que tout marche, <strong>ouvrons Python maintenant</strong>.</p>
</section>
<section id="envoyer-un-message" class="level2">
<h2 class="anchored" data-anchor-id="envoyer-un-message">Envoyer un message</h2>
<p>La première étape a été facile. La deuxième, envoyer un message, un poil plus longue (mais cela reste tout à fait raisonnable).</p>
<p>Je suis reparti des <strong>très bons examples de la documentation</strong> de <a href="https://simple-matrix-bot-lib.readthedocs.io/en/latest/examples.html"><code>simplematrixbotlib</code></a> et de <a href="https://matrix-nio.readthedocs.io/en/latest/#api-documentation"><code>matrix-nio</code></a>.</p>
<p>Pour <strong>comprendre la manière dont marche Matrix</strong>, le déclic a été de comprendre que <strong>tout est un événement dans Matrix.</strong> Un message, une réaction, une connexion : tout cela, ce sont des événements (<em>event</em>) avec un identifiant unique. Concrètement, ne cherchez donc pas la fonction <code>send_message</code> : vous envoyez un evénement qui est de type message (<code>m.room.message</code>). De la même manière que quand vous entrez dans un salon, vous envoyez un événement de type <code>je rentre dans ce salon Tchap</code>.</p>
<p>Cela <em>n’a pas été beaucoup plus simple</em> par contre quand je me suis rendu compte que <strong>le chiffrement, c’est très bien, mais ca complique tout.</strong> Indispensable pour la sécurité, mais ça vous complique la vie. De ce que j’ai compris sur la manière dont Matrix marche quand les messages sont chiffrés : dès que vous envoyez un message, la clé de chiffrement change. Vous avez l’ancienne clé et le message, avec cela vous trouvez la nouvelle clé. Par contre, à partir de la clé actuelle, vous ne pouvez pas déduire l’ancienne clé et donc déchiffrer les anciens messages. Mais vous pourrez voir les prochains. Et ceux d’après, etc etc.</p>
<p>Concrètement, cela veut dire que <strong>le bot n’a pas accès au passé</strong>. Il ne peut voir que les messages depuis qu’il a été créé.</p>
<p>Une fois ces idées en tête, je suis reparti de la <a href="https://simple-matrix-bot-lib.readthedocs.io/en/latest/examples.html">doc de <code>simplematrixbotlib</code></a> pour bâtir <strong>un cas tout simple</strong> : un bot qui répond à un mot. Vous lui dites <code>coucou</code>, il vous donne l’heure.</p>
<p>Voici donc un bot complet, prêt à lancer - il suffit d’avoir installé les packages nécessaires avec <code>uv add</code> et d’avoir défini vos identifiants dans un fichier <code>.env</code>:</p>
<div class="code-with-filename">
<div class="code-with-filename-file">
<pre><strong>.env</strong></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" data-filename=".env" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb3-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># =============================================================================</span></span>
<span id="cb3-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># .env - variables d'environnement du bot Tchap</span></span>
<span id="cb3-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Copiez ce fichier, renseignez les valeurs, et NE LE COMMITEZ PAS</span></span>
<span id="cb3-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># (ajoutez `.env` à votre .gitignore).</span></span>
<span id="cb3-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># =============================================================================</span></span>
<span id="cb3-6"></span>
<span id="cb3-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># --- Compte Tchap du bot (idéalement une BALF dédiée) ---------------------</span></span>
<span id="cb3-8"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Identifiant Matrix complet, ex. @votre-bot:agent.finances.tchap.gouv.fr</span></span>
<span id="cb3-9">TCHAP_BOT_MATRIX_ID<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"@votre-bot:agent.finances.tchap.gouv.fr"</span></span>
<span id="cb3-10">TCHAP_BOT_PWD<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"votre_mot_de_passe_tchap"</span></span></code></pre></div></div>
</div>
<div id="f3da368e" class="cell">
<div class="code-with-filename">
<details class="code-fold">
<summary>Code</summary>
<div class="code-with-filename-file">
<pre><strong>main.py</strong></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb4-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># uv add "matrix-nio[e2e]" simplematrixbotlib dotenv</span></span>
<span id="cb4-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> os</span>
<span id="cb4-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> datetime <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> datetime</span>
<span id="cb4-4"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> zoneinfo <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> ZoneInfo</span>
<span id="cb4-5"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> simplematrixbotlib <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> botlib</span>
<span id="cb4-6"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> dotenv <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> load_dotenv</span>
<span id="cb4-7"></span>
<span id="cb4-8">load_dotenv() </span>
<span id="cb4-9"></span>
<span id="cb4-10"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># --- Identifiants (à passer en variables d'environnement) ---</span></span>
<span id="cb4-11">creds <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> botlib.Creds(</span>
<span id="cb4-12">    homeserver<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://matrix.agent.finances.tchap.gouv.fr"</span>,</span>
<span id="cb4-13">    username<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>os.environ[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"TCHAP_BOT_MATRIX_ID"</span>],</span>
<span id="cb4-14">    password<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>os.environ[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"TCHAP_BOT_PWD"</span>],</span>
<span id="cb4-15">)</span>
<span id="cb4-16"></span>
<span id="cb4-17"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># --- Config : on laisse le chiffrement activé ---</span></span>
<span id="cb4-18">config <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> botlib.Config()</span>
<span id="cb4-19">config.encryption_enabled <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span></span>
<span id="cb4-20">config.ignore_unverified_devices <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span></span>
<span id="cb4-21"></span>
<span id="cb4-22">bot <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> botlib.Bot(creds, config)</span>
<span id="cb4-23"></span>
<span id="cb4-24"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">@bot.listener.on_message_event</span></span>
<span id="cb4-25"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">async</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> echo(room, message):</span>
<span id="cb4-26">    match <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> botlib.MessageMatch(room, message, bot)</span>
<span id="cb4-27">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> match.is_not_from_this_bot() <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> match.command(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"coucou"</span>):</span>
<span id="cb4-28">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> bot.api.send_text_message(</span>
<span id="cb4-29">            room.room_id,</span>
<span id="cb4-30">            <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Coucou, il est "</span></span>
<span id="cb4-31">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> datetime.now(ZoneInfo(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Europe/Paris"</span>)).strftime(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"%H:%M:%S"</span>)</span>
<span id="cb4-32">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">" à Paris."</span>,</span>
<span id="cb4-33">        )</span>
<span id="cb4-34"></span>
<span id="cb4-35"></span>
<span id="cb4-36"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">__name__</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"__main__"</span>:</span>
<span id="cb4-37">    bot.run()</span></code></pre></div></div>
</details>
</div>
</div>
<p>Lancez-le avec un <code>uv run main.py</code>.</p>
<p><strong>Bravo ! Vous avez maintenant un bot qui vous répond l’heure quand vous lui dites “coucou”</strong> : et ça, c’est magique et parfaitement inutile.</p>
<div class="callout callout-style-default callout-caution callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Mise en garde
</div>
</div>
<div class="callout-body-container callout-body">
<p>Je n’ai pas réussi à régler proprement la <strong>vérification du bot</strong> (le fameux échange d’emojis qui certifie l’appareil). Le bot tourne, mais il reste « non vérifié ». Cela ne pose pas de problème particulier.</p>
</div>
</div>
</section>
</section>
<section id="deuxième-étape-brancher-un-llm" class="level1">
<h1>Deuxième étape : brancher un LLM</h1>
<p>Bonne nouvelle : <strong>utiliser</strong> <a href="https://llm.lab.sspcloud.fr/"><code>llm.lab.sspcloud.fr</code></a>, <strong>c’est en fait super simple</strong>.</p>
<p>Comme llm.lab expose une API compatible OpenAI, il suffit de réutiliser le package <code>openai</code> en pointant vers la bonne URL avec sa clé API de <a href="https://llm.lab.sspcloud.fr">llm.lab</a>. Pour récupérer votre clé API, vous pouvez suivre <a href="https://aiml4os.github.io/funathon-project2/2-rag-intro.html#getting-your-llm.lab-api-key">cette procédure</a>. On stocke le tout dans le <code>.env</code> sous <code>LLM_LAB_API_KEY</code>.</p>
<p>Pour échanger avec le LLM, vous utilisez le client LLM <code>openai</code> avec les méthodes <code>chat.completions.create</code> en précisant le modèle utilisé et le tchat (sous la forme d’un dictionnaire). Vous aurez la réponse du LLM stockée dans le contenu de ce qu’il renverra et que <code>openai</code> stocke dans <code>choices[0].message.content</code>.</p>
<p>On peut créer un petit bout de code qui génère l’historique des échanges et permet d’échanger avec le LLM en entrant les questions directement via Python. Tout est dans le code ci-dessous, qui s’exécute avec <code>uv run main.py</code>:</p>
<div class="code-with-filename">
<div class="code-with-filename-file">
<pre><strong>.env</strong></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" data-filename=".env" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb5-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># =============================================================================</span></span>
<span id="cb5-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># .env - variables d'environnement</span></span>
<span id="cb5-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Copiez ce fichier, renseignez les valeurs, et NE LE COMMITEZ PAS</span></span>
<span id="cb5-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># (ajoutez `.env` à votre .gitignore).</span></span>
<span id="cb5-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># =============================================================================</span></span>
<span id="cb5-6"></span>
<span id="cb5-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># --- Accès au LLM (llm.lab.sspcloud.fr) -----------------------------------</span></span>
<span id="cb5-8">LLM_LAB_API_KEY<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"votre_cle_api_llm_lab"</span></span></code></pre></div></div>
</div>
<div id="4b2dc0cf" class="cell">
<div class="code-with-filename">
<details class="code-fold">
<summary>Code</summary>
<div class="code-with-filename-file">
<pre><strong>main.py</strong></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb6-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># uv add openai</span></span>
<span id="cb6-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> os</span>
<span id="cb6-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> openai <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> OpenAI</span>
<span id="cb6-4"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> dotenv <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> load_dotenv</span>
<span id="cb6-5"></span>
<span id="cb6-6">load_dotenv()</span>
<span id="cb6-7">model_name <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gemma4-26b-moe"</span></span>
<span id="cb6-8">client <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> OpenAI(</span>
<span id="cb6-9">    base_url<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://llm.lab.sspcloud.fr/api"</span>,</span>
<span id="cb6-10">    api_key<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>os.environ.get(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"LLM_LAB_API_KEY"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">""</span>),</span>
<span id="cb6-11">)</span>
<span id="cb6-12"></span>
<span id="cb6-13"></span>
<span id="cb6-14"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> h_append(role, content):</span>
<span id="cb6-15">    history.append({<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"role"</span>: role, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"content"</span>: content})</span>
<span id="cb6-16">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> history</span>
<span id="cb6-17"></span>
<span id="cb6-18"></span>
<span id="cb6-19"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> ask(question: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>):</span>
<span id="cb6-20">    h_append(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"user"</span>, question)</span>
<span id="cb6-21"></span>
<span id="cb6-22">    response <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> client.chat.completions.create(</span>
<span id="cb6-23">        model<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>model_name,</span>
<span id="cb6-24">        messages<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>history,</span>
<span id="cb6-25">    )</span>
<span id="cb6-26"></span>
<span id="cb6-27">    answer <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> response.choices[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].message.content</span>
<span id="cb6-28">    h_append(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"assistant"</span>, answer)</span>
<span id="cb6-29">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> answer</span>
<span id="cb6-30"></span>
<span id="cb6-31"></span>
<span id="cb6-32"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># --- Exemple d'utilisation ---</span></span>
<span id="cb6-33"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">__name__</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"__main__"</span>:</span>
<span id="cb6-34">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">while</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>:</span>
<span id="cb6-35">        history <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> []</span>
<span id="cb6-36">        question <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">input</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"You : "</span>)</span>
<span id="cb6-37">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> question.lower() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"quit"</span>:</span>
<span id="cb6-38">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">break</span></span>
<span id="cb6-39"></span>
<span id="cb6-40">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"LLM : </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>ask(question)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span></code></pre></div></div>
</details>
</div>
</div>
<p>Le truc à retenir avec le format <code>openai</code>, c’est qu’<strong>un échange avec un LLM n’est qu’une simple liste Python</strong> : chaque message est un dictionnaire avec un rôle stocké dans la clé <code>role</code> et le contenu stocké, étonnament, dans la clé <code>content</code>.</p>
<div class="code-with-filename">
<div class="code-with-filename-file">
<pre><strong>Ceci est un chat</strong></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" data-filename="Ceci est un chat" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb7-1">[</span>
<span id="cb7-2">    {<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"role"</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"user"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"content"</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Bonjour, tu peux m'aider ?"</span>},</span>
<span id="cb7-3">    {<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"role"</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"assistant"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"content"</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Bien sûr !"</span>},</span>
<span id="cb7-4">]</span></code></pre></div></div>
</div>
<p><em>Fun fact (pour moi)</em> : chez OpenAI, l’IA n’est ni un « bot » ni un « modèle », mais un <em>assistant</em>. Sans doute pour ne pas faire peur 🙂.</p>
<p><strong>Vous avez maintenant de quoi envoyer des requêtes à un LLM.</strong></p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb8-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">onyxia@vscode-python-118218-0:~/work$</span> uv run main.py </span>
<span id="cb8-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">You</span> : Bonjour</span>
<span id="cb8-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">LLM</span> : Bonjour ! Comment puis-je vous aider aujourd<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'hui ?</span></span>
<span id="cb8-4"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">You : Je voudrais parler avec une IA</span></span>
<span id="cb8-5"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">LLM : Bonjour ! Vous y êtes. Je suis une intelligence artificielle, prête à discuter avec vous.</span></span>
<span id="cb8-6"></span>
<span id="cb8-7"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">De quoi aimeriez-vous parler ? Je peux vous aider dans de nombreux domaines, par exemple :</span></span>
<span id="cb8-8"></span>
<span id="cb8-9"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">1.  **Discuter tout simplement** (échanger des idées, philosopher, ou parler de votre journée).</span></span>
<span id="cb8-10"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">2.  **Apprendre quelque chose** (histoire, science, langue étrangère, etc.).</span></span>
<span id="cb8-11"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">3.  **Aide créative** (écrire un poème, une histoire, des paroles de chanson ou un email).</span></span>
<span id="cb8-12"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">4.  **Résoudre des problèmes** (mathématiques, code informatique, conseils pratiques).</span></span>
<span id="cb8-13"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">5.  **Organisation** (planifier un voyage, créer un menu de la semaine, rédiger un CV).</span></span>
<span id="cb8-14"></span>
<span id="cb8-15"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">Dites-moi ce qui vous passe par la tête ! Je vous écoute.</span></span>
<span id="cb8-16"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">You : quit</span></span></code></pre></div></div>
</section>
<section id="troisième-étape-préparer-la-quatrième-étape" class="level1">
<h1>Troisième étape : préparer la quatrième étape</h1>
<p>Là je triche, je n’ai pas suivi cet ordre là mais j’aurai dû le suivre. Un peu comme dans Pulp Fiction où les chapitres sont pas vraiment dans l’ordre.</p>
<p>Donc, maintenant, avant de combiner les deux, j’aurai dû construire le code petit à petit pour que tout marche depuis Python, en rangeant au passage le tout en package avec des sous-modules (<code>config</code>, <code>core</code>, <code>listeners</code>).</p>
<details>
<summary>
Voici la structure après cette étape :
</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb9-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">tchap_bot_llm/</span></span>
<span id="cb9-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">│</span></span>
<span id="cb9-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">├──</span> main.py                  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Point d'entrée : appelle src.run("!")</span></span>
<span id="cb9-4"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">├──</span> pyproject.toml           <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Dépendances (matrix-nio[e2e], openai, simplematrixbotlib)</span></span>
<span id="cb9-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">├──</span> uv.lock                  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Verrouillage des versions (uv)</span></span>
<span id="cb9-6"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">├──</span> .python-version          <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Version Python du projet (3.13)</span></span>
<span id="cb9-7"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">├──</span> LICENSE</span>
<span id="cb9-8"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">│</span></span>
<span id="cb9-9"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">├──</span> src/                     <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Le code du bot, organisé en package</span></span>
<span id="cb9-10"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">│</span>   ├── __init__.py          <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># run() : charge la config, crée le bot, branche les listeners</span></span>
<span id="cb9-11"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">│</span>   │</span>
<span id="cb9-12"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">│</span>   ├── config/              <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ── Couche configuration ──</span></span>
<span id="cb9-13"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">│</span>   │   ├── __init__.py</span>
<span id="cb9-14"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">│</span>   │   └── settings.py      <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Creds, BotConfig, Settings + lecture des variables d'env</span></span>
<span id="cb9-15"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">│</span>   │</span>
<span id="cb9-16"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">│</span>   ├── core/                <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ── Couche cœur ──</span></span>
<span id="cb9-17"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">│</span>   │   ├── __init__.py</span>
<span id="cb9-18"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">│</span>   │   └── bot.py           <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># create_bot() : instancie le bot simplematrixbotlib</span></span>
<span id="cb9-19"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">│</span>   │</span>
<span id="cb9-20"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">│</span>   └── listeners/           <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ── Couche fonctionnalités (une par fichier) ──</span></span>
<span id="cb9-21"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">│</span>       ├── __init__.py      <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># load_all() : charge auto. tous les modules avec register()</span></span>
<span id="cb9-22"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">│</span>       └── echo.py          <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># coucou → renvoie l'heure (la fonctionnalité de test)</span></span>
<span id="cb9-23"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">│</span></span>
<span id="cb9-24"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">└──</span> bash/                    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Scripts d'exploration de l'API Matrix (phase de découverte)</span></span>
<span id="cb9-25">   <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">└──</span> get_token.sh         <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Récupère un jeton d'accès</span></span></code></pre></div></div>
</details>
<p>Les <code>listeners</code> stockent toutes les fonctionnalités de notre bot Tchap. L’architecture de ce dossier est volontairement modulaire : chaque fonctionnalité a son propre fichier avec une fonction <code>register</code>, et toutes sont chargées automatiquement au démarrage. Pour désactiver un module, pas besoin de toucher au reste : on renomme juste sa fonction <code>register</code> en <code>no_register</code>, et il ne sera pas chargé par le bot.</p>
<p>Un petit coup d’IA permet de rédiger le code d’initialisation qui charge tous les <code>listeners</code> à partir des scripts dans le dossier <code>listeners</code>. On stocke ce code dans une fonction <code>load_all</code> dans le script <code>__init__.py</code> du dossier <code>listeners</code>.</p>
<p>À ce stade, l’organisation en package avec <a href="https://docs.astral.sh/uv/"><code>uv</code></a> rend le tout reproductible. Les dépendances vivent dans le <code>pyproject.toml</code>, et lancer le bot tient en une ligne :</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb10-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">uv</span> run main.py</span></code></pre></div></div>
<p><strong>Pour la simplicité de la suite, tout reste dans un seul fichier <code>main.py</code>. Si vous voulez adopter cette organisation,</strong> <strong>forkez le repo du bot !</strong></p>
</section>
<section id="quatrième-étape-combiner-1-et-2" class="level1">
<h1>Quatrième étape : combiner 1 et 2</h1>
<p>Comme le dit l’adage, on a de la pâte à crêpe, on a du sucre, on va <strong>créer une crêpe au sucre</strong>.</p>
<section id="un-bot-simple-sans-mémoire" class="level2">
<h2 class="anchored" data-anchor-id="un-bot-simple-sans-mémoire">Un bot simple sans mémoire</h2>
<p>On crée une commande <code>llm</code> maintenant dans les <code>listener</code> et on la branche sur <code>llm.lab</code> avec une fonctionnalité simple : si on pose une question, il répond. Pas de chat (encore).</p>
<p>Cela se fait avec un peu de douleur mais rien que l’on aime pas : on repère si on reçoit un message avec <code>@bot.listener.on_message_event</code> et on le récupère avec <code>match = botlib.MessageMatch(room, message, bot)</code>. Si le message correspond au prefix et à la commande, on envoie son contenu au LLM. Et puis on renvoie la réponse du LLM sur Tchap.</p>
</section>
<section id="ajouter-la-mémoire-des-échanges" class="level2">
<h2 class="anchored" data-anchor-id="ajouter-la-mémoire-des-échanges">Ajouter la mémoire des échanges</h2>
<p>La vraie prise de tête - relative, ça n’a duré que quelques heures - c’était de <strong>reconstituer le fil de la conversation pour faire un vrai tchat</strong> et que le bot ait la mémoire des échanges passés. Concrètement, je voulais que si je réponde au message du bot dans Tchap, le bot récupère les messages liés à la conversation et les envoie en contexte au LLM. Pour mimer un chat avec un LLM et éviter à chaque fois de recommencer à 0.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/bot_tchap/endless_loop.png" class="img-fluid figure-img"></p>
<figcaption>Ce que je voulais éviter</figcaption>
</figure>
</div>
<p>Dans Matrix, chaque message a bien son identifiant unique, mais le lien « ce message répond à celui-là » est caché dans des balises bien imbriquées (<code>content</code> → <code>m.relates_to</code> → <code>m.in_reply_to</code> → <code>event_id</code>).</p>
<section id="la-plomberie-derrière-un-message" class="level3">
<h3 class="anchored" data-anchor-id="la-plomberie-derrière-un-message">La plomberie derrière un message</h3>
<p>L’astuce pour ne pas rester perdu trop longtemps : <strong>exporter une conversation Tchap au format JSON</strong>. En voyant la vraie tête des événements, je me suis moins perdu dans les étages de balises.</p>
<p>Voici l’échange ci-dessus au format JSON Matrix :</p>
<details>
<summary>
Voir un échange Tchap au format JSON
</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode json code-with-copy"><code class="sourceCode json"><span id="cb11-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb11-2">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"content"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb11-3">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"msgtype"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"m.text"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-4">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"body"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"llm écris moi un sonnet sur la beauté des canicules"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-5">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"m.mentions"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb11-6">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb11-7">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"origin_server_ts"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1780409269941</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-8">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"sender"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"@n-insee.fr:agent.finances.tchap.gouv.fr"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-9">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"type"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"m.room.message"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-10">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"unsigned"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb11-11">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"membership"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"join"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-12">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"age"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">854394</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-13">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"transaction_id"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"m1780409269135.40"</span></span>
<span id="cb11-14">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb11-15">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"event_id"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"$DGvRZB3GL8brmKFqBZEOASDLxL8d8"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-16">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"room_id"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"!UDagJdADqqUSKBW:agent.finances.tchap.gouv.fr"</span></span>
<span id="cb11-17"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span><span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-18"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb11-19">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"content"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb11-20">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"body"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Voici un sonnet célébrant la splendeur de la canicule, conçu dans la tradition classique.</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">JE VOUS PASSE LA FIN DE CE SONNET"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-21">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"format"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"org.matrix.custom.html"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-22">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"formatted_body"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"&lt;p&gt;Voici un sonnet célébrant la splendeur de la canicule, conçu dans la tradition classique.&lt;/p&gt;</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">&lt;p&gt;JE VOUS PASSE LA FIN DE CE SONNET"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-23">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"m.relates_to"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb11-24">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"m.in_reply_to"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb11-25">                <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"event_id"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"$DGvRZB3GL8brmKFqBZEOASDLxL8d8"</span></span>
<span id="cb11-26">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb11-27">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb11-28">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"msgtype"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"m.text"</span></span>
<span id="cb11-29">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb11-30">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"origin_server_ts"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1780409279931</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-31">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"sender"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"@bot-insee.fr:agent.finances.tchap.gouv.fr"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-32">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"type"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"m.room.message"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-33">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"unsigned"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{},</span></span>
<span id="cb11-34">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"event_id"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"$EGOl-wWZbY5GsjjoYzMpIdcn75xadQnClmSSYd1mZjw"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-35">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"room_id"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"!UDagJdADqqUSKBW:agent.finances.tchap.gouv.fr"</span></span>
<span id="cb11-36"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span><span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-37"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb11-38">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"content"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb11-39">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"msgtype"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"m.text"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-40">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"body"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"llm merci, ajoute y des comparaisons avec l'hiver"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-41">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"m.mentions"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb11-42">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb11-43">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"origin_server_ts"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1780409290426</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-44">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"sender"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"@n-insee.fr:agent.finances.tchap.gouv.fr"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-45">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"type"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"m.room.message"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-46">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"unsigned"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb11-47">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"membership"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"join"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-48">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"age"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">833909</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-49">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"transaction_id"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"m1780409289583.41"</span></span>
<span id="cb11-50">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb11-51">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"event_id"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"$Zkuyln4UY3x29vHRIKZ0"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-52">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"room_id"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"!UDagJdADqqUSKBW:agent.finances.tchap.gouv.fr"</span></span>
<span id="cb11-53"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span><span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-54"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb11-55">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"content"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb11-56">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"body"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Comme tu n'as pas précisé le texte initial, je vais imaginer que tu souhaites une description poétique ou une analyse de la **vie**, de la **douceur** ou d'un **nouveau départ**, en y intégrant des métaphores hivernales.</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">Voici une proposition de texte enrichi de comparaisons avec l'hiver JE VOUS PASSE LA FIN DE CE MESSAGE"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-57">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"m.relates_to"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb11-58">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"m.in_reply_to"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb11-59">                <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"event_id"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"$Zkuyln4UY3x29vHRIKZ0"</span></span>
<span id="cb11-60">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb11-61">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb11-62">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"msgtype"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"m.text"</span></span>
<span id="cb11-63">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb11-64">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"origin_server_ts"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1780409294370</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-65">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"sender"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"@bot-insee.fr:agent.finances.tchap.gouv.fr"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-66">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"type"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"m.room.message"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-67">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"unsigned"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{},</span></span>
<span id="cb11-68">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"event_id"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"$iHbLWft9X2h_0MkMG7jr_GE4IE87Q3M"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-69">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"room_id"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"!UDagJdADqqUSKBW:agent.finances.tchap.gouv.fr"</span></span>
<span id="cb11-70"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
</details>
</section>
<section id="architecture-de-remonter-la-mémoire-des-échanges" class="level3">
<h3 class="anchored" data-anchor-id="architecture-de-remonter-la-mémoire-des-échanges">Architecture de remonter la mémoire des échanges</h3>
<p>Ensuite, il “suffit” de remonter le fil réponse après réponse, de façon récursive. Concrètement, <strong>à partir de l’ID d’un événement</strong>, il faut :</p>
<ul>
<li>récupérer l’événement (aka : le message) - une fonction <code>get_event</code> permet de le faire;</li>
<li>avec l’événement, déterminer qui de l’humain ou de l’“assistant” a envoyé le message - c’est le rôle de <code>get_role_event</code>;</li>
<li>extraire le contenu - <code>extract_info</code> extrait les informations sender, body et replied_to d’un <code>event</code> Tchap ;</li>
<li>stocker tout cela dans l’historique - c’est le rôle de la fonction <code>history_append</code>;</li>
<li>savoir si un événement lui même est en réponse à un événement - la fonction <code>get_in_reply_to_event_id</code> fait cela;</li>
<li>et puis on boucle et on boucle.</li>
</ul>
<p>Par ailleurs, <strong>Tchap permet de formatter son message</strong> : soit vous êtes une/un boss et vous l’écrivez directement en html, soit vous l’écrivez en markdown et Tchap le transformera en html pour vous.</p>
<p>Pour que la réponse de notre assistant préféré passe bien dans Tchap, <strong>il faut lui ajouter un prompt système qui demande de répondre en markdown</strong> sans échapper les caractères spéciaux. <code>add_system_prompt</code> fait cela pour nous.</p>
</section>
<section id="les-fonctions-asynchrones" class="level3">
<h3 class="anchored" data-anchor-id="les-fonctions-asynchrones">Les fonctions asynchrones</h3>
<p>Après, il faut gérer <strong>les problèmes de fonction <code>async</code> dans Python</strong>. J’ai compris que je n’avais pas tout compris mais en gros, pour les requêtes “compliquées”, c’est à dire celles dont la réponse peut prendre un peu de temps, <strong>on met un <code>await</code> devant</strong>. Concrètement, les réponses de Tchap peuvent être longues à récupérer (cf.&nbsp;le blabla sur le chiffrement), donc quand on récupère un message de l’API de <code>nio</code> on doit indiquer <code>await bot.async_client.room_get_event</code>.</p>
<p>Et <code>await</code>, ce petit coquin, se propage. C’est à dire qu’une fonction qui comprend un <code>await</code> dans le code sera une fonction <code>async</code> qu’on définit en <code>async def get_event</code>. Et ainsi toute fonction qui appelerait <code>get_event</code> devrait le faire avec un <code>await get_event</code> et serait elle-même <code>async</code>.</p>
</section>
<section id="grand-final" class="level3">
<h3 class="anchored" data-anchor-id="grand-final">Grand final</h3>
<p>Une fois tout cela compris, avec l’aide d’un assistant bien-tombé, on arrive à ce bloc ci-dessous. Il est autonome (les fonctions utilitaires sont incluses) et prend en entrée un <code>bot</code>, l’<code>id</code> du salon et l’<code>id</code> du message auquel on répond :</p>
<div id="acdf07f4" class="cell">
<div class="code-with-filename">
<details class="code-fold">
<summary>Code</summary>
<div class="code-with-filename-file">
<pre><strong>main.py</strong></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb12-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> os</span>
<span id="cb12-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> openai <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> OpenAI</span>
<span id="cb12-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> dotenv <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> load_dotenv</span>
<span id="cb12-4"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> nio</span>
<span id="cb12-5"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> simplematrixbotlib <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> botlib</span>
<span id="cb12-6"></span>
<span id="cb12-7">load_dotenv()</span>
<span id="cb12-8"></span>
<span id="cb12-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Partie bot </span></span>
<span id="cb12-10"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># --- Identifiants (à passer en variables d'environnement) ---</span></span>
<span id="cb12-11">creds <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> botlib.Creds(</span>
<span id="cb12-12">    homeserver<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://matrix.agent.finances.tchap.gouv.fr"</span>,</span>
<span id="cb12-13">    username<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>os.environ[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"TCHAP_BOT_MATRIX_ID"</span>],</span>
<span id="cb12-14">    password<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>os.environ[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"TCHAP_BOT_PWD"</span>],</span>
<span id="cb12-15">)</span>
<span id="cb12-16"></span>
<span id="cb12-17"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># --- Config : on laisse le chiffrement activé ---</span></span>
<span id="cb12-18">config <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> botlib.Config()</span>
<span id="cb12-19">config.encryption_enabled <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span></span>
<span id="cb12-20">config.ignore_unverified_devices <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span></span>
<span id="cb12-21"></span>
<span id="cb12-22">bot <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> botlib.Bot(creds, config)</span>
<span id="cb12-23"></span>
<span id="cb12-24"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Partie LLM</span></span>
<span id="cb12-25">end_point <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://llm.lab.sspcloud.fr/api"</span></span>
<span id="cb12-26"></span>
<span id="cb12-27">openai_client <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> OpenAI(</span>
<span id="cb12-28">    base_url<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>end_point,</span>
<span id="cb12-29">    api_key<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>os.environ.get(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"LLM_LAB_API_KEY"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">""</span>),</span>
<span id="cb12-30">)</span>
<span id="cb12-31"></span>
<span id="cb12-32"></span>
<span id="cb12-33"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> history_append(</span>
<span id="cb12-34">    history: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">list</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>,</span>
<span id="cb12-35">    role: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"user"</span>,</span>
<span id="cb12-36">    content: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">""</span>,</span>
<span id="cb12-37">    at_first_pos: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">bool</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>,</span>
<span id="cb12-38">):</span>
<span id="cb12-39">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">"""</span></span>
<span id="cb12-40"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    Function to add a message to history with role and content</span></span>
<span id="cb12-41"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    Args:</span></span>
<span id="cb12-42"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">        - history: list : the history to append the message to</span></span>
<span id="cb12-43"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">        - role: str : the role to give to the message</span></span>
<span id="cb12-44"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">        - content: str : the content of the message</span></span>
<span id="cb12-45"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">        - at_first_pos: boolean : append at first position (top) or at the end</span></span>
<span id="cb12-46"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    """</span></span>
<span id="cb12-47">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> history <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">is</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>:</span>
<span id="cb12-48">        history <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> []</span>
<span id="cb12-49"></span>
<span id="cb12-50">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> at_first_pos:</span>
<span id="cb12-51">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> [{<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"role"</span>: role, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"content"</span>: content}] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> history</span>
<span id="cb12-52">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb12-53">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> history <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> [{<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"role"</span>: role, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"content"</span>: content}]</span>
<span id="cb12-54"></span>
<span id="cb12-55"></span>
<span id="cb12-56"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> get_in_reply_to_event_id(event):</span>
<span id="cb12-57">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> (</span>
<span id="cb12-58">        event.source.get(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"content"</span>, {})</span>
<span id="cb12-59">        .get(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"m.relates_to"</span>, {})</span>
<span id="cb12-60">        .get(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"m.in_reply_to"</span>, {})</span>
<span id="cb12-61">        .get(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"event_id"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">""</span>)</span>
<span id="cb12-62">    )</span>
<span id="cb12-63"></span>
<span id="cb12-64"></span>
<span id="cb12-65"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> get_role_event(event, bot):</span>
<span id="cb12-66">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> event.sender <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> bot.async_client.user_id:</span>
<span id="cb12-67">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"assistant"</span></span>
<span id="cb12-68">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb12-69">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"user"</span></span>
<span id="cb12-70"></span>
<span id="cb12-71"></span>
<span id="cb12-72"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> extract_info(event) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">tuple</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>:</span>
<span id="cb12-73">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">"""</span></span>
<span id="cb12-74"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    Extract info from event.  Returns sender, body, and replied-to event ID</span></span>
<span id="cb12-75"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    """</span></span>
<span id="cb12-76"></span>
<span id="cb12-77">    content <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> event.source.get(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"content"</span>, {})</span>
<span id="cb12-78"></span>
<span id="cb12-79">    sender <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> event.sender</span>
<span id="cb12-80">    body <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> content.get(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"body"</span>)</span>
<span id="cb12-81">    replied_to_id <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> get_in_reply_to_event_id(event<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>event)</span>
<span id="cb12-82"></span>
<span id="cb12-83">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> (sender, body, replied_to_id)</span>
<span id="cb12-84"></span>
<span id="cb12-85"></span>
<span id="cb12-86"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> get_model_name():</span>
<span id="cb12-87">    model_name <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gemma4-26b-moe"</span></span>
<span id="cb12-88">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> model_name</span>
<span id="cb12-89"></span>
<span id="cb12-90"></span>
<span id="cb12-91"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> add_system_prompt(history: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">list</span>):</span>
<span id="cb12-92">    history_with_system_prompt <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> history_append(</span>
<span id="cb12-93">        history<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>history,</span>
<span id="cb12-94">        role<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"system"</span>,</span>
<span id="cb12-95">        content<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Respond with  markdown formatting. Do not use escape characters."</span>,</span>
<span id="cb12-96">        at_first_pos<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>,</span>
<span id="cb12-97">    )</span>
<span id="cb12-98"></span>
<span id="cb12-99">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> history_with_system_prompt</span>
<span id="cb12-100"></span>
<span id="cb12-101"></span>
<span id="cb12-102"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> ask(prompt: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">list</span>):</span>
<span id="cb12-103">    response <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> openai_client.chat.completions.create(</span>
<span id="cb12-104">        model<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>get_model_name(),</span>
<span id="cb12-105">        messages<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>prompt,</span>
<span id="cb12-106">    )</span>
<span id="cb12-107"></span>
<span id="cb12-108">    answer <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> response.choices[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>].message.content</span>
<span id="cb12-109">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> answer</span>
<span id="cb12-110"></span>
<span id="cb12-111"></span>
<span id="cb12-112"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">@bot.listener.on_message_event</span></span>
<span id="cb12-113"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">async</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> tchat_with_llm(room, message):</span>
<span id="cb12-114">    match <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> botlib.MessageMatch(room, message, bot)</span>
<span id="cb12-115">    command <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"llm"</span></span>
<span id="cb12-116">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> match.is_not_from_this_bot() <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> match.command(command):</span>
<span id="cb12-117">        prompt <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> generate_prompt(bot, room.room_id, match<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>match)</span>
<span id="cb12-118">        first <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> command</span>
<span id="cb12-119">        prompt <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> clean_prompt(prompt, first)</span>
<span id="cb12-120">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Prod mode</span></span>
<span id="cb12-121">        response_llm <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> ask(prompt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>prompt)</span>
<span id="cb12-122">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> bot.api.send_markdown_message(</span>
<span id="cb12-123">            room_id<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>room.room_id,</span>
<span id="cb12-124">            message<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>response_llm,</span>
<span id="cb12-125">            reply_to<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>match.event.event_id,</span>
<span id="cb12-126">        )</span>
<span id="cb12-127"></span>
<span id="cb12-128">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Debug mode</span></span>
<span id="cb12-129">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># response_llm = "\n\n".join(str(d) for d in prompt)</span></span>
<span id="cb12-130">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># await bot.api.send_text_message(</span></span>
<span id="cb12-131">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#     room_id=room.room_id,</span></span>
<span id="cb12-132">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#     message=response_llm,</span></span>
<span id="cb12-133">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#     reply_to=match.event.event_id,</span></span>
<span id="cb12-134">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># )</span></span>
<span id="cb12-135"></span>
<span id="cb12-136"></span>
<span id="cb12-137"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">async</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> generate_prompt(bot: botlib.Bot, room_id: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>, match):</span>
<span id="cb12-138">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">"""</span></span>
<span id="cb12-139"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    Function to generate the full prompt from an event id</span></span>
<span id="cb12-140"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    Arg:</span></span>
<span id="cb12-141"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">        - bot: botlib.Bot</span></span>
<span id="cb12-142"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">        - room_id: str : the Matrix room id where the message is</span></span>
<span id="cb12-143"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">        - match: a simplebot match</span></span>
<span id="cb12-144"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    Returns:</span></span>
<span id="cb12-145"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">        - a list with history, from oldest to newest</span></span>
<span id="cb12-146"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    """</span></span>
<span id="cb12-147">    history <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> history_append(</span>
<span id="cb12-148">        history<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[], role<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"user"</span>, content<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>match.event.body, at_first_pos<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span></span>
<span id="cb12-149">    )</span>
<span id="cb12-150"></span>
<span id="cb12-151">    reply_id <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> get_in_reply_to_event_id(match.event)</span>
<span id="cb12-152"></span>
<span id="cb12-153">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> reply_id <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">""</span>:</span>
<span id="cb12-154">        history <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (</span>
<span id="cb12-155">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> retrieve_history(bot, room_id, reply_event_id<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>reply_id) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> history</span>
<span id="cb12-156">        )</span>
<span id="cb12-157"></span>
<span id="cb12-158">    prompt <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> add_system_prompt(history)</span>
<span id="cb12-159"></span>
<span id="cb12-160">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> prompt</span>
<span id="cb12-161"></span>
<span id="cb12-162"></span>
<span id="cb12-163"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> clean_prompt(prompt: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">list</span>, pattern_start: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>):</span>
<span id="cb12-164">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">"""</span></span>
<span id="cb12-165"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    Removes characters at the beginning of a prompt that match the pattern</span></span>
<span id="cb12-166"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    """</span></span>
<span id="cb12-167">    n_pattern <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(pattern_start)</span>
<span id="cb12-168">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> [</span>
<span id="cb12-169">        {<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">**</span>chat, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"content"</span>: chat[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"content"</span>][n_pattern <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> :]}</span>
<span id="cb12-170">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> chat[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"content"</span>].startswith(pattern_start)</span>
<span id="cb12-171">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> chat</span>
<span id="cb12-172">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> chat <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> prompt</span>
<span id="cb12-173">    ]</span>
<span id="cb12-174"></span>
<span id="cb12-175"></span>
<span id="cb12-176"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">async</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> retrieve_history(bot: botlib.Bot, room_id: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>, reply_event_id: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">list</span>:</span>
<span id="cb12-177">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">"""</span></span>
<span id="cb12-178"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    Retrieves full history of chat in this discussion between the LLM and the user.</span></span>
<span id="cb12-179"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    History is defined by message being sent in reply to a message</span></span>
<span id="cb12-180"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    Args :</span></span>
<span id="cb12-181"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    - bot : the botlib bot. Used to fetch back other message</span></span>
<span id="cb12-182"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    - room_id : the room to search for past message</span></span>
<span id="cb12-183"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    - reply_event_id: the id of the message replied to</span></span>
<span id="cb12-184"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    """</span></span>
<span id="cb12-185"></span>
<span id="cb12-186">    event <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> get_event(bot, room_id, reply_event_id)</span>
<span id="cb12-187">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> event <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">is</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>:</span>
<span id="cb12-188">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> []</span>
<span id="cb12-189"></span>
<span id="cb12-190">    sender, body, reply_id_level2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> extract_info(event)</span>
<span id="cb12-191">    role <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> get_role_event(event<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>event, bot<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>bot)</span>
<span id="cb12-192"></span>
<span id="cb12-193">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> reply_id_level2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">""</span>:</span>
<span id="cb12-194">        history <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> retrieve_history(bot, room_id, reply_id_level2)</span>
<span id="cb12-195">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> history_append(</span>
<span id="cb12-196">            history<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>history, role<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>role, content<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>body, at_first_pos<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span></span>
<span id="cb12-197">        )</span>
<span id="cb12-198">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb12-199">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> history_append(history<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[], role<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>role, content<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>body, at_first_pos<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>)</span>
<span id="cb12-200"></span>
<span id="cb12-201"></span>
<span id="cb12-202"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">async</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> get_event(bot: botlib.Bot, room_id: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>, event_id: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>):</span>
<span id="cb12-203">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">"""</span></span>
<span id="cb12-204"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    Fetches an event by ID and returns it.</span></span>
<span id="cb12-205"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    Returns None if the event could not be fetched.</span></span>
<span id="cb12-206"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    """</span></span>
<span id="cb12-207">    response <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> bot.async_client.room_get_event(room_id, event_id)</span>
<span id="cb12-208"></span>
<span id="cb12-209">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">isinstance</span>(response, nio.RoomGetEventError):</span>
<span id="cb12-210">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"  ✘ Could not fetch event </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>event_id<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>response<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>message<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb12-211">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span></span>
<span id="cb12-212"></span>
<span id="cb12-213">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> response.event</span>
<span id="cb12-214"></span>
<span id="cb12-215"></span>
<span id="cb12-216"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># --- Exemple d'utilisation ---</span></span>
<span id="cb12-217"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">__name__</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"__main__"</span>:</span>
<span id="cb12-218">    bot.run()</span></code></pre></div></div>
</details>
</div>
</div>
<div class="callout callout-style-default callout-tip callout-titled" title="Pour passer en debug mode">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
<span class="screen-reader-only">Astuce</span>Pour passer en debug mode
</div>
</div>
<div class="callout-body-container callout-body">
<p>Pour débugger le code, vous avez un mode “debug” dans la fonction <code>tchat_with_llm</code> qui vous renvoie sur Tchap la requête que le bot aurait envoyé au LLM. Pour cela, décommenter les lignes après “debug” et commentez celles après “prod mode”.</p>
</div>
</div>
<p>Côté utilisateur, le résultat est tout bête : il suffit de <strong>répondre</strong> à un message du bot (toujours en commençant par <code>llm</code>) pour qu’il se souvienne de tout ce qui précède.</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>Pour la simplicité de ce post, j’ai un petit peu simplifié le contenu du repo. Il n’y a pas d’organisation en package Python ici, tout est <em>peu proprement</em> placé dans un seul script <code>main.py</code>. Par ailleurs, il n’y a pas de préfixe à la commande : il faut commencer un message Tchap par <code>llm</code> et non par <code>!llm</code>. Allez voir le repo pour une cible plus propre et utilisant le préfixe <code>!</code>.</p>
</div>
</div>
<p>On lance à nouveau le bot avec un <code>uv run main.py</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb13-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">onyxia@vscode-python-118218-0:~/work$</span> uv run main.py </span>
<span id="cb13-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Connected</span> to https://matrix.agent.finances.tchap.gouv.fr as @bot-insee.fr:agent.finances.tchap.gouv.fr <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">XXXXXX</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span></span>
<span id="cb13-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">This</span> bot<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'s public fingerprint ("Session key") for one-sided verification is: MXte gC/K MXte gC/K MXte gC/K MXte gC/K MXte gC/K 1A1</span></span></code></pre></div></div>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/bot_tchap/endfull_loop.png" class="img-fluid figure-img"></p>
<figcaption>Tatam</figcaption>
</figure>
</div>
<div class="callout callout-style-default callout-caution callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Mise en garde
</div>
</div>
<div class="callout-body-container callout-body">
<p>Cela marche bien mais dans les faits, le bot se déconnecte régulièrement et perd donc les messages passées. Si le message auquel vous répondez a plus d’un jour, il y a de fortes chances que le bot n’y ait pas accès. Il faudrait donc ajouter une gestion de ce cas là - pas fait ici.</p>
</div>
</div>
</section>
</section>
</section>
<section id="cinquième-étape-mise-en-production-sur-le-ssp-cloud" class="level1">
<h1>Cinquième étape : mise en production sur le SSP Cloud</h1>
<p>Dernière marche, et pas la plus petite : <strong>faire tourner le bot en continu, sans dépendre de ma machine</strong>. L’équipe du SSP Cloud m’a bien guidé (mille mercis à elle ! et à mon assistant IA préféré aussi).</p>
<p>Les étapes sont :</p>
<ul>
<li>de conteneuriser son application avec Docker;</li>
<li>de la déployer à proprement parler sur l’infrastructure Kubernetes du SSPCloud.</li>
</ul>
<section id="docker-mon-amour" class="level2">
<h2 class="anchored" data-anchor-id="docker-mon-amour">Docker mon amour</h2>
<p>Cela demande de découvrir <strong>Docker</strong> et ses ressources de débutant bien faites (<a href="https://docs.docker.com/get-started/introduction/get-docker-desktop/">ici</a> par exemple).</p>
<p>Il faut aller <strong>se créer un compte sur</strong> <a href="https://www.docker.com/"><strong>Docker</strong></a>. L’installation de Docker est pas évidente sur des PC contraints (et hic : impossible de le tester directement sur le SSP Cloud - pas de Docker dans Docker). Il faut donc l’avoir en local (à l’Insee, Podman peut s’installer en local) ou tester via des GitHub Action ou bien le VS Code de GitHub (dans <code>&lt;&gt; Code</code> / <code>Codespaces</code> dans GitHub, cela vous ouvre un espace similaire à Onyxia) permet de faire des Docker dans Docker.</p>
<section id="le-dockerfile-la-recette-pour-construire-limage-docker" class="level3">
<h3 class="anchored" data-anchor-id="le-dockerfile-la-recette-pour-construire-limage-docker">Le dockerfile : la recette pour construire l’image Docker</h3>
<p>On doit écrire ensuite le <code>Dockerfile</code>, qui est la recette pour construire l’image Docker. Le dockerfile est assez basique et un assitant IA aide facilement à le rédiger.</p>
<p>Le morceau le plus pénible, ça a été <strong>les bibliothèques de chiffrement</strong> (<code>python-olm</code>, qui compile <code>libolm</code> depuis les sources) : il a fallu glisser les bons outils de compilation dans l’image. Mais là encore, cela a été tout à fait respectable et mon assistant préféré m’a aidé.</p>
<p>Voici le <code>Dockerfile</code> final, utilisable tel quel :</p>
<div class="code-with-filename">
<div class="code-with-filename-file">
<pre><strong>dockerfile</strong></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb14" data-filename="dockerfile" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb14-1">FROM python:<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.13</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>slim</span>
<span id="cb14-2"></span>
<span id="cb14-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Installation de uv</span></span>
<span id="cb14-4">COPY <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">--</span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>ghcr.io<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>astral<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>sh<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>uv:latest <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>uv <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>usr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>local<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">bin</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>uv</span>
<span id="cb14-5">WORKDIR <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>app</span>
<span id="cb14-6"></span>
<span id="cb14-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Dépendances de compilation pour python-olm (chiffrement)</span></span>
<span id="cb14-8">RUN apt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>get update <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> apt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>get install <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">--</span>no<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>install<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>recommends <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb14-9">    build<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>essential cmake <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb14-10">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> rm <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>rf <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>lib<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>apt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span>lists<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/*</span></span>
<span id="cb14-11"></span>
<span id="cb14-12"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Installation des dépendances du projet</span></span>
<span id="cb14-13">COPY pyproject.toml .</span>
<span id="cb14-14">RUN uv sync</span>
<span id="cb14-15"></span>
<span id="cb14-16">COPY . .</span>
<span id="cb14-17">CMD [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"uv"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"run"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"main.py"</span>]</span></code></pre></div></div>
</div>
</section>
<section id="le-workflow-github-action-pour-exécuter-la-tambouille-du-dockerfile" class="level3">
<h3 class="anchored" data-anchor-id="le-workflow-github-action-pour-exécuter-la-tambouille-du-dockerfile">Le workflow github action pour exécuter la tambouille du dockerfile</h3>
<p>J’ai choisi de construire l’image <strong>Docker à chaque <code>push</code> sur GitHub</strong>, grâce à une <em>GitHub Action</em> qui la pousse ensuite sur Docker Hub (qui est un site où sont stockées des images Docker, un peu comme GitHub pour le code).</p>
<div class="callout callout-style-default callout-tip callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Astuce
</div>
</div>
<div class="callout-body-container callout-body">
<p>N’oubliez pas d’ajouter en secret GitHub vos identifiants Docker. Il faut pour cela avoir créé avant un Token Docker avec les permissions “read and write” sur votre repo Docker pour pouvoir y pousser l’image.</p>
</div>
</div>
<details>
<summary>
Voir le fichier GitHub Action qui construit l’image et la push sur Docker-Hub
</summary>
<div class="code-with-filename">
<div class="code-with-filename-file">
<pre><strong>.github/workflows/deploy.yaml</strong></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb15" data-filename=".github/workflows/deploy.yaml" style="background: #f1f3f5;"><pre class="sourceCode yaml code-with-copy"><code class="sourceCode yaml"><span id="cb15-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">name</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> Build and push Docker image</span></span>
<span id="cb15-2"></span>
<span id="cb15-3"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">on</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb15-4"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">  </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">push</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb15-5"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">branches</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> </span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">main</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span>
<span id="cb15-6"></span>
<span id="cb15-7"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">jobs</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb15-8"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">  </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">build-and-push</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb15-9"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">runs-on</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> ubuntu-latest</span></span>
<span id="cb15-10"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">steps</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb15-11"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">      </span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">-</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">name</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> Checkout code</span></span>
<span id="cb15-12"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">        </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">uses</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> actions/checkout@v6</span></span>
<span id="cb15-13"></span>
<span id="cb15-14"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">      </span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">-</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">name</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> Log in to Docker Hub</span></span>
<span id="cb15-15"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">        </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">uses</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> docker/login-action@v4</span></span>
<span id="cb15-16"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">        </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">with</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb15-17"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">          </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">username</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> ${{ secrets.DOCKERHUB_USERNAME }}</span></span>
<span id="cb15-18"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">          </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">password</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> ${{ secrets.DOCKERHUB_TOKEN }}</span></span>
<span id="cb15-19"></span>
<span id="cb15-20"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">      </span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">-</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">name</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> Build and push</span></span>
<span id="cb15-21"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">        </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">uses</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> docker/build-push-action@v7</span></span>
<span id="cb15-22"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">        </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">with</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb15-23"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">          </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">context</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> .</span></span>
<span id="cb15-24"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">          </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">push</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> </span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">true</span></span>
<span id="cb15-25"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">          </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tags</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> ${{ secrets.DOCKERHUB_USERNAME }}/tchap-bot:latest</span></span></code></pre></div></div>
</div>
</details>
</section>
</section>
<section id="sspcloud-mon-amour" class="level2">
<h2 class="anchored" data-anchor-id="sspcloud-mon-amour">SSPCloud mon amour</h2>
<p>Reste à écrire le <strong>manifeste Kubernetes</strong> pour déployer le conteneur sur le SSP Cloud.</p>
<section id="ciel-mes-secrets" class="level3">
<h3 class="anchored" data-anchor-id="ciel-mes-secrets">Ciel, mes secrets</h3>
<p>Une petite angoisse une fois l’image poussée sur Docker : <em>mais où sont tous mes secrets (identifiants Tchap, clé d’API du LLM) ?</em>. Bon, après vérification, <strong>ils ne sont pas poussées dans l’image Docker s’ils ne sont pas dans le code</strong>. Les secrets sont injectés en variables d’environnement via des <code>secretKeyRef</code>.</p>
<p>Donc <strong>si vous respectez les bonnes pratiques jusque là, cela devrait bien aller</strong>. Sinon, changez vos tokens :)</p>
<details>
<summary>
Voir le fichier .env récapitulant tous les secrets à avoir
</summary>
<div class="code-with-filename">
<div class="code-with-filename-file">
<pre><strong>.env</strong></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb16" data-filename=".env" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb16-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># =============================================================================</span></span>
<span id="cb16-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># .env - variables d'environnement du bot Tchap</span></span>
<span id="cb16-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Copiez ce fichier, renseignez les valeurs, et NE LE COMMITEZ PAS</span></span>
<span id="cb16-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># (ajoutez `.env` à votre .gitignore).</span></span>
<span id="cb16-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># =============================================================================</span></span>
<span id="cb16-6"></span>
<span id="cb16-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># --- Compte Tchap du bot (idéalement une BALF dédiée) ---------------------</span></span>
<span id="cb16-8"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Identifiant Matrix complet, ex. @votre-bot:agent.finances.tchap.gouv.fr</span></span>
<span id="cb16-9">TCHAP_BOT_MATRIX_ID<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"@votre-bot:agent.finances.tchap.gouv.fr"</span></span>
<span id="cb16-10">TCHAP_BOT_PWD<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"votre_mot_de_passe_tchap"</span></span>
<span id="cb16-11"></span>
<span id="cb16-12"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># --- Accès au LLM (llm.lab.sspcloud.fr) -----------------------------------</span></span>
<span id="cb16-13">LLM_LAB_API_KEY<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"votre_cle_api_llm_lab"</span></span>
<span id="cb16-14"></span>
<span id="cb16-15"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># --- Salon(s) Tchap surveillé(s) ------------------------------------------</span></span>
<span id="cb16-16"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Toute variable commençant par TCHAP_ROOM_ID est prise en compte.</span></span>
<span id="cb16-17"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Pour plusieurs salons : TCHAP_ROOM_ID_1, TCHAP_ROOM_ID_2, etc.</span></span>
<span id="cb16-18">TCHAP_ROOM_ID<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"!identifiantDuSalon:agent.finances.tchap.gouv.fr"</span></span>
<span id="cb16-19"></span>
<span id="cb16-20"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># --- Déploiement (CI/CD + Kubernetes) -------------------------------------</span></span>
<span id="cb16-21"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Utilisés par la GitHub Action et la substitution du manifeste k8s.</span></span>
<span id="cb16-22">DOCKERHUB_USERNAME<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"votre_compte_dockerhub"</span></span>
<span id="cb16-23">DOCKERHUB_TOKEN<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"votre_token_dockerhub"</span></span>
<span id="cb16-24">SSP_USERNAME<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"votre_identifiant_sspcloud"</span></span></code></pre></div></div>
</div>
</details>
</section>
<section id="la-recette-de-déploiement-kubernetes" class="level3">
<h3 class="anchored" data-anchor-id="la-recette-de-déploiement-kubernetes">La recette de déploiement Kubernetes</h3>
<p>En Kubernetes, il faut donc <strong>passer un manifeste ou un “contrat”</strong> (j’aime l’idée de passer un contrat avec une machine). Le “contrat” définit comment on déploit l’image qu’on a construite avant.</p>
<p>C’est un peu comme si le gateau était sorti du four, maintenant on contracte avec le serveur pour lui dire comment il doit nous amener le gateau à table et comment nous le servir.</p>
<p>Tout cela se passe dans un fichier YAML à stocker dans un répertoire idoine nommé <code>k8s</code> (je ne sais pas pourquoi). Le contrat spécifie :</p>
<ul>
<li>l’espace SSPCloud lié au déployement et le nom du pod;</li>
<li>ce qu’il se passe si le pod est tué (ici on le recrée, <code>recreate</code>, pour qu’il y en ait toujours un <code>replica</code>);</li>
<li>on injecte le lien vers l’image docker à tirer;
<ul>
<li>on spécifie tous les secrets dont il a besoin pour travailler;</li>
<li>on lui donne de la ressource pour qu’il travaille;</li>
<li>on lui alloue aussi un petit espace de stockage (<code>PersistentVolumeClaim</code>) pour qu’il puisse stocker ses token Tchap;</li>
</ul></li>
</ul>
<p>Et voilà, le serveur est censé pouvoir nous amener notre gateau tout sorti du four.</p>
<details>
<summary>
Voir le contrat Kubernetes
</summary>
<div class="code-with-filename">
<div class="code-with-filename-file">
<pre><strong>k8s/deployment.yaml</strong></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb17" data-filename="k8s/deployment.yaml" style="background: #f1f3f5;"><pre class="sourceCode yaml code-with-copy"><code class="sourceCode yaml"><span id="cb17-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">apiVersion</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> apps/v1</span></span>
<span id="cb17-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kind</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> Deployment</span></span>
<span id="cb17-3"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">metadata</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb17-4"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">  </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">name</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> tchap-bot</span></span>
<span id="cb17-5"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">  </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">namespace</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> user-${SSP_USERNAME}</span></span>
<span id="cb17-6"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">spec</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb17-7"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">  </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">replicas</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> </span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span></span>
<span id="cb17-8"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">  </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">strategy</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb17-9"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">type</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> Recreate</span></span>
<span id="cb17-10"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">  </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">selector</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb17-11"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">matchLabels</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb17-12"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">      </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">app</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> tchap-bot</span></span>
<span id="cb17-13"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">  </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">template</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb17-14"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">metadata</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb17-15"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">      </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">labels</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb17-16"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">        </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">app</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> tchap-bot</span></span>
<span id="cb17-17"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">spec</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb17-18"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">      </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">containers</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb17-19"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">        </span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">-</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">name</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> tchap-bot</span></span>
<span id="cb17-20"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">          </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">image</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> ${DOCKERHUB_USERNAME}/tchap-bot:latest</span></span>
<span id="cb17-21"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">          </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">imagePullPolicy</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> Always</span></span>
<span id="cb17-22"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">          </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">env</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb17-23"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">            </span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">-</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">name</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> TCHAP_BOT_MATRIX_ID</span></span>
<span id="cb17-24"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">              </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">valueFrom</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb17-25"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">                </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">secretKeyRef</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb17-26"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">                  </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">name</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> tchap-bot-secrets</span></span>
<span id="cb17-27"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">                  </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">key</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> TCHAP_BOT_MATRIX_ID</span></span>
<span id="cb17-28"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">            </span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">-</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">name</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> TCHAP_BOT_PWD</span></span>
<span id="cb17-29"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">              </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">valueFrom</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb17-30"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">                </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">secretKeyRef</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb17-31"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">                  </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">name</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> tchap-bot-secrets</span></span>
<span id="cb17-32"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">                  </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">key</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> TCHAP_BOT_PWD</span></span>
<span id="cb17-33"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">            </span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">-</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">name</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> LLM_LAB_API_KEY</span></span>
<span id="cb17-34"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">              </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">valueFrom</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb17-35"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">                </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">secretKeyRef</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb17-36"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">                  </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">name</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> tchap-bot-secrets</span></span>
<span id="cb17-37"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">                  </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">key</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> LLM_LAB_API_KEY</span></span>
<span id="cb17-38"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">          </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">resources</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb17-39"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">            </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">requests</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb17-40"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">              </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">memory</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> </span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"128Mi"</span></span>
<span id="cb17-41"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">              </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">cpu</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> </span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"100m"</span></span>
<span id="cb17-42"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">            </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">limits</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb17-43"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">              </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">memory</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> </span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"256Mi"</span></span>
<span id="cb17-44"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">              </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">cpu</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> </span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"500m"</span></span>
<span id="cb17-45"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">          </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">volumeMounts</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb17-46"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">            </span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">-</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">name</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> bot-data</span></span>
<span id="cb17-47"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">              </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mountPath</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> /app/session</span></span>
<span id="cb17-48"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">      </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">volumes</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb17-49"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">        </span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">-</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">name</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> bot-data</span></span>
<span id="cb17-50"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">          </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">persistentVolumeClaim</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb17-51"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">            </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">claimName</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> tchap-bot-pvc</span></span>
<span id="cb17-52"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">---</span></span>
<span id="cb17-53"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">apiVersion</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> v1</span></span>
<span id="cb17-54"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kind</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> PersistentVolumeClaim</span></span>
<span id="cb17-55"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">metadata</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb17-56"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">  </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">name</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> tchap-bot-pvc</span></span>
<span id="cb17-57"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">  </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">namespace</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> user-${SSP_USERNAME}</span></span>
<span id="cb17-58"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">spec</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb17-59"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">  </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">accessModes</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb17-60"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">-</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> ReadWriteOnce</span></span>
<span id="cb17-61"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">  </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">resources</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb17-62"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">requests</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb17-63"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">      </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">storage</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> 1Gi</span></span></code></pre></div></div>
</div>
</details>
</section>
</section>
<section id="décollage-de-la-fusée" class="level2">
<h2 class="anchored" data-anchor-id="décollage-de-la-fusée">Décollage de la fusée</h2>
<p>Et maintenant pour le lancer, vous ouvrez un VSCode avec droits d’admin Kubernetes dans le SSPCloud.</p>
<div class="callout callout-style-default callout-tip callout-titled" title="Lancer un service avec un rôle admin Kubernetes">
<div class="callout-header d-flex align-content-center collapsed" data-bs-toggle="collapse" data-bs-target=".callout-6-contents" aria-controls="callout-6" aria-expanded="false" aria-label="Toggle callout">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
<span class="screen-reader-only">Astuce</span>Lancer un service avec un rôle admin Kubernetes
</div>
<div class="callout-btn-toggle d-inline-block border-0 py-1 ps-1 pe-0 float-end"><i class="callout-toggle"></i></div>
</div>
<div id="callout-6" class="callout-6-contents callout-collapse collapse">
<div class="callout-body-container callout-body">
<p>Dans les détails de création de votre service, vous avez l’onglet “Role”:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/bot_tchap/admin_role.png" class="img-fluid figure-img"></p>
<figcaption>Comment créer un service avec un rôle administrateur Kubernetes</figcaption>
</figure>
</div>
</div>
</div>
</div>
<p>J’ai enlevé mes identifiants dans le contrat mais vous pouvez les committer si vous voulez. En tout cas pour les remplacer avant de lancer le code, il suffit de lancer avec <code>DOCKERHUB_USERNAME</code> et <code>SSP_USERNAME</code> enregistrés en variable d’environnement dans bash :</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb18-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sed</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"s/</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\$</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">{DOCKERHUB_USERNAME}/</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$DOCKERHUB_USERNAME</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">/g; s/</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\$</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">{SSP_USERNAME}/</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$SSP_USERNAME</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">/g"</span> k8s/deployment.yaml <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">kubectl</span> apply <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-f</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-</span></span></code></pre></div></div>
<p>Les deux variables <code>${SSP_USERNAME}</code> et <code>${DOCKERHUB_USERNAME}</code> ne sont pas en soit des données sensibles. Je l’ai fait pour que vous puissiez bien voir où les changer dans le contrat yaml ci-dessus. Vous pouvez donc les changer en dur dans le contrat et ne pas les avoir en variable d’environnement. Vous pouvez alors lancer le déployement avec un plus simple <code>kubectl apply -f k8s/deployment.yaml</code>.</p>
<div class="callout callout-style-default callout-tip callout-titled" title="Kubernetes en 2min">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
<span class="screen-reader-only">Astuce</span>Kubernetes en 2min
</div>
</div>
<div class="callout-body-container callout-body">
<p>Les commandes essentielles de Kubernetes sont :</p>
<ul>
<li><code>kubectl get pods</code> : va lister tous les pods liés à votre compte SSPCloud.</li>
</ul>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb19" style="background: #f1f3f5;"><pre class="sourceCode .bash code-with-copy"><code class="sourceCode bash"><span id="cb19-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">onyxia@vscode-python-118218-0:~/work/tchap_bot_llm$</span> kubectl get pods</span>
<span id="cb19-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">NAME</span>                            READY   STATUS    RESTARTS       AGE</span>
<span id="cb19-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">tchap-bot-118218-6vmfk</span>          1/1     Running   43 <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">12m</span> ago<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span>   <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">36h</span></span>
<span id="cb19-4"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">vscode-python-118218-0</span>          1/1     Running   0              18h</span>
<span id="cb19-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">vscode-python-118219-0</span>          1/1     Running   0              101m</span>
<span id="cb19-6"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">vscode-r-python-julia-118218-0</span>  1/1     Running   0              20h</span></code></pre></div></div>
<ul>
<li><p><code>kubectl logs -f deployment/tchap-bot</code> : pour savoir ce qu’il se passe à l’intérieur du pod déployé</p></li>
<li><p>vous pouvez aussi voir ce qu’il se passe dans le stockage persistent avec <code>kubectl exec -it deployment/tchap-bot -- ls -la /app/session</code> et particulièrement y supprimer des fichiers ou dossier, comme sur le terminal avec <code>kubectl exec -it deployment/tchap-bot -- rm -rf /app/session/store /app/session/session.txt</code> par exemple</p></li>
<li><p><code>kubectl delete pod &lt;pod-name&gt;</code> : pour arrêter un pod : mais un pod n’est pas un déploiement, donc vous pouvez tester sur votre déploiement cela ne va pas marcher. <em>Cf.</em> partie suivante.</p></li>
</ul>
</div>
</div>
<p>Et voilà <strong>tatam</strong> : <strong>un bot qui tourne en continu sur le SSP Cloud, qui répond à nos</strong> <strong>questions dans le salon de l’équipe, et qui garde même le fil de la discussion en</strong> <strong>mémoire.</strong></p>
</section>
<section id="exploser-la-fusée" class="level2">
<h2 class="anchored" data-anchor-id="exploser-la-fusée">Exploser la fusée</h2>
<p>Tout marche, on est content. Mais au fait, <strong>on fait comment pour arrêter ce déploiement</strong> ?</p>
<p>Comme on a spécifié qu’on <strong>voulait toujours un pod actif dans notre contrat</strong>, un simple <code>kubectl delete pod &lt;pod-name&gt;</code> va le tuer mais le processus de déploiement va en recréer un pour arriver au nombre spécifié de replicas (ici : 1 - fun fact, mettez deux pods et vous aurez des messages en double à chaque fois).</p>
<p>Comment on fait pour tuer cette bougie qui se rallume à chaque fois qu’on lui souffle dessus alors ?</p>
<ul>
<li>soit on arrête complètement le déploiement avec <code>kubectl delete deployment &lt;name&gt;</code> (en l’occurence avec le nom du contrat ci-avant : <code>kubectl delete deployment tchap-bot</code>)</li>
<li>soit on lui de deployer 0 pod avec <code>kubectl scale deployment &lt;name&gt; --replicas=0</code> (en l’occurence avec le nom du contrat ci-avant : <code>kubectl scale deployment tchap-bot --replicas=0</code>)</li>
</ul>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb20-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">onyxia@vscode-python-118218-0:~/work/tchap_bot_llm$</span> kubectl scale deployment tchap-bot <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--replicas</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>0</span>
<span id="cb20-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">deployment.apps/tchap-bot</span> scaled</span>
<span id="cb20-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">onyxia@vscode-python-118218-0:~/work/tchap_bot_llm$</span> kubectl get pods</span>
<span id="cb20-4"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">NAME</span>                            READY   STATUS    RESTARTS   AGE</span>
<span id="cb20-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">vscode-python-118218-0</span>          1/1     Running   0          19h</span>
<span id="cb20-6"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">vscode-python-118219-0</span>          1/1     Running   0          113m</span>
<span id="cb20-7"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">vscode-r-python-julia-118218-0</span>  1/1     Running   0          20h</span>
<span id="cb20-8"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">onyxia@vscode-python-118218-0:~/work/tchap_bot_llm$</span> kubectl scale deployment tchap-bot <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--replicas</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>1</span>
<span id="cb20-9"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">deployment.apps/tchap-bot</span> scaled</span>
<span id="cb20-10"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">onyxia@vscode-python-118218-0:~/work/tchap_bot_llm$</span> kubectl get pods</span>
<span id="cb20-11"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">NAME</span>                            READY   STATUS              RESTARTS   AGE</span>
<span id="cb20-12"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">tchap-bot-118218118218-lb6</span>      0/1     ContainerCreating   0          2s</span>
<span id="cb20-13"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">vscode-python-118218-0</span>          1/1     Running             0          19h</span>
<span id="cb20-14"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">vscode-python-118219-0</span>          1/1     Running             0          114m</span>
<span id="cb20-15"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">vscode-r-python-julia-118218-0</span>  1/1     Running             0          20h</span></code></pre></div></div>
<div class="callout callout-style-default callout-caution callout-titled" title="Et t'es mignon mais combien de temps cela t'a pris tout ça ?">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
<span class="screen-reader-only">Mise en garde</span>Et t’es mignon mais combien de temps cela t’a pris tout ça ?
</div>
</div>
<div class="callout-body-container callout-body">
<p>Je trouve intéressant de savoir combien de temps prend un exercice. Tout dépend des compétences de bases, que je vous auto-spécifie ici :</p>
<p><strong>Expérience :</strong></p>
<ul>
<li>connaissance inexistante du sujet bot/Tchap;</li>
<li>connaissance inexistante de la manière dont marche llm.lab;</li>
<li>0 déploiement réussi sur Kubernetes;</li>
<li>compétence intermédiaire en Python.</li>
</ul>
<p><strong>Outils :</strong></p>
<ul>
<li>avec un assistant IA (essentiel);</li>
<li>avec accès au SSPCloud (essentiel).</li>
</ul>
<p><strong>Et à grosses mailles :</strong></p>
<ul>
<li>Découverte de Matrix, la manière dont marchent les bots, test à droite à gauche : 2 jours</li>
<li>Premier bot simple : 3h</li>
<li>Découverte de LLM lab : 2h</li>
<li>Bot et LLM Lab : 3h</li>
<li>déploiement du bot: 3h</li>
<li>Docker : 6h</li>
<li>post de blog : 7h (3h pour le premier jet, 4h de relecture 🥵)</li>
</ul>
<p>Soit au total <strong>environ une semaine de travail</strong> emballé c’est pesé.</p>
</div>
</div>
</section>
</section>
<section id="ce-quil-reste-à-faire-pour-une-v1-plus-propre" class="level1">
<h1>Ce qu’il reste à faire pour une v1 plus propre</h1>
<p>Ce projet, très agréable à mener et qui fonctionne, reste à consolider pour le stabiliser et le renforcer. Maintenant qu’il est en production, je vois au moins les <strong>champs suivants à améliorer</strong> :</p>
<ul>
<li>la <strong>gestion des logs</strong> : l’application ne renvoie pour le moment aucun log. Impossible en cas de problème de détecter son origine ;</li>
<li><strong>l’identification à Matrix</strong> saute régulièrement : la récupération des messages passés ne fonctionne donc souvent pas forcément. Inclure une gestion des erreurs permettrait de renforcer cela ;</li>
<li>le bot ne gère pas tout seul <strong>les contacts</strong> avec qui il échange : si un nouveau contact parle au bot, il ne va rien se passer tant que je ne me connecte pas à l’interface de Tchap et que j’accepte pas de démarrer la conversation. Ceci dit, c’est aussi une protection pour éviter de submerger llm.lab de requêtes ;</li>
<li>une <strong>gestion des requêtes envoyées à llm.lab</strong> : pour le moment, le bot est censé répondre à tout, aucune limite de messages etc n’est incluse.</li>
</ul>
<p>Et encorement sûrement d’autres choses auxquelles je n’ai pas pensé !</p>
</section>
<section id="ressources" class="level1">
<h1>Ressources</h1>
<p>Pour aller plus loin ou refaire l’expérience chez vous :</p>
<ul>
<li>le code source complet du bot : <a href="https://github.com/SSPHub/tchap_bot_llm" class="uri">https://github.com/SSPHub/tchap_bot_llm</a> ;</li>
<li>l’image Docker du bot : <a href="https://hub.docker.com/r/ssphub/tchap-bot" class="uri">https://hub.docker.com/r/ssphub/tchap-bot</a> ;</li>
<li>la <a href="https://aide.tchap.beta.gouv.fr/fr/article/documentation-technique-bot-et-integrations-tchap-1z3dfx/">doc technique des bots Tchap</a> ;</li>
<li>la <a href="https://simple-matrix-bot-lib.readthedocs.io/en/latest/">doc de <code>simplematrixbotlib</code></a> ;</li>
<li>la <a href="https://spec.matrix.org/latest/client-server-api/">documentation des API Matrix</a> ;</li>
<li>le service de modèles de langage du SSP Cloud : <a href="https://llm.lab.sspcloud.fr/" class="uri">https://llm.lab.sspcloud.fr/</a> ;</li>
<li>la <a href="https://docs.docker.com/">documentation de Docker</a> ;</li>
<li>le <a href="https://ensae-reproductibilite.github.io/slides/#/d%C3%A9ploiement">chapitre déploiement du cours de mise en production de l’ENSAE</a>.</li>
</ul>


</section>

 ]]></description>
  <category>Tchap</category>
  <category>LLM</category>
  <category>Bot</category>
  <category>Python</category>
  <category>Docker</category>
  <category>Kubernetes</category>
  <guid>https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/bot_tchap/</guid>
  <pubDate>Mon, 15 Jun 2026 00:00:00 GMT</pubDate>
  <media:content url="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/bot_tchap/robot_bot_tchap.png" medium="image" type="image/png" height="100" width="144"/>
</item>
<item>
  <title>Guide d’utilisation des données du recensement de la population au format Parquet</title>
  <link>https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/parquetRP/</link>
  <description><![CDATA[ 





<p>Ce guide présente quelques exemples d’utilisation des données du recensement de la population diffusées au format <code>Parquet</code>. Il s’agit d’une version HTML enrichissant le guide publié sur le site <a href="https://www.insee.fr/fr/statistiques/7637890">insee.fr</a> pour les langages <code>Python</code> <i class="fa-brands fa-python" aria-label="python"></i> et <i class="fa-brands fa-r-project" aria-label="r-project"></i> avec des exemples interactifs pouvant être construits par le biais de <code>Quarto Markdown</code> et <code>Observable</code>.</p>
<p>L’ensemble des codes utilisés pour produire cette note est disponible sur le dépôt <a href="https://github.com/InseeFrLab/exemples-recensement-parquet"><code>Github</code> <i class="fa-brands fa-github" aria-label="github"></i> InseeFrLab/exemples-recensement-parquet</a> au format <a href="https://quarto.org/"><code>Quarto Markdown</code></a>.</p>
<p>Pour plus d’informations sur le format <code>Parquet</code>, dans un contexte de statistique publique, se référer à <span class="citation" data-cites="dondon-lamarche-2023">Dondon et Lamarche (2023)</span>. Pour un exemple sur la différence entre format <code>CSV</code> et <code>Parquet</code> illustré sur les données du recensement de la population, voir <span class="citation" data-cites="mauviere-2022">Mauvière (2022)</span>.</p>
<p>Ce guide propose d’utiliser <a href="https://duckdb.org/"><code>DuckDB</code></a> à travers plusieurs langages pour effectuer des traitements sur les fichiers détails du recensement. Par rapport à d’autres approches, <a href="https://duckdb.org/"><code>DuckDB</code></a> a été choisi pour son efficacité ainsi que pour son universalité<sup>1</sup>.</p>
<details>
<summary>
Afficher le dictionnaire des variables
</summary>
<p>Il est possible de rechercher dans la documentation des noms de variables ou des informations dans les descriptions. Lorsqu’une variable présente de nombreuses modalités, seules la première est la dernière sont retournées. Un exemple ci-dessous montre comment utiliser une requête SQL pour récupérer l’ensemble des valeurs d’une telle variable.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb1" data-startfrom="67" data-source-offset="0" style="background: #f1f3f5;"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 66;"><span id="cb1-67">viewof unique_description_filter <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">search</span>(</span>
<span id="cb1-68">  documentation<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> {</span>
<span id="cb1-69">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">placeholder</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Trouver une information dans la documentation"</span></span>
<span id="cb1-70">  }</span>
<span id="cb1-71">  )</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div id="ojs-cell-1" data-nodetype="declaration">

</div>
</div>
</div>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb2" data-startfrom="76" data-source-offset="0" style="background: #f1f3f5;"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 75;"><span id="cb2-76">table_filtre_description <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(</span>
<span id="cb2-77">  unique_description_filter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-78">  {</span>
<span id="cb2-79">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">header</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> {</span>
<span id="cb2-80">      <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">description_variable</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Description de la variable"</span></span>
<span id="cb2-81">    }    </span>
<span id="cb2-82">  }</span>
<span id="cb2-83">)</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div id="ojs-cell-2" data-nodetype="declaration">

</div>
</div>
</div>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb3" data-startfrom="88" data-source-offset="0" style="background: #f1f3f5;"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 87;"><span id="cb3-88">documentation <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(<span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`SELECT * FROM documentation_indiv`</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div id="ojs-cell-3" data-nodetype="declaration">

</div>
</div>
</div>
</details>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>Ce <em>post</em> accompagne la mise à disposition des données du recensement de la population au format <code>Parquet</code> sur le site <a href="https://www.insee.fr/fr/statistiques/7706119?sommaire=7637890">insee.fr</a>.</p>
<p>Il vise à fournir une expérience plus ergonomique et des exemples supplémentaires liés au langage <code>Javascript</code> au guide PDF disponible sur la page du site <a href="https://www.insee.fr/fr/statistiques/7706119?sommaire=7637890">insee.fr</a>.</p>
<p>⚠️ Cette page s’appuie sur l’exploitation de données qui sont préalablement téléchargées de manière automatique par le navigateur <em>web</em>. Celles-ci représentent une volumétrie autour de 1Go, ce qui peut nécessiter un certain temps en fonction de la bande passante. Une fois téléchargées, l’exploitation de ces données nécessite néanmoins beaucoup moins de ressources grâce à l’optimisation permise par <code>DuckDB</code>.</p>
</div>
</div>
<section id="initialisation" class="level1">
<h1>Initialisation</h1>
<p>Les données sont disponibles sur le site <code>data.gouv</code> aux adresses suivantes :</p>
<ul>
<li><a href="https://www.insee.fr/fr/statistiques/7706119?sommaire=7637890">Fichier détail individuel</a> ;</li>
<li><a href="https://www.insee.fr/fr/statistiques/7705908?sommaire=7637890">Fichier détail logement</a>.</li>
</ul>
<p>Dans la suite de ce guide, il sera fait l’hypothèse pour <code>Python</code> et <code>R</code> que les données sont récupérées depuis les URL stables, enregistrées dans un même dossier et qu’il existe une variable <em>ad hoc</em> enregistrant ce chemin dans <code>Python</code> ou <code>R</code>. En ce qui concerne <code>Observable</code>, il est proposé d’utiliser directement l’URL de mise à disposition des fichiers.</p>
<div class="tabset-margin-container"></div><div class="panel-tabset" data-group="language">
<ul class="nav nav-tabs"><li class="nav-item"><a class="nav-link active" id="tabset-1-1-tab" data-bs-toggle="tab" data-bs-target="#tabset-1-1" aria-controls="tabset-1-1" aria-selected="true" href=""><code>Observable</code> via <code>Quarto</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-1-2-tab" data-bs-toggle="tab" data-bs-target="#tabset-1-2" aria-controls="tabset-1-2" aria-selected="false" href=""><code>Python</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-1-3-tab" data-bs-toggle="tab" data-bs-target="#tabset-1-3" aria-controls="tabset-1-3" aria-selected="false" href=""><code>R</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-1-4-tab" data-bs-toggle="tab" data-bs-target="#tabset-1-4" aria-controls="tabset-1-4" aria-selected="false" href=""><code>R (dbplyr)</code></a></li></ul>
<div class="tab-content" data-group="language">
<div id="tabset-1-1" class="tab-pane active" aria-labelledby="tabset-1-1-tab">
<p>Les URL stables de mise à dispositon des données seront directement renseignées dans la création de la base de données.</p>
<div class="callout callout-style-default callout-caution callout-titled">
<div class="callout-header d-flex align-content-center collapsed" data-bs-toggle="collapse" data-bs-target=".callout-2-contents" aria-controls="callout-2" aria-expanded="false" aria-label="Toggle callout">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
<span class="screen-reader-only">Mise en garde</span>Emplacement des données pour les exemples <code>Observable</code>
</div>
<div class="callout-btn-toggle d-inline-block border-0 py-1 ps-1 pe-0 float-end"><i class="callout-toggle"></i></div>
</div>
<div id="callout-2" class="callout-2-contents callout-collapse collapse">
<div class="callout-body-container callout-body">
<p>En ce qui concerne <code>Observable</code>, il est proposé d’utiliser directement l’URL de mise à disposition des fichiers car l’extension <code>httpfs</code> est nativement intégrée à la librairie <code>DuckDB</code>, <em>a contrario</em> des clients <code>Python</code> et <code>R</code>.</p>
<p>Ces jeux de données sont automatiquement téléchargés par le navigateur et mis en <em>cache</em> pour accélérer des utilisations ultérieures de la page. Le premier chargement de tous les tableaux et graphiques sur celle-ci peut ainsi prendre un peu plus de temps.</p>
</div>
</div>
</div>
</div>
<div id="tabset-1-2" class="tab-pane" aria-labelledby="tabset-1-2-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb4-1">path_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'C:/MesDocuments/dossierpersonnel'</span></span>
<span id="cb4-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># remplacer par l'emplacement où sont stockées </span></span>
<span id="cb4-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># les données</span></span></code></pre></div></div>
</div>
<div id="tabset-1-3" class="tab-pane" aria-labelledby="tabset-1-3-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb5-1">path_data <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'C:/MesDocuments/dossierpersonnel'</span></span>
<span id="cb5-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># remplacer par l'emplacement où sont stockées </span></span>
<span id="cb5-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># les données</span></span></code></pre></div></div>
</div>
<div id="tabset-1-4" class="tab-pane" aria-labelledby="tabset-1-4-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb6-1">path_data <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'C:/MesDocuments/dossierpersonnel'</span></span>
<span id="cb6-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># remplacer par l'emplacement où sont stockées </span></span>
<span id="cb6-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># les données</span></span></code></pre></div></div>
</div>
</div>
</div>
<p>Il est proposé, pour initialiser la connexion entre les données <code>Parquet</code> et le langage client (<code>Javascript</code>, <code>R</code> ou <code>Python</code>) d’utiliser des vues. Ceci permet de faire référence de manière répétée à la même source de données par le biais d’un alias (<code>table_logement</code> ou <code>table_individu</code>).</p>
<div class="tabset-margin-container"></div><div class="panel-tabset" data-group="language">
<ul class="nav nav-tabs"><li class="nav-item"><a class="nav-link active" id="tabset-2-1-tab" data-bs-toggle="tab" data-bs-target="#tabset-2-1" aria-controls="tabset-2-1" aria-selected="true" href=""><code>Observable</code> via <code>Quarto</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-2-2-tab" data-bs-toggle="tab" data-bs-target="#tabset-2-2" aria-controls="tabset-2-2" aria-selected="false" href=""><code>Python</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-2-3-tab" data-bs-toggle="tab" data-bs-target="#tabset-2-3" aria-controls="tabset-2-3" aria-selected="false" href=""><code>R</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-2-4-tab" data-bs-toggle="tab" data-bs-target="#tabset-2-4" aria-controls="tabset-2-4" aria-selected="false" href=""><code>R (dbplyr)</code></a></li></ul>
<div class="tab-content" data-group="language">
<div id="tabset-2-1" class="tab-pane active" aria-labelledby="tabset-2-1-tab">
<details>
<summary>
Dérouler pour découvrir le code <code>Observable</code> d’initialisation de la base de données avec <code>DuckDB</code>
</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode markdown code-with-copy"><code class="sourceCode markdown"><span id="cb7-1"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```{ojs}</span></span>
<span id="cb7-2">url_table_logement <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://www.data.gouv.fr/fr/datasets/r/f314175a-6d33-4ee4-b5eb-2cb6c29df2c2"</span></span>
<span id="cb7-3">url_table_individu <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://www.data.gouv.fr/fr/datasets/r/c8e1b241-75fe-43e9-a266-830fc30ec61d"</span></span>
<span id="cb7-4">url_doc_logement <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://www.data.gouv.fr/fr/datasets/r/c274705f-98db-4d9b-9674-578e04f03198"</span></span>
<span id="cb7-5">url_doc_individu <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://www.data.gouv.fr/fr/datasets/r/1c6c6ab2-b766-41a4-90f0-043173d5e9d1"</span></span>
<span id="cb7-6"></span>
<span id="cb7-7">renommage_documentation <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`SELECT </span></span>
<span id="cb7-8"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">  COD_VAR AS nom_variable, </span></span>
<span id="cb7-9"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">  LIB_VAR AS description_variable, </span></span>
<span id="cb7-10"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">  TYPE_VAR AS type_variable, </span></span>
<span id="cb7-11"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">  COD_MOD AS code_modalite, </span></span>
<span id="cb7-12"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">  LIB_MOD AS description_modalite,</span></span>
<span id="cb7-13"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">  LONG_VAR as longueur_variable`</span></span>
<span id="cb7-14"></span>
<span id="cb7-15">db <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {</span>
<span id="cb7-16">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">const</span> configuredClient <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> DuckDBClient<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">of</span>()<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-17"></span>
<span id="cb7-18">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> configuredClient<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(<span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span></span>
<span id="cb7-19"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    CREATE OR REPLACE VIEW table_individu </span></span>
<span id="cb7-20"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    AS SELECT *</span></span>
<span id="cb7-21"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    FROM read_parquet('</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">${</span>url_table_individu<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">')`</span></span>
<span id="cb7-22">  ) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-23"></span>
<span id="cb7-24">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> configuredClient<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(<span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span></span>
<span id="cb7-25"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    CREATE OR REPLACE VIEW table_logement </span></span>
<span id="cb7-26"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    AS SELECT *</span></span>
<span id="cb7-27"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    FROM read_parquet('</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">${</span>url_table_logement<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">')`</span></span>
<span id="cb7-28">  ) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-29"></span>
<span id="cb7-30">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> configuredClient<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(<span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span></span>
<span id="cb7-31"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    CREATE OR REPLACE VIEW documentation_logement</span></span>
<span id="cb7-32"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    AS </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">${</span>renommage_documentation<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;"> FROM read_csv_auto('</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">${</span>url_doc_logement<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">', header=true)`</span></span>
<span id="cb7-33">  ) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-34">  </span>
<span id="cb7-35">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> configuredClient<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(<span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span></span>
<span id="cb7-36"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    CREATE OR REPLACE VIEW documentation_indiv</span></span>
<span id="cb7-37"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    AS </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">${</span>renommage_documentation<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;"> FROM read_csv_auto('</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">${</span>url_doc_individu<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">', header=true)`</span></span>
<span id="cb7-38">  ) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-39"></span>
<span id="cb7-40">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> configuredClient</span>
<span id="cb7-41">}</span>
<span id="cb7-42"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```</span></span></code></pre></div></div>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb8" data-startfrom="247" data-source-offset="-0" style="background: #f1f3f5;"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 246;"><span id="cb8-247">url_table_logement <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://static.data.gouv.fr/resources/recensement-de-la-population-fichiers-detail-logements-ordinaires-en-2020-1/20231023-123618/fd-logemt-2020.parquet"</span></span>
<span id="cb8-248">url_table_individu <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://static.data.gouv.fr/resources/recensement-de-la-population-fichiers-detail-individus-localises-au-canton-ou-ville-2020-1/20231023-122841/fd-indcvi-2020.parquet"</span></span>
<span id="cb8-249">url_doc_logement <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://www.data.gouv.fr/fr/datasets/r/c274705f-98db-4d9b-9674-578e04f03198"</span></span>
<span id="cb8-250">url_doc_individu <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://www.data.gouv.fr/fr/datasets/r/1c6c6ab2-b766-41a4-90f0-043173d5e9d1"</span></span>
<span id="cb8-251"></span>
<span id="cb8-252">renommage_documentation <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`SELECT </span></span>
<span id="cb8-253"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">  COD_VAR AS nom_variable, </span></span>
<span id="cb8-254"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">  LIB_VAR AS description_variable, </span></span>
<span id="cb8-255"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">  TYPE_VAR AS type_variable, </span></span>
<span id="cb8-256"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">  COD_MOD AS code_modalite, </span></span>
<span id="cb8-257"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">  LIB_MOD AS description_modalite,</span></span>
<span id="cb8-258"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">  LONG_VAR as longueur_variable`</span></span>
<span id="cb8-259"></span>
<span id="cb8-260">db <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {</span>
<span id="cb8-261">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">const</span> configuredClient <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> DuckDBClient<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">of</span>()<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb8-262"></span>
<span id="cb8-263">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> configuredClient<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(<span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span></span>
<span id="cb8-264"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    CREATE OR REPLACE VIEW table_individu </span></span>
<span id="cb8-265"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    AS SELECT *</span></span>
<span id="cb8-266"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    FROM read_parquet('</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">${</span>url_table_individu<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">')`</span></span>
<span id="cb8-267">  ) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb8-268"></span>
<span id="cb8-269">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> configuredClient<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(<span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span></span>
<span id="cb8-270"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    CREATE OR REPLACE VIEW table_logement </span></span>
<span id="cb8-271"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    AS SELECT *</span></span>
<span id="cb8-272"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    FROM read_parquet('</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">${</span>url_table_logement<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">')`</span></span>
<span id="cb8-273">  ) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb8-274">  </span>
<span id="cb8-275">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> configuredClient<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(<span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span></span>
<span id="cb8-276"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    CREATE OR REPLACE VIEW documentation_indiv</span></span>
<span id="cb8-277"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    AS </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">${</span>renommage_documentation<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;"> FROM read_csv_auto('</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">${</span>url_doc_individu<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">', header=true)`</span></span>
<span id="cb8-278">  ) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb8-279"></span>
<span id="cb8-280">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> configuredClient<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(<span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span></span>
<span id="cb8-281"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    CREATE OR REPLACE VIEW documentation_logement</span></span>
<span id="cb8-282"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    AS </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">${</span>renommage_documentation<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;"> FROM read_csv_auto('</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">${</span>url_doc_logement<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">', header=true)`</span></span>
<span id="cb8-283">  ) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb8-284"></span>
<span id="cb8-285">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> configuredClient</span>
<span id="cb8-286">}</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div>
<div id="ojs-cell-4-1" data-nodetype="declaration">

</div>
</div>
</div>
<div class="cell-output cell-output-display">
<div>
<div id="ojs-cell-4-2" data-nodetype="declaration">

</div>
</div>
</div>
<div class="cell-output cell-output-display">
<div>
<div id="ojs-cell-4-3" data-nodetype="declaration">

</div>
</div>
</div>
<div class="cell-output cell-output-display">
<div>
<div id="ojs-cell-4-4" data-nodetype="declaration">

</div>
</div>
</div>
<div class="cell-output cell-output-display">
<div>
<div id="ojs-cell-4-5" data-nodetype="declaration">

</div>
</div>
</div>
<div class="cell-output cell-output-display">
<div>
<div id="ojs-cell-4-6" data-nodetype="declaration">

</div>
</div>
</div>
</div>
</details>
</div>
<div id="tabset-2-2" class="tab-pane" aria-labelledby="tabset-2-2-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb9-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> duckdb</span>
<span id="cb9-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> os</span>
<span id="cb9-3"></span>
<span id="cb9-4"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> os.path.isdir(path_data):</span>
<span id="cb9-5">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">raise</span> <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">ValueError</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"path_data n'est pas un répertoire valide."</span>)</span>
<span id="cb9-6"></span>
<span id="cb9-7">duckdb.sql(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'''</span></span>
<span id="cb9-8"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">  CREATE OR REPLACE VIEW table_individu</span></span>
<span id="cb9-9"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">  AS SELECT * FROM read_parquet("</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>path_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/FD_INDCVI_2020.parquet")</span></span>
<span id="cb9-10"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">'''</span></span>
<span id="cb9-11">)</span>
<span id="cb9-12"></span>
<span id="cb9-13">duckdb.sql(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'''</span></span>
<span id="cb9-14"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">  CREATE OR REPLACE VIEW table_logement</span></span>
<span id="cb9-15"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">  AS SELECT * FROM read_parquet("</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>path_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/FD_LOGEMT_2020.parquet")</span></span>
<span id="cb9-16"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">'''</span></span>
<span id="cb9-17">)</span>
<span id="cb9-18"></span>
<span id="cb9-19">duckdb.sql(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'''</span></span>
<span id="cb9-20"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">  CREATE OR REPLACE VIEW documentation_indiv</span></span>
<span id="cb9-21"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">  AS SELECT COD_VAR AS nom_variable,</span></span>
<span id="cb9-22"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">     LIB_VAR AS description_variable,</span></span>
<span id="cb9-23"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">     TYPE_VAR AS type_variable,</span></span>
<span id="cb9-24"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">     COD_MOD AS code_modalite,</span></span>
<span id="cb9-25"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">     LIB_MOD AS description_modalite,</span></span>
<span id="cb9-26"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">     LONG_VAR as longueur_variable</span></span>
<span id="cb9-27"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">  FROM read_csv_auto("</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>path_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/dictionnaire_variables_indcvi_2020.csv", header=true)</span></span>
<span id="cb9-28"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">'''</span></span>
<span id="cb9-29">)</span>
<span id="cb9-30"></span>
<span id="cb9-31">duckdb.sql(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'''</span></span>
<span id="cb9-32"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">  CREATE OR REPLACE VIEW documentation_logement</span></span>
<span id="cb9-33"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">  AS SELECT COD_VAR AS nom_variable,</span></span>
<span id="cb9-34"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">     LIB_VAR AS description_variable,</span></span>
<span id="cb9-35"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">     TYPE_VAR AS type_variable,</span></span>
<span id="cb9-36"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">     COD_MOD AS code_modalite,</span></span>
<span id="cb9-37"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">     LIB_MOD AS description_modalite,</span></span>
<span id="cb9-38"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">     LONG_VAR as longueur_variable</span></span>
<span id="cb9-39"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">  FROM read_csv_auto("</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>path_data<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/dictionnaire_variables_logemt_2020.csv", header=true)</span></span>
<span id="cb9-40"><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">'''</span></span>
<span id="cb9-41">)</span></code></pre></div></div>
</div>
<div id="tabset-2-3" class="tab-pane" aria-labelledby="tabset-2-3-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb10-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(duckdb)</span>
<span id="cb10-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(glue)</span>
<span id="cb10-3"></span>
<span id="cb10-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Pour créer une base de données en mémoire</span></span>
<span id="cb10-5">con <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbConnect</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">duckdb</span>())</span>
<span id="cb10-6"></span>
<span id="cb10-7">path_data_sql <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> DBI<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">SQL</span>(path_data)</span>
<span id="cb10-8"></span>
<span id="cb10-9"></span>
<span id="cb10-10">renommage_documentation <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span>  DBI<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">SQL</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">paste</span>(</span>
<span id="cb10-11"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT"</span>,</span>
<span id="cb10-12"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"COD_VAR AS nom_variable,"</span>,</span>
<span id="cb10-13"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"LIB_VAR AS description_variable,"</span>,</span>
<span id="cb10-14"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"TYPE_VAR AS type_variable,"</span>,</span>
<span id="cb10-15"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"COD_MOD AS code_modalite,"</span>,</span>
<span id="cb10-16"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"LIB_MOD AS description_modalite,"</span>,</span>
<span id="cb10-17"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"LONG_VAR as longueur_variable"</span></span>
<span id="cb10-18">))</span>
<span id="cb10-19"></span>
<span id="cb10-20"></span>
<span id="cb10-21"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbExecute</span>(</span>
<span id="cb10-22">  con,</span>
<span id="cb10-23">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">glue_sql</span>(  </span>
<span id="cb10-24">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'CREATE OR REPLACE VIEW table_individu AS '</span>,</span>
<span id="cb10-25">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'SELECT * FROM read_parquet("{path_data_sql}/FD_INDCVI_2020.parquet")'</span>,</span>
<span id="cb10-26">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.con=</span>con</span>
<span id="cb10-27">  )</span>
<span id="cb10-28">)</span>
<span id="cb10-29"></span>
<span id="cb10-30"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbExecute</span>(</span>
<span id="cb10-31">  con,</span>
<span id="cb10-32">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">glue_sql</span>(  </span>
<span id="cb10-33">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'CREATE OR REPLACE VIEW table_logement AS '</span>,</span>
<span id="cb10-34">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'SELECT * FROM read_parquet("{path_data_sql}/FD_LOGEMT_2020.parquet")'</span>,</span>
<span id="cb10-35">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.con=</span>con</span>
<span id="cb10-36">  )</span>
<span id="cb10-37">)</span>
<span id="cb10-38"></span>
<span id="cb10-39"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbExecute</span>(</span>
<span id="cb10-40">  con,</span>
<span id="cb10-41">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">glue_sql</span>(</span>
<span id="cb10-42">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'CREATE OR REPLACE VIEW documentation_indiv AS '</span>,</span>
<span id="cb10-43">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'{renommage_documentation} FROM '</span>,</span>
<span id="cb10-44">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'read_csv_auto("{path_data_sql}/dictionnaire_variables_indcvi_2020.csv", header=true)'</span>,</span>
<span id="cb10-45">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.con=</span>con</span>
<span id="cb10-46">  )</span>
<span id="cb10-47">)</span>
<span id="cb10-48"></span>
<span id="cb10-49"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbExecute</span>(</span>
<span id="cb10-50">  con,</span>
<span id="cb10-51">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">glue_sql</span>(</span>
<span id="cb10-52">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'CREATE OR REPLACE VIEW documentation_logement AS '</span>,</span>
<span id="cb10-53">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'{renommage_documentation} FROM '</span>,</span>
<span id="cb10-54">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'read_csv_auto("{path_data_sql}/dictionnaire_variables_logemt_2020.csv", header=true)'</span>,</span>
<span id="cb10-55">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.con=</span>con</span>
<span id="cb10-56">  )</span>
<span id="cb10-57">)</span></code></pre></div></div>
</div>
<div id="tabset-2-4" class="tab-pane" aria-labelledby="tabset-2-4-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb11-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(duckdb)</span>
<span id="cb11-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(dplyr)</span>
<span id="cb11-3"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(stringr)</span>
<span id="cb11-4"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(glue)</span>
<span id="cb11-5"></span>
<span id="cb11-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Pour créer une base de données en mémoire</span></span>
<span id="cb11-7">con <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbConnect</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">duckdb</span>())</span>
<span id="cb11-8"></span>
<span id="cb11-9">path_data_sql <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> DBI<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">SQL</span>(path_data)</span>
<span id="cb11-10"></span>
<span id="cb11-11">renommage_documentation <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span>  DBI<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">SQL</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">paste</span>(</span>
<span id="cb11-12"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT"</span>,</span>
<span id="cb11-13"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"COD_VAR AS nom_variable,"</span>,</span>
<span id="cb11-14"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"LIB_VAR AS description_variable,"</span>,</span>
<span id="cb11-15"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"TYPE_VAR AS type_variable,"</span>,</span>
<span id="cb11-16"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"COD_MOD AS code_modalite,"</span>,</span>
<span id="cb11-17"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"LIB_MOD AS description_modalite,"</span>,</span>
<span id="cb11-18"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"LONG_VAR as longueur_variable"</span></span>
<span id="cb11-19">))</span>
<span id="cb11-20"></span>
<span id="cb11-21"></span>
<span id="cb11-22"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbExecute</span>(</span>
<span id="cb11-23">  con,</span>
<span id="cb11-24">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">glue_sql</span>(  </span>
<span id="cb11-25">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'CREATE OR REPLACE VIEW table_individu AS '</span>,</span>
<span id="cb11-26">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'SELECT * FROM read_parquet("{path_data_sql}/FD_INDCVI_2020.parquet")'</span>,</span>
<span id="cb11-27">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.con=</span>con</span>
<span id="cb11-28">  )</span>
<span id="cb11-29">)</span>
<span id="cb11-30"></span>
<span id="cb11-31">table_individu <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tbl</span>(con, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"table_individu"</span>)</span>
<span id="cb11-32"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># La requête pourrait aussi s'écrire directement dans l'appel à tbl :</span></span>
<span id="cb11-33">table_individu_direct <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tbl</span>(con, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">glue</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'read_parquet("{path_data}/FD_INDCVI_2020.parquet")'</span>))</span>
<span id="cb11-34"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">print</span>(table_individu_direct)</span>
<span id="cb11-35"></span>
<span id="cb11-36"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbExecute</span>(</span>
<span id="cb11-37">  con,</span>
<span id="cb11-38">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">glue_sql</span>(  </span>
<span id="cb11-39">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'CREATE OR REPLACE VIEW table_logement AS '</span>,</span>
<span id="cb11-40">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'SELECT * FROM read_parquet("{path_data_sql}/FD_LOGEMT_2020.parquet")'</span>,</span>
<span id="cb11-41">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.con=</span>con</span>
<span id="cb11-42">  )</span>
<span id="cb11-43">)</span>
<span id="cb11-44">table_logement <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tbl</span>(con, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"table_logement"</span>)</span>
<span id="cb11-45"></span>
<span id="cb11-46"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbExecute</span>(</span>
<span id="cb11-47">  con,</span>
<span id="cb11-48">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">glue_sql</span>(</span>
<span id="cb11-49">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'CREATE OR REPLACE VIEW documentation_indiv AS '</span>,</span>
<span id="cb11-50">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'{renommage_documentation} FROM '</span>,</span>
<span id="cb11-51">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'read_csv_auto("{path_data_sql}/dictionnaire_variables_indcvi_2020.csv", header=true)'</span>,</span>
<span id="cb11-52">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.con=</span>con</span>
<span id="cb11-53">  )</span>
<span id="cb11-54">)</span>
<span id="cb11-55">documentation_indiv <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tbl</span>(con, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"documentation_indiv"</span>)</span>
<span id="cb11-56"></span>
<span id="cb11-57"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbExecute</span>(</span>
<span id="cb11-58">  con,</span>
<span id="cb11-59">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">glue_sql</span>(</span>
<span id="cb11-60">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'CREATE OR REPLACE VIEW documentation_logement AS '</span>,</span>
<span id="cb11-61">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'{renommage_documentation} FROM '</span>,</span>
<span id="cb11-62">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'read_csv_auto("{path_data_sql}/dictionnaire_variables_logemt_2020.csv", header=true)'</span>,</span>
<span id="cb11-63">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.con=</span>con</span>
<span id="cb11-64">  )</span>
<span id="cb11-65">)</span>
<span id="cb11-66">documentation_logement <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tbl</span>(con, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"documentation_logement"</span>)</span></code></pre></div></div>
</div>
</div>
</div>
<p>Pour rapidement avoir une idée des informations présentes dans ces données, le code ci-dessous peut être utilisé :</p>
<div class="tabset-margin-container"></div><div class="panel-tabset" data-group="language">
<ul class="nav nav-tabs"><li class="nav-item"><a class="nav-link active" id="tabset-3-1-tab" data-bs-toggle="tab" data-bs-target="#tabset-3-1" aria-controls="tabset-3-1" aria-selected="true" href=""><code>Observable</code> via <code>Quarto</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-3-2-tab" data-bs-toggle="tab" data-bs-target="#tabset-3-2" aria-controls="tabset-3-2" aria-selected="false" href=""><code>Python</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-3-3-tab" data-bs-toggle="tab" data-bs-target="#tabset-3-3" aria-controls="tabset-3-3" aria-selected="false" href=""><code>R</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-3-4-tab" data-bs-toggle="tab" data-bs-target="#tabset-3-4" aria-controls="tabset-3-4" aria-selected="false" href=""><code>R (dbplyr)</code></a></li></ul>
<div class="tab-content" data-group="language">
<div id="tabset-3-1" class="tab-pane active" aria-labelledby="tabset-3-1-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode markdown code-with-copy"><code class="sourceCode markdown"><span id="cb12-1"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```{ojs}</span></span>
<span id="cb12-2">schema_table_logement <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(</span>
<span id="cb12-3">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM documentation_logement"</span></span>
<span id="cb12-4">  )</span>
<span id="cb12-5">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(documentation_logement)</span>
<span id="cb12-6"></span>
<span id="cb12-7">schema_table_individu <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(</span>
<span id="cb12-8">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM documentation_indiv"</span></span>
<span id="cb12-9">  )</span>
<span id="cb12-10">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(schema_table_individu)</span>
<span id="cb12-11"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```</span></span></code></pre></div></div>
</div>
<div id="tabset-3-2" class="tab-pane" aria-labelledby="tabset-3-2-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb13-1">schema_table_individu <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> duckdb.sql(</span>
<span id="cb13-2">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM documentation_indiv"</span></span>
<span id="cb13-3">  ).to_df()</span>
<span id="cb13-4">display(schema_table_individu.head(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>))</span>
<span id="cb13-5"></span>
<span id="cb13-6">schema_table_logement <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> duckdb.sql(</span>
<span id="cb13-7">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM documentation_logement"</span></span>
<span id="cb13-8">  ).to_df()</span>
<span id="cb13-9">display(schema_table_logement.head(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>))</span></code></pre></div></div>
</div>
<div id="tabset-3-3" class="tab-pane" aria-labelledby="tabset-3-3-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb14-1">schema_table_individu <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbGetQuery</span>(</span>
<span id="cb14-2">  con,</span>
<span id="cb14-3">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM documentation_indiv"</span></span>
<span id="cb14-4">)</span>
<span id="cb14-5"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">print</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">head</span>(schema_table_individu))</span>
<span id="cb14-6"></span>
<span id="cb14-7">schema_table_logement <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbGetQuery</span>(</span>
<span id="cb14-8">  con,</span>
<span id="cb14-9">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM documentation_logement"</span></span>
<span id="cb14-10">)</span>
<span id="cb14-11"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">print</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">head</span>(schema_table_logement))</span></code></pre></div></div>
</div>
<div id="tabset-3-4" class="tab-pane" aria-labelledby="tabset-3-4-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb15-1"></span>
<span id="cb15-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">print</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">head</span>(documentation_indiv))</span>
<span id="cb15-3"></span>
<span id="cb15-4"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">print</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">head</span>(documentation_logement))</span></code></pre></div></div>
</div>
</div>
</div>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb16" data-startfrom="259" data-source-offset="-0" style="background: #f1f3f5;"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 258;"><span id="cb16-259">schema_table_individu <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(</span>
<span id="cb16-260">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM documentation_indiv"</span></span>
<span id="cb16-261">  )</span>
<span id="cb16-262">schema_table_logement <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(</span>
<span id="cb16-263">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM documentation_logement"</span></span>
<span id="cb16-264">  )</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div>
<div id="ojs-cell-5-1" data-nodetype="declaration">

</div>
</div>
</div>
<div class="cell-output cell-output-display">
<div>
<div id="ojs-cell-5-2" data-nodetype="declaration">

</div>
</div>
</div>
</div>
<p>Voici le dictionnaire des variables de la table logement:</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb17" data-startfrom="265" data-source-offset="0" style="background: #f1f3f5;"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 264;"><span id="cb17-265">viewof search_logement <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">search</span>(schema_table_logement<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> {</span>
<span id="cb17-266">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">placeholder</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Rechercher une information dans la table logement"</span></span>
<span id="cb17-267">})</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div id="ojs-cell-6" data-nodetype="declaration">

</div>
</div>
</div>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb18" data-startfrom="272" data-source-offset="0" style="background: #f1f3f5;"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 271;"><span id="cb18-272">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(search_logement)</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div id="ojs-cell-7" data-nodetype="expression">

</div>
</div>
</div>
<p>Et voici celui de la table individus:</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb19" data-startfrom="279" data-source-offset="0" style="background: #f1f3f5;"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 278;"><span id="cb19-279">viewof search_individus <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">search</span>(schema_table_individu<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> {</span>
<span id="cb19-280">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">placeholder</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Rechercher une information dans la table individus"</span></span>
<span id="cb19-281">})</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div id="ojs-cell-8" data-nodetype="declaration">

</div>
</div>
</div>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb20" data-startfrom="315" data-source-offset="0" style="background: #f1f3f5;"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 314;"><span id="cb20-315">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(search_individus)</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div id="ojs-cell-9" data-nodetype="expression">

</div>
</div>
</div>
<p>Pour découvrir les informations présentes dans la base, il est possible d’utiliser les fonctions pré-implémentées de <code>DuckDB</code> pour la <a href="https://duckdb.org/docs/sql/functions/char.html">manipulation de données textuelles</a>. Par exemple, pour extraire toutes les modalités des variables dont la description contient le terme <em>“catégorie”</em> :</p>
<div class="tabset-margin-container"></div><div class="panel-tabset" data-group="language">
<ul class="nav nav-tabs"><li class="nav-item"><a class="nav-link active" id="tabset-4-1-tab" data-bs-toggle="tab" data-bs-target="#tabset-4-1" aria-controls="tabset-4-1" aria-selected="true" href=""><code>Observable</code> via <code>Quarto</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-4-2-tab" data-bs-toggle="tab" data-bs-target="#tabset-4-2" aria-controls="tabset-4-2" aria-selected="false" href=""><code>Python</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-4-3-tab" data-bs-toggle="tab" data-bs-target="#tabset-4-3" aria-controls="tabset-4-3" aria-selected="false" href=""><code>R</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-4-4-tab" data-bs-toggle="tab" data-bs-target="#tabset-4-4" aria-controls="tabset-4-4" aria-selected="false" href=""><code>R (dbplyr)</code></a></li></ul>
<div class="tab-content" data-group="language">
<div id="tabset-4-1" class="tab-pane active" aria-labelledby="tabset-4-1-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb21" style="background: #f1f3f5;"><pre class="sourceCode markdown code-with-copy"><code class="sourceCode markdown"><span id="cb21-1"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```{ojs}</span></span>
<span id="cb21-2">query <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM documentation_logement WHERE CONTAINS(description_variable, 'Catégorie')"</span></span>
<span id="cb21-3">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(</span>
<span id="cb21-4">    db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(query)</span>
<span id="cb21-5">)</span>
<span id="cb21-6"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```</span></span></code></pre></div></div>
</div>
<div id="tabset-4-2" class="tab-pane" aria-labelledby="tabset-4-2-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb22" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb22-1">query <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM documentation_logement WHERE CONTAINS(description_variable, 'Catégorie')"</span></span>
<span id="cb22-2">duckdb.sql(query)</span></code></pre></div></div>
</div>
<div id="tabset-4-3" class="tab-pane" aria-labelledby="tabset-4-3-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb23" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb23-1">query <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM documentation_logement WHERE CONTAINS(description_variable, 'Catégorie')"</span></span>
<span id="cb23-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbGetQuery</span>(con, query)</span></code></pre></div></div>
</div>
<div id="tabset-4-4" class="tab-pane" aria-labelledby="tabset-4-4-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb24" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb24-1">documentation_logement <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb24-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_detect</span>(description_variable, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"catégorie"</span>))</span></code></pre></div></div>
</div>
</div>
</div>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb25" data-startfrom="350" data-source-offset="-0" style="background: #f1f3f5;"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 349;"><span id="cb25-350">query <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM documentation_logement WHERE CONTAINS(description_variable, 'Catégorie')"</span></span>
<span id="cb25-351">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(</span>
<span id="cb25-352">    db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(query)</span>
<span id="cb25-353">)</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div>
<div id="ojs-cell-10-1" data-nodetype="declaration">

</div>
</div>
</div>
<div class="cell-output cell-output-display">
<div>
<div id="ojs-cell-10-2" data-nodetype="expression">

</div>
</div>
</div>
</div>
<p>Cette approche peut permettre de récupérer les modalités d’une variable. Dans cette base de données, les valeurs <code>Z</code> sont à part. Il est possible d’avoir du détail sur celles-ci avec la requête suivante :</p>
<div class="tabset-margin-container"></div><div class="panel-tabset" data-group="language">
<ul class="nav nav-tabs"><li class="nav-item"><a class="nav-link active" id="tabset-5-1-tab" data-bs-toggle="tab" data-bs-target="#tabset-5-1" aria-controls="tabset-5-1" aria-selected="true" href=""><code>Observable</code> via <code>Quarto</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-5-2-tab" data-bs-toggle="tab" data-bs-target="#tabset-5-2" aria-controls="tabset-5-2" aria-selected="false" href=""><code>Python</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-5-3-tab" data-bs-toggle="tab" data-bs-target="#tabset-5-3" aria-controls="tabset-5-3" aria-selected="false" href=""><code>R</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-5-4-tab" data-bs-toggle="tab" data-bs-target="#tabset-5-4" aria-controls="tabset-5-4" aria-selected="false" href=""><code>R (dbplyr)</code></a></li></ul>
<div class="tab-content" data-group="language">
<div id="tabset-5-1" class="tab-pane active" aria-labelledby="tabset-5-1-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb26" style="background: #f1f3f5;"><pre class="sourceCode markdown code-with-copy"><code class="sourceCode markdown"><span id="cb26-1"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```{ojs}</span></span>
<span id="cb26-2">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(</span>
<span id="cb26-3">  db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(</span>
<span id="cb26-4">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM documentation_indiv WHERE CONTAINS(code_modalite, 'Z')"</span></span>
<span id="cb26-5">  )<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb26-6">  {</span>
<span id="cb26-7">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">columns</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> [</span>
<span id="cb26-8">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"nom_variable"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"code_modalite"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb26-9">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"description_modalite"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"description_variable"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb26-10">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"type_variable"</span></span>
<span id="cb26-11">      ]</span>
<span id="cb26-12">  }</span>
<span id="cb26-13">)</span>
<span id="cb26-14"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```</span></span></code></pre></div></div>
</div>
<div id="tabset-5-2" class="tab-pane" aria-labelledby="tabset-5-2-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb27" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb27-1">duckdb.sql(</span>
<span id="cb27-2">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM documentation_indiv WHERE CONTAINS(code_modalite, 'Z')"</span></span>
<span id="cb27-3">)</span></code></pre></div></div>
</div>
<div id="tabset-5-3" class="tab-pane" aria-labelledby="tabset-5-3-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb28" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb28-1">query <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM documentation_indiv WHERE CONTAINS(code_modalite, 'Z')"</span></span>
<span id="cb28-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbGetQuery</span>(con, query)</span></code></pre></div></div>
</div>
<div id="tabset-5-4" class="tab-pane" aria-labelledby="tabset-5-4-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb29" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb29-1">documentation_indiv <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb29-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_detect</span>(code_modalite, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Z"</span>))</span></code></pre></div></div>
</div>
</div>
</div>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb30" data-startfrom="396" data-source-offset="0" style="background: #f1f3f5;"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 395;"><span id="cb30-396">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(</span>
<span id="cb30-397">  db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(</span>
<span id="cb30-398">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM documentation_indiv WHERE CONTAINS(code_modalite, 'Z')"</span></span>
<span id="cb30-399">  )<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb30-400">  {</span>
<span id="cb30-401">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">columns</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> [</span>
<span id="cb30-402">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"nom_variable"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"code_modalite"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb30-403">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"description_modalite"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"description_variable"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb30-404">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"type_variable"</span></span>
<span id="cb30-405">      ]</span>
<span id="cb30-406">  }</span>
<span id="cb30-407">)</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div id="ojs-cell-11" data-nodetype="expression">

</div>
</div>
</div>
</section>
<section id="lecture-et-affichage-de-quelques-valeurs" class="level1">
<h1>Lecture et affichage de quelques valeurs</h1>
<p>Pour visualiser un nombre limité de valeurs, par exemple 5, deux approches sont possibles :</p>
<ul>
<li>Sélectionner un échantillon restreint sur les premières lignes du <code>Parquet</code>, par exemple les 5 premières lignes ;</li>
<li>Sélectionner un échantillon aléatoire.</li>
</ul>
<p>Pour les premières lignes, la commande à utiliser est <code>LIMIT</code>.</p>
<div class="tabset-margin-container"></div><div class="panel-tabset" data-group="language">
<ul class="nav nav-tabs"><li class="nav-item"><a class="nav-link active" id="tabset-6-1-tab" data-bs-toggle="tab" data-bs-target="#tabset-6-1" aria-controls="tabset-6-1" aria-selected="true" href=""><code>Observable</code> via <code>Quarto</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-6-2-tab" data-bs-toggle="tab" data-bs-target="#tabset-6-2" aria-controls="tabset-6-2" aria-selected="false" href=""><code>Python</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-6-3-tab" data-bs-toggle="tab" data-bs-target="#tabset-6-3" aria-controls="tabset-6-3" aria-selected="false" href=""><code>R</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-6-4-tab" data-bs-toggle="tab" data-bs-target="#tabset-6-4" aria-controls="tabset-6-4" aria-selected="false" href=""><code>R (dbplyr)</code></a></li></ul>
<div class="tab-content" data-group="language">
<div id="tabset-6-1" class="tab-pane active" aria-labelledby="tabset-6-1-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb31" style="background: #f1f3f5;"><pre class="sourceCode markdown code-with-copy"><code class="sourceCode markdown"><span id="cb31-1"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```{ojs}</span></span>
<span id="cb31-2">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(</span>
<span id="cb31-3">    db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM table_logement LIMIT 5"</span>)</span>
<span id="cb31-4">)</span>
<span id="cb31-5"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```</span></span></code></pre></div></div>
</div>
<div id="tabset-6-2" class="tab-pane" aria-labelledby="tabset-6-2-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb32" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb32-1">duckdb.sql(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM table_logement LIMIT 5"</span>)</span></code></pre></div></div>
</div>
<div id="tabset-6-3" class="tab-pane" aria-labelledby="tabset-6-3-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb33" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb33-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbGetQuery</span>(</span>
<span id="cb33-2">  con,</span>
<span id="cb33-3">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM table_logement LIMIT 5"</span></span>
<span id="cb33-4">)</span></code></pre></div></div>
</div>
<div id="tabset-6-4" class="tab-pane" aria-labelledby="tabset-6-4-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb34" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb34-1">table_logement <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">head</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>)</span></code></pre></div></div>
</div>
</div>
</div>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb35" data-startfrom="405" data-source-offset="0" style="background: #f1f3f5;"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 404;"><span id="cb35-405">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(</span>
<span id="cb35-406">    db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM table_logement LIMIT 5"</span>)</span>
<span id="cb35-407">)</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div id="ojs-cell-12" data-nodetype="expression">

</div>
</div>
</div>
<p>Pour un échantillon aléatoire, la commande à utiliser est <code>USING SAMPLE</code>.</p>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb36" data-startfrom="434" data-source-offset="0" style="background: #f1f3f5;"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 433;"><span id="cb36-434">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(</span>
<span id="cb36-435">    db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM table_logement USIN SAMPLE 5"</span>)</span>
<span id="cb36-436">)</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div id="ojs-cell-13" data-nodetype="expression">

</div>
</div>
</div>
<div class="tabset-margin-container"></div><div class="panel-tabset" data-group="language">
<ul class="nav nav-tabs"><li class="nav-item"><a class="nav-link active" id="tabset-7-1-tab" data-bs-toggle="tab" data-bs-target="#tabset-7-1" aria-controls="tabset-7-1" aria-selected="true" href=""><code>Observable</code> via <code>Quarto</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-7-2-tab" data-bs-toggle="tab" data-bs-target="#tabset-7-2" aria-controls="tabset-7-2" aria-selected="false" href=""><code>Python</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-7-3-tab" data-bs-toggle="tab" data-bs-target="#tabset-7-3" aria-controls="tabset-7-3" aria-selected="false" href=""><code>R</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-7-4-tab" data-bs-toggle="tab" data-bs-target="#tabset-7-4" aria-controls="tabset-7-4" aria-selected="false" href=""><code>R (dbplyr)</code></a></li></ul>
<div class="tab-content" data-group="language">
<div id="tabset-7-1" class="tab-pane active" aria-labelledby="tabset-7-1-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb37" style="background: #f1f3f5;"><pre class="sourceCode markdown code-with-copy"><code class="sourceCode markdown"><span id="cb37-1"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```{ojs}</span></span>
<span id="cb37-2">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(</span>
<span id="cb37-3">    db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM table_logement USING SAMPLE 5"</span>)</span>
<span id="cb37-4">)</span>
<span id="cb37-5"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```</span></span></code></pre></div></div>
</div>
<div id="tabset-7-2" class="tab-pane" aria-labelledby="tabset-7-2-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb38" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb38-1">duckdb.sql(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM table_logement USING SAMPLE 5"</span>)</span></code></pre></div></div>
</div>
<div id="tabset-7-3" class="tab-pane" aria-labelledby="tabset-7-3-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb39" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb39-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbGetQuery</span>(</span>
<span id="cb39-2">  con,</span>
<span id="cb39-3">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM table_logement USING SAMPLE 5"</span></span>
<span id="cb39-4">)</span></code></pre></div></div>
</div>
<div id="tabset-7-4" class="tab-pane" aria-labelledby="tabset-7-4-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb40" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb40-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tbl</span>(con, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sql</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM table_logement USING SAMPLE 5"</span>))</span></code></pre></div></div>
</div>
</div>
</div>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb41" data-startfrom="469" data-source-offset="0" style="background: #f1f3f5;"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 468;"><span id="cb41-469">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(</span>
<span id="cb41-470">    db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM table_logement USING SAMPLE 5"</span>)</span>
<span id="cb41-471">)</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div id="ojs-cell-14" data-nodetype="expression">

</div>
</div>
</div>
</section>
<section id="sélectionner-des-observations-ou-des-variables" class="level1">
<h1>Sélectionner des observations ou des variables</h1>
<section id="requêtes-sur-les-colonnes-select" class="level2">
<h2 class="anchored" data-anchor-id="requêtes-sur-les-colonnes-select">Requêtes sur les colonnes (<code>SELECT</code>)</h2>
<p>La liste des colonnes à extraire du fichier peut être renseignée avec la clause <code>SELECT</code>. Celles-ci peuvent être renommées en appliquant au passage la clause <code>AS</code>.</p>
<div class="tabset-margin-container"></div><div class="panel-tabset" data-group="language">
<ul class="nav nav-tabs"><li class="nav-item"><a class="nav-link active" id="tabset-8-1-tab" data-bs-toggle="tab" data-bs-target="#tabset-8-1" aria-controls="tabset-8-1" aria-selected="true" href=""><code>Observable</code> via <code>Quarto</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-8-2-tab" data-bs-toggle="tab" data-bs-target="#tabset-8-2" aria-controls="tabset-8-2" aria-selected="false" href=""><code>Python</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-8-3-tab" data-bs-toggle="tab" data-bs-target="#tabset-8-3" aria-controls="tabset-8-3" aria-selected="false" href=""><code>R</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-8-4-tab" data-bs-toggle="tab" data-bs-target="#tabset-8-4" aria-controls="tabset-8-4" aria-selected="false" href=""><code>R (dbplyr)</code></a></li></ul>
<div class="tab-content" data-group="language">
<div id="tabset-8-1" class="tab-pane active" aria-labelledby="tabset-8-1-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb42" style="background: #f1f3f5;"><pre class="sourceCode markdown code-with-copy"><code class="sourceCode markdown"><span id="cb42-1"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```{ojs}</span></span>
<span id="cb42-2">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(</span>
<span id="cb42-3">    db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT IPONDI AS poids, AGED, VOIT FROM table_individu LIMIT 10"</span>)</span>
<span id="cb42-4">)</span>
<span id="cb42-5"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```</span></span></code></pre></div></div>
</div>
<div id="tabset-8-2" class="tab-pane" aria-labelledby="tabset-8-2-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb43" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb43-1">duckdb.sql(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT IPONDI AS poids, AGED, VOIT FROM table_individu LIMIT 10"</span>)</span></code></pre></div></div>
</div>
<div id="tabset-8-3" class="tab-pane" aria-labelledby="tabset-8-3-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb44" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb44-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbGetQuery</span>(</span>
<span id="cb44-2">  con,</span>
<span id="cb44-3">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT IPONDI AS poids, AGED, VOIT FROM table_individu LIMIT 10"</span></span>
<span id="cb44-4">)</span></code></pre></div></div>
</div>
<div id="tabset-8-4" class="tab-pane" aria-labelledby="tabset-8-4-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb45" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb45-1">table_individu <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb45-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">poids =</span> IPONDI, AGED, VOIT) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb45-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">head</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>)</span></code></pre></div></div>
</div>
</div>
</div>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb46" data-startfrom="501" data-source-offset="0" style="background: #f1f3f5;"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 500;"><span id="cb46-501">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(</span>
<span id="cb46-502">    db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT IPONDI AS poids, AGED, VOIT FROM table_individu LIMIT 10"</span>)</span>
<span id="cb46-503">)</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div id="ojs-cell-15" data-nodetype="expression">

</div>
</div>
</div>
<p><code>DuckDB</code> propose également des fonctionnalités pour extraire des colonnes à travers des <a href="https://fr.wikipedia.org/wiki/Expression_r%C3%A9guli%C3%A8re">expressions régulières</a>. De nombreux exemples peuvent être trouvés sur <a href="https://duckdb.org/2023/08/23/even-friendlier-sql.html">cette page</a>.</p>
<div class="tabset-margin-container"></div><div class="panel-tabset" data-group="language">
<ul class="nav nav-tabs"><li class="nav-item"><a class="nav-link active" id="tabset-9-1-tab" data-bs-toggle="tab" data-bs-target="#tabset-9-1" aria-controls="tabset-9-1" aria-selected="true" href=""><code>Observable</code> via <code>Quarto</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-9-2-tab" data-bs-toggle="tab" data-bs-target="#tabset-9-2" aria-controls="tabset-9-2" aria-selected="false" href=""><code>Python</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-9-3-tab" data-bs-toggle="tab" data-bs-target="#tabset-9-3" aria-controls="tabset-9-3" aria-selected="false" href=""><code>R</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-9-4-tab" data-bs-toggle="tab" data-bs-target="#tabset-9-4" aria-controls="tabset-9-4" aria-selected="false" href=""><code>R (dbplyr)</code></a></li></ul>
<div class="tab-content" data-group="language">
<div id="tabset-9-1" class="tab-pane active" aria-labelledby="tabset-9-1-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb47" style="background: #f1f3f5;"><pre class="sourceCode markdown code-with-copy"><code class="sourceCode markdown"><span id="cb47-1"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```{ojs}</span></span>
<span id="cb47-2">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(</span>
<span id="cb47-3">    db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT IPONDI AS poids, COLUMNS('.*AGE.*') FROM table_individu LIMIT 10"</span>)</span>
<span id="cb47-4">)</span>
<span id="cb47-5"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```</span></span></code></pre></div></div>
</div>
<div id="tabset-9-2" class="tab-pane" aria-labelledby="tabset-9-2-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb48" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb48-1">duckdb.sql(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT IPONDI AS poids, COLUMNS('.*AGE.*') FROM table_individu LIMIT 10"</span>)</span></code></pre></div></div>
</div>
<div id="tabset-9-3" class="tab-pane" aria-labelledby="tabset-9-3-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb49" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb49-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbGetQuery</span>(</span>
<span id="cb49-2">  con,</span>
<span id="cb49-3">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT IPONDI AS poids, COLUMNS('.*AGE.*') FROM table_individu LIMIT 10"</span></span>
<span id="cb49-4">)</span></code></pre></div></div>
</div>
<div id="tabset-9-4" class="tab-pane" aria-labelledby="tabset-9-4-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb50" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb50-1">table_individu <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb50-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">poids =</span> IPONDI, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">contains</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"AGE"</span>)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb50-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">head</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>)</span></code></pre></div></div>
</div>
</div>
</div>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb51" data-startfrom="539" data-source-offset="0" style="background: #f1f3f5;"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 538;"><span id="cb51-539">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(</span>
<span id="cb51-540">    db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT IPONDI AS poids, COLUMNS('.*AGE.*') FROM table_individu LIMIT 10"</span>)</span>
<span id="cb51-541">)</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div id="ojs-cell-16" data-nodetype="expression">

</div>
</div>
</div>
</section>
<section id="requêtes-sur-les-lignes-where" class="level2">
<h2 class="anchored" data-anchor-id="requêtes-sur-les-lignes-where">Requêtes sur les lignes (<code>WHERE</code>)</h2>
<p>Pour extraire un sous-échantillon des données complètes, la clause <code>WHERE</code> permet d’appliquer des filtres à partir de conditions logiques. Par exemple, il est possible de ne conserver, du fichier national, que les données de l’Aude (11), de la Haute-Garonne (31) et de l’Hérault (34).</p>
<div class="tabset-margin-container"></div><div class="panel-tabset" data-group="language">
<ul class="nav nav-tabs"><li class="nav-item"><a class="nav-link active" id="tabset-10-1-tab" data-bs-toggle="tab" data-bs-target="#tabset-10-1" aria-controls="tabset-10-1" aria-selected="true" href=""><code>Observable</code> via <code>Quarto</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-10-2-tab" data-bs-toggle="tab" data-bs-target="#tabset-10-2" aria-controls="tabset-10-2" aria-selected="false" href=""><code>Python</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-10-3-tab" data-bs-toggle="tab" data-bs-target="#tabset-10-3" aria-controls="tabset-10-3" aria-selected="false" href=""><code>R</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-10-4-tab" data-bs-toggle="tab" data-bs-target="#tabset-10-4" aria-controls="tabset-10-4" aria-selected="false" href=""><code>R (dbplyr)</code></a></li></ul>
<div class="tab-content" data-group="language">
<div id="tabset-10-1" class="tab-pane active" aria-labelledby="tabset-10-1-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb52" style="background: #f1f3f5;"><pre class="sourceCode markdown code-with-copy"><code class="sourceCode markdown"><span id="cb52-1"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```{ojs}</span></span>
<span id="cb52-2">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(</span>
<span id="cb52-3">    db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM table_individu WHERE DEPT IN ('11', '31', '34') LIMIT 10"</span>)</span>
<span id="cb52-4">)</span>
<span id="cb52-5"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```</span></span></code></pre></div></div>
</div>
<div id="tabset-10-2" class="tab-pane" aria-labelledby="tabset-10-2-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb53" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb53-1">duckdb.sql(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM table_individu WHERE DEPT IN ('11', '31', '34')"</span>)</span></code></pre></div></div>
</div>
<div id="tabset-10-3" class="tab-pane" aria-labelledby="tabset-10-3-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb54" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb54-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbGetQuery</span>(</span>
<span id="cb54-2">  con,</span>
<span id="cb54-3">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM table_individu WHERE DEPT IN ('11', '31', '34')"</span></span>
<span id="cb54-4">)</span></code></pre></div></div>
</div>
<div id="tabset-10-4" class="tab-pane" aria-labelledby="tabset-10-4-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb55" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb55-1">table_individu <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb55-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(DEPT <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%in%</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"11"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"31"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"34"</span>)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb55-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">head</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>)</span></code></pre></div></div>
</div>
</div>
</div>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb56" data-startfrom="572" data-source-offset="0" style="background: #f1f3f5;"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 571;"><span id="cb56-572">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(</span>
<span id="cb56-573">    db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM table_individu WHERE DEPT IN ('11', '31', '34') LIMIT 10"</span>)</span>
<span id="cb56-574">)</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div id="ojs-cell-17" data-nodetype="expression">

</div>
</div>
</div>
<p>Il est également possible de formater cette liste telle qu’attendue par SQL à partir d’une liste <code>Python</code> ou d’un vecteur <code>R</code> plus classique. Pour cela, le code suivant peut servir de modèle :</p>
<div class="tabset-margin-container"></div><div class="panel-tabset" data-group="language">
<ul class="nav nav-tabs"><li class="nav-item"><a class="nav-link active" id="tabset-11-1-tab" data-bs-toggle="tab" data-bs-target="#tabset-11-1" aria-controls="tabset-11-1" aria-selected="true" href=""><code>Observable</code> via <code>Quarto</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-11-2-tab" data-bs-toggle="tab" data-bs-target="#tabset-11-2" aria-controls="tabset-11-2" aria-selected="false" href=""><code>Python</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-11-3-tab" data-bs-toggle="tab" data-bs-target="#tabset-11-3" aria-controls="tabset-11-3" aria-selected="false" href=""><code>R</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-11-4-tab" data-bs-toggle="tab" data-bs-target="#tabset-11-4" aria-controls="tabset-11-4" aria-selected="false" href=""><code>R (dbplyr)</code></a></li></ul>
<div class="tab-content" data-group="language">
<div id="tabset-11-1" class="tab-pane active" aria-labelledby="tabset-11-1-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb57" style="background: #f1f3f5;"><pre class="sourceCode markdown code-with-copy"><code class="sourceCode markdown"><span id="cb57-1"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```{ojs}</span></span>
<span id="cb57-2">liste_regions <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"11"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"31"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"34"</span>]</span>
<span id="cb57-3">liste_regions_sql <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> liste_regions<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">map</span>(item <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=&gt;</span> <span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">${</span>item<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">'`</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">join</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">","</span>)</span>
<span id="cb57-4">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(</span>
<span id="cb57-5">    db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(<span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`SELECT * FROM table_individu WHERE DEPT IN (</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">${</span>liste_regions_sql<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">) LIMIT 10`</span>)</span>
<span id="cb57-6">)</span>
<span id="cb57-7"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```</span></span></code></pre></div></div>
</div>
<div id="tabset-11-2" class="tab-pane" aria-labelledby="tabset-11-2-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb58" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb58-1">con <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> duckdb.<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">connect</span>()</span>
<span id="cb58-2"></span>
<span id="cb58-3">con.execute(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'''</span></span>
<span id="cb58-4"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  CREATE OR REPLACE VIEW table_individu</span></span>
<span id="cb58-5"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  AS SELECT * FROM read_parquet("FD_INDCVI_2020.parquet")</span></span>
<span id="cb58-6"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'''</span></span>
<span id="cb58-7">)</span>
<span id="cb58-8"></span>
<span id="cb58-9">liste_regions <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"11"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"31"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"34"</span>]</span>
<span id="cb58-10"></span>
<span id="cb58-11">dep_slots <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">", "</span>.join([<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"?"</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> _ <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> liste_regions])</span>
<span id="cb58-12">query <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM table_individu WHERE DEPT IN (</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">)"</span>.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">format</span>(dep_slots)</span>
<span id="cb58-13">liste_regions_sql <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">", "</span>.join([<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>dep<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">'"</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> dep <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> liste_regions])</span>
<span id="cb58-14">con.execute(query, liste_regions).fetchdf()</span></code></pre></div></div>
</div>
<div id="tabset-11-3" class="tab-pane" aria-labelledby="tabset-11-3-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb59" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb59-1">liste_regions <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"11"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"31"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"34"</span>)</span>
<span id="cb59-2">liste_regions_sql <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">glue_sql_collapse</span>(</span>
<span id="cb59-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">lapply</span>(</span>
<span id="cb59-4">    liste_regions, <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(dep) <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">glue_sql</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"'{`dep`}'"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.con=</span>con)</span>
<span id="cb59-5">    ),</span>
<span id="cb59-6">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">", "</span></span>
<span id="cb59-7">)</span>
<span id="cb59-8">query <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">glue_sql</span>(</span>
<span id="cb59-9">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM table_individu WHERE DEPT IN ({liste_regions_sql})"</span>,</span>
<span id="cb59-10">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.con=</span>con</span>
<span id="cb59-11">)</span>
<span id="cb59-12"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbGetQuery</span>(con, query)</span></code></pre></div></div>
</div>
<div id="tabset-11-4" class="tab-pane" aria-labelledby="tabset-11-4-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb60" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb60-1">liste_regions <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"11"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"31"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"34"</span>)</span>
<span id="cb60-2">table_individu <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb60-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(DEPT <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%in%</span> liste_regions)</span></code></pre></div></div>
</div>
</div>
</div>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb61" data-startfrom="614" data-source-offset="-0" style="background: #f1f3f5;"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 613;"><span id="cb61-614">liste_regions <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"11"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"31"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"34"</span>]</span>
<span id="cb61-615">liste_regions_sql <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> liste_regions<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">map</span>(item <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=&gt;</span> <span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">${</span>item<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">'`</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">join</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">","</span>)</span>
<span id="cb61-616">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(</span>
<span id="cb61-617">    db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(<span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`SELECT * FROM table_individu WHERE DEPT IN (</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">${</span>liste_regions_sql<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">) LIMIT 10`</span>)</span>
<span id="cb61-618">)</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div>
<div id="ojs-cell-18-1" data-nodetype="declaration">

</div>
</div>
</div>
<div class="cell-output cell-output-display">
<div>
<div id="ojs-cell-18-2" data-nodetype="declaration">

</div>
</div>
</div>
<div class="cell-output cell-output-display">
<div>
<div id="ojs-cell-18-3" data-nodetype="expression">

</div>
</div>
</div>
</div>
<p>Pour en savoir plus sur les <em>prepared statements</em> avec DuckDB en Python, et plus généralement pour avoir des exemples d’utilisations différentes, c’est <a href="https://duckdb.org/docs/api/python/dbapi.html">ici</a> que ça se passe.</p>
<p><br></p>
<p>Les filtres sur les observations peuvent être faits à partir de critères sur plusieurs colonnes. Par exemple, pour ne conserver que les observations de la ville de Nice où la date d’emménagement est postérieure à 2020, la requête suivante peut être utilisée :</p>
<div class="tabset-margin-container"></div><div class="panel-tabset" data-group="language">
<ul class="nav nav-tabs"><li class="nav-item"><a class="nav-link active" id="tabset-12-1-tab" data-bs-toggle="tab" data-bs-target="#tabset-12-1" aria-controls="tabset-12-1" aria-selected="true" href=""><code>Observable</code> via <code>Quarto</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-12-2-tab" data-bs-toggle="tab" data-bs-target="#tabset-12-2" aria-controls="tabset-12-2" aria-selected="false" href=""><code>Python</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-12-3-tab" data-bs-toggle="tab" data-bs-target="#tabset-12-3" aria-controls="tabset-12-3" aria-selected="false" href=""><code>R</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-12-4-tab" data-bs-toggle="tab" data-bs-target="#tabset-12-4" aria-controls="tabset-12-4" aria-selected="false" href=""><code>R (dbplyr)</code></a></li></ul>
<div class="tab-content" data-group="language">
<div id="tabset-12-1" class="tab-pane active" aria-labelledby="tabset-12-1-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb62" style="background: #f1f3f5;"><pre class="sourceCode markdown code-with-copy"><code class="sourceCode markdown"><span id="cb62-1"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```{ojs}</span></span>
<span id="cb62-2">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(</span>
<span id="cb62-3">    db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(</span>
<span id="cb62-4">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM table_logement WHERE COMMUNE = '06088' and AEMM &gt; 2020"</span></span>
<span id="cb62-5">    )</span>
<span id="cb62-6">)</span>
<span id="cb62-7"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```</span></span></code></pre></div></div>
</div>
<div id="tabset-12-2" class="tab-pane" aria-labelledby="tabset-12-2-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb63" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb63-1">query <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM table_logement WHERE COMMUNE = '06088' and AEMM &gt; 2020"</span></span>
<span id="cb63-2">duckdb.sql(query)</span></code></pre></div></div>
</div>
<div id="tabset-12-3" class="tab-pane" aria-labelledby="tabset-12-3-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb64" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb64-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbGetQuery</span>(</span>
<span id="cb64-2">  con,</span>
<span id="cb64-3">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM table_logement WHERE COMMUNE = '06088' and AEMM &gt; 2020"</span></span>
<span id="cb64-4">)</span></code></pre></div></div>
</div>
<div id="tabset-12-4" class="tab-pane" aria-labelledby="tabset-12-4-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb65" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb65-1">table_logement <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb65-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(COMMUNE <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"06088"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb65-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(AEMM <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2020</span>)</span>
<span id="cb65-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Peut aussi s'écrire en une fois :</span></span>
<span id="cb65-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># table_logement %&gt;% filter(COMMUNE == "06088", AEMM &gt; 2020)</span></span></code></pre></div></div>
</div>
</div>
</div>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb66" data-startfrom="668" data-source-offset="0" style="background: #f1f3f5;"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 667;"><span id="cb66-668">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(</span>
<span id="cb66-669">    db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(</span>
<span id="cb66-670">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM table_logement WHERE COMMUNE = '06088' and AEMM &gt; 2020"</span></span>
<span id="cb66-671">    )</span>
<span id="cb66-672">)</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div id="ojs-cell-19" data-nodetype="expression">

</div>
</div>
</div>
</section>
</section>
<section id="statistiques-agrégées" class="level1">
<h1>Statistiques agrégées</h1>
<p>Le langage <code>SQL</code> permet d’exécuter de manière très efficace des requêtes complexes afin de construire, à partir de données fines, des statistiques agrégées.</p>
<p>Cette partie illustre d’abord ceci avec deux exemples de statistiques agrégées renvoyant une unique statistique :</p>
<ul>
<li>Extraire la liste des codes arrondissements de Paris, Lyon, Marseille où au moins une personne a été recensée ;</li>
<li>Reproduire l’exemple de <span class="citation" data-cites="mauviere-2022">Mauvière (2022)</span> permettant de calculer le nombre d’habitants de Toulouse qui ont changé de logement en un an ;</li>
</ul>
<p>Ensuite, des statistiques plus fines sont construites par le biais d’agrégations par groupe :</p>
<ul>
<li>Calculer le nombre de personnes recensées par cohorte pour les départements de l’Aude (11), de la Haute-Garonne (31) et de l’Hérault (34) ;</li>
<li>Calculer le nombre de centenaires recensés par département.</li>
</ul>
<p>La fonction <code>DISTINCT</code> appliquée à la variable <code>ARM</code> permet d’extraire la liste des codes arrondissements présents dans la base de données.</p>
<div class="tabset-margin-container"></div><div class="panel-tabset" data-group="language">
<ul class="nav nav-tabs"><li class="nav-item"><a class="nav-link active" id="tabset-13-1-tab" data-bs-toggle="tab" data-bs-target="#tabset-13-1" aria-controls="tabset-13-1" aria-selected="true" href=""><code>Observable</code> via <code>Quarto</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-13-2-tab" data-bs-toggle="tab" data-bs-target="#tabset-13-2" aria-controls="tabset-13-2" aria-selected="false" href=""><code>Python</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-13-3-tab" data-bs-toggle="tab" data-bs-target="#tabset-13-3" aria-controls="tabset-13-3" aria-selected="false" href=""><code>R</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-13-4-tab" data-bs-toggle="tab" data-bs-target="#tabset-13-4" aria-controls="tabset-13-4" aria-selected="false" href=""><code>R (dbplyr)</code></a></li></ul>
<div class="tab-content" data-group="language">
<div id="tabset-13-1" class="tab-pane active" aria-labelledby="tabset-13-1-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb67" style="background: #f1f3f5;"><pre class="sourceCode markdown code-with-copy"><code class="sourceCode markdown"><span id="cb67-1"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```{ojs}</span></span>
<span id="cb67-2">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(</span>
<span id="cb67-3">    db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(</span>
<span id="cb67-4">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT DISTINCT(ARM) FROM table_logement WHERE NOT CONTAINS(ARM, 'ZZZZZ') ORDER BY ARM"</span></span>
<span id="cb67-5">    )</span>
<span id="cb67-6">)</span>
<span id="cb67-7"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```</span></span></code></pre></div></div>
</div>
<div id="tabset-13-2" class="tab-pane" aria-labelledby="tabset-13-2-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb68" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb68-1">query <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT DISTINCT(ARM) "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+\</span></span>
<span id="cb68-2">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"FROM table_logement "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+\</span></span>
<span id="cb68-3">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"WHERE NOT CONTAINS(ARM, 'ZZZZZ') "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+\</span></span>
<span id="cb68-4">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ORDER BY ARM"</span></span>
<span id="cb68-5">duckdb.sql(query)</span></code></pre></div></div>
</div>
<div id="tabset-13-3" class="tab-pane" aria-labelledby="tabset-13-3-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb69" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb69-1">query <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">glue_sql</span>(</span>
<span id="cb69-2">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT DISTINCT(ARM) "</span>,</span>
<span id="cb69-3">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"FROM table_logement "</span>,</span>
<span id="cb69-4">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"WHERE NOT CONTAINS(ARM, 'ZZZZZ') "</span>,</span>
<span id="cb69-5">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ORDER BY ARM"</span>,</span>
<span id="cb69-6">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.con=</span>con</span>
<span id="cb69-7">)</span>
<span id="cb69-8"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbGetQuery</span>(con, query)</span></code></pre></div></div>
</div>
<div id="tabset-13-4" class="tab-pane" aria-labelledby="tabset-13-4-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb70" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb70-1">table_logement <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb70-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_detect</span>(ARM, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ZZZZZ"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">negate =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span>)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb70-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">ARM =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">distinct</span>(ARM)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb70-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">arrange</span>(ARM)</span></code></pre></div></div>
</div>
</div>
</div>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb71" data-startfrom="702" data-source-offset="0" style="background: #f1f3f5;"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 701;"><span id="cb71-702">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(</span>
<span id="cb71-703">    db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(</span>
<span id="cb71-704">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT DISTINCT(ARM) FROM table_logement WHERE NOT CONTAINS(ARM, 'ZZZZZ') ORDER BY ARM"</span></span>
<span id="cb71-705">    )</span>
<span id="cb71-706">)</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div id="ojs-cell-20" data-nodetype="expression">

</div>
</div>
</div>
<p>Il est possible d’extraire des statistiques beaucoup plus raffinées par le biais d’une requête SQL plus complexe. Par exemple pour calculer le nombre d’habitants de Toulouse qui ont changé de logement en un an:</p>
<div class="tabset-margin-container"></div><div class="panel-tabset" data-group="language">
<ul class="nav nav-tabs"><li class="nav-item"><a class="nav-link active" id="tabset-14-1-tab" data-bs-toggle="tab" data-bs-target="#tabset-14-1" aria-controls="tabset-14-1" aria-selected="true" href=""><code>Observable</code> via <code>Quarto</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-14-2-tab" data-bs-toggle="tab" data-bs-target="#tabset-14-2" aria-controls="tabset-14-2" aria-selected="false" href=""><code>Python</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-14-3-tab" data-bs-toggle="tab" data-bs-target="#tabset-14-3" aria-controls="tabset-14-3" aria-selected="false" href=""><code>R</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-14-4-tab" data-bs-toggle="tab" data-bs-target="#tabset-14-4" aria-controls="tabset-14-4" aria-selected="false" href=""><code>R (dbplyr)</code></a></li></ul>
<div class="tab-content" data-group="language">
<div id="tabset-14-1" class="tab-pane active" aria-labelledby="tabset-14-1-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb72" style="background: #f1f3f5;"><pre class="sourceCode markdown code-with-copy"><code class="sourceCode markdown"><span id="cb72-1"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```{ojs}</span></span>
<span id="cb72-2">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(</span>
<span id="cb72-3">  db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(</span>
<span id="cb72-4">    <span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span></span>
<span id="cb72-5"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    SELECT CAST(</span></span>
<span id="cb72-6"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">      SUM(IPONDL*CAST(INPER AS INT)) AS INT</span></span>
<span id="cb72-7"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    ) AS habitants_toulouse_demenagement</span></span>
<span id="cb72-8"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    FROM table_logement</span></span>
<span id="cb72-9"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    WHERE COMMUNE == '31555' AND IRANM NOT IN ('1', 'Z') AND INPER != 'Y'</span></span>
<span id="cb72-10"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    `</span></span>
<span id="cb72-11">  )</span>
<span id="cb72-12">)</span>
<span id="cb72-13"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```</span></span></code></pre></div></div>
</div>
<div id="tabset-14-2" class="tab-pane" aria-labelledby="tabset-14-2-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb73" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb73-1">query <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb73-2"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"""</span></span>
<span id="cb73-3"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">SELECT CAST(</span></span>
<span id="cb73-4"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  SUM(IPONDL*CAST(INPER AS INT)) AS INT</span></span>
<span id="cb73-5"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">) AS habitants_toulouse_demenagement</span></span>
<span id="cb73-6"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">FROM table_logement</span></span>
<span id="cb73-7"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">WHERE COMMUNE == '31555' AND IRANM NOT IN ('1', 'Z') AND INPER != 'Y'</span></span>
<span id="cb73-8"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"""</span></span>
<span id="cb73-9">duckdb.sql(query).df()</span></code></pre></div></div>
</div>
<div id="tabset-14-3" class="tab-pane" aria-labelledby="tabset-14-3-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb74" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb74-1">query <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">paste</span>(</span>
<span id="cb74-2">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT CAST(SUM(IPONDL*CAST(INPER AS INT)) AS INT) "</span>,</span>
<span id="cb74-3">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"AS habitants_toulouse_demenagement"</span>,</span>
<span id="cb74-4">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"FROM table_logement"</span>,</span>
<span id="cb74-5">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"WHERE COMMUNE == '31555' AND IRANM NOT IN ('1', 'Z') AND INPER != 'Y'"</span>,</span>
<span id="cb74-6">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">sep =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">" "</span>)</span>
<span id="cb74-7"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbGetQuery</span>(con, query)</span></code></pre></div></div>
</div>
<div id="tabset-14-4" class="tab-pane" aria-labelledby="tabset-14-4-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb75" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb75-1">table_logement <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb75-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(COMMUNE <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'31555'</span>, <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!</span>IRANM <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%in%</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'1'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Z'</span>), INPER <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Y"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb75-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">INPER =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as.integer</span>(INPER)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb75-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">habitants_toulouse_demenagement =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as.integer</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sum</span>(IPONDL <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> INPER)))</span></code></pre></div></div>
</div>
</div>
</div>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb76" data-startfrom="757" data-source-offset="0" style="background: #f1f3f5;"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 756;"><span id="cb76-757">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(</span>
<span id="cb76-758">  db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(</span>
<span id="cb76-759">    <span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span></span>
<span id="cb76-760"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    SELECT CAST(</span></span>
<span id="cb76-761"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">      SUM(IPONDL*CAST(INPER AS INT)) AS INT</span></span>
<span id="cb76-762"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    ) AS habitants_toulouse_demenagement</span></span>
<span id="cb76-763"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    FROM table_logement</span></span>
<span id="cb76-764"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    WHERE COMMUNE == '31555' AND IRANM NOT IN ('1', 'Z') AND INPER != 'Y'</span></span>
<span id="cb76-765"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    `</span></span>
<span id="cb76-766">  )</span>
<span id="cb76-767">)</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div id="ojs-cell-21" data-nodetype="expression">

</div>
</div>
</div>
<p>Pour représenter la pyramide des âges recensés dans ces trois départements, il est possible de procéder en deux étapes</p>
<ul>
<li>Effectuer une agrégation par le biais de <code>DuckDB</code> et transformer ces résultats sous forme de <em>dataframe</em></li>
<li>Utiliser ce <em>dataframe</em> avec un <em>package</em> d’analyse graphique pour représenter la pyramide des âges.</li>
</ul>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>Pour illustrer le parallélisme possible entre les codes <code>R</code> et <code>Python</code>, l’exemple de représentation graphique ci-dessus s’appuie sur le <em>package</em> <code>plotnine</code> - dont la syntaxe reproduit celle du <em>package</em> <code>R</code> <code>ggplot2</code>, plutôt que sur <code>matplotlib</code> ou <code>seaborn</code>.</p>
</div>
</div>
<div class="tabset-margin-container"></div><div class="panel-tabset" data-group="language">
<ul class="nav nav-tabs"><li class="nav-item"><a class="nav-link active" id="tabset-15-1-tab" data-bs-toggle="tab" data-bs-target="#tabset-15-1" aria-controls="tabset-15-1" aria-selected="true" href=""><code>Observable</code> via <code>Quarto</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-15-2-tab" data-bs-toggle="tab" data-bs-target="#tabset-15-2" aria-controls="tabset-15-2" aria-selected="false" href=""><code>Python</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-15-3-tab" data-bs-toggle="tab" data-bs-target="#tabset-15-3" aria-controls="tabset-15-3" aria-selected="false" href=""><code>R</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-15-4-tab" data-bs-toggle="tab" data-bs-target="#tabset-15-4" aria-controls="tabset-15-4" aria-selected="false" href=""><code>R (dbplyr)</code></a></li></ul>
<div class="tab-content" data-group="language">
<div id="tabset-15-1" class="tab-pane active" aria-labelledby="tabset-15-1-tab">
<div class="callout callout-style-default callout-caution callout-titled">
<div class="callout-header d-flex align-content-center collapsed" data-bs-toggle="collapse" data-bs-target=".callout-4-contents" aria-controls="callout-4" aria-expanded="false" aria-label="Toggle callout">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
<span class="screen-reader-only">Mise en garde</span>Version de <code>Plot</code> embarquée dans <code>Quarto</code>
</div>
<div class="callout-btn-toggle d-inline-block border-0 py-1 ps-1 pe-0 float-end"><i class="callout-toggle"></i></div>
</div>
<div id="callout-4" class="callout-4-contents callout-collapse collapse">
<div class="callout-body-container callout-body">
<p>Pour les versions de <code>Quarto</code> antérieures à la v1.4, la version embarquée par défaut de la librairie <code>Plot</code> ne propose pas d’interactivité par le biais des <a href="https://observablehq.com/plot/marks/tip"><em>tooltips</em></a>.</p>
<p>Pour utiliser une version compatible, par exemple la <code>0.6.11</code>, faire:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb77" style="background: #f1f3f5;"><pre class="sourceCode markdown code-with-copy"><code class="sourceCode markdown"><span id="cb77-1"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```{ojs}</span></span>
<span id="cb77-2">Plot <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">require</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://cdn.jsdelivr.net/npm/@observablehq/plot@0.6.11/dist/plot.umd.min.js"</span>)</span>
<span id="cb77-3"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```</span></span></code></pre></div></div>
</div>
</div>
</div>
<details>
<summary>
Code pour structurer les données pour la représentation graphique.
</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb78" style="background: #f1f3f5;"><pre class="sourceCode markdown code-with-copy"><code class="sourceCode markdown"><span id="cb78-1"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```{ojs}</span></span>
<span id="cb78-2">pyramide_ages <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(</span>
<span id="cb78-3"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span></span>
<span id="cb78-4"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">SELECT</span></span>
<span id="cb78-5"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">  CAST(SUM(IPONDI) AS INT) AS individus,</span></span>
<span id="cb78-6"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">  CAST(AGED AS INT) AS AGED,</span></span>
<span id="cb78-7"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">  DEPT AS departement</span></span>
<span id="cb78-8"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">FROM table_individu</span></span>
<span id="cb78-9"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">  WHERE DEPT IN ('11', '31', '34')</span></span>
<span id="cb78-10"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">GROUP BY AGED, DEPT ORDER BY DEPT, AGED</span></span>
<span id="cb78-11"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span></span>
<span id="cb78-12">)</span>
<span id="cb78-13">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(pyramide_ages)</span>
<span id="cb78-14"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```</span></span></code></pre></div></div>
</details>
<details>
<summary>
Code pour produire la représentation graphique.
</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb79" style="background: #f1f3f5;"><pre class="sourceCode markdown code-with-copy"><code class="sourceCode markdown"><span id="cb79-1"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```{ojs}</span></span>
<span id="cb79-2">Plot<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">plot</span>({</span>
<span id="cb79-3">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">x</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> {<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">label</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">null</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb79-4">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">y</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> {<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">percent</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">true</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb79-5">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">marks</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> [</span>
<span id="cb79-6">    Plot<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">barY</span>(</span>
<span id="cb79-7">        pyramide_ages<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb79-8">        {<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">x</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"AGED"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">y</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> d <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=&gt;</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">individus</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1000</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">fy</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'departement'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">fill</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"departement"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">tip</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">true</span>}</span>
<span id="cb79-9">        )<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb79-10">    Plot<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ruleX</span>([<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">18</span>]<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> {<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">stroke</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"red"</span>})<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb79-11">    Plot<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tickY</span>(</span>
<span id="cb79-12">        pyramide_ages<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb79-13">        {<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">x</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"AGED"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">y</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> d <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=&gt;</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">individus</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1000</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">fy</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'departement'</span>}</span>
<span id="cb79-14">        )<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb79-15">    Plot<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ruleY</span>([<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>])<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb79-16">    Plot<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">axisY</span>({<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">label</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Population (en milliers)"</span>})<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb79-17">    Plot<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">axisX</span>({<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">ticks</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> d3<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ticks</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">120</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">label</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Âge"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">fontSize</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span>})</span>
<span id="cb79-18">  ]</span>
<span id="cb79-19">})</span>
<span id="cb79-20"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```</span></span></code></pre></div></div>
</details>
</div>
<div id="tabset-15-2" class="tab-pane" aria-labelledby="tabset-15-2-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb80" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb80-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> matplotlib.pyplot <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> plt</span>
<span id="cb80-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> plotnine <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span></span>
<span id="cb80-3"></span>
<span id="cb80-4">pyramide_ages <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> duckdb.sql(</span>
<span id="cb80-5"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"""</span></span>
<span id="cb80-6"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">SELECT</span></span>
<span id="cb80-7"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  SUM(IPONDI) AS individus,</span></span>
<span id="cb80-8"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  CAST(AGED AS int) AS AGED,</span></span>
<span id="cb80-9"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  DEPT AS departement</span></span>
<span id="cb80-10"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">FROM table_individu</span></span>
<span id="cb80-11"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  WHERE DEPT IN ('11', '31', '34')</span></span>
<span id="cb80-12"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">GROUP BY AGED, DEPT ORDER BY DEPT, AGED</span></span>
<span id="cb80-13"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"""</span></span>
<span id="cb80-14">).to_df()</span>
<span id="cb80-15"></span>
<span id="cb80-16">(</span>
<span id="cb80-17">    ggplot(pyramide_ages, aes(x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"AGED"</span>, y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"individus"</span>)) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb80-18">    geom_bar(</span>
<span id="cb80-19">      aes(fill <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"departement"</span>),</span>
<span id="cb80-20">      stat <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"identity"</span>, show_legend<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span></span>
<span id="cb80-21">    ) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb80-22">    geom_vline(xintercept <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">18</span>, color <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"grey"</span>, linetype <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"dashed"</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb80-23">    facet_wrap(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'departement'</span>, scales <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"free_y"</span>, nrow <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb80-24">    theme_minimal() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb80-25">    labs(y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Individus recensés"</span>, x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Âge"</span>)</span>
<span id="cb80-26">)</span></code></pre></div></div>
</div>
<div id="tabset-15-3" class="tab-pane" aria-labelledby="tabset-15-3-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb81" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb81-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(labeling)</span>
<span id="cb81-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(ggplot2)</span>
<span id="cb81-3"></span>
<span id="cb81-4">query <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">paste</span>(</span>
<span id="cb81-5">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT SUM(IPONDI) AS individus, AGED, DEPT AS departement"</span>,</span>
<span id="cb81-6">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"FROM table_individu"</span>,</span>
<span id="cb81-7">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"WHERE DEPT IN ('11', '31', '34')"</span>,</span>
<span id="cb81-8">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"GROUP BY AGED, DEPT"</span>,</span>
<span id="cb81-9">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ORDER BY DEPT, AGED"</span>,</span>
<span id="cb81-10">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">sep =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">" "</span></span>
<span id="cb81-11">)</span>
<span id="cb81-12">pyramide_ages <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbGetQuery</span>(con, query)</span>
<span id="cb81-13"></span>
<span id="cb81-14"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(pyramide_ages, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> AGED, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> individus)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb81-15">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_bar</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">fill =</span> departement), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">stat =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"identity"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb81-16">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_vline</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">xintercept =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">18</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">color =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"grey"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">linetype =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"dashed"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb81-17">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">facet_wrap</span>(<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span>departement, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">scales =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"free_y"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">nrow =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb81-18">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">theme_minimal</span>() <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb81-19">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">labs</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Individus recensés"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Âge"</span>)</span></code></pre></div></div>
</div>
<div id="tabset-15-4" class="tab-pane" aria-labelledby="tabset-15-4-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb82" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb82-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(labeling)</span>
<span id="cb82-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(ggplot2)</span>
<span id="cb82-3"></span>
<span id="cb82-4">pyramide_ages <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> table_individu <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb82-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(DEPT <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%in%</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'11'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'31'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'34'</span>)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb82-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(AGED, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">departement =</span> DEPT) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb82-7">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">individus =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sum</span>(IPONDI), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.groups =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"drop"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb82-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">arrange</span>(departement, AGED) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb82-9">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">collect</span>()</span>
<span id="cb82-10"></span>
<span id="cb82-11"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(pyramide_ages, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> AGED, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> individus)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb82-12">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_bar</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">fill =</span> departement), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">stat =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"identity"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb82-13">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_vline</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">xintercept =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">18</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">color =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"grey"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">linetype =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"dashed"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb82-14">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">facet_wrap</span>(<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span>departement, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">scales =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"free_y"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">nrow =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb82-15">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">theme_minimal</span>() <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb82-16">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">labs</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Individus recensés"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Âge"</span>)</span></code></pre></div></div>
</div>
</div>
</div>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb83" data-startfrom="775" data-source-offset="-0" style="background: #f1f3f5;"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 774;"><span id="cb83-775">pyramide_ages <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(</span>
<span id="cb83-776"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span></span>
<span id="cb83-777"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">SELECT</span></span>
<span id="cb83-778"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">  CAST(SUM(IPONDI) AS INT) AS individus,</span></span>
<span id="cb83-779"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">  CAST(AGED AS INT) AS AGED,</span></span>
<span id="cb83-780"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">  DEPT AS departement</span></span>
<span id="cb83-781"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">FROM table_individu</span></span>
<span id="cb83-782"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">  WHERE DEPT IN ('11', '31', '34')</span></span>
<span id="cb83-783"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">GROUP BY AGED, DEPT ORDER BY DEPT, AGED</span></span>
<span id="cb83-784"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span></span>
<span id="cb83-785">)</span>
<span id="cb83-786">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(pyramide_ages)</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div>
<div id="ojs-cell-22-1" data-nodetype="declaration">

</div>
</div>
</div>
<div class="cell-output cell-output-display">
<div>
<div id="ojs-cell-22-2" data-nodetype="expression">

</div>
</div>
</div>
</div>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb84" data-startfrom="824" data-source-offset="0" style="background: #f1f3f5;"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 823;"><span id="cb84-824">Plot<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">plot</span>({</span>
<span id="cb84-825">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">x</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> {<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">label</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">null</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb84-826">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">y</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> {<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">percent</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">true</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb84-827">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">marks</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> [</span>
<span id="cb84-828">    Plot<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">barY</span>(</span>
<span id="cb84-829">        pyramide_ages<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb84-830">        {<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">x</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"AGED"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">y</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> d <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=&gt;</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">individus</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1000</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">fy</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'departement'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">fill</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"departement"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">tip</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">true</span>}</span>
<span id="cb84-831">        )<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb84-832">    Plot<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ruleX</span>([<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">18</span>]<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> {<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">stroke</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"red"</span>})<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb84-833">    Plot<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tickY</span>(</span>
<span id="cb84-834">        pyramide_ages<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb84-835">        {<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">x</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"AGED"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">y</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> d <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=&gt;</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">individus</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1000</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">fy</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'departement'</span>}</span>
<span id="cb84-836">        )<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb84-837">    Plot<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ruleY</span>([<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>])<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb84-838">    Plot<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">axisY</span>({<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">label</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Population (en milliers)"</span>})<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb84-839">    Plot<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">axisX</span>({<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">ticks</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> d3<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ticks</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">120</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">label</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Âge"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">fontSize</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span>})</span>
<span id="cb84-840">  ]</span>
<span id="cb84-841">})</span></code></pre></div></div>
<div id="fig-ojs-cell-23" class="cell-output cell-output-display quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-ojs-cell-23-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div id="ojs-cell-23" data-nodetype="expression">

</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-ojs-cell-23-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;1: Un exemple de représentation graphique produite à partir du recensement de la population
</figcaption>
</figure>
</div>
</div>
<p>Si on s’intéresse plus spécifiquement au nombre de centenaires recensés par département et qu’on désire classer ces derniers par ordre décroissant.</p>
<div class="tabset-margin-container"></div><div class="panel-tabset" data-group="language">
<ul class="nav nav-tabs"><li class="nav-item"><a class="nav-link active" id="tabset-16-1-tab" data-bs-toggle="tab" data-bs-target="#tabset-16-1" aria-controls="tabset-16-1" aria-selected="true" href=""><code>Observable</code> via <code>Quarto</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-16-2-tab" data-bs-toggle="tab" data-bs-target="#tabset-16-2" aria-controls="tabset-16-2" aria-selected="false" href=""><code>Python</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-16-3-tab" data-bs-toggle="tab" data-bs-target="#tabset-16-3" aria-controls="tabset-16-3" aria-selected="false" href=""><code>R</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-16-4-tab" data-bs-toggle="tab" data-bs-target="#tabset-16-4" aria-controls="tabset-16-4" aria-selected="false" href=""><code>R (dbplyr)</code></a></li></ul>
<div class="tab-content" data-group="language">
<div id="tabset-16-1" class="tab-pane active" aria-labelledby="tabset-16-1-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb85" style="background: #f1f3f5;"><pre class="sourceCode markdown code-with-copy"><code class="sourceCode markdown"><span id="cb85-1"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```{ojs}</span></span>
<span id="cb85-2">db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(</span>
<span id="cb85-3"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span></span>
<span id="cb85-4"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">SELECT</span></span>
<span id="cb85-5"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">  SUM(IPONDI) AS individus_recenses,</span></span>
<span id="cb85-6"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">  DEPT</span></span>
<span id="cb85-7"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">FROM table_individu</span></span>
<span id="cb85-8"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">  WHERE AGED &gt;= 100</span></span>
<span id="cb85-9"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">GROUP BY DEPT</span></span>
<span id="cb85-10"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">ORDER BY individus_recenses DESC</span></span>
<span id="cb85-11"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span></span>
<span id="cb85-12">)</span>
<span id="cb85-13"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```</span></span></code></pre></div></div>
</div>
<div id="tabset-16-2" class="tab-pane" aria-labelledby="tabset-16-2-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb86" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb86-1">duckdb.sql(</span>
<span id="cb86-2"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"""</span></span>
<span id="cb86-3"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">SELECT</span></span>
<span id="cb86-4"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  SUM(IPONDI) AS individus_recenses,</span></span>
<span id="cb86-5"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  DEPT</span></span>
<span id="cb86-6"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">FROM table_individu</span></span>
<span id="cb86-7"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  WHERE AGED &gt;= 100</span></span>
<span id="cb86-8"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">GROUP BY DEPT</span></span>
<span id="cb86-9"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">ORDER BY individus_recenses DESC</span></span>
<span id="cb86-10"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"""</span></span>
<span id="cb86-11">)</span></code></pre></div></div>
</div>
<div id="tabset-16-3" class="tab-pane" aria-labelledby="tabset-16-3-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb87" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb87-1">query <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">paste</span>(</span>
<span id="cb87-2">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT SUM(IPONDI) AS individus_recenses, DEPT"</span>,</span>
<span id="cb87-3">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"FROM table_individu"</span>,</span>
<span id="cb87-4">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"WHERE AGED &gt;= 100"</span>,</span>
<span id="cb87-5">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"GROUP BY DEPT"</span>,</span>
<span id="cb87-6">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ORDER BY individus_recenses DESC"</span>,</span>
<span id="cb87-7">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">sep =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">" "</span></span>
<span id="cb87-8">)</span>
<span id="cb87-9"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbGetQuery</span>(con, query)</span></code></pre></div></div>
</div>
<div id="tabset-16-4" class="tab-pane" aria-labelledby="tabset-16-4-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb88" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb88-1">table_individu <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb88-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(AGED <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb88-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(DEPT) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb88-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">individus_recenses =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as.integer</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sum</span>(IPONDI)), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.groups =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"drop"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb88-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">arrange</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">desc</span>(individus_recenses))</span></code></pre></div></div>
</div>
</div>
</div>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb89" data-startfrom="922" data-source-offset="0" style="background: #f1f3f5;"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 921;"><span id="cb89-922">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(</span>
<span id="cb89-923">  db<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(</span>
<span id="cb89-924">  <span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span></span>
<span id="cb89-925"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">  SELECT</span></span>
<span id="cb89-926"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    CAST(SUM(IPONDI) AS INT) AS individus_recenses,</span></span>
<span id="cb89-927"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    DEPT</span></span>
<span id="cb89-928"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">  FROM table_individu</span></span>
<span id="cb89-929"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    WHERE AGED &gt;= 100</span></span>
<span id="cb89-930"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">  GROUP BY DEPT</span></span>
<span id="cb89-931"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">  ORDER BY individus_recenses DESC</span></span>
<span id="cb89-932"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">  `</span></span>
<span id="cb89-933">  )</span>
<span id="cb89-934">)</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div id="ojs-cell-24" data-nodetype="expression">

</div>
</div>
</div>
</section>
<section id="associer-à-dautres-sources-de-données" class="level1">
<h1>Associer à d’autres sources de données</h1>
<p>Le <a href="https://www.insee.fr/fr/information/6800675"><em>code officiel géographique</em> (COG)</a> est utile pour illuster l’ajout d’information annexe. Le code commune va être utilisé pour associer les deux bases de données. Cette variable porte des noms différents dans les deux bases, ce qui n’est pas un problème.</p>
<p>Il est proposé, ci-dessous, de télécharger les données de manière reproductible, via une fonction adaptée (ici à travers le <em>package</em> <code>requests</code> pour <code>Python</code> ou via <code>download.file</code> en <code>R</code>). Bien que <code>DuckDB</code> permette l’import direct depuis un <em>url</em>, ceci implique l’installation en amont de l’<a href="https://duckdb.org/docs/extensions/httpfs.html">extension <code>httpfs</code></a>.</p>
<p>L’association de sources de données passe généralement par un <code>JOIN</code>. Pour illustrer cette clause, il est possible d’associer les agrégats de la table logement à un niveau communal avec celles du COG grâce au code commune.</p>
<div class="tabset-margin-container"></div><div class="panel-tabset" data-group="language">
<ul class="nav nav-tabs"><li class="nav-item"><a class="nav-link active" id="tabset-17-1-tab" data-bs-toggle="tab" data-bs-target="#tabset-17-1" aria-controls="tabset-17-1" aria-selected="true" href=""><code>Observable</code> via <code>Quarto</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-17-2-tab" data-bs-toggle="tab" data-bs-target="#tabset-17-2" aria-controls="tabset-17-2" aria-selected="false" href=""><code>Python</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-17-3-tab" data-bs-toggle="tab" data-bs-target="#tabset-17-3" aria-controls="tabset-17-3" aria-selected="false" href=""><code>R</code></a></li><li class="nav-item"><a class="nav-link" id="tabset-17-4-tab" data-bs-toggle="tab" data-bs-target="#tabset-17-4" aria-controls="tabset-17-4" aria-selected="false" href=""><code>R (dbplyr)</code></a></li></ul>
<div class="tab-content" data-group="language">
<div id="tabset-17-1" class="tab-pane active" aria-labelledby="tabset-17-1-tab">
<p>La lecture directe depuis <code>Observable</code> du fichier par le biais du protocole <code>https</code> vers le site de l’Insee ne fonctionnant pas, il est recommandé de télécharger en amont le fichier par l’intermédiaire de <code>Python</code> ou de <code>R</code>.</p>
<details>
<summary>
Code <code>Python</code> pour récupérer le code officiel géographique
</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb90" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb90-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> requests</span>
<span id="cb90-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> os</span>
<span id="cb90-3"></span>
<span id="cb90-4">url_cog <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://www.insee.fr/fr/statistiques/fichier/6800675/v_commune_2023.csv"</span></span>
<span id="cb90-5"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> os.path.exists(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"cog.csv"</span>) <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">is</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span>:</span>
<span id="cb90-6">  response <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> requests.get(url_cog)</span>
<span id="cb90-7">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">with</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">open</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"cog.csv"</span>, mode<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"wb"</span>) <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">file</span>:</span>
<span id="cb90-8">      <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">file</span>.write(response.content)</span></code></pre></div></div>
</details>
<details>
<summary>
Code <code>R</code> pour récupérer le code officiel géographique
</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb91" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb91-1">url <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://www.insee.fr/fr/statistiques/fichier/6800675/v_commune_2023.csv"</span></span>
<span id="cb91-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">download.file</span>(url, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"cog.csv"</span>)</span></code></pre></div></div>
</details>
<p>Après avoir récupérées les données, ce code peut permettre de créer une base de données intégrant le code officiel géographique:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb92" style="background: #f1f3f5;"><pre class="sourceCode markdown code-with-copy"><code class="sourceCode markdown"><span id="cb92-1"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```{ojs}</span></span>
<span id="cb92-2">db2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {</span>
<span id="cb92-3">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">const</span> configuredClient <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> db <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb92-4">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> configuredClient<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(</span>
<span id="cb92-5">    <span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span></span>
<span id="cb92-6"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    CREATE OR REPLACE VIEW cog2023 AS</span></span>
<span id="cb92-7"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    SELECT * FROM read_csv_auto('cog.csv', header = true)</span></span>
<span id="cb92-8"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    `</span></span>
<span id="cb92-9">    )</span>
<span id="cb92-10"></span>
<span id="cb92-11">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> configuredClient <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb92-12"></span>
<span id="cb92-13">}</span>
<span id="cb92-14"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```</span></span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb93" style="background: #f1f3f5;"><pre class="sourceCode markdown code-with-copy"><code class="sourceCode markdown"><span id="cb93-1"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```{ojs}</span></span>
<span id="cb93-2">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(</span>
<span id="cb93-3">  db2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(</span>
<span id="cb93-4">    <span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span></span>
<span id="cb93-5"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    SELECT cog2023.NCCENR, CAST(SUM(table_logement.IPONDL) AS INT) AS recenses</span></span>
<span id="cb93-6"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    FROM table_logement</span></span>
<span id="cb93-7"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    LEFT OUTER JOIN cog2023 ON table_logement.COMMUNE = cog2023.COM</span></span>
<span id="cb93-8"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    GROUP BY cog2023.NCCENR</span></span>
<span id="cb93-9"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    ORDER BY recenses;</span></span>
<span id="cb93-10"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    `</span></span>
<span id="cb93-11">  )  </span>
<span id="cb93-12">)</span>
<span id="cb93-13"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">```</span></span></code></pre></div></div>
</div>
<div id="tabset-17-2" class="tab-pane" aria-labelledby="tabset-17-2-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb94" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb94-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> requests</span>
<span id="cb94-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> os</span>
<span id="cb94-3"></span>
<span id="cb94-4">url_cog <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://www.insee.fr/fr/statistiques/fichier/6800675/v_commune_2023.csv"</span></span>
<span id="cb94-5"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> os.path.exists(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"cog.csv"</span>) <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">is</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span>:</span>
<span id="cb94-6">  response <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> requests.get(url_cog)</span>
<span id="cb94-7">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">with</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">open</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"cog.csv"</span>, mode<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"wb"</span>) <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">file</span>:</span>
<span id="cb94-8">      <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">file</span>.write(response.content)</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb95" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb95-1">duckdb.sql(</span>
<span id="cb95-2">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'CREATE OR REPLACE VIEW cog2023 AS '</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+\</span></span>
<span id="cb95-3">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'SELECT * FROM read_csv_auto("cog.csv", header=true)'</span></span>
<span id="cb95-4">)</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb96" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb96-1">duckdb.sql(</span>
<span id="cb96-2"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"""</span></span>
<span id="cb96-3"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">SELECT cog2023.NCCENR, CAST(SUM(table_logement.IPONDL) AS INT) AS recenses</span></span>
<span id="cb96-4"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">FROM table_logement</span></span>
<span id="cb96-5"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">LEFT OUTER JOIN cog2023 ON table_logement.COMMUNE = cog2023.COM</span></span>
<span id="cb96-6"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">GROUP BY cog2023.NCCENR</span></span>
<span id="cb96-7"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">ORDER BY recenses;</span></span>
<span id="cb96-8"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"""</span></span>
<span id="cb96-9">)</span></code></pre></div></div>
</div>
<div id="tabset-17-3" class="tab-pane" aria-labelledby="tabset-17-3-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb97" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb97-1">url <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://www.insee.fr/fr/statistiques/fichier/6800675/v_commune_2023.csv"</span></span>
<span id="cb97-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">download.file</span>(url, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"cog.csv"</span>)</span>
<span id="cb97-3"></span>
<span id="cb97-4"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbExecute</span>(</span>
<span id="cb97-5">  con,</span>
<span id="cb97-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">glue_sql</span>(</span>
<span id="cb97-7">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"CREATE OR REPLACE VIEW cog2023 AS "</span>,</span>
<span id="cb97-8">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT * FROM read_csv_auto("</span>cog.csv<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">", header=true)"</span>,</span>
<span id="cb97-9">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.con=</span>con</span>
<span id="cb97-10">  )</span>
<span id="cb97-11">)</span>
<span id="cb97-12"></span>
<span id="cb97-13">query <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">paste</span>(</span>
<span id="cb97-14">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SELECT cog2023.NCCENR, CAST(SUM(table_logement.IPONDL) AS INT) AS recenses"</span>,</span>
<span id="cb97-15">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"FROM table_logement"</span>,</span>
<span id="cb97-16">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"LEFT OUTER JOIN cog2023 ON table_logement.COMMUNE = cog2023.COM"</span>,</span>
<span id="cb97-17">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"GROUP BY cog2023.NCCENR ORDER BY recenses"</span>,</span>
<span id="cb97-18">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">sep =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">" "</span></span>
<span id="cb97-19">)</span>
<span id="cb97-20"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dbGetQuery</span>(con, query)</span></code></pre></div></div>
</div>
<div id="tabset-17-4" class="tab-pane" aria-labelledby="tabset-17-4-tab">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb98" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb98-1">url <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://www.insee.fr/fr/statistiques/fichier/6800675/v_commune_2023.csv"</span></span>
<span id="cb98-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">download.file</span>(url, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"cog.csv"</span>)</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb99" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb99-1">cog <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tbl</span>(con, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">glue</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'read_csv_auto("{path_data}/cog.csv", header = true)'</span>))</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb100" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb100-1">table_logement <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb100-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">left_join</span>(cog, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">by =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"COMMUNE"</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"COM"</span>)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb100-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(NCCENR) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb100-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">recenses =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as.integer</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sum</span>(IPONDL)), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.groups =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"drop"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%&gt;%</span></span>
<span id="cb100-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">arrange</span>(recenses)</span></code></pre></div></div>
</div>
</div>
</div>
<div class="cell">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code hidden" id="cb101" data-startfrom="943" data-source-offset="-0" style="background: #f1f3f5;"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 942;"><span id="cb101-943">proxy <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://corsproxy.io/?"</span></span>
<span id="cb101-944">url_cog <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://www.insee.fr/fr/statistiques/fichier/6800675/v_commune_2023.csv"</span></span>
<span id="cb101-945">db2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {</span>
<span id="cb101-946">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">const</span> configuredClient <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> db <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb101-947">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">await</span> configuredClient<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(</span>
<span id="cb101-948">    <span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span></span>
<span id="cb101-949"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    CREATE OR REPLACE VIEW cog2023 AS</span></span>
<span id="cb101-950"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    SELECT * FROM read_csv_auto('</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">${</span>proxy <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> url_cog<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">', header = true)</span></span>
<span id="cb101-951"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    `</span></span>
<span id="cb101-952">    )</span>
<span id="cb101-953"></span>
<span id="cb101-954">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> configuredClient <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb101-955"></span>
<span id="cb101-956">}</span></code></pre></div></div>
<div class="cell-output cell-output-display">
<div>
<div id="ojs-cell-25-1" data-nodetype="declaration">

</div>
</div>
</div>
<div class="cell-output cell-output-display">
<div>
<div id="ojs-cell-25-2" data-nodetype="declaration">

</div>
</div>
</div>
<div class="cell-output cell-output-display">
<div>
<div id="ojs-cell-25-3" data-nodetype="declaration">

</div>
</div>
</div>
</div>
<p>Les données du code officiel géographique présentent l’aspect suivant :</p>
<div class="cell">
<details class="code-fold">
<summary>Requête Observable pour explorer les premières lignes</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb102" data-startfrom="955" data-source-offset="0" style="background: #f1f3f5;"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 954;"><span id="cb102-955">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(</span>
<span id="cb102-956">  db2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(<span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`SELECT * FROM cog2023 LIMIT 10`</span>)</span>
<span id="cb102-957">)</span></code></pre></div></div>
</details>
<div class="cell-output cell-output-display">
<div id="ojs-cell-26" data-nodetype="expression">

</div>
</div>
</div>
<p>Voici par exemple le résultat d’une fusion avec une agrégation produite à la volée sur la table logement :</p>
<div class="cell">
<details class="code-fold">
<summary>Requête pour explorer les premières lignes</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb103" data-startfrom="1" data-source-offset="0" style="background: #f1f3f5;"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript"><span id="cb103-1">Inputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(</span>
<span id="cb103-2">  db2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">query</span>(</span>
<span id="cb103-3">    <span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span></span>
<span id="cb103-4"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    SELECT cog2023.NCCENR, CAST(SUM(table_logement.IPONDL) AS INT) AS recenses</span></span>
<span id="cb103-5"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    FROM table_logement</span></span>
<span id="cb103-6"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    LEFT OUTER JOIN cog2023 ON table_logement.COMMUNE = cog2023.COM</span></span>
<span id="cb103-7"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    GROUP BY cog2023.NCCENR</span></span>
<span id="cb103-8"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    ORDER BY recenses;</span></span>
<span id="cb103-9"><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">    `</span></span>
<span id="cb103-10">  )  </span>
<span id="cb103-11">)</span></code></pre></div></div>
</details>
<div class="cell-output cell-output-display">
<div id="ojs-cell-27" data-nodetype="expression">

</div>
</div>
</div>
<section id="références" class="level2">




</section>
</section>


<div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-bibliography"><h2 class="anchored quarto-appendix-heading">Références</h2><div id="refs" class="references csl-bib-body hanging-indent">
<div id="ref-dondon-lamarche-2023" class="csl-entry">
Dondon, Alexis, et Pierre Lamarche. 2023. <span>«&nbsp;Quels formats pour quelles données?&nbsp;»</span> <em>Courrier des statistiques</em>, nᵒ 9.
</div>
<div id="ref-mauviere-2022" class="csl-entry">
Mauvière, Éric. 2022. <span>«&nbsp;Parquet devrait remplacer le format CSV&nbsp;»</span>. Post de blog [Consulté le 12 octobre 2023]. <a href="https://www.icem7.fr/cartographie/parquet-devrait-remplacer-le-format-csv/">https://www.icem7.fr/cartographie/parquet-devrait-remplacer-le-format-csv/</a>.
</div>
</div></section><section id="footnotes" class="footnotes footnotes-end-of-document"><h2 class="anchored quarto-appendix-heading">Notes de bas de page</h2>

<ol>
<li id="fn1"><p>Des propositions d’enrichissements de cette documentation à partir d’implémentations alternatives, par exemple s’appuyant sur <code>Arrow</code> et <code>dbplyr</code> ou sur <code>Polars</code> sont bienvenues sur le <a href="https://github.com/InseeFrLab/exemples-recensement-parquet">Github InseeFrLab/exemples-recensement-parquet</a>.↩︎</p></li>
</ol>
</section></div> ]]></description>
  <category>Python</category>
  <category>R</category>
  <category>Parquet</category>
  <guid>https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/parquetRP/</guid>
  <pubDate>Mon, 23 Oct 2023 00:00:00 GMT</pubDate>
  <media:content url="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/parquetRP/ducks.png" medium="image" type="image/png" height="144" width="144"/>
</item>
<item>
  <title>Onyxia: l’infrastructure cloud mère des dragons</title>
  <link>https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/onyxia/</link>
  <description><![CDATA[ 





<p><code>Onyxia</code> est un logiciel <em>open source</em> développé par l’Insee (<a href="https://github.com/InseeFrLab/onyxia-web">disponible sur <code>Github</code> <i class="fa-brands fa-github"></i></a>) permettant de fournir un environnement de traitement de données à l’état de l’art. Principalement conçu pour permettre le travail interactif des data scientists, l’expérience fournie avec <code>Onyxia</code> favorise également la reproductibilité des travaux et leur mise en production.</p>
<p>Le logiciel <code>Onyxia</code> est installé par des organisations souhaitant créer un <em>datalab</em>, c’est-à-dire une plateforme interactive de traitement de données. Ces organisations ont toutes le point commun de vouloir construire une plateforme qui embrasse les technologies <em>cloud</em> que sont la conteneurisation et le stockage objet tout en mettant à disposition celles-ci dans un environnement <em>user-friendly</em> où l’interconnexion entre ces différentes briques est gérée de manière cohérente. Les technologies <em>cloud native</em> sont devenues indispensables dans l’écosystème de la donnée, du fait d’une meilleure gestion des ressources de traitement ou de la capacité à créer un environnement parfaitement reproductible pour une mise en production accélérée.</p>
<p>Ce <em>post</em> de blog a pour objectif de présenter la raison d’être d’<code>Onyxia</code>, sa génèse et les solutions qu’apporte cette infrastructure à des irritants classiques des projets novateurs de data science.</p>
<section id="contexte" class="level2">
<h2 class="anchored" data-anchor-id="contexte">Contexte</h2>
<p>L’écosystème de la data science est en mouvement accéléré depuis 10 ans et le rôle du <em>data scientist</em> dans les organisations valorisant de la donnée évolue continuellement <span class="citation" data-cites="davenport2022data">(Davenport et Patil 2022)</span>. Les data scientists modernes sont amenés à utiliser de plus en plus de langages et doivent être capables de maîtriser plusieurs architectures informatiques. La frontière est ainsi moins nette que par le passé entre statisticiens et informaticiens. De plus, les innovations récentes dans le monde du développement logiciel, notamment l’adoption massive de l’approche <code>DevOps</code> - approche qui consiste à automatiser la production de livrables dès la conception du prototype - a également fait évoluer les pratiques des data scientists.</p>
<p>Ce besoin de ressources informatiques croissantes, de flexibilité dans le prototypage de solutions informatiques et l’évolution des pratiques consistant à mettre à disposition en continu des livrables ont eu des implications importantes sur les architectures informatiques dominantes dans l’écosystème de la donnée. Pour répondre au besoin croissant de puissance de traitement, les serveurs partagés, organisés sous forme de <em>clusters</em>, se sont développés dans de nombreuses organisations. Après avoir connue son heure de gloire au début des années 2010, l’infrastructure <a href="https://openclassrooms.com/fr/courses/4467481-creez-votre-data-lake/4509426-decouvrez-le-systeme-de-fichiers-distribue-hdfs"><code>HDFS</code> (<em>Hadoop Distributed File System</em>)</a>, qui reposait sur des <em>clusters</em> où les données et la puissance de traitement étaient distribuées et collocalisées, a laissé place à des infrastructures plus <em>scalables</em>, basées sur l’approche de la conteneurisation.</p>
</section>
<section id="de-hdfs-à-la-conteneurisation" class="level2">
<h2 class="anchored" data-anchor-id="de-hdfs-à-la-conteneurisation">De HDFS à la conteneurisation</h2>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>Cette partie plus technique développe des éléments pour comprendre le succès récent des infrastructures conteneurisées.</p>
<p>Elle pourra intéresser le lecteur curieux sur les fondements des infrastructures <em>cloud</em> modernes mais n’est pas nécessaire à la compréhension générale de l’article.</p>
</div>
</div>
<p>La conteneurisation, qui repose sur l’idée que les serveurs de stockage de la donnée peuvent être dissociés de ceux effectuant les traitements, sert de fondement aux principales plateformes <em>cloud</em> actuelles fournissant des services à la demande.</p>
<p>Ce nouveau paradigme part de deux constats. Le premier est que les échanges de données entre les noeuds d’un serveur sont aujourd’hui peu coûteux. Avec des flux réseaux suffisants et une technologie performante, il est donc possible d’échanger à un coût modéré de gros volumes de données au sein d’une infrastructure. Le deuxième constat est que la maintenance d’une infrastructure conteneurisée, faite pour être très malléable, est plus légère que celle d’une infrastructure basée sur des machines virtuelles ou sur les infrastructrures calibrées pour l’analytique <em>big data</em> comme <code>HDFS</code> reposant sur la collocalisation des données et des traitements<sup>1</sup>.</p>
<p>Les données étant stockées sur des serveurs différents de ceux exécutant les traitements, l’accès à celles-ci se fait à travers des API qui permettent de traiter le système de stockage distant comme un système de fichiers classique. <code>Onyxia</code> a adopté une implémentation <em>open source</em> du système de stockage <a href="https://fr.wikipedia.org/wiki/Amazon_S3"><code>S3</code></a> appelée <a href="https://min.io/"><code>MinIO</code></a>.</p>
<p>En ce qui concerne le traitement des données, le fait d’utiliser un système de conteneurs, c’est-à-dire une configuration logicielle portable minimaliste prête à l’emploi (par opposition aux machines virtuelles qui impliquent un système d’exploitation complet), offre une grande liberté sur le choix des logiciels de traitement. De nombreuses technologies <em>open source</em> devenues standards dans le monde de la <em>data science</em> (<code>Jupyter</code>, <code>RStudio</code>, <code>ElasticSearch</code>…) existent déjà sous cette forme et peuvent ainsi être adoptées dans une telle infrastructure pour fournir des services prêts-à-l’emploi pour les data scientists. La mise en musique de toutes ces petites boites auto-suffisantes, notamment l’optimisation des ressources concurrentes sur un serveur, est permise par la technologie d’orchestration <a href="https://kubernetes.io/fr/"><code>Kubernetes</code></a>.</p>
<p><br></p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<figcaption><em>Centralisation des ressources par <code>Onyxia</code></em></figcaption>
<p><img src="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/onyxia/onyxia_logic.svg" class="img-fluid figure-img"></p>
</figure>
</div>
<p><br></p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center collapsed" data-bs-toggle="collapse" data-bs-target=".callout-2-contents" aria-controls="callout-2" aria-expanded="false" aria-label="Toggle callout">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
<span class="screen-reader-only">Note</span>Plus de détails pour comprendre le changement de paradigme vers la conteuneurisation 👇
</div>
<div class="callout-btn-toggle d-inline-block border-0 py-1 ps-1 pe-0 float-end"><i class="callout-toggle"></i></div>
</div>
<div id="callout-2" class="callout-2-contents callout-collapse collapse">
<div class="callout-body-container callout-body">
<p>Les infrastructures <em>big data</em> reposent sur le principe du <em>cluster</em> (grappe) informatique. Des serveurs sont connectés entre eux, ce qui forme de manière imagée une grappe. Cette interconnexion de plusieurs serveurs entre eux peut se faire au niveau :</p>
<ul>
<li>du <strong>stockage</strong> : les données volumineuses ne sont pas stockées sur un seul serveur mais au contraire réparties ;</li>
<li>du <strong>traitement</strong> : les calculs sont effectués par blocs sur plusieurs serveurs et le résultat de ceux-ci est ensuite transmis à un serveur maître.</li>
</ul>
<p>Le système <em>Hadoop Distributed File System</em> a été pensé pour tirer parti de l’algorithme de traitement parallélisé <a href="https://fr.wikipedia.org/wiki/MapReduce"><code>MapReduce</code></a> proposé en 2004 par <code>Google</code>. Les fichiers volumineux sont fractionnés et répartis sur plusieurs serveurs.</p>
<p><img src="https://i0.wp.com/datascientest.com/wp-content/uploads/2021/04/illu_schema_mapreduce-04.png?w=1024&amp;ssl=1" class="img-fluid"></p>
<p><em>Fonctionnement d’une architecture <code>MapReduce</code> (source: <a href="https://datascientest.com/mapreduce">Datascientest</a>)</em></p>
<p>La spécificité de l’architecture <code>HDFS</code> est que non seulement le stockage est distribué mais également aussi la puissance de traitement associée. On parle à ce propos de <strong>collocalisation</strong> : les traitements ont lieu sur les mêmes serveurs que ceux où sont stockés les données. Cela permet de réduire les mouvements de données (<em>shuffle</em> dans l’image ci-dessus) qui sont coûteux du point de vue de la performance. Cette collocalisation a permis au système <code>HDFS</code> de devenir, au début de la décennie 2010, le paradigme dominant. En tirant parti de la parallélisation permise par des langages très efficaces comme <code>Spark</code> tout en limitant les échanges réseaux pouvant faire perdre en performance, cette architecture a attiré au-delà de l’écosystème du <em>big data</em>.</p>
<p>Le système HDFS présente néanmoins certaines limites qui expliquent sa perte de succès avec l’émergence d’un nouveau paradigme plus flexible.</p>
<p>En premier lieu, ce système nécessite beaucoup de ressources du fait de son <em>design</em>. Comme les traitements sont lourds et partagés pour des usages concurrents, les noeuds constituant le <em>cluster</em> peuvent subir des arrêts à cause de surcharge des ressources. Pour tenir compte de la nature instable de cette infrastructure <em>big data</em>, les fichiers sont dupliqués. Ainsi, lors d’une erreur sur le serveur générant un arrêt du nœud (par exemple à cause de traitements trop gourmands), les traitements sur l’ensemble des données sont sécurisés évitant également la perte partielle ou totale de ces dernières.</p>
<p>L’implication est que les données, déjà volumineuses, sont dupliquées plusieurs fois impliquant des architectures assez monumentales. Si la duplication de la donnée n’est pas en soi choquante afin d’éviter la perte de données, cela a un effet pervers dans un système de collocalisation. A chaque ajout de noeuds pour le stockage de données, il est également nécessaire d’ajouter des ressources pour les traiter. Il est donc compliqué de décorréler l’ajout de ressources de stockage et de traitement. Cette absence de flexibilité est pénalisante dans un monde où les données sont mises à jour fréquemment et où les technologies de traitement, donc les besoins associés, évoluent rapidement. Les infrastructures <code>HDFS</code> sont donc lourdes à changer, que ce soit pour ajouter des ressources ou faire évoluer les distributions logicielles présentes dessus.</p>
<p>Le deuxième facteur qui a favorisé le changement de paradigme est l’amélioration des échanges réseaux. Il n’est plus aussi coûteux que par le passé de transférer des volumes importants de données au sein d’une infrastructure. Cela facilite la décorrélation entre environnement de stockage et de traitement.</p>
<p>Cette séparation des environnements de stockage et de traitement permet alors d’adopter pour chacun les technologies les plus performantes. Dans le domaine du stockage, celle qui a rencontré le plus de succès est le système de stockage <a href="https://aws.amazon.com/fr/s3/"><code>S3</code></a> développé par Amazon. L’implémentation <em>open source</em> du système S3 est <a href="https://min.io/"><code>MinIO</code></a>, utilisée par <code>Onyxia</code>.</p>
<p>Dans le domaine du traitement, la technologie la plus performante dépend de la nature de la tâche réalisée. Selon qu’on désire effectuer de la recherche textuelle, des visualisations de données ou de l’analyse d’image, on ne va pas vouloir utiliser la même technologie. Pour mettre à disposition des logiciels sur un serveur, il existe principalement deux approches concurrentes.</p>
<p>La première repose sur le principe des machines virtuelles. Cette approche n’est pas nouvelle et de nombreuses organisations ont proposé ou proposent encore ce type d’infrastructures pour des serveurs collectifs de traitement. Cette approche est néanmoins lourde : elle nécessite un système d’exploitation complet dont il faudra ensuite adapter la configuration lors de l’installation de chaque logiciel. Plusieurs logiciels coexistent donc dans ce système d’exploitation même si un seul, par exemple, <code>Python</code>, est utilisé. Les machines virtuelles sont des infrastructures assez polluantes puisque pour faire fonctionner un système d’exploitation dans son ensemble, il est nécessaire de mobiliser des ressources plus importantes que celles seulement nécessaires aux traitements. De plus, la configuration d’un système d’exploitation, et notamment, la gestion de la dépendance de multiples logiciels à des configurations systèmes qui peuvent ne pas correspondre, n’est pas triviale. Il est donc lourd de faire évoluer une infrastructure reposant sur des machines virtuelles. L’absence de flexibilité d’une infrastructure reposant sur le principe des machines virtuelles est pénalisante dans un écosystème mouvant comme celui de la <em>data science</em>, où une partie importante du travail de prototypage consiste à tester plusieurs technologies pour déterminer celle s’intégrant le mieux dans un processus de traitement de données.</p>
<p>Le système de la conteneurisation a justement été pensé pour cela : plutôt qu’installer de nombreuses librairies au niveau du système, pour une fraction d’utilisateurs limitée à chacune, il est plus intéressant de créer des environnements complets qui vont exister de manière conjointe. Chaque <em>framework</em> va être construit comme un conteneur autosuffisant avec un système d’exploitation minime et un nombre minimal de couches de configurations supplémentaires. Un <em>framework</em> est livré sous la forme d’une image <a href="https://fr.wikipedia.org/wiki/Docker_(logiciel)"><code>Docker</code></a>, une technologie qui permet d’empaqueter un logiciel et ses dépendances sous la forme de boites minimalistes et les mettre à disposition facilement pour une réutilisation. Il existe par exemple des images <code>Docker</code> pour pouvoir utiliser <code>RStudio</code>, <code>Jupyter</code>, <code>VSCode</code> avec des configurations minimales afin d’exécuter du <code>Python</code> ou du <code>R</code>. A partir de celles-ci, l’utilisateur qui désire des configurations supplémentaires peut ajouter les couches qui lui sont utiles.</p>
<p>Mais les images <code>Docker</code> ne se réduisent pas à la mise à disposition d’environnements de développement. Une partie des technologies les plus appréciées de l’écosystème de la data science sont également livrées sous forme d’images <code>Docker</code>. Par exemple, le moteur de recherche <code>ElasticSearch</code>, très utilisé pour la recherche textuelle, peut être empaqueté dans une image <code>Docker</code>. Le logiciel <code>Onyxia</code> propose dès lors, dans un catalogue vivant, un certain nombre de logiciels très utiles pour les <em>data scientists</em> ayant fait l’objet d’un tel empaquetage. Les nombreuses images <code>Docker</code> servant à créer des services pour les <em>data scientists</em> sont disponibles en <em>open source</em> sur <a href="https://github.com/InseeFrLab/images-datascience"><code>Github</code></a>.</p>
<p>Pour organiser sur un serveur la coexistence de multiples utilisateurs de services gourmands en ressource, la solution <a href="https://kubernetes.io/fr/"><code>Kubernetes</code></a> fait aujourd’hui office de référence. Entre sa création en 2014 et aujourd’hui, cette solution d’orchestration, c’est-à-dire de gestion d’une infrastructure, est devenue incontournable. Outre son allocation dynamique des ressources, elle permet de transformer facilement le livrable d’une chaine de traitement en application disponible en continu. Ceci est particulièrement adapté dans un contexte de diversification des livrables fournis par les <em>data scientists</em> (API, application web, modèle…) et d’adoption d’une démarche <code>DevOps</code> voire <code>MLOps</code>.</p>
</div>
</div>
</div>
</section>
<section id="la-solution-onyxia" class="level2">
<h2 class="anchored" data-anchor-id="la-solution-onyxia">La solution Onyxia</h2>
<section id="dun-cloud-de-ladministration-à-un-logiciel-ouvert" class="level3">
<h3 class="anchored" data-anchor-id="dun-cloud-de-ladministration-à-un-logiciel-ouvert">D’un <em>cloud</em> de l’administration à un logiciel ouvert</h3>
<p>Pour permettre aux <em>data scientists</em> des administrations françaises de bénéficier de technologies <em>cloud</em> sans être dépendant d’un fournisseur de service privé, l’équipe innovation de l’Insee a eu l’idée de créer un <em>datalab</em> basé sur la philosophie de la conteneurisation en mobilisant exclusivement des composants open-source.</p>
<p>Ce <em>datalab</em>, né à l’Insee en 2018, a été ouvert à l’administration publique sous la forme d’une instance https://www.sspcloud.fr/ à condition d’utiliser des données ouvertes. En plus des agents déjà en poste dans l’administration, cette infrastructure sert depuis deux ans à former les élèves de l’ENSAE et de l’ENSAI dans le cadre de leur formation en <em>data science</em>.</p>
<p>Début 2023, ce sont plus de 3000 agents et étudiants qui sont inscrits sur cette infrastructure avec, en moyenne, 300 utilisateurs hebdomadaires. L’infrastructure de traitement propose 10 TB de RAM, 1100 CPU disponibles et 34 GPU. La capacité de stockage associée est de 150 TB.</p>
<p>Pour les utilisations internes de données plus sensibles, l’équipe innovation de l’Insee a rendu disponible le code source derrière le <code>SSP Cloud</code> dans le cadre d’un logiciel nommé <code>Onyxia</code> (https://www.onyxia.sh/). Ce logiciel est pensé comme un kit qui peut être installé sur un <em>cluster</em> <code>Kubernetes</code>, technologie détaillée précédemment.</p>
</section>
</section>
<section id="onyxia-en-bref" class="level2">
<h2 class="anchored" data-anchor-id="onyxia-en-bref">Onyxia en bref</h2>
<p><img src="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/onyxia/onyxia_ecailles.svg" class="img-fluid"></p>
<p><code>Onyxia</code> propose principalement deux composants de valeur :</p>
<ul>
<li>une <strong>interface web</strong> qui agit comme la porte d’entrée du <em>data scientist</em> sur son datalab, lui facilitant l’accès aux technologies cloud et lui permettant de démarrer ses environnements de traitement de la donnée. L’interface ergonomique permet aux utilisateurs de données néophytes de démarrer des services standardisés sans se préoccuper de la configuration mais aussi aux <em>data scientists</em> plus aguerris de bénéficier de vastes possibilités de personnalisation du service.</li>
<li>des <strong>catalogues de logiciels</strong> : une petite vingtaine de services interactifs dont les plus utilisés sont <code>RStudio</code>, <code>Jupyter</code>, <code>VScode</code>, une quinzaine de services spécialisés dans les bases de données (<code>Postgres</code>, <code>ElasticSearch</code>…), 5 services d’automatisation (<code>MLflow</code>…) et 2 services de <em>dataviz</em> (<code>Redash</code> et <code>Superset</code>)</li>
</ul>
<p><img src="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/onyxia/catalogue.svg" alt="Le catalogue Onyxia"></p>
<p><em>Le catalogue des services disponibles dans <code>Onyxia</code>.</em></p>
<p><br></p>
<p>Ces deux composants peuvent être adaptés en fonction des besoins internes de chaque organisation. Tous les services interactifs sont automatiquement connectés à l’espace de stockage <code>S3</code>, et au coffre de secret <code>Vault</code>. La gestion des droits d’accès aux données stockées dans l’espace de stockage <code>S3</code> ou dans des services de bases de données (<code>ElasticSearch</code>, <code>PostGreSQL</code>…) est automatisée afin que chaque service puisse accéder aux données sur lesquelles l’utilisateur détient des droits.</p>
<p><code>Onyxia</code> étant un ensemble malléable de logiciels conteneurisés, il est possible de ne pas adopter l’ensemble des services proposés par l’équipe de l’Insee qui maintient <code>Onyxia</code>. Il est également possible de changer certaines des briques de base pour l’adapter à des éléments d’infrastructure interne. Par exemple, il est possible d’adapter la destination du service de stockage ou les configurations des environnements data science pour l’adapter à des ressources.</p>
</section>
<section id="linterface-et-les-services-proposés-par-onyxia" class="level2">
<h2 class="anchored" data-anchor-id="linterface-et-les-services-proposés-par-onyxia">L’interface et les services proposés par <code>Onyxia</code></h2>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<figcaption><em>Onyxia offre des marges de manoeuvre sur l’interface</em></figcaption>
<p><img src="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/onyxia/multiple_instances.svg" class="img-fluid figure-img"></p>
</figure>
</div>
<p>L’une des principales forces d’<code>Onyxia</code> est d’offrir une multiplicité de services différents avec une interconnexion entre eux gérée de manière cohérente.</p>
<p>Les conteneurs sont démarrés comme des services à la demande et la configuration automatique de ceux-ci permet d’assurer aux <em>data scientists</em> l’accès aux données disponibles dans des espaces de stockage ou des bases de données créées par l’utilisateur.</p>
<p>Le catalogue de services se présente par le biais d’un formulaire ergonomique où l’utilisateur choisit la brique qu’il désire utiliser:</p>
<p><img src="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/onyxia/onyxia_ui1.png" class="img-fluid"></p>
<p>Les <em>data scientists</em> et statisticiens n’ont donc pas besoin de connaître les détails du fonctionnement des briques techniques d’<code>Onyxia</code> pour utiliser la plateforme. Les éléments techniques comme la connexion au système de stockage sont, par défaut, déjà configurés :</p>
<p><img src="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/onyxia/onyxia_ui2.png" class="img-fluid"></p>
<p>L’interface ergonomique permet de paramétrer certaines configurations si besoin, notamment les ressources à disposition du conteneur. Néanmoins l’allocation dynamique des ressources offre déjà de la flexibilité :</p>
<p><img src="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/onyxia/onyxia_ui3.png" class="img-fluid"></p>
<p>L’utilisateur a accès à l’ensemble des services qu’il a ouvert depuis une page dédiée :</p>
<p><img src="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/onyxia/onyxia_ui4.png" class="img-fluid"></p>
<p>Les services interactifs comme <code>Jupyter</code>, <code>VSCode</code> ou <code>RStudio</code> permettent alors à l’utilisateur d’accéder à une interface pour exécuter des traitements <code>Python</code> ou <code>R</code>.</p>
<p><img src="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/onyxia/onyxia_ui5.png" class="img-fluid"></p>
<p>L’accès aux données peut se faire depuis la ligne de commande (via un utilitaire <a href="https://min.io/docs/minio/linux/reference/minio-mc.html">Minio Client</a>) ou par un package <code>Python</code> ou <code>R</code> dédié qui permet de traiter le système de stockage distant comme un système local. Les traitements sont exécutés sur les serveurs de la plateforme qui héberge les notebooks, indépendamment de la machine par laquelle l’utilisateur accède au service. Par exemple, dans le cas du <code>SSPCloud</code>, les traitements sont exécutés depuis des serveurs hébergés à l’Insee.</p>
</section>
<section id="la-communauté-onyxia" class="level2">
<h2 class="anchored" data-anchor-id="la-communauté-onyxia">La communauté <code>Onyxia</code></h2>
<p>Tous les composants sont proposés en <em>open source</em> par l’Insee ce qui permet de fédérer une communauté d’utilisateurs et de développeurs de ce produit. Il s’agit d’un bel exemple de mutualisation au sein de l’État et au delà. Les dépôts peuvent être retrouvés sur le <code>Github</code> de l’équipe innovation (celui de <a href="https://github.com/InseeFrLab/onyxia-web">l’interface web</a>, celui des <a href="https://github.com/InseeFrLab/images-datascience">images pour la data-science</a>…). La communauté peut proposer de nouveaux services dans le catalogue.</p>
<p>Cette approche <em>bottom up</em> a déjà permis d’adapter des services aux besoins des utilisateurs ou d’améliorer la solution grâce à des retours des ré-utilisateurs d’<code>Onyxia</code>.</p>
<!-----
<iframe width="100%" height="500px" marginheight="0" marginwidth="0" src="./template/index.html">
Fallback text here for unsupporting browsers, of which there are scant few.
</iframe>
----->
</section>
<section id="les-plateformes-basées-sur-onyxia" class="level2">
<h2 class="anchored" data-anchor-id="les-plateformes-basées-sur-onyxia">Les plateformes basées sur Onyxia</h2>
<p>La plateforme d’origine, le <code>SSPCloud</code>, est ouverte à tous les agents de l’État et à plusieurs écoles. Celle-ci est exclusivement limitée à l’exploitation de données <em>open data</em>. Cette stratégie d’offreur de services de traitement sur l’open data permet de montrer l’expertise de l’Insee sur les sujets <em>data science</em>.</p>
<p>Les principaux usages de cette plateforme sont les suivants :</p>
<ul>
<li>la formation ;</li>
<li>l’organisation de hackathons ;</li>
<li>la mise à disposition de services innovants et visualisations utilisant de l’open data ;</li>
</ul>
<p>Grâce à la mise à disposition de la solution <code>Onyxia</code> sur <code>Github</code>, il est néanmoins possible d’adapter cette plateforme pour des <em>datalab</em> internes, sur données plus sensibles.</p>
<p>L’Insee n’est donc désormais plus seul et fédère de nombreux acteurs autour de son projet. Fin 2021, <code>Eurostat</code> a été la première organisation en dehors de l’Insee à choisir <code>Onyxia</code> pour construire son <a href="https://github.com/eurostat/datalab"><em>Cloud Agnostic Data Lab</em></a>. Expertise France pour le projet <code>DATAFID</code> a fait le choix d’Onyxia tout comme le CASD, le GENES ou encore le <em>BercyHub</em> avec le projet <code>Nubonyxia</code>.</p>
<p>D’autres organisations sont plus dans une phase de POC ou d’étude : l’INS norvégien, Pole Emploi, Data4Good, le ministère de l’Intérieur, le ministère de la Justice, l’Inria…</p>
<p>Dans le cadre du <a href="https://tosit.fr/">TOSIT</a>, association qui réunit de gros acteurs publics et privés autour de solutions <em>open source</em>, un certain nombre d’entreprises s’intéressent à <code>Onyxia</code>.</p>
</section>
<section id="vidéo-de-présentation-donyxia" class="level2">
<h2 class="anchored" data-anchor-id="vidéo-de-présentation-donyxia">Vidéo de présentation d’<code>Onyxia</code></h2>
<div class="quarto-video ratio ratio-16x9"><iframe data-external="1" src="https://www.youtube.com/embed/zwKiO6LcIWE" title="" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe></div>
</section>
<section id="références" class="level2">
<h2 class="anchored" data-anchor-id="références">Références</h2>
<div id="refs" class="references csl-bib-body hanging-indent">
<div id="ref-davenport2022data" class="csl-entry">
Davenport, Thomas H, et DJ Patil. 2022. <span>«&nbsp;Is Data Scientist Still the Sexiest Job of the 21st Century?&nbsp;»</span> <em>Harvard business review</em>. <a href="https://hbr.org/2022/07/is-data-scientist-still-the-sexiest-job-of-the-21st-century">https://hbr.org/2022/07/is-data-scientist-still-the-sexiest-job-of-the-21st-century</a>.
</div>
</div>


</section>


<div id="quarto-appendix" class="default"><section id="footnotes" class="footnotes footnotes-end-of-document"><h2 class="anchored quarto-appendix-heading">Notes de bas de page</h2>

<ol>
<li id="fn1"><p>On peut ajouter que cette question n’est pas exclusivement technologique. Même s’il est volontairement polémique, l’article de <a href="https://motherduck.com/blog/big-data-is-dead/">Jordan Tigani “Big Data is Dead”</a> illustre bien le changement de paradigme du monde de la <em>tech</em>.↩︎</p></li>
</ol>
</section></div> ]]></description>
  <category>Insee</category>
  <category>sspcloud</category>
  <guid>https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/onyxia/</guid>
  <pubDate>Wed, 10 May 2023 00:00:00 GMT</pubDate>
  <media:content url="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/onyxia/featured.png" medium="image" type="image/png" height="161" width="144"/>
</item>
<item>
  <title>Polars, une alternative fraîche à Pandas</title>
  <link>https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/polars/</link>
  <description><![CDATA[ 





<p>Le concept de <strong><a href="https://www.databricks.com/glossary/what-are-dataframes"><em>dataframe</em></a></strong> est central pour le <em>data scientist</em> qui manipule des données tabulaires. En <code>Python</code>, <a href="https://pandas.pydata.org/"><code>Pandas</code></a> est la solution de loin la plus populaire. En moyenne, le <em>package</em> est téléchargé 4 millions de fois par semaine, depuis des années.</p>
<p>Un petit nouveau apporte un vent de fraîcheur dans le domaine : <a href="https://www.pola.rs/"><code>Polars</code></a>.</p>
<p>Ses atouts ? D’excellentes performances et une expressibilité qui le rapproche d’un <a href="https://dplyr.tidyverse.org/"><code>dplyr</code></a>.</p>
<p>Ce post de blog revient sur les principaux atouts de <code>Polars</code>, sans vouloir être exhaustif. Un <em>notebook</em> illustrant les principales fonctionnalités du package vise à le compléter :</p>
<p><a href="https://datalab.sspcloud.fr/launcher/ide/jupyter-python?name=Tutoriel%20polars&amp;version=2.4.6&amp;s3=region-79669f20&amp;init.personalInit=«https%3A%2F%2Fraw.githubusercontent.com%2FSSPHub%2FFormation-polars%2Frefs%2Fheads%2Fmain%2Finit.sh»&amp;autoLaunch=true" target="_blank" rel="noopener"><img src="https://img.shields.io/badge/SSPcloud-Tester%20via%20SSP--cloud-informational&amp;color=yellow?logo=Python" alt="Onyxia"></a> <a href="https://colab.research.google.com/github/SSPHub/Formation-polars/blob/main/polars-tuto.ipynb" target="_blank" rel="noopener"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"></a></p>
<section id="les-secrets-de-la-performance" class="level1">
<h1>Les secrets de la performance</h1>
<p>Les <em>benchmarks</em> disponibles <a href="https://h2oai.github.io/db-benchmark/">sont clairs</a> : <code>Polars</code> est un ours qui court vite !</p>
<p>Le benchmark suivant, <a href="https://h2oai.github.io/db-benchmark/">effectué par H2O</a>, propose un comparatif de la vitesse des principaux frameworks de manipulation de données pour effectuer une agrégation par groupe avec un jeu de données de 50GB:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/polars/polars-benchmark-short.png" class="img-fluid figure-img"></p>
<figcaption>Benchmark H2O</figcaption>
</figure>
</div>
<p><code>Polars</code> devance des solutions connues pour leur efficacité sur ce type d’opérations, comme le package <code>R</code> <code>data.table</code>. L’utilisateur habituel de <code>Pandas</code> ne pourrait même pas traiter ces données, qui excèdent les capacités computationnelles de sa machine.</p>
<section id="lévaluation-lazy" class="level2">
<h2 class="anchored" data-anchor-id="lévaluation-lazy">L’évaluation <em>lazy</em></h2>
<p>Plusieurs éléments expliquent cette rapidité.</p>
<p>En premier lieu, <code>Polars</code> est conçu pour optimiser les requêtes : grâce au mode <em>lazy</em> (<em>“paresseux”</em>), on laisse la possibilité au moteur d’analyser ce qu’on souhaite faire pour proposer une exécution optimale (pour la lecture comme pour la transformation des jeux de données). La <em>lazy evaluation</em> est une méthode assez commune pour améliorer la vitesse des traitements et est utilisée, entre autres, par <code>Spark</code>.</p>
<p>Du fait de la <em>lazy evaluation</em> il est ainsi possible, par exemple, si un filtre sur les lignes arrive tardivement, de le remonter dans l’ordre des opérations effectuées par <code>Python</code> afin que les opérations ultérieures ne soient effectuées que sur l’ensemble optimal de données. Ces optimisations sont détaillées dans la <a href="https://pola-rs.github.io/polars-book/user-guide/optimizations/intro.html">documentation officielle</a>.</p>
</section>
<section id="lecture-optimisée-des-fichiers" class="level2">
<h2 class="anchored" data-anchor-id="lecture-optimisée-des-fichiers">Lecture optimisée des fichiers</h2>
<p>L’utilisateur <code>Pandas</code> est habitué à lire du CSV avec <code>pd.read_csv</code>. Avec <code>Polars</code>, il existe deux manières, très ressemblantes de le faire.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb1-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> polars <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> pl</span>
<span id="cb1-2"></span>
<span id="cb1-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Création d'une requête</span></span>
<span id="cb1-4">q <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (</span>
<span id="cb1-5">    pl.scan_csv(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"iris.csv"</span>) <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Lecture lazy</span></span>
<span id="cb1-6">    .<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">filter</span>(pl.col(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sepal_length"</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>)</span>
<span id="cb1-7">    .groupby(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"species"</span>)</span>
<span id="cb1-8">    .agg(pl.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">all</span>().<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>())</span>
<span id="cb1-9">)</span>
<span id="cb1-10"></span>
<span id="cb1-11"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Exécution de la requête</span></span>
<span id="cb1-12">df <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> q.collect()</span></code></pre></div></div>
<p>Avec cette syntaxe, les connaisseurs de <code>Pyspark</code> retrouveront facilement leurs petits (ours 🐻).</p>
<p>On peut toujours lire de manière plus directe (en mode <em>eager</em>, <em>“impatient”</em>) en utilisant la fonction <code>read_csv</code>, et ensuite appliquer des transformations optimisables en glissant habilement <code>lazy</code> :</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb2-1">df <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pl.read_csv(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"iris.csv"</span>)</span>
<span id="cb2-2"></span>
<span id="cb2-3">df_res <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> df.lazy() <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ←  ici :)</span></span>
<span id="cb2-4">  .<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">filter</span>(pl.col(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sepal_length"</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>)</span>
<span id="cb2-5">  .groupby(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"species"</span>)</span>
<span id="cb2-6">  .agg(pl.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">all</span>().<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>())</span>
<span id="cb2-7">  .collect()</span></code></pre></div></div>
<p><code>Polars</code> fonctionne également très bien avec le format <code>Parquet</code>, comme illustré dans le <em>notebook</em> qui accompagne ce <em>post</em>.</p>
</section>
<section id="parallélisation" class="level2">
<h2 class="anchored" data-anchor-id="parallélisation">Parallélisation</h2>
<p><code>Polars</code> parallélise les traitements dès que cela est possible, notamment dans le cas d’agrégation. Chaque coeur se charge d’une partie de l’agrégation et envoie des données plus légères à <code>Python</code> qui va finaliser l’agrégation.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/polars/polars-split-parallel-apply-combine.svg" class="img-fluid figure-img"></p>
<figcaption>Parallélisation</figcaption>
</figure>
</div>
<p><em>Illustration du principe de la parallélisation</em></p>
<p>Sur les systèmes proposant de nombreux coeurs, cela peut faire gagner beaucoup de temps.</p>
</section>
<section id="des-couches-basses-à-la-pointe" class="level2">
<h2 class="anchored" data-anchor-id="des-couches-basses-à-la-pointe">Des couches basses à la pointe</h2>
<p>Enfin, le choix d’utiliser à la fois le format de représentation en mémoire <a href="https://arrow.apache.org/">Arrow</a> et le langage <a href="https://www.rust-lang.org/fr">Rust</a> pour le coeur de la bibliothèque n’est pas étranger à cette performance.</p>
</section>
<section id="calculs-out-of-memory" class="level2">
<h2 class="anchored" data-anchor-id="calculs-out-of-memory">Calculs <em>out of memory</em></h2>
<p><code>Polars</code> travaille vite mais présente aussi l’avantage de lire naturellement des jeux de données hors des limites de la mémoire de l’ordinateur grâce à <a href="https://www.youtube.com/watch?v=3-C0Afs5TXQ">sa capacité de lire en flux</a> (méthode qu’on appelle le <em>streaming</em>).</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb3-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># La même requête que tout à l'heure va lire le fichier "en flux"</span></span>
<span id="cb3-2">df <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> q.collect(streaming<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>)</span></code></pre></div></div>
<p>De plus, <code>Polars</code> lit nativement les fichiers <code>Parquet</code> qui par ses propriétés permet d’aller beaucoup plus vite que le CSV !</p>
</section>
</section>
<section id="une-api-fluide" class="level1">
<h1>Une API fluide</h1>
<p>C’est un reproche régulièrement fait à <code>Pandas</code> : la syntaxe de manipulations des données est parfois complexe ou peu lisible, et les choix d’écriture ne sont pas transparents du point de vue des performances.</p>
<p>L’API proposée par Polars est à la fois expressive et transparente. Voici un exemple d’exploitation de la BPE, issu du <em>notebook</em> accompagnant ce <em>post</em> :</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb4-1">df.lazy()</span>
<span id="cb4-2">  .<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">filter</span>(</span>
<span id="cb4-3">    pl.col(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"TYPEQU"</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"B316"</span></span>
<span id="cb4-4">  )</span>
<span id="cb4-5">  .groupby(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"DEP"</span>)</span>
<span id="cb4-6">  .agg(</span>
<span id="cb4-7">    pl.count().alias(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"NB_STATION_SERVICE"</span>)</span>
<span id="cb4-8">  )</span>
<span id="cb4-9">  .collect()</span></code></pre></div></div>
<p>On retrouve une sémantique d’opérations de haut niveau qui s’enchaînent à la manière de <a href="https://www.book.utilitr.org/03_fiches_thematiques/fiche_tidyverse#comment-utiliser-lop%C3%A9rateur-pipe-avec-le-tidyverse">ce que l’on peut faire en <code>dplyr</code></a>.</p>
</section>
<section id="les-autres-concurrents" class="level1">
<h1>Les autres concurrents</h1>
<p><code>Pandas</code> et <code>Polars</code> ne sont pas seuls dans le grand zoo de la manipulation de données en Python : des solutions comme <a href="https://github.com/vaexio/vaex">Vaex</a> ou <a href="https://github.com/dask/dask">Dask</a> ont des arguments à faire valoir. <code>DuckDB</code>, un autre <em>framework</em> de manipulation de données, s’intègre quand à lui très bien avec <code>Polars</code> dans la ménagerie.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/polars/dalle_polar_duck.png" class="img-fluid quarto-figure quarto-figure-center figure-img" style="width:40.0%"></p>
</figure>
</div>
<p><em>Le duo DuckDB-Polars illustré par Dall-E-2</em></p>
</section>
<section id="ressources-supplémentaires" class="level1">
<h1>Ressources supplémentaires</h1>
<ul>
<li><a href="https://github.com/ddotta/awesome-polars"><em>Awesome Polars</em> par Damien Dotta (INSEE)</a></li>
<li><a href="https://rpolars.github.io/">Polars pour R</a></li>
<li><a href="https://www.rhosignal.com/tags/polars/">rhosignal.com/tags/polars/</a></li>
<li><a href="https://kevinheavey.github.io/modern-polars/">kevinheavey.github.io/modern-polars/</a></li>
</ul>


</section>

 ]]></description>
  <category>Python</category>
  <category>Pandas</category>
  <category>Polars</category>
  <category>Data wrangling</category>
  <guid>https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/polars/</guid>
  <pubDate>Fri, 10 Feb 2023 00:00:00 GMT</pubDate>
  <media:content url="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/polars/featured.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>Infolettre n°9</title>
  <link>https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/recap2022/</link>
  <description><![CDATA[ 





<p><em>Vous désirez intégrer la liste de diffusion ? Un mail à <a href="mailto:contact-ssphub@insee.fr" class="email">contact-ssphub@insee.fr</a> suffit</em></p>
<p>La <a href="../../blog/retrospective2022/index.html">rétrospective de l’année 2022</a> promettait une version plus personnalisée, inspirée des visualisations proposées par les réseaux sociaux pour synthétiser l’activité de leurs utilisateurs.</p>
<p>Cette <em>newsletter</em> un peu spéciale propose un retour sur la première année du réseau des data scientists de la statistique publique dont la préfiguration a commencé en mars 2022 et qui a été lancé officiellement en septembre. Vous pourrez retrouver à la fin de la <em>newsletter</em> des informations plus classiques: événements, retour sur les actions du réseau, formations, etc.</p>
<p>Elle permet aussi d’illustrer le potentiel d’outils qui ont été présentés dans la <a href="../../blog/retrospective2022/index.html">rétrospective de l’année 2022</a>. Toutes les figures sont réactives, notamment quand vous passez votre souris dessus. Les principaux ingrédients qui ont été ici utilisés, et qui avaient été mentionnés dans la première partie de la rétrospective, sont <code>Observable</code>, <code>Quarto</code> et <code>DuckDB</code>. Les données sont stockées sur le système de stockage <code>S3</code> du <code>SSPCloud</code>.</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>Ce <em>notebook</em> utilise certaines les fonctionalités d’<code>Observable</code> pour proposer des visualisations interactives de manière efficace.</p>
<details>
<summary>
<p>Si vous êtes intéressés par le <em>making-of</em> de cette page <em>web</em>, cliquez sur le menu déroulant (partie plus technique).</p>
</summary>
<p><br> <code>Observable</code> est à la fois un langage visant à simplifier l’usage de <code>JavaScript</code> pour mettre en oeuvre des visualisations interactives et une <a href="https://observablehq.com/">plateforme</a> permettant de simplifier la mise à disposition de ces visualisations sous une forme de <em>notebook</em>.</p>
<p>Les statistiques de comptage sont enregistrées sous format <code>Parquet</code> sur le système de stockage <code>S3</code> du <code>SSPCloud</code>. L’intégration native de <code>DuckDB</code> à <code>Observable</code> permet au navigateur <em>web</em> de lire et d’effectuer des manipulations de données à travers des requêtes SQL de manière très efficace. Sur ce sujet, outre la <a href="https://observablehq.com/@observablehq/duckdb">documentation officielle d’<code>Observable</code></a>, je recommande vivement le <a href="https://observablehq.com/@ericmauviere/duckdb-redonne-nouvelle-vie-sql">tutoriel d’Eric Mauvière</a>.</p>
<p>La librairie <a href="https://observablehq.com/@observablehq/plot"><code>Plot</code></a> propose de nombreuses fonctionalités utiles pour construire des visualisations interactives. Sa logique est assez proche de celle des <em>frameworks</em> <a href="https://observablehq.com/@observablehq/plot-from-ggplot2"><code>ggplot2</code> en <code>R</code></a> ou <a href="https://observablehq.com/@observablehq/plot-overview-for-matplotlib-users"><code>matplotlib</code> en <code>Python</code></a>. Lorsque la librairie <code>Plot</code> n’est plus suffisante, comme pour le <em>treemap</em> sur cette page, le <em>framework</em> <code>d3.js</code> est utile.</p>
<p>L’intégration de figures construites à partir du langage <code>Observable</code> peut être faite de plusieurs manières:</p>
<ul>
<li>Utiliser <a href="https://quarto.org/docs/interactive/ojs/"><code>Quarto</code></a> qui permet de créer une page <em>web</em> statique autosuffisante à partir d’une suite d’instructions dans des blocs <code>{ojs}</code>. Cette méthode est très intéressante pour l’intégration de figures <code>JavaScript</code> dans des sites <em>web</em> complets générés de manière automatique. Bien qu’initialement envisagée, cette méthode ne fait pas encore bon ménage avec <a href="https://gohugo.io/"><code>Hugo</code></a> qui n’attend pas des <code>Quarto Markdown</code> mais des <code>Markdown</code> classiques</li>
<li>Utiliser la plateforme <a href="https://observablehq.com/@linogaliana"><code>observablehq</code></a> pour créer un <em>notebook</em> proposant le code à l’origine des visualisations puis intégrer ces dernières par le biais d’<code>&lt;iframe&gt;</code> ou de l’intégration via <code>Runtime JS</code>. Cela permet d’avoir ces visualisations sur une page statique sans stocker au même endroit le code ayant permis de les générer et permettant de les reproduire, qui n’intéresse pas nécessairement le même public.</li>
</ul>
<p>La deuxième approche, celle de l’intégration depuis un <em>notebook</em> <code>observable</code> a été choisie. Ce <em>notebook</em> est disponible sur <a href="https://observablehq.com/@linogaliana/2022-year-recap-data-scientists-network">la plateforme</a> pour les utilisateurs intéressés par la réutilisation des figures, des données sous-jacentes ou des utilitaires ayant permis d’aboutir à certaines visualisations. Le code source de cette page, disponible sur le <a href="https://raw.githubusercontent.com/InseeFrLab/ssphub/main/content/blog/recap2022/index.md"><code>Github inseefrlab/ssphub</code></a> illustre la manière dont les figures peuvent être intégrées à un site <em>web</em> depuis la plateforme <a href="https://observablehq.com/"><code>observablehq</code></a>. Bien que j’ai privilégié la méthode <code>Runtime JS</code>, qui permet d’intégrer la visualisation sans le bandeau <code>Observable</code> sous la figure, pour certaines d’entre elles, j’ai dû utiliser la méthode <code>&lt;iframe&gt;</code> du fait de certaines limitations dans l’héritage de règles CSS aux <code>svg</code> générés par <code>Plot</code> qui affectaient la colorisation et donc la lecture de certaines figures.</p>
</details>
</div>
</div>
<section id="lannée-du-réseau" class="level2">
<h2 class="anchored" data-anchor-id="lannée-du-réseau">L’année du réseau</h2>
<p>Le réseau comporte deux canaux de communication: une liste de diffusion mail et un canal de discussions instantanées. Intéressons nous d’abord à la liste de diffusion mail !</p>
<div id="observablehq-evolution-bbfd8ffe">

</div>
<p>Pendant l’année 2022, <strong>7 <em>newsletters</em></strong> ont été diffusées par mail. Chacune a permis d’augmenter sensiblement le nombre de personnes dans la liste de diffusion. A la fin de l’année, il y avait <strong>312 inscrits</strong><sup>1</sup> dans la liste de diffusion.</p>
<p>Le réseau a organisé <strong>trois événements</strong> pendant l’année 2022. D’abord, avant l’été, deux <em>open hours</em> ont eu lieu. Cet événement informel prenant la forme de retour d’expérience a été l’occasion de discussions stimulantes autour de d’usage de la <em>data science</em> pour l’administration. En novembre, l’<a href="../../event/presentation-dobservable-par-nicolas-lambert/">événement autour d’<code>Observable</code></a> animé par <a href="https://observablehq.com/@neocartocnrs">Nicolas Lambert</a> a réuni près de 50 personnes.</p>
</section>
<section id="répartition-des-modes-daccès-au-réseau" class="level2">
<h2 class="anchored" data-anchor-id="répartition-des-modes-daccès-au-réseau">Répartition des modes d’accès au réseau</h2>
<p>Le réseau propose <strong>deux canaux de diffusion</strong> de l’information: une liste de diffusion par mail et un canal de discussion instantanée qui utilise la messagerie sécurisée de l’Etat <a href="https://www.tchap.gouv.fr/"><code>Tchap</code></a>. Environ <strong>55%</strong> des membres de la liste de diffusion (soit plus de 180 personnes) sont également inscrits sur le canal de discussion instantanée.</p>
<iframe width="100%" height="529" frameborder="0" src="https://observablehq.com/embed/@linogaliana/2022-year-recap-data-scientists-network?cells=repartition">
</iframe>
</section>
<section id="composition-du-réseau" class="level2">
<h2 class="anchored" data-anchor-id="composition-du-réseau">Composition du réseau</h2>
<p>La diffusion d’informations par le réseau a permis de réunir des <em>data scientists</em> de <strong>27 organisations différentes</strong>. L’<a href="https://www.insee.fr/fr/accueil">Insee</a>, qui représente 47% de l’effectif du réseau, est majoritaire. Suivent dans le palmarès, les services statistiques du <a href="https://drees.solidarites-sante.gouv.fr/">Ministère de la Santé (DREES)</a> et du <a href="https://www.statistiques.developpement-durable.gouv.fr/">Ministère du Développement Durable (SDES)</a>.</p>
<div id="observablehq-treemap_network-81108356">

</div>
</section>
<section id="évolution-de-la-composition-du-réseau" class="level2">
<h2 class="anchored" data-anchor-id="évolution-de-la-composition-du-réseau">Évolution de la composition du réseau</h2>
<p>La diffusion progressive d’informations par le biais des <em>newsletters</em> a permis de diversifier progressivement la composition de la liste de diffusion. Alors que la première <em>newsletter</em> de l’année 2022 avait été diffusée auprès de <strong>14 institutions</strong>, ce sont des agents de <strong>27 organisations</strong> qui ont reçues la dernière.</p>
<p>Les événements organisés par le réseau ou les présentations spéciales, comme celle pour les <a href="https://prez-nouveaux-admin-ssphub-20221125.netlify.app/#/title-slide">administrateurs de l’INSEE en poste à l’ENSAE</a>, ont également pu motiver des personnes à intégrer le réseau.</p>
<div id="observablehq-grid-bbfd8ffe">

</div>
</section>
<section id="programme-10" class="level2">
<h2 class="anchored" data-anchor-id="programme-10">Programme 10%</h2>
<p>Les membres du réseau des <em>data scientists</em> ont été particulièrement actifs dans le cadre du <strong><a href="https://10pourcent.etalab.studio/">programme interministériel 10%</a></strong>, issu des recommandations d’un <a href="https://www.numerique.gouv.fr/uploads/RAPPORT-besoins-competences-donnee.pdf">rapport INSEE-DINUM “Évaluation des besoins de l’État en compétences et expertises en matière de donnée”</a>.</p>
<p>La saison 1 a donné sa chance à <strong>quatre projets</strong>, portés par différentes administrations. Si l’un d’eux existait déjà depuis plus de deux ans (projet <a href="https://github.com/spyrales/gouvdown"><code>Gouvdown</code></a>), trois sont nés pour l’occasion, avec la mise en ligne de code immédiate (<code>Cartiflette</code>) ou postérieure au <em>bootcamp</em> de lancement (<code>Socratext</code> et <code>matchSIRET</code>) .</p>
<p>Tous les projets sont ouverts et disponible sur <code>Github</code>. Une statistique qui permet de représenter leur succès est le nombre de ⭐: c’est un peu un mélange entre un site en favori sous <code>Firefox</code> puisque cela permet de facilement retrouver un projet dans <code>Github</code> et le nombre de <em>followers</em> d’une page sur <code>Facebook</code> ou sur <code>Twitter</code> puisque cela permet de suivre l’activité d’un dépôt <code>Github</code>.</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>Cette visualisation fait appel à l’API <code>Github</code>. Si les figures ne s’affichent pas, cela peut être dû à un dépassement du nombre de requêtes par heure autorisées par l’API <code>Github</code> sans jeton. A l’heure actuelle, il n’existe pas encore de fonctionalité gratuite sous <code>Observable</code> pour stocker de manière sécurisée un jeton pour l’API <code>Github</code>.</p>
<details>
<summary>
Dérouler pour afficher une version non réactive
</summary>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/recap2022/cartiflette.png" class="img-fluid figure-img"></p>
<figcaption>Projet <code>cartiflette</code></figcaption>
</figure>
</div>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/recap2022/socratext.png" class="img-fluid figure-img"></p>
<figcaption>Projet <code>Socratext</code></figcaption>
</figure>
</div>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/recap2022/gouvdown.png" class="img-fluid figure-img"></p>
<figcaption>Projet <code>Gouvdown</code></figcaption>
</figure>
</div>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/recap2022/matchsiret.png" class="img-fluid figure-img"></p>
<figcaption>Projet <code>matchSIRET</code></figcaption>
</figure>
</div>
</details>
</div>
</div>
<iframe width="100%" height="967" frameborder="0" src="https://observablehq.com/embed/@linogaliana/2022-year-recap-data-scientists-network?cells=containeur_github"></iframe>
</section>
<section id="autres-actualités-du-réseau" class="level2">
<h2 class="anchored" data-anchor-id="autres-actualités-du-réseau">Autres actualités du réseau</h2>
<section id="présentation-de-gridviz-par-julien-gaffuri" class="level3">
<h3 class="anchored" data-anchor-id="présentation-de-gridviz-par-julien-gaffuri">Présentation de <code>Gridviz</code> par Julien Gaffuri</h3>
<p>Pour rappel, le <strong>20 Janvier 2023 de 11h à 12h30</strong> Julien Gaffuri (Eurostat) viendra nous présenter la librairie open-source <a href="https://eurostat.github.io/gridviz/"><code>Gridviz</code></a>. Réservez ce créneau pour découvrir cette librairie qui ouvre de nouvelles perspectives pour la mise à disposition de données géographiques !</p>
<p><a href="gridviz.ics">Télécharger l’invitation à l’événement sous format <code>Outlook</code></a></p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/recap2022/gridviz.png" class="img-fluid figure-img" style="width:70.0%"></p>
<figcaption>Source: <a href="https://observablehq.com/@neocartocnrs/hello-gridviz">Notebook <code>Hello Gridviz</code> par <code>neocarto</code> sur <code>Observable</code></a></figcaption>
</figure>
</div>
</section>
<section id="première-place-européenne-au-hackathon-big-data-de-lonu" class="level3">
<h3 class="anchored" data-anchor-id="première-place-européenne-au-hackathon-big-data-de-lonu">Première place européenne au <em>hackathon</em> Big Data de l’ONU</h3>
<p>Les résultats du <em>hackathon big data</em> de l’ONU, ayant eu lieu du 7 au Novembre 2022, ont été annoncés ! L’<a href="https://github.com/InseeFrLab/hackathon-un-2022">équipe <code>Datadive</code></a> - constituée de membres du réseau de l’INSEE, de la DGFIP et du CASD - est arrivée à la <a href="https://unstats.un.org/bigdata/events/2022/hackathon/winners-bde.cshtml">première place des équipes européennes</a> 🎉.</p>
</section>
<section id="git-et-bonnes-pratiques-des-formations-de-formateurs-prévus-pour-les-statisticiens-publics" class="level3">
<h3 class="anchored" data-anchor-id="git-et-bonnes-pratiques-des-formations-de-formateurs-prévus-pour-les-statisticiens-publics"><code>Git</code> et bonnes pratiques: des formations de formateurs prévus pour les statisticiens publics</h3>
<p>Les nouvelles formations à <code>Git</code> et aux bonnes pratiques avec <code>R</code>, testées récemment à l’Insee et au service statistique du Ministère du Travail, la DARES, (voir <em>newsletters</em> de <a href="https://minio.lab.sspcloud.fr/ssphub/diffusion/website/infolettre_old/Infolettre_n6.pdf">Novembre</a> et <a href="https://minio.lab.sspcloud.fr/ssphub/diffusion/website/infolettre_old/Infolettre_n7.pdf">Décembre</a>), deviennent des formations nationales.</p>
<p>Pour pouvoir diffuser les bonnes pratiques favorisant le partage de codes et la qualité des projets statistiques, il est nécessaire d’avoir le plus d’enseignants possibles pour cette formation. Pour permettre cela, un appel à candidat pour une <strong>formation de formateurs</strong> a été diffusée à l’Insee et dans les services statistiques ministériels. Si vous êtes intéressés et ne l’avez pas reçu, n’hésitez pas à envoyer un mail à <a href="mailto:contact-ssphub@insee.fr" class="email">contact-ssphub@insee.fr</a>.</p>
<p>En attendant, les supports de ces formations sont déjà disponibles sur <a href="https://inseefrlab.github.io/formation-bonnes-pratiques-git/#/title-slide">inseefrlab.github.io/formation-bonnes-pratiques-git/</a> et sur <a href="https://inseefrlab.github.io/formation-bonnes-pratiques-R/#/title-slide">inseefrlab.github.io/formation-bonnes-pratiques-R/</a>. Les codes sources sont bien-sûr ouverts et disponibles sur <code>Github</code>, tant pour la <a href="https://github.com/InseeFrLab/formation-bonnes-pratiques-git">première partie</a> que pour <a href="https://github.com/InseeFrLab/formation-bonnes-pratiques-R">la seconde</a>. Ceux-ci sont construits collectivement, n’hésitez pas à suggérer des modifications depuis <code>Github</code>.</p>
<p>Un site web plus complet devrait prochainement voir le jour pour accompagner cette formation. En complément de celui-ci, des éléments peuvent déjà être trouvés dans le cours de 3e année de l’ENSAE sur la <a href="https://ensae-reproductibilite.netlify.app/">mise en production de projets <em>data science</em></a> et dans la documentation collaborative <a href="https://www.utilitr.org/"><code>utilitR</code></a>.</p>
<style media="screen">


  #observablehq-evolution-bbfd8ffe .has-title {
    font-size: 18px;
  }


  #observablehq-treemap_network-81108356 .has-title {
    fill: black;
    font-size: 18px;
    font-weight: bold;
  }

  .slidecontainer {
    width: 100%;
  }

  .slider {
    -webkit-appearance: none;
    width: 100%;
    height: 15px;
    border-radius: 5px;
    background: #d3d3d3;
    outline: none;
    opacity: 0.7;
    -webkit-transition: .2s;
    transition: opacity .2s;
  }

  .slider:hover {
    opacity: 1;
  }

  .slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 25px;
    height: 25px;
    border-radius: 50%;
    background: #4CAF50;
    cursor: pointer;
  }

  .slider::-moz-range-thumb {
    width: 25px;
    height: 25px;
    border-radius: 50%;
    background: #4CAF50;
    cursor: pointer;
  }

  svg {
    background-color: white !important;
    color: black !important;
  }
  
  figure figcaption {
    /* text-align: center; */
    text-align: left;
  }
.fullwidth {
  width: 100vw;
  position: relative;
  left: 50%;
  right: 50%;
  margin-left: -50vw;
  margin-right: -50vw;
}  
</style>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@observablehq/inspector@5/dist/inspector.css">
<script type="module">
import {Runtime, Inspector} from "https://cdn.jsdelivr.net/npm/@observablehq/runtime@5/dist/runtime.js";
import define from "https://api.observablehq.com/@linogaliana/2022-year-recap-data-scientists-network.js?v=3";
new Runtime().module(define, name => {
  if (name === "evolution") return new Inspector(document.querySelector("#observablehq-evolution-bbfd8ffe"));
  if (name === "treemap_network") return new Inspector(document.querySelector("#observablehq-treemap_network-81108356"));
  if (name === "grid") return new Inspector(document.querySelector("#observablehq-grid-bbfd8ffe"));
});
</script>


</section>
</section>


<div id="quarto-appendix" class="default"><section id="footnotes" class="footnotes footnotes-end-of-document"><h2 class="anchored quarto-appendix-heading">Notes de bas de page</h2>

<ol>
<li id="fn1"><p>Les actions de communication du mois de janvier ont permis d’augmenter sensiblement le nombre de personnes dans cette liste (340 début janvier). Un retour spécial sur le mois de janvier sera l’occasion idéale pour une autre rétrospective quantitative.↩︎</p></li>
</ol>
</section></div> ]]></description>
  <category>Insee</category>
  <category>Retrospective</category>
  <category>Infolettre</category>
  <guid>https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/recap2022/</guid>
  <pubDate>Tue, 10 Jan 2023 00:00:00 GMT</pubDate>
  <media:content url="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/recap2022/featured.png" medium="image" type="image/png" height="80" width="144"/>
</item>
<item>
  <title>Rétrospective de l’année 2022</title>
  <link>https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/retrospective2022/</link>
  <description><![CDATA[ 





<p><em>Vous désirez intégrer la liste de diffusion ? Un mail à <a href="mailto:contact-ssphub@insee.fr" class="email">contact-ssphub@insee.fr</a> suffit</em></p>
<p>La fin de l’année est généralement synonyme de bétisiers, <em>best of</em> ou rétrospectives personnalisées qui nous permettent de nous rappeler les événements marquants de l’année.</p>
<p>Pour célébrer la fin de l’année 2022, la <em>newsletter</em> de janvier adopte un format un peu spécial pour proposer, en deux temps, deux rétrospectives.</p>
<p>Cette première <em>newsletter</em> revient sur les principaux événements de l’année 2022 dans le monde de la <em>data science</em>. La <a href="../../blog/retrospective2022/index.html">seconde <em>newsletter</em></a> proposera une rétrospective quantitative sur le réseau des <em>data scientists</em> de la statistique publique, à la manière des rétrospectives personnalisées de nos applications préférées.</p>
<section id="les-ia-créatrices-de-contenu-à-lhonneur" class="level1">
<h1>Les IA créatrices de contenu à l’honneur</h1>
<p>Si l’année 2022 a été particulièrement riche dans le domaine de la <em>data science</em>, c’est principalement grâce à deux coups médiatiques d’<a href="https://openai.com/">OpenAI</a>, à savoir <a href="https://openai.com/dall-e-2/"><code>Dall-E</code></a> et <a href="https://openai.com/blog/chatgpt/"><code>ChatGPT</code></a>.</p>
<p>Ces deux outils ont beaucoup fait parler d’eux, au-delà de la sphère traditionnelle de la <em>data science</em>. Le <em>buzz</em> a été intense sur <code>Twitter</code> ou sur <code>Mastodon</code>, le réseau social dont le nombre d’utilisateurs a nettement augmenté en réaction au rachat de <code>Twitter</code> par Elon Musk en fin d’année.</p>
<p><img src="https://i.chzbgr.com/full/9717138688/hC5E738A3/chatgpt-will-see-all-criticisms-its-training-data-on-next-update-some-are-not-surviving-uprising.png" class="img-fluid" style="width:60.0%"></p>
<p>Ces innovations, parce qu’elles pourraient avoir des effets à long terme sur la manière dont le grand public appréhende l’intelligence artificielle, ont beaucoup intéressé les médias traditionnels, notamment <a href="https://www.lemonde.fr/economie/article/2022/12/06/chatgpt-le-logiciel-capable-d-ecrire-des-petits-textes-confondants_6153252_3234.html"><em>Le Monde</em></a>, <a href="https://www.economist.com/news/2022/06/11/how-a-computer-designed-this-weeks-cover"><em>The Economist</em> et sa <em>“Nouvelle Frontière”</em></a> ou <a href="https://www.theguardian.com/commentisfree/2022/dec/10/i-wrote-this-column-myself-but-how-long-before-a-chatbot-could-do-it-for-me">le <em>Guardian</em></a> qui s’interroge sur la nature des tâches que l’intelligence artificielle pourra remplacer à terme : procédurales et régies par des règles bien définies ou bien également des activités nécessitant de la créativité et des capacités d’analyse ?</p>
<p>Pour une fois, il ne s’agit donc pas de souligner exclusivement les limites de ces modèles voire leurs dérives (<a href="https://fr.wikipedia.org/wiki/Deepfake"><em>deep fake</em></a>, <a href="https://www.washingtonpost.com/technology/2022/07/16/racist-robots-ai/">biais racistes</a>…) mais aussi de s’enthousiasmer sur leur <a href="https://www.platformer.news/p/how-dall-e-could-power-a-creative">potentiel créatif</a>. Il est difficile de rester insensible à certaines des créations artistiques des modèles <a href="https://dalle2.gallery/#search-random"><code>Dall-E</code></a>, <a href="https://stablediffusion.fr/gallery"><code>Stable Diffusion</code></a>, <a href="https://www.midjourney.com/showcase/recent/">Midjourney</a> et consorts ou de résister à la tentation de tester la capacité de <code>ChatGPT</code> à répondre à des questions complexes Les chercheurs, et pas des moindres (notamment <a href="https://twitter.com/andrewyng/status/1600284752258686976?lang=fr">Andrew Ng</a> ou <a href="https://theconversation.com/beau-parleur-comme-une-ia-196084">Gaël Varoquaux</a>) se sont également saisis de cette question et ont souligné les biais de raisonnement et excès de confiance de ces IA.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://raw.githubusercontent.com/CompVis/stable-diffusion/2ff270f4e0c884d9684fa038f6d84d8600a94b39/assets/stable-samples/txt2img/merged-0006.png" class="img-fluid figure-img"></p>
<figcaption>https://github.com/Stability-AI/stablediffusion</figcaption>
</figure>
</div>
<p>Si vous désirez utiliser <code>Python</code> de manière créative pour générer du contenu avec <code>Stable Diffusion</code>, vous pouvez consulter <a href="https://pythonds.linogaliana.fr/dalle/">ce tutoriel</a> qui fonctionne sur le <a href="https://www.sspcloud.fr/"><code>SSPCloud</code></a> ou sur <code>Google Colab</code>.</p>
<p><img src="https://i.chzbgr.com/full/9717140480/hD779E54E/writing-shit-like-elon-musk-suicide-note-and-robert-ebert-goncharov-review-please-stop-need-sleep.png" class="img-fluid" style="width:50.0%"></p>
</section>
<section id="le-succès-des-modèles-de-diffusion" class="level1">
<h1>Le succès des modèles de diffusion</h1>
<p>Ces <a href="https://pub.towardsai.net/generative-ai-and-future-c3b1695876f2">IA génératrices de contenu</a> reposent toutes, à plusieurs niveaux, sur des réseaux de neurone.</p>
<p>Le premier étage de la fusée est un <a href="https://en.wikipedia.org/wiki/Language_model">modèle de langage</a> (<em>large language model</em>) qui synthétise un langage en un ensemble complexe de paramètres. Les plus connus sont <a href="https://en.wikipedia.org/wiki/BERT_(language_model)">BERT</a> et <a href="https://en.wikipedia.org/wiki/GPT-3">GPT-3</a>. L’inflation dans le nombre de paramètres n’est pas prête de s’arrêter. Si les ressources nécessaires à entraîner en 2018 le modèle BERT (110 millions de paramètres) avaient déjà <a href="https://arxiv.org/abs/1906.02243">été critiquées</a> en raison de leur coût financier et environnemental, cette complexité a encore augmenté depuis. Le modèle <code>GPT-3</code>, sorti en 2020, et qui sert de base à <code>Dall-E</code> et <code>ChatGPT</code> intègre 175 milliards de paramètres. Un chiffre qui apparaît minime par rapport aux 17O trillions de paramètres attendus pour le modèle <code>GPT-4</code> en 2023.</p>
<p>En ce qui concerne les IA créatrices de contenu visuel, le deuxième étage de la fusée est un modèle d’analyse d’image qui apprend à associer des images à une description textuelle afin de détecter des structures communes entre des mots ou des séquences de mots et des formes sur des images. Il s’agit de déconstruire une forme en une structure minimale de pixels qui permet de l’identifier.</p>
<figure class="figure">
<img src="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb4ef038-9c72-42b5-9383-26952d95aea0_740x141.jpeg" alt="Illustration d'un modèle de diffusion" class="figure-img">
<figcaption>
<i>Source: <a href="https://magazine.sebastianraschka.com/p/ahead-of-ai-1-a-diffusion-of-innovations" target="_blank">Sebastian Raschka</a></i>
</figcaption>
</figure>
<p>Ensuite, pour générer une image à partir d’une description inédite intervient le <a href="https://en.wikipedia.org/wiki/Diffusion_model">modèle de diffusion</a> qui reconstruit une image à partir du mélange de l’ensemble des pixels qui traduisent les concepts principaux d’une instruction. L’une des explications les plus pédagogiques pour comprendre le fonctionnement de ces modèles vient du <a href="https://www.washingtonpost.com/technology/interactive/2022/ai-image-generator/"><em>Washington Post</em></a>.</p>
<p>Sinon, on peut demander directement à <code>ChatGPT</code> de nous expliquer:</p>
<p><img src="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/retrospective2022/diffusion.png" class="img-fluid"></p>
</section>
<section id="lactualité-dans-le-monde-du-deep-learning" class="level1">
<h1>L’actualité dans le monde du <em>deep learning</em></h1>
<p>Si le succès d’estime de ces IA génératrices consacre les modèles de diffusion, l’année du <em>deep learning</em> ne se réduit pas à cette actualité.</p>
<p>L’année a notamment été marquée par la compétition entre les librairies et écosystèmes <a href="https://www.tensorflow.org/?hl=fr"><code>TensorFlow</code></a>, développé par <code>Google</code>, et <a href="https://pytorch.org/"><code>PyTorch</code></a> projet initié par <code>Facebook/Meta</code>. <code>PyTorch</code>, plus récent, bénéficie d’une dynamique plus ascendante que <code>TensorFlow</code>. Le <a href="https://twitter.com/huggingface/status/1609162974626779136?s=20&amp;t=XUCGBC_PL60IdHjia8wXNA">succès d’<code>HuggingFace</code></a>, plateforme de mise à disposition de modèles, et où les <a href="https://www.assemblyai.com/blog/pytorch-vs-tensorflow-in-2022/#pytorch-vs-tensorflowmodel-availability">implémentations <code>PyTorch</code> sont systématiques alors que celles en <code>TensorFlow</code> sont rares</a> a participé à la diffusion de <code>PyTorch</code>.</p>
<p>Preuve du succès de <code>PyTorch</code>, cet écosystème est dissocié de <code>Meta</code> depuis septembre afin de devenir un outil généraliste <a href="https://www.linuxfoundation.org/blog/blog/welcoming-pytorch-to-the-linux-foundation">géré par la <code>Linux Foundation</code></a>. À l’inverse, <a href="https://twitter.com/ylecun/status/1538419932475555840"><code>Google</code> semble se détacher graduellement de <code>TensorFlow</code></a> pour privilégier son nouvel écosystème <code>JAX</code>.</p>
</section>
<section id="du-changement-côté-rstudio" class="level1">
<h1>Du changement côté <code>RStudio</code></h1>
<p>Depuis quelques années, <code>RStudio</code> a fait le choix de devenir un écosystème de <em>data science</em> généraliste et non plus exclusivement attaché au langage <code>R</code>.</p>
<p>Cette année, cela s’est traduit par la publication, très commentée, de <a href="https://quarto.org/"><code>Quarto</code></a> qui vise à proposer, dans de nombreux langages de programmation, des fonctionalités de publications reproductibles équivalentes à l’un des produits emblématiques de <code>RStudio</code>, à savoir <a href="https://rmarkdown.rstudio.com/"><code>R Markdown</code></a>. Rien de mieux pour être convaincu de l’intérêt de cet outil que d’observer <a href="https://quarto.org/docs/gallery/">la galerie d’exemples</a>, d’explorer <a href="https://quarto.org/">la documentation très riche</a>, ou de <a href="https://quarto.org/docs/get-started/hello/rstudio.html">tester soi-même</a> sur un exemple. Cet été, <code>RStudio</code> a également annoncé que <code>Shiny</code>, un autre produit emblématique, serait maintenant disponible sous <a href="https://shiny.rstudio.com/py/"><code>Python</code></a>, comme alternative à <a href="https://dash.plotly.com/"><code>Dash</code></a> ou <a href="https://streamlit.io/"><code>Streamlit</code></a>.</p>
<p>L’année 2022 a été l’occasion, pour <code>RStudio</code>, d’un autre changement, symbolique celui-ci. Afin de détacher son image du langage <code>R</code>, l’entreprise a en effet changé de nom pour devenir <a href="https://posit.co/"><code>posit</code></a>. L’entreprise n’a néanmoins pas abandonné son activité foisonnante dans <code>R</code> puisque Hadley Wickham a commencé à publier de nouveaux chapitres pour une nouvelle édition augmentée de l’ouvrage de référence <a href="https://r4ds.had.co.nz/"><em>R For Data Science</em></a>.</p>
</section>
<section id="observable-devient-un-incontournable-dans-le-monde-de-la-dataviz" class="level1">
<h1><code>Observable</code> devient un incontournable dans le monde de la dataviz</h1>
<p>Pour permettre des visualisations interactives, cela fait plusieurs années que <code>JavaScript</code> est un incontournable et que le <a href="https://fr.wikipedia.org/wiki/WebAssembly"><em>web assembly</em></a> retient <a href="https://twitter.com/solomonstre/status/1111004913222324225">de plus en plus d’attention</a>.</p>
<p>Les journaux traditionnels utilisent ainsi de plus en plus le <em>data scrollytelling</em> , cette technique de narration qui consiste à présenter des informations sous forme de récit interactif, en utilisant une combinaison de texte et de graphiques qui apparaissent et disparaissent en fonction des actions du lecteur. L’un des exemples les plus réussis des dernières années a sans doute été la visualisation du <a href="https://www.nytimes.com/interactive/2020/03/22/world/coronavirus-spread.html"><em>New York Times</em> <em>“How the virus got out”</em></a>. Cette approche a également été adoptée par le Ministère de l’Agriculture pour diffuser les chiffrés clés du <a href="https://vizagreste.agriculture.gouv.fr/">recensement agricole</a>. Nos voisins anglais ne sont pas en reste puisque les derniers résultats du recensement sont proposés sur un <a href="https://www.ons.gov.uk/census/maps/choropleth/population/age/resident-age-3a/aged-16-to-64-years">site web remarquable de fluidité</a>.</p>
<p>Afin de permettre une diffusion accrue de visualisations en <code>JavaScript</code>, <a href="https://en.wikipedia.org/wiki/Mike_Bostock">Mike Bostock</a>, déjà créateur de la librairie de dataviz de référence <a href="https://en.wikipedia.org/wiki/D3.js"><code>D3.js</code></a>, est à l’origine de la plateforme <a href="https://observablehq.com/"><code>observable</code></a>, sorte de <code>Github</code> de la <em>dataviz</em> permettant du partage et de la réutilisation de <em>notebooks</em> réactifs. En cette année 2022, la plateforme a connu un véritable <em>boom</em> et est devenu un incontournable dans le domaine. L’une des raisons est l’ajout de fonctionalités qui permettent d’étendre le public cible au delà des développeurs <em>web</em>, déjà accoutumés à <code>Javascript</code>. Parmi les fonctionalités les plus remarquables, la possibilité depuis Novembre d’utiliser des <a href="https://observablehq.com/@ericmauviere/duckdb-redonne-nouvelle-vie-sql">requêtes SQL</a> grâce à <a href="https://observablehq.com/@observablehq/duckdb"><code>DuckDB</code></a> permet aux habitués de <code>R</code> ou de <code>Python</code> de retrouver des manipulations auxquels ils sont habitués. La librairie <a href="https://observablehq.com/@observablehq/plot"><code>Plot</code></a> offre une <a href="https://observablehq.com/@observablehq/plot-from-ggplot2">grammaire proche de <code>ggplot2</code></a>.</p>
<p>La communauté des cartographes a été particulièrement active sur <code>Observable</code>, notamment à l’occasion du <a href="https://observablehq.com/collection/@observablehq/30-day-map-challenge">#30daymapchallenge</a>. <a href="https://observablehq.com/@neocartocnrs">Nicolas Bertin (<code>neocarto</code>)</a>, dont on ne peut que recommander l’<a href="../../event/presentation-dobservable-par-nicolas-lambert/">introduction à <code>Observable</code></a> faite pour le réseau, ou <a href="https://observablehq.com/@ericmauviere">Eric Mauvière</a> font partie des comptes à suivre dans la communauté francophone.</p>
<p><code>Observable</code>, en tant que langage construit sur <code>JavaScript</code>, est également disponible pour les utilisateurs de <a href="https://quarto.org/docs/interactive/ojs/"><code>Quarto</code></a>, ce qui permet de mettre à disposition des visualisation réactives sans passer nécessairement par la plateforme <a href="https://observablehq.com/">observablehq.com</a> pour mettre à disposition des visualisations réactives, ce qui constitue une alternative intéressante aux applications qui nécessitent un serveur en arrière plan, comme <code>Shiny</code> ou <code>Dash</code>.</p>
<p><img src="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/retrospective2022/observable1.png" class="img-fluid"> <img src="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/retrospective2022/observable2.png" class="img-fluid"></p>
</section>
<section id="les-autres-actualités-en-france" class="level1">
<h1>Les autres actualités en France</h1>
<p>Le rapport du conseil d’État pour la <a href="https://www.conseil-etat.fr/content/download/175739/file/Etude%20%C3%A0%20la%20demande%20du%20PM%20-%20IA%20et%20action%20publique.pdf">construction d’une IA de “confiance”</a> a donc été publié en une année 2022 où les avancées techniques des dernières années commencent à être accessibles grâce à des outils plus grand public, ce qui va nécessairement soulever des enjeux éthiques et juridiques.</p>
<p>Le <a href="https://www.onyxia.sh/">projet <code>Onyxia</code></a>, qui vise à proposer une infrastructure de <em>data science</em> à l’état de l’art pour <em>data scientists</em>, a organisé son deuxième <em>Openlab</em>. L’occasion de revenir sur le projet, sa philosophie, ses dernières avancées mais aussi d’échanger sur les perspectives de réutilisation dans de multiples environnements et de nouer des partenariats qui permettront au projet de grandir encore en 2023.</p>
<!-----
- onyxia
- IA: rapport conseil d'Etat: https://www.conseil-etat.fr/content/download/175739/file/Etude%20%C3%A0%20la%20demande%20du%20PM%20-%20IA%20et%20action%20publique.pdf + UNECE Adasmm
- Ryanair v lastminute.com, j’ai grossièrement résumé le cas page 85 dans le support
- Data scientist 10 ans après
------->


</section>

 ]]></description>
  <category>NLP</category>
  <category>Observable</category>
  <category>Quarto</category>
  <category>Deep learning</category>
  <category>Insee</category>
  <category>Retrospective</category>
  <category>Infolettre</category>
  <guid>https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/retrospective2022/</guid>
  <pubDate>Sat, 31 Dec 2022 00:00:00 GMT</pubDate>
  <media:content url="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/retrospective2022/featured.png" medium="image" type="image/png" height="144" width="144"/>
</item>
<item>
  <title>Le plongement lexical ou comment apprendre à lire à un ordinateur</title>
  <link>https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/embedding/</link>
  <description><![CDATA[ 





<p>Avec le développement de la collecte automatisée d’information numérique, les données textuelles sont devenues omniprésentes, que ce soit sous la forme d’e-mails, de réponses à des enquêtes, d’articles de presse ou encore de commentaires sur les réseaux sociaux. Ces données peuvent être une source très riche d’informations mobilisable par les statisticiens, pour peu qu’ils parviennent à en faire un traitement statistique. Ainsi, une problématique récurrente dans la statistique publique consiste à classer des informations formulées en langage courant (professions, noms de produits, noms de communes, etc.) dans des nomenclatures standardisées (PCS<sup>1</sup>, NAF<sup>2</sup>, COG<sup>3</sup>…).</p>
<p>Or, le traitement des données textuelles pose une difficulté particulière: <strong>le langage naturel n’a pas de sens pour un ordinateur !</strong> Un ordinateur ne travaille qu’avec des nombres, et ne peut pas manipuler directement des mots, des expressions ou des phrases. C’est pourquoi de multiples méthodes ont été développées au cours des dernières décennies pour proposer des solutions génériques permettant de traiter des corpus de données textuelles à la fois peu structurés et hétérogènes. Cet ensemble de méthodes de traitement automatisé du langage, plus connues sous l’acronyme <code>NLP</code> (<em>natural langage processing</em>) constituent encore aujourd’hui un champ de recherche particulièrement actif.</p>
<p>Ce billet de blog n’a pas l’ambition de proposer un aperçu des méthodes de NLP, mais simplement de présenter deux méthodes fréquemment utilisées pour transformer l’information textuelle pour la rendre compréhensible et utilisable par une machine:</p>
<ul>
<li>le sac de mots (<em>bag of words</em>),</li>
<li>le plongement lexical (<em>word embedding</em>).</li>
</ul>
<section id="traiter-un-texte-comme-une-information-numérique-les-approches-possibles" class="level2">
<h2 class="anchored" data-anchor-id="traiter-un-texte-comme-une-information-numérique-les-approches-possibles">Traiter un texte comme une information numérique : les approches possibles</h2>
<section id="bag-of-words" class="level3">
<h3 class="anchored" data-anchor-id="bag-of-words">L’approche <em>bag of words</em></h3>
<p>Le principe du <em>bag of words</em> est qu’on peut décrire un document comme un dictionnaire de mots (un <em>sac de mots</em>) dans lequel on pioche plus ou moins fréquemment un terme en fonction de son nombre d’occurrences.</p>
<p>La manière la plus simple de transformer des phrases ou des libellés textuels en une information numérique est de passer par un objet que l’on appelle la <strong>matrice document-terme</strong>. L’idée est de compter le nombre de fois où les mots (les termes, en colonne) sont présents dans chaque phrase ou libellé (le document, en ligne). Cette matrice fournit alors une représentation <strong>numérique</strong> des données textuelles.</p>
<p>Considérons un corpus constitué des trois phrases suivantes :</p>
<ul>
<li>_“La pratique du tricot et du crochet_”</li>
<li><em>“Transmettre la passion du timbre”</em></li>
<li><em>“Vivre de sa passion”</em></li>
</ul>
<p>La matrice document-terme associée à ce corpus est la suivante :</p>
<table class="caption-top table">
<colgroup>
<col style="width: 29%">
<col style="width: 7%">
<col style="width: 3%">
<col style="width: 3%">
<col style="width: 3%">
<col style="width: 3%">
<col style="width: 7%">
<col style="width: 8%">
<col style="width: 3%">
<col style="width: 6%">
<col style="width: 10%">
<col style="width: 6%">
<col style="width: 5%">
</colgroup>
<thead>
<tr class="header">
<th></th>
<th style="text-align: center;">crochet</th>
<th style="text-align: center;">de</th>
<th style="text-align: center;">du</th>
<th style="text-align: center;">et</th>
<th style="text-align: center;">la</th>
<th style="text-align: center;">passion</th>
<th style="text-align: center;">pratique</th>
<th style="text-align: center;">sa</th>
<th style="text-align: center;">timbre</th>
<th style="text-align: center;">transmettre</th>
<th style="text-align: center;">tricot</th>
<th style="text-align: center;">vivre</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>La pratique du tricot et du crochet</td>
<td style="text-align: center;">1</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">2</td>
<td style="text-align: center;">1</td>
<td style="text-align: center;">1</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">1</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">1</td>
<td style="text-align: center;">0</td>
</tr>
<tr class="even">
<td>Transmettre sa passion du timbre</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">1</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">1</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">1</td>
<td style="text-align: center;">1</td>
<td style="text-align: center;">1</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">0</td>
</tr>
<tr class="odd">
<td>Vivre de sa passion</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">1</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">1</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">1</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">1</td>
</tr>
</tbody>
</table>
<p><strong>Mission accomplie !</strong> 🎉 Chaque phrase du corpus est associée à un vecteur numérique.</p>
<p>Il est maintenant possible de manipuler cette matrice comme des données tabulaires classiques. Par exemple, on pourrait appliquer l’un des algorithmes usuels de classification (régression logistique, forêt aléatoire, <em>gradient boosting</em>, etc.) pour classer ces phrases dans des catégories.</p>
<p>L’approche <em>bag-of-words</em> répond donc au besoin initial de transformer les données pour les rendre manipulables par une machine, en représentant les données textuelles sous la forme d’une matrice document-terme. Cette approche présente néanmoins une limite: elle traite tous les termes de façon indépendante et ne restitue pas la proximité de certains termes. Par exemple, rien dans la matrice document-terme de l’exemple précédent n’indique que les termes <em>’tricot”</em> et <em>“crochet”</em> relèvent du même champ lexical. Un autre type de représentation plus complexe et plus riche constitue souvent comme une meilleure option : le plongement lexical.</p>
</section>
<section id="embedding" class="level3">
<h3 class="anchored" data-anchor-id="embedding">Le plongement lexical</h3>
<p>Le plongement lexical (<em>word embedding</em> en anglais) consiste à projeter l’ensemble des termes qui apparaissent dans le corpus dans un espace numérique à <img src="https://latex.codecogs.com/png.latex?n"> dimensions. Chaque mot est représenté par un vecteur de taille fixe (comprenant <img src="https://latex.codecogs.com/png.latex?n"> nombres), de façon à ce que deux mots dont le sens est proche possèdent des représentations numériques proches. Ainsi les mots « chat » et « chaton » devraient avoir des vecteurs de plongement assez similaires, eux-mêmes également assez proches de celui du mot « chien » et plus éloignés de la représentation du mot « maison ».</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/embedding/word_embedding.png" class="img-fluid figure-img"></p>
<figcaption>Illustration du word embedding</figcaption>
</figure>
</div>
<div style="text-align: center">
Illustration du plongement lexical. Source : Post de blog <a href="https://medium.com/@hari4om/word-embedding-d816f643140" target="_blank">Word Embedding : Basics</a>
</div>
<p>&nbsp;</p>
<p>Chacune des <img src="https://latex.codecogs.com/png.latex?n"> composantes va encoder des informations différentes, comme le fait d’être un être vivant ou un objet, le genre, l’âge, le niveau d’abstraction, etc. C’est pour cette raison que des termes appartenant au même champ lexical auront des représentations numériquement proches. En pratique, les vecteurs de plongement ont des dizaines voire des centaines de composantes et il est impossible d’associer à chacune une interprétation univoque : toutes les notions s’entremêlent, mais chaque composante a un rôle à jouer.</p>
<p>Le plongement lexical possède deux avantages par rapport à l’approche <em>bag of words</em>. D’une part, il fournit une représentation dense des termes, qui est plus adaptée aux algorithmes d’apprentissage statistique que la représentation creuse (matrice contenant beaucoup de zéros) de l’approche <em>bag of words</em>. D’autre part, les opérations mathématiques ont un sens sur les vecteurs du plongement. C’est là la magie du plongement lexical: <strong>il devient possible de faire des mathématiques avec les mots</strong>. Ainsi par exemple, les vecteurs résultant de la différence entre les représentations des mots « femme » et « homme » d’une part, et des mots « reine » et « roi » d’autre part, devraient être proches, car conceptuellement ces couples de mots sont régis par la même relation : un changement de genre.</p>
<p>Cette formule, souvent résumée sous la forme,</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Ctext%7Bking%7D%20-%20%5Ctext%7Bman%7D%20+%20%5Ctext%7Bwoman%7D%20%E2%89%88%20%5Ctext%7Bqueen%7D"></p>
<p>a assuré le succès des <em>embeddings</em>, car elle permet à une machine d’appréhender les relations logiques entre les mots.</p>
<p>Jusqu’ici, nous avons parlé du plongement de mots, mais comment obtenir le plongement d’un libellé textuel ? Une possibilité est de considérer tous les mots qui composent le libellé et de calculer la moyenne de leurs vecteurs de plongement.</p>
</section>
</section>
<section id="construction-dun-plongement-lexical" class="level2">
<h2 class="anchored" data-anchor-id="construction-dun-plongement-lexical">Construction d’un plongement lexical</h2>
<p>Un plongement lexical se construit en parcourant un grand corpus de textes et en repérant les mots qui apparaissent souvent dans le même contexte. L’ensemble des articles <code>Wikipedia</code> est un des corpus de prédilection des personnes ayant construit des plongements lexicaux. Il comporte en effet des phrases complètes, contrairement à des informations issues de commentaires de réseaux sociaux, et propose des rapprochements intéressants entre des personnes, des lieux, etc.</p>
<p>Le contexte d’un mot est défini par une fenêtre de taille fixe autour de ce mot. La taille de la fenêtre est un paramètre de la construction de l’<em>embedding</em>. Le corpus fournit un grand ensemble d’exemples mots-contexte, qui peuvent servir à entraîner un réseau de neurones.</p>
<p>Plus précisément, il existe deux approches :</p>
<ul>
<li><em>Continuous bag of words</em> (CBOW), où le modèle est entraîné à prédire un mot à partir de son contexte ;</li>
<li><em>Skip-gram</em>, où le modèle tente de prédire le contexte à partir d’un seul mot.</li>
</ul>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/embedding/CBOW_Skipgram_training.png" class="img-fluid figure-img"></p>
<figcaption>Illustration de la différence entre les approches CBOW et Skip-gram</figcaption>
</figure>
</div>
<div style="text-align: center">
Illustration de la différence entre les approches CBOW et Skip-gram. Source : Anwarvic sur <a href="https://stackoverflow.com/questions/57507056/difference-between-max-length-of-word-ngrams-and-size-of-context-window" target="_blank">StackOverflow</a>
</div>
<p>&nbsp;</p>
<section id="algorithmes-célèbres" class="level3">
<h3 class="anchored" data-anchor-id="algorithmes-célèbres">Algorithmes célèbres</h3>
<p>La méthode de construction d’un plongement lexical présentée ci-dessus est celle de l’algorithme <a href="https://fr.wikipedia.org/wiki/Word2vec"><code>Word2Vec</code></a>. Il s’agit d’un modèle <em>open-source</em> développé par une équipe de <code>Google</code> en 2013. <code>Word2Vec</code> a été le pionnier en termes de modèles de plongement lexical.</p>
<p>Le modèle <a href="https://nlp.stanford.edu/projects/glove/"><code>GloVe</code></a> constitue un autre exemple<sup>4</sup>. Développé en 2014 à Stanford, ce modèle ne repose pas sur des réseaux de neurones mais sur la construction d’une grande matrice de co-occurrences de mots. Pour chaque mot, il s’agit de calculer les fréquences d’apparition des autres mots dans une fenêtre de taille fixe autour de lui. La matrice de co-occurrences obtenue est ensuite factorisée par une décomposition en valeurs singulières. Il est également possible de produire des plongements de mots à partir du <a href="https://jalammar.github.io/illustrated-bert/">modèle de langage <code>BERT</code></a>, développé par <code>Google</code> en 2019, dont il existe des déclinaisons dans différentes langues, notamment en Français (les modèles <a href="https://camembert-model.fr/"><code>CamemBERT</code></a> ou <a href="https://github.com/getalp/Flaubert"><code>FlauBERT</code></a>)</p>
<p>Enfin, le modèle <a href="https://fasttext.cc/"><code>FastText</code></a>, développé en 2016 par une équipe de <code>Facebook</code>, fonctionne de façon similaire à <code>Word2Vec</code> mais se distingue particulièrement sur deux points :</p>
<ul>
<li>En plus des mots eux-mêmes, le modèle apprend des représentations pour les n-grams de caractères (sous-séquences de caractères de taille \(n\), par exemple <em>« tar »</em>, <em>« art »</em> et <em>« rte »</em> sont les trigrammes du mot <em>« tarte »</em>), ce qui le rend notamment robuste aux variations d’orthographe ;</li>
<li>Le modèle a été optimisé pour que son entraînement soit particulièrement rapide.</li>
</ul>
<p>A <code>l’Insee</code>, plusieurs modèles de classification de libellés textuels dans des nomenclatures reposent sur l’algorithme de plongement lexical <a href="https://fasttext.cc/"><code>FastText</code></a>.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/embedding/fasttext.png" class="img-fluid figure-img"></p>
<figcaption>Illustration du modèle fastText</figcaption>
</figure>
</div>
<div style="text-align: center">
Illustration du fonctionnement du modèle fastText sur un libellé de profession
</div>
<p>&nbsp;</p>
</section>
<section id="comment-utiliser-ces-modèles-en-pratique" class="level3">
<h3 class="anchored" data-anchor-id="comment-utiliser-ces-modèles-en-pratique">Comment utiliser ces modèles en pratique ?</h3>
<p>Collecter à nouveau les données ayant servi à entrainer un modèle puis le ré-entraîner implique énormément de ressources, ce qui est coûteux en temps et peu écologique<sup>5</sup>.</p>
<p>En <code>Python</code>, plusieurs librairies proposent les modèles <code>Word2Vec</code>, <code>GloVe</code>, <code>BERT</code> ou <code>FastText</code>. Le <a href="https://radimrehurek.com/gensim/">package <code>gensim</code></a> les met toutes en œuvre à l’exception de <code>BERT</code>. Ce dernier est disponible sur <a href="https://huggingface.co/docs/transformers/model_doc/bert"><code>HuggingFace</code></a>, la principale plateforme de mise à disposition de modèles pré-entraînés. Il est ainsi possible d’utiliser <code>BERT</code> avec les librairies <a href="https://pytorch.org/hub/huggingface_pytorch-transformers/"><code>PyTorch</code></a> ou <a href="https://keras.io/examples/nlp/text_extraction_with_bert/"><code>Keras</code></a>. Chacun des modèles présentés possède également son package dédié, généralement développé par l’équipe de recherche ayant entraîné le modèle.</p>
<p>En <code>R</code>, il faut utiliser les packages <code>word2vec</code>, <code>text2vec</code> (pour le modèle GloVe) et <code>fastTextR</code>.</p>
</section>
</section>
<section id="bonus-le-plongement-lexical-en-version-ludique" class="level2">
<h2 class="anchored" data-anchor-id="bonus-le-plongement-lexical-en-version-ludique">Bonus : le plongement lexical en version ludique</h2>
<p>Le résultat d’un plongement lexical peut avoir de nombreux usages. Il rend notamment possible le calcul de la proximité entre deux mots quelconques.</p>
<p>Une manière de procéder est de calculer la similarité cosinus entre les vecteurs de plongement des deux mots. Plus précisément, la similarité entre deux mots de représentations vectorielles \(u\) et \(v\) est définie comme le cosinus de leur angle \( \) : <img src="https://latex.codecogs.com/png.latex?cos(%5Ctheta)%20=%20%5Cfrac%7Bu%20%5Ccdot%20v%7D%7B%5ClVert%20u%5CrVert%20%5ClVert%20v%5CrVert%7D"></p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/embedding/similarite_cosinus.png" class="img-fluid figure-img"></p>
<figcaption>Illustration de la similarité cosinus</figcaption>
</figure>
</div>
<div style="text-align: center">
Illustration de la similarité cosinus en deux dimensions
</div>
<p>&nbsp;</p>
<p>Le calcul de la proximité entre les mots est à la base du jeu <a href="https://cemantix.certitudes.org/">cemantix</a>. Le principe est proche du jeu <code>Wordle</code> mais s’en distingue sur un point : il y a certes un mot à trouver chaque jour et il s’agit de faire des propositions de mots mais le jeu répond en donnant la proximité entre les mots proposés et le mot du jour. Ainsi, au fil des propositions, on a une vision de plus en plus précise du champ lexical associé au mot mystère, jusqu’à finalement le trouver.</p>


</section>


<div id="quarto-appendix" class="default"><section id="footnotes" class="footnotes footnotes-end-of-document"><h2 class="anchored quarto-appendix-heading">Notes de bas de page</h2>

<ol>
<li id="fn1"><p>La nomenclature <code>PCS</code> (professions et catégories socioprofessionnelles) sert à la codification des professions dans le recensement et les enquêtes auprès des ménages. Elle permet ainsi de classer un ensemble de professions dans une même catégorie. Par exemple, dans sa dernière version (<a href="https://www.insee.fr/fr/information/6205305">PCS 2020</a>), la catégorie des <em>“Professions libérales de santé”</em> (31A) regroupe diverses professions médicales: médecins libéraux, dentistes, psychologues, vétérinaires, pharmaciens libéraux… Une description plus complète de cette nomenclature et de son historique est disponible sur <a href="https://www.insee.fr/fr/information/6208292">le site de l’Insee</a>↩︎</p></li>
<li id="fn2"><p>La <code>NAF</code> (nomenclature d’activités française), est une nomenclature des activités économiques productives, principalement élaborée pour faciliter l’organisation de l’information économique et sociale. Il s’agit d’une typologie facilitant la représentation de l’économie sous forme de secteurs. Par exemple, au sein de l’industrie manufacturière (section C), la NAF distingue les industries alimentaires de l’industrie de l’habillement ou de l’industrie automobile. Une description plus complète de cette nomenclature et de son historique est disponible sur <a href="https://www.insee.fr/fr/information/2406147">le site de l’Insee</a>↩︎</p></li>
<li id="fn3"><p>Le Code Officiel Géographique est le référentiel permettant de relier des adresses, des noms de communes ou encore des noms de collectivités locales à un identifiant unique. Pour plus d’informations, voir le <a href="https://www.insee.fr/fr/information/5230987">site de l’Insee</a>↩︎</p></li>
<li id="fn4"><p>Jeffrey Pennington, Richard Socher, and Christopher D. Manning. 2014. GloVe: Global Vectors for Word Representation↩︎</p></li>
<li id="fn5"><p>Strubell, Ganesh, and McCallum (2019) estiment que l’entraînement d’un modèle à l’état de l’art dans le domaine du NLP nécessite autant d’énergie que ce que consommeraient cinq voitures, en moyenne, au cours de l’ensemble de leur cycle de vie.↩︎</p></li>
</ol>
</section></div> ]]></description>
  <category>Insee</category>
  <category>NLP</category>
  <guid>https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/embedding/</guid>
  <pubDate>Mon, 03 Oct 2022 00:00:00 GMT</pubDate>
  <media:content url="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/embedding/featured.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>Le machine learning aux Journées de la Méthodologie Statistique 2022 (JMS)</title>
  <link>https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/2022_jms/</link>
  <description><![CDATA[ 





<p>Signes des temps, l’édition 2022 des Journées de la Méthodologie Statistique (JMS) a mis en lumière la part croissante du <em>machine learning</em> dans les travaux menés au sein de la statistique publique, et au delà. Ainsi, cette année, ce sont 12 papiers utilisant ce type de méthodes qui ont été présentés - contre, à titre de comparaison, 4 en 2018.</p>
<p>En particulier, quatre types d’utilisation de telles méthodes ont été mises en avant :</p>
<ul>
<li>Le redressement de données manquantes</li>
<li>La codification automatique</li>
<li>Les appariements</li>
<li>Les études</li>
</ul>
<section id="le-redressement-de-données-manquantes" class="level1">
<h1>Le redressement de données manquantes</h1>
<p>Cette thématique est la plus représentée, grâce à une session dédiée au traitement de données manquantes. Au sein de cette session, 4 communications présentaient des tentatives d’utilisation de méthodes de machine Learning à cette fin. L’objectif de ces 4 publications est différent :</p>
<ul>
<li>Évaluer de façon théorique la possibilité d’utiliser les forêts aléatoires pour redresser les enquêtes par sondage en grande dimension, dans quel cas les modèles paramétriques sont parfois instables et inefficaces (<a href="https://journees-methodologie-statistique.insee.net/forets-aleatoires-dune-approche-par-modelisation-assistee-au-traitement-de-la-non-reponse/">Forêts aléatoires : D’une approche par modélisation assistée au traitement de la non-réponse</a>) ;</li>
<li>Évaluer l’intérêt des réseaux de neurones dans le cadre du redressement de la non réponse, de façon théorique et en appliquant au cas de l’enquête emploi (<a href="https://journees-methodologie-statistique.insee.net/imputation-de-valeurs-manquantes-avec-des-reseaux-de-neurones-prediction-des-salaires-dans-lenquete-emploi/">Imputation de valeurs manquantes avec des réseaux de neurones : Prédiction des salaires dans l’enquête emploi :</a>) ;</li>
<li>Comparer les différentes méthodes de <em>machine learning</em> de façon empirique dans le cadre d’une imputation de non réponse (<a href="https://journees-methodologie-statistique.insee.net/traitement-de-la-non-reponse-au-moyen-de-methodes-de-machine-learning/">Traitement de la non-réponse au moyen de méthodes de machine learning</a>) ;</li>
<li>Évaluer un processus complet de correction de non-réponse, dans lequel le machine Learning n’est qu’une facette (<a href="https://journees-methodologie-statistique.insee.net/estimation-des-montants-manquants-de-versements-de-tva-exploitation-des-donnees-du-controle-fiscal/">Estimation des montants manquants de versements de TVA : Exploitation des données du contrôle fiscal</a>).</li>
</ul>
</section>
<section id="la-codification-automatique-et-lextraction-de-données" class="level1">
<h1>La codification automatique et l’extraction de données</h1>
<p>Trois communications sur ces thèmes ont été présentées :</p>
<ul>
<li>Une tentative de codification automatique de la PCS au moyen de méthodes de machine Learning (<a href="https://journees-methodologie-statistique.insee.net/application-de-techniques-de-machine-learning-pour-coder-les-professions-dans-la-nomenclature-des-professions-et-categories-socio-professionnelles-2020/">Application de techniques de machine learning pour coder les professions dans la nomenclature des professions et catégories socio-professionnelles 2020</a>) - <em>cf.</em> la page dédiée au <a href="../../project/2021_codif_PCS/index.html">projet</a> sur le site ;</li>
<li>Une tentative d’extraction automatique d’informations des documents scannés issues des comptes sociaux des entreprises (<a href="https://journees-methodologie-statistique.insee.net/extraction-automatique-de-donnees-issues-dimages-scannees-une-illustration-par-les-comptes-sociaux-dentreprises/">Extraction automatique de données issues d’images scannées : Une illustration par les comptes sociaux d’entreprises</a>) - <em>cf.</em> la page dédiée au <a href="../../project/2021_Extraction_CS/index.html">projet</a> sur le site ;</li>
<li>Une classification automatique des infractions commises à partir d’une analyse textuelle et de l’utilisation de réseau de neurones (<a href="https://journees-methodologie-statistique.insee.net/detection-des-infractions-relevant-de-la-cyberdelinquance-a-partir-dune-analyse-textuelle-des-manieres-doperer/">Détection des infractions relevant de la cyberdélinquance</a>) - <em>cf.</em> la page dédiée au <a href="../../project/2021_detection_cyber/index.html">projet</a> sur le site.</li>
</ul>
</section>
<section id="méthodes-dappariements" class="level1">
<h1>Méthodes d’appariements</h1>
<p>Le <em>machine learning</em> peut également être utilisé pour faciliter les appariements. A cet égard, deux communications ont été présentées :</p>
<ul>
<li>Une communication discutant globalement des méthodes d’appariements, incluant - sans se restreindre - le <em>machine learning</em> (<a href="https://journees-methodologie-statistique.insee.net/probabilistes-ou-deterministes-des-methodes-dappariements-au-banc-dessai-du-programme-resil/">Probabilistes ou déterministes, des méthodes d’appariements au banc d’essai du programme RéSIL</a>) - <em>cf.</em> la page dédiée au <a href="../../project/2021_Appariement/index.html">projet</a> sur le site ;</li>
<li>Une communication présentant une méthode innovante d’appariement flou à partir de l’utilisation d’Elastic Search et d’un réseau de neurone pré-entraîné (<a href="https://journees-methodologie-statistique.insee.net/enrichissement-de-donnees-de-caisses-a-partir-dinformations-nutritionnelles-une-approche-par-appariement-flou-sur-donnees-de-grande-dimension/">Enrichissement de données de caisses à partir d’informations nutritionnelles : Une approche par appariement flou sur données de grande dimension</a>) - <em>cf.</em> la page dédiée au <a href="../../project/2020_donnees_caisse/index.html">projet</a> sur le site.</li>
</ul>
</section>
<section id="etudes" class="level1">
<h1>Etudes</h1>
<p>La sphère la plus large d’exploitation est bien sûr les études. Les sujets sont alors variés :</p>
<ul>
<li>L’estimation d’un parc de véhicules roulants, en modélisant à la fois la probabilité qu’un véhicule roule encore, et le nombre de kilomètres parcourus (<a href="https://journees-methodologie-statistique.insee.net/modelisation-de-lappartenance-au-parc-des-vehicules-routiers-et-de-son-utilisation/">Modélisation de l’appartenance au parc des véhicules routiers et de son utilisation</a>) ;</li>
<li>L’estimation de la valeur d’un patrimoine immobilier dans le cadre du projet FidelImmo (<a href="https://journees-methodologie-statistique.insee.net/estimation-de-la-valeur-du-patrimoine-immobilier-des-menages-a-partir-de-donnees-exhaustives/">Estimation de la valeur du patrimoine immobilier des ménages à partir de données exhaustives</a>) ;</li>
<li>L’utilisation des données du site MeilleursAgents.com pour modéliser les loyers, et mieux comprendre les déterminants sous-jacents (<a href="https://journees-methodologie-statistique.insee.net/apprehender-la-rentabilite-locative-pour-comprendre-les-mecaniques-qui-sous-tendent-les-loyers-et-les-prix-a-laide-de-methodes-de-machine-learning/">Appréhender la rentabilité locative pour comprendre les mécaniques qui sous-tendent les loyers et les prix à l’aide de méthodes de machine learning</a>) ;</li>
<li>L’utilisation de méthodes de machine Learning pour améliorer la prévision du PIB (méthodes de <em>nowcasting</em>) (<a href="https://journees-methodologie-statistique.insee.net/nowcasting-pib-imputation-de-variables-non-encore-publiees/"><em>Nowcasting</em> PIB : imputation de variables non encore publiées</a>).</li>
</ul>


</section>

 ]]></description>
  <category>Insee</category>
  <category>evenement</category>
  <guid>https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/2022_jms/</guid>
  <pubDate>Wed, 06 Apr 2022 00:00:00 GMT</pubDate>
  <media:content url="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/2022_jms/jms2022.png" medium="image" type="image/png" height="205" width="144"/>
</item>
<item>
  <title>Parallélisation des traitements : Hadoop MapReduce vs Spark</title>
  <link>https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/hadoop_spark/</link>
  <description><![CDATA[ 





<p>À la base des systèmes dits « big data », il y a un principe central : la distribution, à la fois des données et des traitements, sur un ensemble de machines/ordinateurs formant un cluster. Le stockage des données brutes s’appuie le plus souvent sur un système de fichiers distribués. <em>MapReduce</em> est la première implémentation pour les big data du principe de parallélisation des traitements appliquée aux fichiers distribués. Il repose sur deux fonctions principales, <code>map</code> et <code>reduce</code>, qui sont appliquées parfois à de multiples reprises.</p>
<p>La première décrit une transformation que l’on applique aux valeurs d’une collection de données au format clé / valeur ; la deuxième applique une opération à toutes les valeurs d’une même clé. Prenons l’exemple du dénombrement des nucléotides composant un brin d’ADN : « AGTCGGGGCT ». L’objet en entrée est donc une séquence, et on souhaite obtenir en sortie une table avec les différents symboles et le nombre d’occurrences de chacun d’entre eux dans la séquence initiale. La démarche « naturelle » consiste à prendre le premier symbole de la séquence, de noter dans la table de sortie son nom et d’initialiser un compteur à 1, puis de revenir à la séquence, d’identifier le second et s’il correspond au premier, d’incrémenter le compteur correspondant… Cette démarche est assez simple à décrire, mais demande en pratique de parcourir tout ou partie de la séquence à chaque itération. Cela n’est pas problématique si la séquence est aussi élémentaire que celle prise dans cet exemple… mais le devient si elle correspond au génome humain, constitué de quelques milliards de nucléotides (symboles). De la même manière et pour utiliser un exemple plus classique pour un statisticien, filtrer une table selon la valeur des attributs d’une variable est une opération a priori simple et classique, mais dont la mise en œuvre pour des très grands volumes peut s’avérer particulièrement inefficace voire impossible..</p>
<p>La même opération réalisée en <em>MapReduce</em>, correspond aux opérations suivantes : lors du chargement des données, la séquence a été coupée en plusieurs sous-séquences chargées sur différentes machines ou nœuds ; la première étape (<code>map</code>) consiste alors à appliquer au niveau de chaque noeud une fonction dont le résultat est une liste de couples constitués chacun d’une clé et d’une valeur. Ici, la clé correspond au symbole lu, et la valeur à l’occurrence 1 : on a donc une liste de couples (A,1), (G,1), (T,1), (A,1),.. Dans une deuxième étape de triage (« shuffling and sorting »), on rassemble sur un même nœud toutes les paires correspondant à une même clé. Finalement, on applique une fonction d’agrégation (<code>reduce</code>) qui combine (ici on somme tout simplement) les valeurs correspondantes à chaque clé. On aboutit dans cet exemple à quatre paires constituées d’un symbole et du nombre d’occurrences de ce symbole sur l’ensemble de la séquence.</p>
<p><img src="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/hadoop_spark/map_reduce.png" class="img-fluid"> <a href="https://hal.archives-ouvertes.fr/file/index/docid/995801/filename/st-stat-bigdata-clones.pdf">Source: Statistique et Big Data Analytics Volumétrie – L’Attaque des Clones</a></p>
<p>Autre exemple plus traditionnel en économétrie, la multiplication d’une très grosse matrice <code>M</code> avec un vecteur <code>x</code> : on pourra répartir les colonnes de la matrice sur différents nœuds et procéder localement à la multiplication de ces colonnes avec les composantes correspondantes de x, avant d’agréger le résultat final.</p>
<p><img src="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/hadoop_spark/map_reduce2.png" class="img-fluid"></p>
<p>Des outils ont rapidement été construits pour rendre l’écriture des programmes <em>MapReduce</em> plus transparente pour l’utilisateur. Hive, une des solutions les plus populaires, propose d’écrire ces programmes en SQL, comme on le ferait pour manipuler les données d’une base relationnelle classique. Ce modèle de programmation permet également d’appliquer efficacement sur un très grand volume de données toute une gamme d’algorithmes. Il existe cependant un certain nombre de limites à ce modèle : la nature même des étapes <code>map</code> et <code>reduce</code> ne permet pas facilement la mise en œuvre d’algorithmes itératifs en particulier pour certains choix d’architecture (après chaque opération <code>map</code> ou <code>reduce</code>, Hadoop <em>MapReduce</em> écrit les résultats intermédiaires sur disque, ces résultats étant ensuite lus si nécessaires, ce qui entraîne d’importants temps d’exécution). La solution Spark propose des performances supérieures (jusqu’à cent fois plus rapide lorsqu’il travaille en mémoire vive) grâce à un certain nombre d’innovations par rapport au modèle historique. En effet, si Spark conserve un modèle d’exécution distribué sa capacité à opérer bien plus souvent en mémoire vive lui permet de gagner en rapidité d’exécution par opposition aux lectures écritures systématiques du modèle Hadoop. Plus précisément, Spark garde en mémoire le maximum de résultats intermédiaires, ainsi que l’historique des opérations. En cas de panne, les opérations seront effectuées à nouveau, ce qui reste moins coûteux que les écritures/lectures systématiques.</p>



 ]]></description>
  <category>données volumineuses</category>
  <guid>https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/hadoop_spark/</guid>
  <pubDate>Wed, 01 Jun 2016 00:00:00 GMT</pubDate>
  <media:content url="https://inseefrlab.github.io/ssphub/pr-preview/pr-157/blog/hadoop_spark/hadoop_spark.png" medium="image" type="image/png" height="64" width="144"/>
</item>
</channel>
</rss>
