6107 links
  • GuiGui's Show
  • Home
  • Login
  • RSS Feed
  • ATOM Feed
  • Tag cloud
  • Picture wall
  • Daily
Links per page: 20 50 100
 
  • Quels représentants d'intérêts causent à la CNIL ?

    La HATVP, instituée à la va-vite pour calmer le bon peuple après l'affaire Cahuzac, collecte et publie le répertoire des représentants d'intérêts.

    Évidemment, il y a de nombreuses limites, notamment que c'est déclaratif, donc au bon vouloir des lobbyistes. Certains déclarent rien. D'autres déclarent une même activité générique (= floue) d'année en année. La loi prévoit de nombreuses exceptions. La HATVP ne permet pas toujours de déclarer le responsable public précis avec lequel un lobbyiste s'est entretenu, souvent, cela reste flou : « agent d'une collectivité territoriale » (laquelle ?), « député » (lequel ?), « agent d'administration centrale de l'État » (mais encore ? Quelle fonction ? Quelle administration ?), etc. La CNIL fait exception : un déclarant peut la sélectionner pour remplir sa déclaration, mais un manque de rigueur peut vite arriver. ;) Bref, il y a de nombreuses lacunes.

    La déclaration est une obligation légale, mais la HATVP est un fantôme aussi vigilant et actif que la CNIL, donc tout le monde s'en cogne. De toute façon, je ne vois pas comment la HATVP pourrait contrôler la véracité et la complétude des déclarations : le boulot est immense et la charge de la preuve est difficilement surmontable sans devenir la Stasi (comment identifier un appel téléphonique, une visio, ou une rencontre non déclarées ?). Je rappelle également que la loi ne distingue pas les méchants lobbyistes des gentils lobbyistes du camp du Bien : tous doivent déclarer.



    Le site web du répertoire de la HATVP ne permet pas de rechercher par responsable public (ici, la CNIL), uniquement par lobbyiste, client d'un lobbyiste, ou activité.

    La HATVP publie son répertoire des lobbyistes aux formats JSON et CSV. Le JSON est ici : https://www.hatvp.fr/agora/opendata/agora_repertoire_opendata.json.

    Mais, là encore, la structure du fichier complique une recherche par responsable public. Les CSV ne sont pas mieux.

    On va devoir dégainer jq, l'outil de manipulation JSON en ligne de commande. J'ai déjà rédigé un article sur des syntaxes jq utiles.



    La commande suivante affiche toutes les activités de représentation conduites auprès de la CNIL en 2025. Pour chaque activité, elle affiche, sur des lignes distinctes, le nom du lobbyiste, le but de l'action, les observations éventuelles, et pour le compte de qui elle a été menée. Les activités sont séparées par une ligne vide.

    jq -r --arg annee 2025 --arg nomRespPublic "Commission nationale de l'informatique et des libertés" '.publications as $lobbyistes |
      $lobbyistes[].exercices[].publicationCourante | select((.activites | length > 0) and (.dateDebut | contains($annee))) as $ExerciceValide |
      $ExerciceValide.activites[].publicationCourante | select(.actionsRepresentationInteret[].reponsablesPublics | contains([$nomRespPublic])) |
      .objet as $but | .actionsRepresentationInteret[] | .observation as $obs | .tiers as $beneficiaires |
      $lobbyistes[] | select(.exercices[].publicationCourante.exerciceId==$ExerciceValide.exerciceId).denomination as $nomLobbyiste |
      " " as $delimiteur | $delimiteur , $nomLobbyiste , $but , $obs , $beneficiaires[]' agora_repertoire_opendata.json



    Évidemment, la structure du JSON détermine la commande jq nécessaire à son analyse. Celui de la HATVP est, très grosse maille, le suivant, les détails sont dans la documentation. Des représentants d'intérêts (nommés « publications » 🤷‍♂️️) sont associés à des périodes temporelles (nommés « exercices », au sens d'exercice moral ou fiscal). Un exercice a, ou non, des activités. Une activité a un but (« objet ») et une ou plusieurs actions de représentation. Celles-ci contiennent les responsables publics sollicités, une éventuelle observation, et les bénéficiaires de l'action.

    La première difficulté est que le nom du lobbyiste est consigné dans une « publication », en haut de l'arbre JSON, alors que le responsable public est en bas de l'arbre. Le pivot (= clé étrangère), est l'exercice, qui contient aussi le début et la fin de la période. En première approximation, on peut penser que le bénéficiaire d'une action est le lobbyiste lui-même, auquel cas, son nom est suffixé de « (en propre) », donc qu'on n'a pas besoin de remonter l'arbre JSON. Mais, un lobbyiste peut intervenir pour le compte d'un client, auquel cas, le client sera déclaré bénéficiaire, mais le nom du lobbyiste n'est pas inintéressant, et justifie une remontée de l'arbre JSON.

    La deuxième difficulté est qu'un exercice peut ne pas contenir d'activités, lorsque la déclaration n'a pas encore eu lieu, ou si le lobbyiste n'a rien fait sur la période. Auquel cas, l'attribut « activites » n'existe pas (alors qu'un tableau vide aurait été préférable). Il faut exclure ces exercices de notre sélection, sinon jq crachera l'erreur « Cannot iterate over null (null) » lors de la tentative d'accès à « activites ». Pour ce faire, il ne faut pas compter sur l'attribut « nombreActivite » qui peut être supérieur à zéro en l'absence d'attribut « activites » 🤷‍♂️️.

    Cette exclusion nécessite un déplacement du curseur de jq dans l'arbre JSON, ce qui crée la difficulté à remonter l'arbre JSON énoncée au point précédent : si l'on filtre les lobbyistes qui ont des activités, alors ceux ayant des activités durant un exercice mais pas durant un autre seront sélectionnés, donc jq crachera l'erreur sus-rapportée. On est donc obligé de descendre dans l'arbre, de travailler uniquement sur les exercices filtrés, puis sur les activités filtrées, donc on perd le nom du lobbyiste resté en haut de l'arbre. Notons qu'on a le même problème dès qu'on filtre les activités d'un exercice donné, ou les actions auprès de la CNIL (une activité sera retenue dès lors qu'elle contient au moins une action auprès de la CNIL), mais ce dernier cas n'a aucune incidence sur le résultat recherché.

    La troisième difficulté, mineure, est que le nom du responsable public, la CNIL, contient une apostrophe, qui entre en conflit avec le shell. Solution : stocker ce nom dans une variable. De surcroît, cela procure un caractère général à la commande jq : elle permet de chercher à partir d'autres responsables publics que la CNIL.

    La dernière difficulté, bien plus légère que les précédentes, est les niveaux superflus du JSON, notamment plusieurs « publicationCourante ». Il faut veiller à ne pas perdre le sens de chaque : tantôt ça désigne ça matérialise un exercice, tantôt une activité.



    Désormais, t'es en capacité de lire la commande :

    • Première ligne : arguments et conservation, dans une variable, des lobbyistes (afin de pouvoir obtenir le nom de l'organisateur d'une action à partir de la référence d'un exercice quand nous aurons cette dernière).

    • Deuxième ligne : on sélectionne, pour une année passée en argument, les exercices qui ont un nombre positif d'activités. On les met en variable afin de pouvoir, plus tard, retrouver le nom du lobbyiste à partir de la référence de l'exercice.

    • Troisième ligne : pour chaque exercice valide, on sélectionne les activités contenant des actions auprès de la CNIL.

    • Quatrième ligne : en variable, on conserve le but de l'activité, et, pour chaque action, les observations éventuelles, et les bénéficiaires.

    • Cinquième ligne : on conserve, en variable, le nom du lobbyiste que l'on retrouve à partir de la référence de l'exercice.

    • Sixième ligne : mise en forme du résultat, d'où, sur la première ligne, la directive -r pour retirer le formatage JSON, comme les guillemets autour d'une chaîne de caractères.



    Si l'on ne veut pas du nom du représentant d'intérêts, la commande se simplifie grandement (j'ai essayé de conserver les mêmes rôles par ligne, même si les lignes deux et trois fusionnent immanquablement) :

    jq -r --arg annee 2025 --arg nomRespPublic "Commission nationale de l'informatique et des libertés" \
      '.publications[].exercices[].publicationCourante | select((.activites | length > 0) and (.dateDebut | contains($annee))).activites[].publicationCourante |
      select(.actionsRepresentationInteret[].reponsablesPublics | contains([$nomRespPublic])) |
      .objet as $but | .actionsRepresentationInteret[] | .observation as $obs | .tiers as $beneficiaires |
      " " as $delimiteur | $delimiteur , $but , $obs , $beneficiaires[]' agora_repertoire_opendata.json



    That's All, Folks!

    August 22, 2026 at 10:59:16 PM UTC * - permalink - http://shaarli.guiguishow.info/?MFJZ8g
Links per page: 20 50 100
 
Mentions légales identiques à celles de mon blog | CC BY-SA 3.0

Shaarli - The personal, minimalist, super fast, database-free, bookmarking service by the Shaarli community