Skip to main content
Glama

French Law MCP Server

by jmtanguy
api_legifrance_search_input.py53.3 kB
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Générateur de requêtes pour l'API Légifrance Basé sur SearchRequestDTO de la documentation Swagger Copyright (c) 2025 Jean-Michel Tanguy Licensed under the MIT License (see LICENSE file) Remarques : Certaines parties de ce code ont été développées avec l’aide de Vibe Coding et d’outils d’intelligence artificielle. """ import json from typing import Any, Dict, List, Optional class LegiFranceSearchInput: """Générateur de requêtes pour l'API Légifrance""" # Constantes pour les types de recherche TYPE_RECHERCHE = { 'UN_DES_MOTS': 'UN_DES_MOTS', 'EXACTE': 'EXACTE', 'TOUS_LES_MOTS_DANS_UN_CHAMP': 'TOUS_LES_MOTS_DANS_UN_CHAMP', 'AUCUN_DES_MOTS': 'AUCUN_DES_MOTS', 'AUCUNE_CORRESPONDANCE_A_CETTE_EXPRESSION': 'AUCUNE_CORRESPONDANCE_A_CETTE_EXPRESSION' } # Constantes pour les types de champs avec descriptions et usage TYPE_CHAMP = { 'ALL': 'ALL', # Recherche dans tous les champs 'TITLE': 'TITLE', # Titre du texte 'TABLE': 'TABLE', # Table des matières 'NOR': 'NOR', # Numéro d'ordre réglementaire 'NUM': 'NUM', # Numéro du texte 'ADVANCED_TEXTE_ID': 'ADVANCED_TEXTE_ID', # Identifiant technique du texte 'NUM_DELIB': 'NUM_DELIB', # Numéro de délibération 'NUM_DEC': 'NUM_DEC', # Numéro de décision 'NUM_ARTICLE': 'NUM_ARTICLE', # Numéro d'article 'ARTICLE': 'ARTICLE', # Contenu des articles 'MINISTERE': 'MINISTERE', # Ministère émetteur 'VISA': 'VISA', # Visas du texte 'NOTICE': 'NOTICE', # Notice du texte 'VISA_NOTICE': 'VISA_NOTICE', # Visas et notice combinés 'TRAVAUX_PREP': 'TRAVAUX_PREP', # Travaux préparatoires 'SIGNATURE': 'SIGNATURE', # Signataires 'NOTA': 'NOTA', # Nota du texte 'NUM_AFFAIRE': 'NUM_AFFAIRE', # Numéro d'affaire (jurisprudence) 'ABSTRATS': 'ABSTRATS', # Résumés/abstracts 'RESUMES': 'RESUMES', # Résumés 'TEXTE': 'TEXTE', # Contenu textuel complet 'ECLI': 'ECLI', # Identifiant ECLI (jurisprudence européenne) 'NUM_LOI_DEF': 'NUM_LOI_DEF', # Numéro de loi déférée 'TYPE_DECISION': 'TYPE_DECISION', # Type de décision 'NUMERO_INTERNE': 'NUMERO_INTERNE', # Numéro interne 'REF_PUBLI': 'REF_PUBLI', # Référence de publication 'RESUME_CIRC': 'RESUME_CIRC', # Résumé de circulaire 'TEXTE_REF': 'TEXTE_REF', # Texte de référence 'TITRE_LOI_DEF': 'TITRE_LOI_DEF', # Titre de loi déférée 'RAISON_SOCIALE': 'RAISON_SOCIALE', # Raison sociale (accords d'entreprise) 'MOTS_CLES': 'MOTS_CLES', # Mots-clés 'IDCC': 'IDCC' # Identifiant de convention collective } # Descriptions détaillées des types de champs TYPE_CHAMP_DESCRIPTIONS = { 'ALL': { 'nom': 'Tous les champs', 'description': 'Recherche dans l\'ensemble des champs disponibles du document', 'usage': 'Recherche générale quand on ne sait pas dans quel champ chercher', 'exemple': 'Rechercher "mariage" dans tout le document' }, 'TITLE': { 'nom': 'Titre', 'description': 'Titre officiel du texte juridique', 'usage': 'Rechercher des textes par leur intitulé exact ou partiel', 'exemple': 'Rechercher "Code civil" ou "loi sur le mariage"' }, 'TABLE': { 'nom': 'Table des matières', 'description': 'Structure et organisation du texte (parties, livres, titres, chapitres)', 'usage': 'Naviguer dans l\'organisation du texte, chercher des sections', 'exemple': 'Rechercher "Livre premier" ou "Titre II"' }, 'NOR': { 'nom': 'Numéro NOR', 'description': 'Numéro d\'ordre réglementaire unique attribué aux textes', 'usage': 'Recherche précise d\'un texte par son identifiant officiel', 'exemple': 'JUSC1732516D pour un décret spécifique' }, 'NUM': { 'nom': 'Numéro du texte', 'description': 'Numéro officiel du texte (loi n°, décret n°, etc.)', 'usage': 'Rechercher un texte par son numéro de publication', 'exemple': 'Loi n°2018-287 ou Décret n°2019-123' }, 'ADVANCED_TEXTE_ID': { 'nom': 'Identifiant technique', 'description': 'Identifiant technique interne du système Légifrance', 'usage': 'Recherche technique par ID système (usage avancé)', 'exemple': 'LEGITEXT000006070721' }, 'NUM_DELIB': { 'nom': 'Numéro de délibération', 'description': 'Numéro de délibération pour les textes délibératifs', 'usage': 'Rechercher des délibérations spécifiques (CNIL, collectivités)', 'exemple': 'Délibération n°2019-001' }, 'NUM_DEC': { 'nom': 'Numéro de décision', 'description': 'Numéro de décision pour la jurisprudence', 'usage': 'Rechercher des décisions de justice par leur numéro', 'exemple': 'Arrêt n°19-12345' }, 'NUM_ARTICLE': { 'nom': 'Numéro d\'article', 'description': 'Numéro ou référence d\'un article spécifique', 'usage': 'Rechercher des articles précis dans les codes ou lois', 'exemple': 'Article 1134 ou Article L123-1' }, 'ARTICLE': { 'nom': 'Contenu des articles', 'description': 'Texte intégral du contenu des articles', 'usage': 'Rechercher dans le contenu même des articles', 'exemple': 'Rechercher "responsabilité" dans les articles' }, 'MINISTERE': { 'nom': 'Ministère', 'description': 'Ministère ou autorité émettrice du texte', 'usage': 'Filtrer les textes par ministère d\'origine', 'exemple': 'Ministère de la Justice, Ministère de l\'Intérieur' }, 'VISA': { 'nom': 'Visas', 'description': 'Références aux textes sur lesquels s\'appuie la décision', 'usage': 'Rechercher les fondements juridiques cités', 'exemple': 'Vu le Code civil, vu la loi du...' }, 'NOTICE': { 'nom': 'Notice', 'description': 'Notice explicative ou informative du texte', 'usage': 'Rechercher des explications ou contexte du texte', 'exemple': 'Informations sur l\'application du texte' }, 'VISA_NOTICE': { 'nom': 'Visas et notice', 'description': 'Recherche combinée dans les visas et la notice', 'usage': 'Rechercher à la fois dans les références et explications', 'exemple': 'Contexte juridique complet du texte' }, 'TRAVAUX_PREP': { 'nom': 'Travaux préparatoires', 'description': 'Documents préparatoires (rapports, débats parlementaires)', 'usage': 'Comprendre l\'intention du législateur', 'exemple': 'Rapport de la commission, exposé des motifs' }, 'SIGNATURE': { 'nom': 'Signataires', 'description': 'Autorités ayant signé ou approuvé le texte', 'usage': 'Rechercher par autorité signataire', 'exemple': 'Ministre, Président de la République' }, 'NOTA': { 'nom': 'Nota', 'description': 'Notes explicatives ou d\'application du texte', 'usage': 'Trouver des précisions sur l\'application', 'exemple': 'Conditions d\'entrée en vigueur, exceptions' }, 'NUM_AFFAIRE': { 'nom': 'Numéro d\'affaire', 'description': 'Numéro d\'affaire judiciaire ou administrative', 'usage': 'Rechercher une affaire judiciaire précise', 'exemple': '19-12.345 pour une affaire en cours d\'appel' }, 'ABSTRATS': { 'nom': 'Abstracts', 'description': 'Résumés courts du contenu principal', 'usage': 'Recherche dans les résumés pour avoir un aperçu', 'exemple': 'Mots-clés du résumé exécutif' }, 'RESUMES': { 'nom': 'Résumés', 'description': 'Résumés détaillés du texte', 'usage': 'Rechercher dans les synthèses du contenu', 'exemple': 'Points principaux du texte' }, 'TEXTE': { 'nom': 'Texte intégral', 'description': 'Contenu textuel complet du document', 'usage': 'Recherche exhaustive dans tout le contenu', 'exemple': 'Rechercher n\'importe quel terme dans le texte' }, 'ECLI': { 'nom': 'Identifiant ECLI', 'description': 'European Case Law Identifier - Identifiant européen de jurisprudence', 'usage': 'Recherche de jurisprudence avec référence européenne', 'exemple': 'ECLI:FR:CCASS:2019:C100123' }, 'NUM_LOI_DEF': { 'nom': 'Numéro de loi déférée', 'description': 'Numéro de la loi contestée devant le Conseil constitutionnel', 'usage': 'Rechercher les décisions constitutionnelles par loi contestée', 'exemple': 'Loi n°2018-123 déférée au Conseil constitutionnel' }, 'TYPE_DECISION': { 'nom': 'Type de décision', 'description': 'Catégorie de la décision de justice', 'usage': 'Filtrer par type de décision judiciaire', 'exemple': 'Arrêt, ordonnance, jugement' }, 'NUMERO_INTERNE': { 'nom': 'Numéro interne', 'description': 'Numéro de référence interne à l\'administration', 'usage': 'Recherche par référence administrative interne', 'exemple': 'Numéro de dossier administratif' }, 'REF_PUBLI': { 'nom': 'Référence de publication', 'description': 'Référence de publication dans les bulletins officiels', 'usage': 'Rechercher par référence de publication officielle', 'exemple': 'JORF n°123 du 15/06/2019' }, 'RESUME_CIRC': { 'nom': 'Résumé de circulaire', 'description': 'Résumé spécifique aux circulaires ministérielles', 'usage': 'Rechercher dans les résumés de circulaires', 'exemple': 'Objectifs et portée de la circulaire' }, 'TEXTE_REF': { 'nom': 'Texte de référence', 'description': 'Références aux textes cités ou modifiés', 'usage': 'Trouver les textes qui citent ou modifient d\'autres textes', 'exemple': 'Références aux codes modifiés' }, 'TITRE_LOI_DEF': { 'nom': 'Titre de loi déférée', 'description': 'Titre de la loi contestée devant le Conseil constitutionnel', 'usage': 'Rechercher les décisions constitutionnelles par titre de loi', 'exemple': 'Loi de finances pour 2019' }, 'RAISON_SOCIALE': { 'nom': 'Raison sociale', 'description': 'Nom de l\'entreprise pour les accords d\'entreprise', 'usage': 'Rechercher les accords par nom d\'entreprise', 'exemple': 'SNCF, Renault, Total' }, 'MOTS_CLES': { 'nom': 'Mots-clés', 'description': 'Mots-clés thématiques associés au texte', 'usage': 'Rechercher par thématique ou domaine juridique', 'exemple': 'Droit du travail, fiscalité, urbanisme' }, 'IDCC': { 'nom': 'IDCC', 'description': 'Identifiant de Convention Collective', 'usage': 'Rechercher une convention collective par son numéro IDCC', 'exemple': 'IDCC 1596 pour la métallurgie' } } # Constantes pour les fonds avec descriptions FONDS = { 'JORF': 'JORF', # Journal Officiel de la République Française - Textes publiés au JO 'CNIL': 'CNIL', # Commission Nationale de l'Informatique et des Libertés - Décisions et délibérations 'CETAT': 'CETAT', # Conseil d'État - Jurisprudence administrative 'JURI': 'JURI', # Jurisprudence judiciaire - Décisions de justice 'JUFI': 'JUFI', # Jurisprudence financière - Décisions des juridictions financières 'CONSTIT': 'CONSTIT', # Conseil Constitutionnel - Décisions constitutionnelles 'KALI': 'KALI', # Conventions collectives - Accords collectifs de travail 'CODE_DATE': 'CODE_DATE', # Codes consolidés - Recherche par date de version 'CODE_ETAT': 'CODE_ETAT', # Codes consolidés - Recherche par état juridique 'LODA_DATE': 'LODA_DATE', # Lois, Ordonnances, Décrets, Arrêtés - Recherche par date de version 'LODA_ETAT': 'LODA_ETAT', # Lois, Ordonnances, Décrets, Arrêtés - Recherche par état juridique 'ALL': 'ALL', # Tous les fonds - Recherche transversale 'CIRC': 'CIRC', # Circulaires et instructions - Textes d'application 'ACCO': 'ACCO' # Accords d'entreprise - Accords collectifs d'entreprise } # Descriptions détaillées des fonds FONDS_DESCRIPTIONS = { 'JORF': { 'nom': 'Journal Officiel de la République Française', 'description': 'Textes publiés au Journal Officiel : lois, décrets, arrêtés, avis, annonces...', 'contenu': 'Publications officielles, textes réglementaires, nominations, marchés publics' }, 'CNIL': { 'nom': 'Commission Nationale de l\'Informatique et des Libertés', 'description': 'Décisions, délibérations et avis de la CNIL en matière de protection des données', 'contenu': 'Autorisations, sanctions, recommandations, délibérations' }, 'CETAT': { 'nom': 'Conseil d\'État', 'description': 'Jurisprudence administrative du Conseil d\'État et des juridictions administratives', 'contenu': 'Arrêts, ordonnances, avis du Conseil d\'État et des cours administratives d\'appel' }, 'JURI': { 'nom': 'Jurisprudence judiciaire', 'description': 'Décisions des juridictions de l\'ordre judiciaire', 'contenu': 'Arrêts de la Cour de cassation, cours d\'appel, tribunaux' }, 'JUFI': { 'nom': 'Jurisprudence financière', 'description': 'Décisions des juridictions financières (Cour des comptes, CRC)', 'contenu': 'Arrêts de la Cour des comptes et des chambres régionales des comptes' }, 'CONSTIT': { 'nom': 'Conseil Constitutionnel', 'description': 'Décisions du Conseil constitutionnel', 'contenu': 'Décisions sur la constitutionnalité des lois, QPC, contrôle des élections' }, 'KALI': { 'nom': 'Conventions collectives', 'description': 'Conventions et accords collectifs de travail étendus', 'contenu': 'Conventions collectives nationales, accords de branche, avenants' }, 'CODE_DATE': { 'nom': 'Codes consolidés (par date)', 'description': 'Codes en vigueur recherchés par date de version', 'contenu': 'Tous les codes français consolidés avec historique des versions' }, 'CODE_ETAT': { 'nom': 'Codes consolidés (par état juridique)', 'description': 'Codes en vigueur recherchés par état juridique', 'contenu': 'Codes français avec statut juridique (en vigueur, abrogé, etc.)' }, 'LODA_DATE': { 'nom': 'LODA (par date)', 'description': 'Lois, Ordonnances, Décrets, Arrêtés recherchés par date de version', 'contenu': 'Textes législatifs et réglementaires consolidés avec historique' }, 'LODA_ETAT': { 'nom': 'LODA (par état juridique)', 'description': 'Lois, Ordonnances, Décrets, Arrêtés recherchés par état juridique', 'contenu': 'Textes législatifs et réglementaires avec statut juridique' }, 'ALL': { 'nom': 'Tous les fonds', 'description': 'Recherche transversale dans tous les fonds disponibles', 'contenu': 'Ensemble de la base juridique Légifrance' }, 'CIRC': { 'nom': 'Circulaires et instructions', 'description': 'Circulaires et instructions ministérielles', 'contenu': 'Textes d\'application, instructions, notes de service' }, 'ACCO': { 'nom': 'Accords d\'entreprise', 'description': 'Accords collectifs d\'entreprise déposés', 'contenu': 'Accords d\'entreprise, protocoles d\'accord, avenants d\'entreprise' } } def __init__(self): self.query = { "fond": "", "recherche": { "champs": [], "filtres": [], "pageNumber": 1, "pageSize": 50, "operateur": "ET", "sort": "PERTINENCE", "secondSort": "DATE_DESC", "typePagination": "DEFAUT", } } def set_fond(self, fond: str) -> 'LegiFranceSearchInput': """ Définit le fonds de recherche. Args: fond (str): Fonds sur lequel appliquer la recherche. Pour rechercher dans tous les fonds, utiliser 'ALL'. Pour les fonds LODA et CODE, deux types de recherche existent : - _DATE : recherche par date de version (CODE_DATE, LODA_DATE) - _ETAT : recherche par état juridique (CODE_ETAT, LODA_ETAT) Valeurs possibles: - JORF : Journal Officiel de la République Française - CNIL : Commission Nationale de l'Informatique et des Libertés - CETAT : Conseil d'État - JURI : Jurisprudence judiciaire - JUFI : Jurisprudence financière - CONSTIT : Conseil Constitutionnel - KALI : Conventions collectives - CODE_DATE : Codes consolidés (par date) - CODE_ETAT : Codes consolidés (par état juridique) - LODA_DATE : Lois, Ordonnances, Décrets, Arrêtés (par date) - LODA_ETAT : Lois, Ordonnances, Décrets, Arrêtés (par état) - ALL : Tous les fonds - CIRC : Circulaires et instructions - ACCO : Accords d'entreprise Returns: LegiFranceSearchInput: Instance pour chaînage des méthodes Raises: ValueError: Si le fonds spécifié n'est pas valide Example: >>> search = LegiFranceSearchInput() >>> search.set_fond("LODA_DATE") """ if fond not in self.FONDS.values(): raise ValueError(f"Fonds invalide. Utilisez une des valeurs: {list(self.FONDS.values())}") self.query["fond"] = fond return self def add_champ(self, type_champ: str, criteres: List[Dict], operateur: str = "ET") -> 'LegiFranceSearchInput': """ Ajoute un champ de recherche (objet ChampDTO dans l'API Légifrance). Cette méthode permet de définir dans quel champ de document effectuer la recherche et quels critères de recherche y appliquer. Args: type_champ (str): Type de champ dans lequel rechercher. Il est possible d'utiliser 'ALL' pour rechercher dans tous les champs. Valeurs possibles (selon ChampDTO de l'API): - ALL : Tous les champs - TITLE : Titre du texte - TABLE : Table des matières - NOR : Numéro d'ordre réglementaire - NUM : Numéro du texte - ADVANCED_TEXTE_ID : Identifiant technique du texte - NUM_DELIB : Numéro de délibération - NUM_DEC : Numéro de décision - NUM_ARTICLE : Numéro d'article - ARTICLE : Contenu des articles - MINISTERE : Ministère émetteur - VISA : Visas du texte - NOTICE : Notice du texte - VISA_NOTICE : Visas et notice combinés - TRAVAUX_PREP : Travaux préparatoires - SIGNATURE : Signataires - NOTA : Nota du texte - NUM_AFFAIRE : Numéro d'affaire (jurisprudence) - ABSTRATS : Résumés/abstracts - RESUMES : Résumés - TEXTE : Contenu textuel complet - ECLI : Identifiant ECLI (jurisprudence européenne) - NUM_LOI_DEF : Numéro de loi déférée - TYPE_DECISION : Type de décision - NUMERO_INTERNE : Numéro interne - REF_PUBLI : Référence de publication - RESUME_CIRC : Résumé de circulaire - TEXTE_REF : Texte de référence - TITRE_LOI_DEF : Titre de loi déférée - RAISON_SOCIALE : Raison sociale (accords d'entreprise) - MOTS_CLES : Mots-clés - IDCC : Identifiant de convention collective criteres (List[Dict]): Liste des critères/groupes de critères de recherche pour ce champ. Chaque critère doit être créé avec la méthode create_critere(). Les critères définissent les mots ou expressions à rechercher dans le champ. operateur (str, optional): Opérateur entre les critères de recherche. Défaut: "ET" Valeurs possibles: - "ET" : Tous les critères doivent être satisfaits (AND logique) - "OU" : Au moins un critère doit être satisfait (OR logique) Returns: LegiFranceSearchInput: Instance pour chaînage des méthodes Raises: ValueError: Si le type de champ spécifié n'est pas valide Example: >>> search = LegiFranceSearchInput() >>> critere1 = search.create_critere("mariage", "EXACTE") >>> critere2 = search.create_critere("divorce", "UN_DES_MOTS") >>> search.add_champ("TITLE", [critere1, critere2], "OU") """ if type_champ not in self.TYPE_CHAMP.values(): raise ValueError(f"Type de champ invalide. Utilisez une des valeurs: {list(self.TYPE_CHAMP.values())}") champ = { "typeChamp": type_champ, "criteres": criteres, "operateur": operateur } self.query["recherche"]["champs"].append(champ) return self def create_critere(self, valeur: str, type_recherche: str = "UN_DES_MOTS", operateur: str = "ET", proximite: Optional[int] = None, criteres: Optional[List[Dict]] = None) -> Dict: """ Crée un critère de recherche (objet CritereDTO dans l'API Légifrance). Un critère définit ce qui doit être recherché dans un champ spécifique. Les critères peuvent être imbriqués pour créer des groupes de critères complexes. Args: valeur (str): Mot(s) ou expression recherchés. Exemples: "dispositions", "mariage pour tous", "Code civil" type_recherche (str, optional): Type de recherche effectuée. Défaut: "UN_DES_MOTS" Valeurs possibles (selon CritereDTO de l'API): - "UN_DES_MOTS" : Au moins un des mots doit être présent - "EXACTE" : L'expression exacte doit être présente - "TOUS_LES_MOTS_DANS_UN_CHAMP" : Tous les mots doivent être présents dans le champ - "AUCUN_DES_MOTS" : Aucun des mots ne doit être présent (exclusion) - "AUCUNE_CORRESPONDANCE_A_CETTE_EXPRESSION" : L'expression ne doit pas être présente (exclusion) operateur (str, optional): Opérateur entre les sous-critères (si criteres est défini). Défaut: "ET" Valeurs possibles: - "ET" : Tous les sous-critères doivent être satisfaits (AND logique) - "OU" : Au moins un sous-critère doit être satisfait (OR logique) proximite (int, optional): Proximité maximum entre les mots du champ valeur. La proximité représente la distance maximale, en mots, entre deux termes recherchés. Par exemple, proximite=2 signifie qu'au maximum 2 mots peuvent séparer les termes recherchés. Défaut: None (pas de contrainte de proximité) Exemple: Avec valeur="fonction publique" et proximite=3, les expressions suivantes seront trouvées: - "fonction publique" (0 mots entre) - "fonction de la publique" (2 mots entre) - "fonction territoriale ou publique" (2 mots entre) Mais pas: "fonction de la République publique" (3 mots entre, dépasse la limite) criteres (List[Dict], optional): Sous-critère/Sous-groupe de critères. Permet de créer des requêtes imbriquées complexes. Chaque élément doit être un dictionnaire créé avec create_critere(). Défaut: None (pas de sous-critères) Exemple de structure imbriquée: critere_parent avec sous-critères: - critere_enfant_1: "soins" ET - critere_enfant_2: "fonction publique" (avec proximité) Returns: Dict: Dictionnaire représentant le critère, conforme au format CritereDTO de l'API Raises: ValueError: Si le type de recherche spécifié n'est pas valide Examples: >>> # Recherche simple d'un mot >>> search = LegiFranceSearchInput() >>> critere = search.create_critere("mariage", "EXACTE") >>> # Recherche avec proximité >>> critere = search.create_critere("fonction publique", "TOUS_LES_MOTS_DANS_UN_CHAMP", proximite=3) >>> # Recherche avec sous-critères imbriqués >>> sous_critere1 = search.create_critere("soins", "UN_DES_MOTS") >>> sous_critere2 = search.create_critere("fonction publique", "TOUS_LES_MOTS_DANS_UN_CHAMP", proximite=3) >>> critere_parent = search.create_critere( ... "dispositions", ... "UN_DES_MOTS", ... operateur="ET", ... proximite=2, ... criteres=[sous_critere1, sous_critere2] ... ) """ if type_recherche not in self.TYPE_RECHERCHE.values(): raise ValueError(f"Type de recherche invalide. Utilisez une des valeurs: {list(self.TYPE_RECHERCHE.values())}") critere: Dict[str, Any] = { "valeur": valeur, "typeRecherche": type_recherche, "operateur": operateur } if proximite is not None: critere["proximite"] = proximite if criteres is not None: critere["criteres"] = criteres return critere def add_filtre_valeurs(self, facette: str, valeurs: List[str]) -> 'LegiFranceSearchInput': """ Ajoute un filtre par valeurs (objet FiltreDTO dans l'API Légifrance). Les filtres permettent de restreindre les résultats selon des critères spécifiques comme la nature du texte, la juridiction, etc. La requête est effectuée automatiquement avec un opérateur ET entre les filtres listés. Args: facette (str): Nom de la facette => nom du filtre. Les facettes disponibles dépendent du fonds recherché et sont retournées dynamiquement dans les réponses de l'API (SearchResponseDTO.facets). **FACETTES COMMUNES À PLUSIEURS FONDS:** - **NATURE** : Nature du texte Valeurs possibles: LOI, ORDONNANCE, ARRETE, DECRET, CODE, CIRCULAIRE, CONSTITUTION, TRAITE, ACCORD, CONVENTION, REGLEMENT, etc. - **ETAT_JURIDIQUE** (ou legalStatus) : État juridique du texte Valeurs possibles: VIGUEUR, ABROGE, ABROGE_DIFF, VIGUEUR_DIFF, VIGUEUR_ETEN, VIGUEUR_NON_ETEN, PERIME, ANNULE, MODIFIE, DISJOINT, SUBSTITUE, TRANSFERE, INITIALE, MODIFIE_MORT_NE, SANS_ETAT, DENONCE, REMPLACE **FACETTES SPÉCIFIQUES AUX FONDS JURIDICTIONNELS (CETAT, JURI, JUFI, CONSTIT):** - **JURIDICTION** : Juridiction émettrice Valeurs possibles: Conseil d'État, Cour de cassation, Cour des comptes, Conseil constitutionnel, Tribunal administratif, Cour d'appel, etc. - **JURIDICTION_NATURE** : Nature de la juridiction Valeurs possibles: TRIBUNAL_ADMINISTRATIF, COURS_APPEL, COURS_COMPTES, CONSEIL_ETAT, COUR_CASSATION, TRIBUNAL_CONFLITS, COUR_JUSTICE_REPUBLIQUE, etc. - **TYPE_DECISION** : Type de décision Valeurs possibles: ARRET, ORDONNANCE, AVIS, DECISION, JUGEMENT, etc. - **CHAMBRE** : Chambre de la juridiction Valeurs possibles: Première chambre civile, Chambre criminelle, Chambre sociale, Chambre commerciale, etc. - **FORMATION** : Formation de jugement Valeurs possibles: Plénière, Section, Assemblée, etc. **FACETTES SPÉCIFIQUES AU FONDS JORF (Journal Officiel):** - **MINISTERE** : Ministère émetteur Valeurs possibles: Ministère de la Justice, Ministère de l'Intérieur, Ministère des Finances, Ministère de la Santé, etc. - **NUM_PARUTION** : Numéro de parution du JO **FACETTES SPÉCIFIQUES AU FONDS KALI (Conventions collectives):** - **IDCC** : Identifiant de Convention Collective Valeurs possibles: Numéros IDCC (ex: "1880", "2120", etc.) - **MOTS_CLES** : Mots-clés thématiques Valeurs possibles: ABATTOIRS, CHAUX HYDRAULIQUES, ENSEIGNEMENT, TRANSPORT, COMMERCE, etc. - **TYPE_TEXTE** : Type de texte conventionnel Valeurs possibles: TEXTE_BASE, TEXTE_ATTACHE, TEXTE_ETENDU, etc. **FACETTES SPÉCIFIQUES AU FONDS CIRC (Circulaires):** - **MINISTERE_DEPOSANT** : Ministère déposant la circulaire - **ETAT_CIRCULAIRE** : État de la circulaire Valeurs possibles: VIGUEUR (V), ABROGE (A), etc. **FACETTES SPÉCIFIQUES AU FONDS ACCO (Accords d'entreprise):** - **RAISON_SOCIALE** : Raison sociale de l'entreprise - **THEME** : Thème de l'accord Valeurs possibles: Salaires, Temps de travail, Formation, etc. **FACETTES SPÉCIFIQUES AUX DÉBATS ET QUESTIONS PARLEMENTAIRES:** - **TYPE_PARLEMENT** : Type de parlement Valeurs possibles: AN (Assemblée Nationale), SENAT (Sénat) - **LEGISLATURE** : Législature Valeurs possibles: 14, 15, 16, etc. **AUTRES FACETTES:** - **ANNEE** (years) : Année de publication/signature - **CODE_NAME** : Nom du code (pour le fonds CODE) Valeurs possibles: Code civil, Code pénal, Code du travail, etc. valeurs (List[str]): Liste des valeurs du filtre dans le cas d'un filtre textuel. Les valeurs exactes dépendent de la facette choisie. Utilisez les valeurs retournées par l'API dans les facettes de réponse. Returns: LegiFranceSearchInput: Instance pour chaînage des méthodes Note: - Plusieurs filtres peuvent être ajoutés. Ils seront combinés avec un opérateur ET. - Les facettes disponibles varient selon le fonds recherché. - Consultez d'abord les résultats d'une recherche pour voir les facettes disponibles et leurs valeurs possibles dans le contexte de votre fonds. Examples: >>> search = LegiFranceSearchInput() >>> # Filtrer par nature de texte (JORF, LODA) >>> search.add_filtre_valeurs("NATURE", ["LOI", "ORDONNANCE", "ARRETE"]) >>> >>> # Filtrer par juridiction (CETAT, JURI) >>> search.add_filtre_valeurs("JURIDICTION_NATURE", ["TRIBUNAL_ADMINISTRATIF", "COURS_APPEL"]) >>> >>> # Filtrer par état juridique >>> search.add_filtre_valeurs("ETAT_JURIDIQUE", ["VIGUEUR", "VIGUEUR_DIFF"]) >>> >>> # Filtrer par IDCC pour conventions collectives (KALI) >>> search.add_filtre_valeurs("IDCC", ["1880", "2120"]) >>> >>> # Filtrer par ministère (JORF) >>> search.add_filtre_valeurs("MINISTERE", ["Ministère de la Justice"]) """ filtre = { "facette": facette, "valeurs": valeurs } self.query["recherche"]["filtres"].append(filtre) return self def add_filtre_dates(self, facette: str, start_date: str, end_date: str) -> 'LegiFranceSearchInput': """ Ajoute un filtre par période de dates (objet FiltreDTO avec DatePeriod dans l'API Légifrance). Permet de filtrer les résultats sur une plage de dates définie. Args: facette (str): Nom de la facette de date => nom du filtre. **FACETTES DE DATES PRINCIPALES:** - **DATE_SIGNATURE** : Date de signature du texte Applicable aux fonds: JORF, LODA, CODE, CIRC - **DATE_PUBLICATION** (ou DATE_PUBLI) : Date de publication officielle Applicable aux fonds: JORF, LODA, CODE, CIRC, KALI - **DATE_VERSION** : Date de version du texte consolidé Applicable aux fonds: CODE, LODA (recherche par date) - **DATE_PARUTION** : Date de parution au Journal Officiel Applicable au fonds: JORF - **DATE_DECISION** : Date de la décision judiciaire Applicable aux fonds: CETAT, JURI, JUFI, CONSTIT - **DATE_ARRET** : Date de l'arrêt Applicable aux fonds: JURI, CETAT - **DATE_CREATION** : Date de création du document Applicable aux fonds: ACCO, CIRC - **DATE_MODIFICATION** (ou DATE_UPDATE, lastUpdate) : Date de dernière modification Applicable à plusieurs fonds pour le suivi des mises à jour - **DATE_EFFET** : Date d'entrée en vigueur/effet Applicable aux fonds: ACCO, KALI - **DATE_ABROGATION** : Date d'abrogation du texte Applicable aux fonds: LODA, CODE - **DATE_DEPOT** : Date de dépôt (pour accords d'entreprise) Applicable au fonds: ACCO - **DATE_EXPORT** : Date d'export du document Applicable au fonds: CIRC - **DATE_OPPOSABILITE** : Date de déclaration d'opposabilité Applicable au fonds: CIRC - **DATE_DELIBERATION** : Date de délibération Applicable au fonds: CNIL start_date (str): Date de début de la période. Format: "YYYY-MM-DD" (ex: "2015-01-01") Le format ISO 8601 est requis. end_date (str): Date de fin de la période. Format: "YYYY-MM-DD" (ex: "2018-01-31") Le format ISO 8601 est requis. Returns: LegiFranceSearchInput: Instance pour chaînage des méthodes Examples: >>> search = LegiFranceSearchInput() >>> # Filtrer les textes signés entre le 1er janvier 2015 et le 31 janvier 2018 >>> search.add_filtre_dates("DATE_SIGNATURE", "2015-01-01", "2018-01-31") >>> # Filtrer les textes publiés en 2020 >>> search.add_filtre_dates("DATE_PUBLICATION", "2020-01-01", "2020-12-31") """ filtre = { "facette": facette, "dates": { "start": start_date, "end": end_date } } self.query["recherche"]["filtres"].append(filtre) return self def add_filtre_date_unique(self, facette: str, date: str) -> 'LegiFranceSearchInput': """ Ajoute un filtre par date unique (objet FiltreDTO dans l'API Légifrance). Permet de filtrer les résultats sur une date précise. Args: facette (str): Nom de la facette de date => nom du filtre. **FACETTES DE DATES PRINCIPALES:** - **DATE_SIGNATURE** : Date de signature du texte Applicable aux fonds: JORF, LODA, CODE, CIRC - **DATE_PUBLICATION** (ou DATE_PUBLI) : Date de publication officielle Applicable aux fonds: JORF, LODA, CODE, CIRC, KALI - **DATE_VERSION** : Date de version du texte consolidé Applicable aux fonds: CODE, LODA (recherche par date) - **DATE_PARUTION** : Date de parution au Journal Officiel Applicable au fonds: JORF - **DATE_DECISION** : Date de la décision judiciaire Applicable aux fonds: CETAT, JURI, JUFI, CONSTIT - **DATE_ARRET** : Date de l'arrêt Applicable aux fonds: JURI, CETAT - **DATE_CREATION** : Date de création du document Applicable aux fonds: ACCO, CIRC - **DATE_MODIFICATION** (ou DATE_UPDATE, lastUpdate) : Date de dernière modification Applicable à plusieurs fonds pour le suivi des mises à jour - **DATE_EFFET** : Date d'entrée en vigueur/effet Applicable aux fonds: ACCO, KALI - **DATE_ABROGATION** : Date d'abrogation du texte Applicable aux fonds: LODA, CODE - **DATE_DEPOT** : Date de dépôt (pour accords d'entreprise) Applicable au fonds: ACCO - **DATE_EXPORT** : Date d'export du document Applicable au fonds: CIRC - **DATE_OPPOSABILITE** : Date de déclaration d'opposabilité Applicable au fonds: CIRC - **DATE_DELIBERATION** : Date de délibération Applicable au fonds: CNIL date (str): Date unique pour le filtre. Format: "YYYY-MM-DD" (ex: "2016-01-01") Le format ISO 8601 est requis. Le format datetime complet ISO 8601 est également accepté (ex: "2016-01-01T00:00:00"). Returns: LegiFranceSearchInput: Instance pour chaînage des méthodes Examples: >>> search = LegiFranceSearchInput() >>> # Filtrer les textes signés le 1er janvier 2016 >>> search.add_filtre_date_unique("DATE_SIGNATURE", "2016-01-01") """ filtre = { "facette": facette, "singleDate": date } self.query["recherche"]["filtres"].append(filtre) return self def set_pagination(self, page_number: int = 1, page_size: int = 10, type_pagination: str = "DEFAUT") -> 'LegiFranceSearchInput': """ Configure la pagination des résultats (selon RechercheSpecifiqueDTO de l'API Légifrance). Args: page_number (int, optional): Numéro de la page à consulter. Défaut: 1 (première page) La numérotation commence à 1. page_size (int, optional): Nombre d'éléments par page. Défaut: 10 Maximum: 100 (la valeur sera automatiquement limitée à 100 si dépassée) type_pagination (str, optional): Type de pagination. Défaut: "DEFAUT" Valeurs possibles: - "DEFAUT" : Pagination standard (DEFAULT dans l'API) - "ARTICLE" : Pagination spécifique pour les recherches dans les articles d'un texte Note: Dans la plupart des cas, utiliser "DEFAUT". Lors de la navigation dans plusieurs pages, il est nécessaire de passer la valeur reçue dans la réponse précédente. Returns: LegiFranceSearchInput: Instance pour chaînage des méthodes Examples: >>> search = LegiFranceSearchInput() >>> # Pagination standard : 50 résultats par page, page 1 >>> search.set_pagination(page_number=1, page_size=50) >>> # Aller à la page 3 avec 25 résultats par page >>> search.set_pagination(page_number=3, page_size=25) """ self.query["recherche"]["pageNumber"] = page_number self.query["recherche"]["pageSize"] = min(page_size, 100) # Max 100 self.query["recherche"]["typePagination"] = type_pagination return self def set_operateur_global(self, operateur: str) -> 'LegiFranceSearchInput': """ Définit l'opérateur global entre les champs de recherche (selon RechercheSpecifiqueDTO de l'API). Cet opérateur détermine comment les différents champs de recherche sont combinés. Args: operateur (str): Opérateur entre les champs de recherche. Valeurs possibles: - "ET" : Tous les champs doivent correspondre (AND logique) Exemple: Si vous recherchez "mariage" dans TITLE ET "divorce" dans ARTICLE, seuls les documents contenant les deux seront retournés. - "OU" : Au moins un champ doit correspondre (OR logique) Exemple: Si vous recherchez "mariage" dans TITLE OU "divorce" dans ARTICLE, les documents contenant l'un ou l'autre (ou les deux) seront retournés. Returns: LegiFranceSearchInput: Instance pour chaînage des méthodes Raises: ValueError: Si l'opérateur n'est pas "ET" ou "OU" Examples: >>> search = LegiFranceSearchInput() >>> # Les documents doivent correspondre à TOUS les champs >>> search.set_operateur_global("ET") >>> # Les documents doivent correspondre à AU MOINS UN champ >>> search.set_operateur_global("OU") """ if operateur not in ["ET", "OU"]: raise ValueError("L'opérateur doit être 'ET' ou 'OU'") self.query["recherche"]["operateur"] = operateur return self def set_sort(self, sort: str, second_sort: Optional[str] = None) -> 'LegiFranceSearchInput': """ Configure le tri des résultats (selon RechercheSpecifiqueDTO de l'API Légifrance). Les tris possibles dépendent du fonds recherché. Args: sort (str): Tri principal des éléments trouvés. Exemples de valeurs courantes (selon le fonds): - "PERTINENCE" : Tri par pertinence (défaut recommandé) - "SIGNATURE_DATE_DESC" : Date de signature décroissante (plus récent en premier) - "SIGNATURE_DATE_ASC" : Date de signature croissante - "DATE_PUBLI_DESC" : Date de publication décroissante - "DATE_PUBLI_ASC" : Date de publication croissante - "DATE_VERSION_DESC" : Date de version décroissante - "DATE_VERSION_ASC" : Date de version croissante - "ID_DESC" : Identifiant décroissant - "ID_ASC" : Identifiant croissant - "DATE_UPDATE" : Date de mise à jour Note: Les options de tri disponibles varient selon le fonds (JORF, LODA, CODE, etc.) second_sort (str, optional): Tri secondaire des éléments trouvés. Appliqué lorsque le tri principal donne des résultats identiques. Accepte les mêmes valeurs que le paramètre 'sort'. Défaut: None (pas de tri secondaire) Exemples: - "ID" : Par identifiant - "DATE_DESC" : Par date décroissante - "DATE_ASC" : Par date croissante Returns: LegiFranceSearchInput: Instance pour chaînage des méthodes Examples: >>> search = LegiFranceSearchInput() >>> # Tri par pertinence uniquement >>> search.set_sort("PERTINENCE") >>> # Tri par date de signature décroissante, puis par ID >>> search.set_sort("SIGNATURE_DATE_DESC", "ID") >>> # Tri par date de publication, puis par date de signature >>> search.set_sort("DATE_PUBLI_DESC", "SIGNATURE_DATE_DESC") """ self.query["recherche"]["sort"] = sort if second_sort: self.query["recherche"]["secondSort"] = second_sort return self def set_advanced_search(self, advanced: bool = True) -> 'LegiFranceSearchInput': """ Active ou désactive le mode de recherche avancée (selon RechercheSpecifiqueDTO de l'API). Ce paramètre permet d'indiquer s'il s'agit d'une recherche avancée ou simple. Args: advanced (bool, optional): Déterminer s'il s'agit d'une recherche avancée. Défaut: True Valeurs: - True : Mode recherche avancée activé - False : Mode recherche simple Returns: LegiFranceSearchInput: Instance pour chaînage des méthodes Examples: >>> search = LegiFranceSearchInput() >>> # Activer la recherche avancée >>> search.set_advanced_search(True) >>> # Désactiver la recherche avancée (recherche simple) >>> search.set_advanced_search(False) """ self.query["recherche"]["fromAdvancedRecherche"] = advanced return self def build(self) -> Dict: """ Construit et retourne la requête finale au format SearchRequestDTO de l'API Légifrance. Valide que tous les paramètres requis sont définis et retourne un dictionnaire représentant la requête complète prête à être envoyée à l'API. Returns: Dict: Dictionnaire représentant la requête de recherche complète, conforme au format SearchRequestDTO de l'API Légifrance. Structure retournée: { "fond": "LODA_DATE", # Fonds de recherche "recherche": { # Objet RechercheSpecifiqueDTO "champs": [...], # Liste des champs de recherche (ChampDTO) "filtres": [...], # Liste des filtres (FiltreDTO) "pageNumber": 1, # Numéro de page "pageSize": 50, # Taille de page "operateur": "ET", # Opérateur global "sort": "PERTINENCE", # Tri principal "secondSort": "DATE_DESC", # Tri secondaire (optionnel) "typePagination": "DEFAUT", # Type de pagination "fromAdvancedRecherche": false # Mode recherche avancée (optionnel) } } Raises: ValueError: Si le fonds n'a pas été défini avec set_fond() Examples: >>> search = LegiFranceSearchInput() >>> search.set_fond("LODA_DATE") >>> critere = search.create_critere("mariage", "EXACTE") >>> search.add_champ("TITLE", [critere]) >>> query = search.build() >>> print(query) {'fond': 'LODA_DATE', 'recherche': {...}} """ if not self.query["fond"]: raise ValueError("Le fonds doit être défini") return self.query.copy() def to_json(self, indent: int = 2) -> str: """ Retourne la requête au format JSON. Construit la requête avec build() et la sérialise en JSON. Args: indent (int, optional): Nombre d'espaces pour l'indentation du JSON. Défaut: 2 Utilisez None pour obtenir un JSON compact sans indentation. Returns: str: Chaîne JSON représentant la requête de recherche, prête à être envoyée à l'endpoint /search de l'API Légifrance. Raises: ValueError: Si le fonds n'a pas été défini (propagé depuis build()) Examples: >>> search = LegiFranceSearchInput() >>> search.set_fond("LODA_DATE") >>> critere = search.create_critere("mariage", "EXACTE") >>> search.add_champ("TITLE", [critere]) >>> json_str = search.to_json() >>> print(json_str) { "fond": "LODA_DATE", "recherche": { "champs": [...] } } """ return json.dumps(self.build(), indent=indent, ensure_ascii=False) def reset(self) -> 'LegiFranceSearchInput': """ Remet à zéro le générateur de requêtes. Réinitialise toutes les configurations à leurs valeurs par défaut. Utile pour réutiliser le même objet pour construire une nouvelle requête. Returns: LegiFranceSearchInput: Instance réinitialisée pour chaînage des méthodes Examples: >>> search = LegiFranceSearchInput() >>> search.set_fond("LODA_DATE") >>> # ... construire une requête ... >>> search.reset() # Réinitialise tout >>> search.set_fond("JORF") # Commence une nouvelle requête """ self.__init__() return self

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jmtanguy/DroitFrancaisMCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server