
    [ij              	          d Z ddlZddlZddlZddlZddlZddlmZ ddlm	Z	 ddl
Z
ddlmZ  ej        d          Z ee          j        j        Zedz  dz  Ze                    d	d	
           ddiZddiZdedede	e         fdZdedefdZd8dededefdZd8dededefdZdede	e         fdZdededefdZdedefdZdededefd Z d9d"eded#ede!fd$Z"dedede!fd%Z#defd&Z$d'edefd(Z%deded)edefd*Z&dededefd+Z'd,edefd-Z(d,edefd.Z)dedefd/Z*dedefd0Z+dedede!fd1Z, G d2 d3          Z-d4ed5edefd6Z.dede!fd7Z/dS ):u7  
ICAC Data Fetcher v2.2 — Scraping Web Systématique
Fix critique : filtre INSEE/CP strict pour RNA et assoce.fr.
Fouille web PRIMAIRE pour toute requête, RAG secondaire.
v2.2: Intégration subventions 2025 + audit mandats.

Sources:
  - besseges.fr (toujours)
  - RNA / data.gouv.fr (associations)
  - Journal Officiel Associations
  - Annuaire Entreprises data.gouv.fr
  - Pappers (dirigeants)
  - Aides-Territoires
  - BOAMP (marchés publics)
  - RNE (élus)
  - DGFiP: data.economie.gouv.fr (balances comptables)
  - SIRENE: recherche-entreprises.api.gouv.fr
    N)Path)Optional)BeautifulSoupzicac.data_fetchercachedataT)parentsexist_ok30034	21300037530037keymax_agereturnc                 D   t           |  dz  }|                                sd S 	 t          j        |                                          }t          j                    |                    dd          z
  |k    rd S |                    dd          S # t          $ r Y d S w xY w)N.jsontsr   content )	CACHE_DIRexistsjsonloads	read_texttimeget	Exception)r   r   pathr   s       +/var/www/icac/agents_python/data_fetcher.py
_cache_getr   1   s    #}}}$D;;== tz$..**++9;;$***W444xx	2&&&   tts   AB ;B 
BBr   c                     t           |  dz  }|                    t          j        t	          j                    |dd                     d S )Nr   )r   r   F)ensure_ascii)r   
write_textr   dumpsr   )r   r   r   s      r   
_cache_setr$   >   sH    #}}}$DOODJdikkgFFUZ[[[\\\\\      url	max_charsc                   K   	 t          j        dddid          4 d{V 	 }|                    |            d{V }|j        dk    r	 ddd          d{V  dS t	          |j        |          cddd          d{V  S # 1 d{V swxY w Y   dS # t          $ r'}t                              d	| |           Y d}~dS d}~ww xY w)
z3Scrape une URL, nettoie le HTML, retourne le texte.   
User-Agentz.Mozilla/5.0 (compatible; ICAC/1.0; mairie-bot)T)timeoutheadersfollow_redirectsN   r   z_scrape_clean %s: %s)	httpxAsyncClientr   status_code_scrape_clean_from_htmltextr   logwarning)r'   r(   cres        r   _scrape_cleanr:   G   s     $!#ST!
 
 
 	> 	> 	> 	> 	> 	> 	> 	> eeCjj      A}##	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> +169==	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	>    *C333rrrrrsF   B (BB B3B 
BB BB 
C
#CC
htmlc                     t          | d          } |g d          D ]}|                                 |                    dd          }t          j        dd|          }|d |         S )Nhtml.parser)navheaderfooterscriptstyleasideformbutton Tstripz\s{3,}z  )r   	decomposeget_textresub)r;   r(   souptr4   s        r   r3   r3   X   s    }--DT % % % & &   	
==D=))D6)T4((D

r%   queryc                 j    h dt          j        d|           }fd|D             }|r|d         ndS )z+Extrait le premier nom propre significatif.>   	   SociétéDesEstLesQuiSurClubQuelSontDonneListeQuelsDonnezMairieQuelleCombienCommentCommuneQuellesTrouverChercher
Entreprise
Historique
RechercherAssociation	   Bessègesu   \b[A-ZÀÂÉÈÊËÎÏÔÙÛÜÇ][a-zàâéèêëîïôùûüç]+(?:\s+[A-ZÀÂÉÈÊËÎÏÔÙÛÜÇ][a-zàâéèêëîïôùûüç]+)*\bc                     g | ]}|v|	S  rl   ).0n	stopwordss     r   
<listcomp>z#_extract_entity.<locals>.<listcomp>q   s#    777aAY$6$6$6$6$6r%   r   N)rK   findall)rO   namesentitiesro   s      @r   _extract_entityrt   c   s^      I J	U E
 87775777H",8A;;,r%   communec                    K   |                      dd          }d| }t          |d           d{V }|rt          |          dk     rt          dd	           d{V }d
||dS )uD   Recherche sur le moteur interne de besseges.fr — TOUJOURS appelé.rF   +zhttps://www.besseges.fr/?s=i  r(   N2   zhttps://www.besseges.frr&   besseges.frdomainr4   r'   replacer:   len)rO   ru   qr'   txts        r   _fetch_besseges_searchr   y   s      c3A
+
+
+CcT222
2
2
2
2
2
2C M#c((R--!";tLLLLLLLLL  r%   commune_cfgc                 @  K   |                      dd          }|                      dd          }|                      dd          }t                               ||          }d| d}g }	 t          j        d	d
ddi          4 d{V 	 }|                     |           d{V }|j        dk    r|                                }	|	                     dg           }
t                              dt          |
          ||           g }|
D ]}|                     di           }t          |                     dd                    }|                     dd          
                                }||k    s|
                                |v sd|v r|                    |           t                              d|                     dd          ||           t                              dt          |          t          |
                     |D ]}|                     dd          }|                     dd          }|                     di           }|                     dd          p|                     dd          }|                     dd          }|                     d          d k    rd!nd"}|                     d#i                                d$d          }d}|                     d%g           D ]q}|                     d&d                                          }|d'v rC|                     d(d           d)|                     d*d                                           } nr|                    d+| d,|pd- d.| d/| d0| d1| d2|pd-            ddd          d{V  n# 1 d{V swxY w Y   n2# t          $ r%}t                              d3|           Y d}~nd}~ww xY wd4|r.t          |           d5| d6| d7d8                    |          z   nd|d9S ):u   
    RNA via API officielle avec filtre code commune SIRENE strict.
    Le code commune SIRENE (30037) diffère de l'INSEE admin (30034).
    Filtre post-API sur CP 30160 pour exclure les sièges hors commune.
    inseer
   cp30160	nom_courtrj   >https://recherche-entreprises.api.gouv.fr/search?code_commune=;&nature_juridique=9220&page=1&per_page=25&mtm_campaign=icac   Tr+   ICAC/2.1 mairie-bot)r,   r.   r-   Nr/   resultsu>   RNA API: %d résultats bruts pour commune SIRENE %s (INSEE %s)siegecode_postalr   libelle_communeBESSu-   RNA exclu (siège hors commune): %s → %s %snom_complet?u   RNA filtrés Bessèges: %d/%dsirengeo_adresseadressedate_creationetat_administratifAActiveDissoutecomplementsidentifiant_association
dirigeantsqualite)
   président	president   gérant	directeurprenomrF   nom   ■ 
  RNA      : N/Az
  SIREN    : z
  Adresse  : u   
  Création : u   
  État     : u   
  Président: zRNA API: %sz%RNA/recherche-entreprises.api.gouv.fru    associations à z () :



r{   )r   INSEE_TO_SIRENE_COMMUNEr0   r1   r2   r   r5   infor   strupperappenddebuglowerrH   r   r6   join)r   r   r   ru   sirene_communer'   results_textclientr8   r   itemsfiltereditemr   item_cpitem_communer   r   r   creationetatrna_id	dirigeantdqualr9   s                             r   _fetch_rna_bessegesr      s      OOGW--E	w	'	'Book;77G -00>>N	'	 	 	  LJ&$!#89
 
 
 F	 F	 F	 F	 F	 F	 F	 F	 jjoo%%%%%%A}##vvxxB//TJJ   !  D HHWb11E!%))M2">">??G#(99->#C#C#I#I#K#KL2<77,.. ----		K HH]C88('    3MM3u::  
 % ! !D((="55C HHWb11E HHWb11E		-44 1		)R00   $xx<<H'+xx0D'E'E'L'L88R\D!XXmR88<<12 F
 !#I!XXlB77 " " uuY3399;;#VVV#$552#6#6 !6 !6#$55#3#3!6 !66;egg & "E W !''>s > >(.%> >(-> > )0> > *2	> >
 *.> > *3);e> >   }F	 F	 F	 F	 F	 F	 F	 F	 F	 F	 F	 F	 F	 F	 F	 F	 F	 F	 F	 F	 F	 F	 F	 F	 F	 F	 F	P  & & &M1%%%%%%%%& :
 	"<   & && && & &kk,''( (  "  s=   )N8 	LN&N8 &
N00N8 3N04N8 8
O'O""O'c                    K   t          |           p|}d|                    dd           d}t          |d           d{V }|rt          |          dk    rd	||d
S i S )z-JO associations via journal-officiel.gouv.fr.zLhttps://www.journal-officiel.gouv.fr/pages/associations-recherche/?fullText=rF   rw   z&typeAnnonce=fondr&   rx   NP   zjournal-officiel.gouv.frr{   rt   r~   r:   r   rO   ru   namer'   r   s        r   _fetch_jo_associationr      s      5!!,WD	\\#s++	 	 	  cT222
2
2
2
2
2
2C
 
s3xx"}}0
 
 	

 Ir%   r   entityr   c                     g }|r|                                 nd}|                     dd          }|                     dd          }|s`g }|                     dt          j        d	          
          D ]4}|                    g d          }	|	r|	|vr|                    |	           5|D ]^}
|
                    dd          t          fddD                       }|o|                                 v }|s|sRi }|
                    dd          }|r"|                    d          dd         |d<   nx|
                    g d          p=|
                    d          p(|
                    dt          j        d	          
          }|r!|                    d          dd         |d<   |
                    dd          }|r[|                    dd          }|r|                    d          |d<   |	                    dd          }|r|dk    rd|d<   nd|d<   t          j
        d          }|r|                    d          |d <   |
                    dd!"          }t          |          d#k    r/|d#                             d          }|rd$|vr|dd%         |d&<   |	                    d&          sMd'D ]J}t          j
        d(| d)t          j                  }|r"|                    d*          dd%         |d&<    nKd+D ]S}t          j
        | d,t          j                  }|r,|                    d*                                          |d-<    nT|
                    dt          j        d	          
          }|r'|d.         }|                    d/          r|nd0| |d1<   |	                    d          r<t          |	                    dd                    d2k    r|                    |           `|S )3ur   
    Parse assoce.fr avec filtre géographique strict.
    N'inclut que les assos de Bessèges (30160/30034).
    NrF   TrG   liblock)class_awaldec)href)divarticler   trc              3       K   | ]}|v V  	d S Nrl   rm   xr4   s     r   	<genexpr>z%_parse_assoce_page.<locals>.<genexpr>!  s7        !t)      r%   rj   u	   BESSÈGESBESSEGESr   r
   span)rB   d   r   )h2h3h4strongr   aoeDatazdpubli-tokenr   zdata-ddissor   z
0001-01-01dissoutestatutactivezW\d{9}r   rnaF)	recursive   Fiche   objet)r   butu	   activitémissionz(?:z)\s*[:\-]?\s*(.{15,300})   )r   u   présidenter   u   représentantu   \s*[:\-]?\s*([A-ZÀÂÉÈÊËÎÏÔÙÛÜÇ][a-zàâéèêëîïôùûüç]+(?:\s+[A-ZÀÂÉÈÊËÎÏÔÙÛÜÇ][a-zàâéèêëîïôùûüç]+)+)r   r   httpzhttps://assoce.fr	url_fiche   )r   rJ   find_allrK   compilefind_parentr   anyfindr   searchgroupr   
IGNORECASErH   
startswith)rM   r   ru   r   assos
entity_low	text_fullblocksr   parentr   is_bessegesis_entity_matchasso	name_spannom_tagdata_divdpddissorna_mdivs
objet_textlabelma_tagr   r4   s                             @r   _parse_assoce_pager  	  s   
 E#)3tJc..I ]]4]00F  &sI)>)>?? 	& 	&A]]#A#A#ABBF &&..f%%% Y Y~~c~..      .
       '$**,,& 	
  	? 	 JJvTJ22	 		A#,,4,88#>DKK 

---.. <

8$$<

3RZ	%:%:
;; 
  A%..T.::4C4@U ::eI:66 	*vn==B ;#%;;T;#:#:Z \\-44F *&L00!+X!)X 	)T** 	)++a..DK ~~eu~55t99q==a)))55J 1gZ77 *4C4 0Wxx   	A  I<5<<<"-   $%GGAJJtt$4DME
 Q 		 		E	 ] ] ] bm	 A  $%GGAJJ$4$4$6$6[!
 

3RZ	%:%:
;; 	=D// 0/// 
 88E?? 	s488E2#6#677!;;LLLr%   c                   K   |                     dd          }|                     dd          }|                     dd          }t          |           }g }|                                                    dd                              d	d          }g }|r^|                                                    d
d          }	|                    d|	 d|            |                    d|	 d|            |                    d| dd| d| dd| d| g           t          j        ddidd          4 d{V 	 }
|D ]L}	 |
                     |           d{V }|j        dk    r+t          |j
        d          }|                    d
d          t          fddD                       }|st                              d|           t          ||||          }|rg }|D ]}|                    d|d          d|                     dd            d!|                     d"d            d#|                     d$d            d%|                     d&d'           d(|                     d)d*                      |                    d+t!          |           d,| d-d.                    |          z   |t!          |          d/           t                              d0t!          |          |            n|r^t!                    dk    rK|                    d+dd1         |d2           t                              d3t!                                n6# t$          $ r'}t                              d4||           Y d}~Fd}~ww xY wddd          d{V  n# 1 d{V swxY w Y   |st                              d5           |S )6u^   
    Scrape assoce.fr avec filtre code postal strict.
    Bessèges = 30160, INSEE 30034.
    r   rj   r   r   r   r
      èr9      érF   rw   zhttps://assoce.fr/search?q=zhttps://assoce.fr//-r+   r   r   Tr-   r,   r.   Nr/   r=   rG   c              3       K   | ]}|v V  	d S r   rl   r   s     r   r   z _fetch_assoce.<locals>.<genexpr>  s7       ( (aT	 ( ( ( ( ( (r%   r   u.   assoce.fr: page sans Bessèges ignorée → %sr   r   r   r   r   z
  Objet    : r   z
  Dirigeant: r   z
  Statut   : r   r   z
  URL      : r   r   zassoce.fr (WALDEC)u    associations à Bessèges (r   r   )r|   r4   r'   countu'   assoce.fr OK: %d assos Bessèges via %si  r{   zassoce.fr texte brut: %dcz_fetch_assoce %s: %su)   assoce.fr: aucun résultat pour Bessèges)r   rt   r   r~   r   extendr0   r1   r2   r   r4   rJ   r   r5   r   r  r   r   r   r6   )rO   r   ru   r   r   r   r   commune_slugurls_to_tryentity_slugr   r'   r8   rM   page_has_bessegesr   linesr   r9   r4   s                      @r   _fetch_assocer  {  s     
 ook;77G	w	'	'BOOGW--EU##FG ==??**455==dCHHLK  
llnn,,S#66F+FFFF	
 	
 	
 	<+<<<<	
 	
 	

 ,\,,,1R11,1119l99R99     45   D< D< D< D< D< D< D< D< 
 >	< >	<C=< **S//))))))=C''$QV];;}}S}55 %( ( ( ( ( < ( ( ( % %! ) HHH    +4"EE #E"  E1U8 E E,-EE%,?,?E E,-EE'5,A,AE E -.EE+u,E,EE E -.EE(H,E,E	E E
 -.EE+r,B,BE E    NN"6"5zz 6 6*,6 6 6$kk%001  #!$U	$ 	$ 	 	 	 HHAE

C   E ' 3t99s??NN"6 $UdU"$ $   
 HH8#d))DDDE < < <2C;;;;;;;;<GD< D< D< D< D< D< D< D< D< D< D< D< D< D< D< D< D< D< D< D< D< D< D< D< D< D< D<L  A?@@@Nsc   >N!&M+N!,A$MN!D&M7N!9AMN!
N%NN!NN!!
N+.N+c                    |                      dd          }i }|                     d          }|r|                     d          |d<   t          j        d|          }|r|                    d          |d<   d	D ]P}t          j        | d
|          }|r4|                    d                                          dd         |d<    nQt          j        d|t          j                  }|r2|                    d                                          dd         |d<   dD ]S}t          j        | d|t          j                  }|r,|                    d                                          |d<    nT|S )z
    Parse a single assoce.fr/waldec/WXXX/ fiche page.
    Extracts: nom, commune, objet, domaines, dirigeant if available.
    rF   TrG   h1r   z	W\d{9,10}r   r   )rb   u   Siègez$\s+(.+?)(?:\s*\(\d{5}\)|\s*Domaines)r   Nr   r   uR   (?:Activité|Mission|Objet)\s+(.{10,300}?)(?:\s+Revendiquez|\s+Commune|\s+Contact)r/   r   )u
   Président	Dirigeantu   Représentantu   \s*:?\s*([A-ZÀÂÉÈÊËÎÏÔÙÛÜÇ][a-zàâéèêëîïôùûüç]+(?:\s+[A-ZÀÂÉÈÊËÎÏÔÙÛÜÇ][a-zàâéèêëîïôùûüç]+)+)r   )rJ   r   rK   r   r   rH   DOTALLr   )rM   r4   r   r  r  r	  r
  s          r   _parse_assoce_ficher     s   
 ==D=))DD 
4B	 .kkk--U IlD))E %kk!nnU '  I%GGGNN 	ggajj..00#6DOE	
 		g		# 	#A 1

((**4C40W > 	 	I Y Y Y "-	
 
  	 !

 0 0 2 2DE	 Kr%   r   c           
        K   d|  d}	 t          j        ddidd          4 d{V 	 }|                    |           d{V }|j        d	k    ri cddd          d{V  S t	          |j        d
          }t          |          }|rd|                    dd           d|                    d|            d|                    dd           d|                    dd           d|                    dd           g}d|  d                    |          |dcddd          d{V  S i cddd          d{V  S # 1 d{V swxY w Y   dS # t          $ r(}t          
                    d| |           i cY d}~S d}~ww xY w)u{   
    Récupère la fiche directe d'une asso par son RNA.
    Usage : quand on connaît le RNA depuis une autre source.
    zhttps://assoce.fr/waldec/r  r+   z"Mozilla/5.0 (compatible; ICAC/1.0)   Tr  Nr/   r=   zFICHE WALDEC : r   r   z  RNA      : r   z  Objet    : r   z  Adresse  : r   z  Dirigeant: r   zassoce.fr/waldec/
r{   zassoce direct %s: %s)r0   r1   r   r2   r   r4   r   r   r   r5   r6   )r   r'   r7   r8   rM   r   r  r9   s           r   _fetch_assoce_directr$    s     
 -c
,
,
,C$!#GH!
 
 
 	 	 	 	 	 	 	 	 eeCjj      A}##	 	 	 	 	 	 	 	 	 	 	 	 	 	 !77D&t,,D >dhhue&<&<>>:DHHUC$8$8::>DHHWe$<$<>>@DHHY$>$>@@BDHH[%$@$@BB 8#77"ii..! %	 	 	 	 	 	 	 	 	 	 	 	 	 	. /	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	0    *C333						sY   E (EE %B;E E 3E4E 
EE EE 
F$FFFdeptc                    K   t          |           p	| dd         }d|                    dd           d| }t          |d           d{V }|rt          |          d	k    rd
||dS i S )z&Annuaire des entreprises data.gouv.fr.N(   z;https://annuaire-entreprises.data.gouv.fr/rechercher?terme=rF   rw   z&cp_dep=i	  rx   r   z!annuaire-entreprises.data.gouv.frr{   r   )rO   ru   r%  r   r'   r   s         r   _fetch_annuaire_entreprisesr(  9  s      5!!/U3B3ZD	!\\#s33	 		 	 
 cT222
2
2
2
2
2
2C
 
s3xx"}}9
 
 	

 Ir%   c                    K   t          |           p	| dd         }d|                    dd           d|                    dd           }t          |d           d{V }|rt          |          d	k    rd
||dS i S )u    Pappers — dirigeants enrichis.Nr'  z#https://www.pappers.fr/recherche?q=rF   rw   z&ville=r&   rx   r   z
pappers.frr{   r   r   s        r   _fetch_pappersr*  K  s      5!!/U3B3ZD	.ll3$$	. 	.//#s++	. 	. 
 cT222
2
2
2
2
2
2C
 
s3xx#~~"
 
 	

 Ir%   r   c                 r   K   d}t          |d           d{V }|rt          |          dk    rd||dS i S )u8   Élus municipaux — page besseges.fr/conseil-municipal.*https://www.besseges.fr/conseil-municipal/r&   rx   Nr   u   besseges.fr/élusr{   r:   r   r   r'   r   s      r   _fetch_elusr/  ]  sd      
6CcT222
2
2
2
2
2
2C
 
s3xx"}})
 
 	

 Ir%   c                 x   K   d|  }t          |d           d{V }|rt          |          dk    rd||dS i S )z0Aides-territoires.beta.gouv.fr pour subventions.z8https://aides-territoires.beta.gouv.fr/aides/?perimeter=r&   rx   Nr   zaides-territoires.beta.gouv.frr{   r-  r.  s      r   _fetch_aides_territoiresr1  j  sx      	%"	% 	%  cT222
2
2
2
2
2
2C
 
s3xx#~~6
 
 	

 Ir%   c                    K   d|                      dd           }t          |d           d{V }|rt          |          dk    rd||d	S i S )
u   BOAMP — marchés publics.z,https://www.boamp.fr/pages/recherche/?terms=rF   rw   r&   rx   Nr   zboamp.frr{   r}   )ru   r'   r   s      r   _fetch_boampr3  z  s      	.//#s++	. 	.  cT222
2
2
2
2
2
2C
 
s3xx#~~ 
 
 	

 Ir%   c                 n   K   t          | d           d{V }|rt          |          dk    rd|| dS i S )u+   Scrape une page spécifique de besseges.fr.r&   rx   Nry   rz   r{   r-  )r'   r   s     r   _fetch_besseges_pager5    s_      cT222
2
2
2
2
2
2C
 
s3xx"}}#
 
 	

 Ir%   c                   K   g }|                                  |                    dd          }|                    dd          }|                    dd          dd         }g }|                    t          | |                     t	          fd	d
D                       r|                    t          |                     |                    t          | |                     |                    t          | |                     t	          fddD                       r,ddlm	}  ||           }|r|                    d|dd           t	          fddD                       rsddl
m}	  |	|           }
|
r|                    d|
dd           |                    t          | ||                     |                    t          | |                     t	          fddD                       rD|                    t          |                     |                    t          d                     t	          fddD                       rNddlm	}  ||           }|r|                    d|dd           |                    t!          |                     t	          fddD                       r"|                    t#          |                     t%          j        |ddi d{V }|D ]}t)          |t*                    rt,                              d |           3|r@t)          |t0                    r+|                    d!          r|                    |           u|r4t)          |t2                    r|                    d" |D                        t,                              d#t9          |          | dd$                    |S )%u   
    Fouille web systématique pour toute requête.
    Retourne une liste de sources textuelles pour la synthèse.
    Appelé AVANT la synthèse, sans condition.
    r   r
   r   rj   departement30Nr   c              3       K   | ]}|v V  	d S r   rl   rm   kq_lows     r   r   z"fetch_for_query.<locals>.<genexpr>  s7        !1:      r%   )associationclubu   comitér   bureauu   siègeu
   bénévolezloi 1901u   perséphonejardinssportculturemusiqueu	   théâtrefoottennischasseu   pêchegymdansezvie associativeu	   adhérentdirigeu   présideu   félinmaisonc              3       K   | ]}|v V  	d S r   rl   r:  s     r   r   z"fetch_for_query.<locals>.<genexpr>  s'      RRaqEzRRRRRRr%   )
subventionu   versémontantcombienr   )search_subventionsz$Subventions 2025 (document officiel)z/data/documents/Tableau des Subventions 2025.pdfr{   c              3       K   | ]}|v V  	d S r   rl   r:  s     r   r   z"fetch_for_query.<locals>.<genexpr>  s7        !1:      r%   )
entrepriseu	   sociétér   r   patroncommerceartisanboulangerie
restaurantgarage	pharmacieu   médecinnotaireavocatr   siret)search_entreprisesu   CSV local entreprises Bessègesz'data/documents/besseges_entreprises.csvc              3       K   | ]}|v V  	d S r   rl   r:  s     r   r   z"fetch_for_query.<locals>.<genexpr>  7        !1:      r%   )	maire
conseilleru   éluadjointu
   déléguér   vice
commissionzconseil municipalr,  c              3       K   | ]}|v V  	d S r   rl   r:  s     r   r   z"fetch_for_query.<locals>.<genexpr>  r^  r%   )
rL  aidefinancementdetrdsildotationfondsu   appel à projeteuropeu   régionc              3       K   | ]}|v V  	d S r   rl   r:  s     r   r   z"fetch_for_query.<locals>.<genexpr>  s7        !1:      r%   )u   marchézappel d'offreboampattributaireprestatairereturn_exceptionsTzfetch_for_query task error: %sr4   c                 @    g | ]}||                     d           |S )r4   r   )rm   r   s     r   rp   z#fetch_for_query.<locals>.<listcomp>  s,    555q5quuV}}5555r%   u(   fetch_for_query → %d sources pour '%s'<   )r   r   r   r   r   r   r   r  agents_python.csv_subventionsrO  agents_python.csv_entreprisesr\  r(  r*  r/  r5  r1  r3  asynciogather
isinstancer   r5   r6   dictlistr  r   r   )rO   r   sourcesr   ru   r%  tasksrO  sub_textr\  csv_textr   r8   r<  s                @r   fetch_for_queryr    s      GKKMMEOOGW--Eook;77G??=$//3DE 
LL'w77888              	(55666*5'::;;;]5+66777RRRR#QRRRRR 	HHHHHH))%00H D$L                   5 	EDDDDD%%e,, 	NN;"C     	0FFGGG^E733444             
 	[''((()8
 
 	 	 	
             6 	EDDDDD%%e,, 	NN@ H    
 	-e44555             , 	\'**+++ NEBTBBBBBBBBG 	 	a## 	KK8!<<< 	At$$ 	v 	NN1 	:a&& 	NN55A555   HH2GeCRCj   Nr%   c                   t    e Zd ZdZd ZdedededefdZdedefdZdededefd	Zdedefd
Z	dedefdZ
dS )DataFetcherzBFetches context data from official API sources for LLM enrichment.c                     ddddddddddddd| _         t                              dt          | j                              d S )Nr   iQ )status	cache_ttli  )data.gouv.frsireneaides-territoiresjo-associationsu-   DataFetcher initialized — %d sources active)r{  r5   r   r   )selfs    r   __init__zDataFetcher.__init__  sc    '/eDD!)>>,44!H!H*2GG	
 
 	@#dlBSBSTTTTTr%   rO   r   categoryr   c                   K   g }|dk    r0|                     |                     ||           d{V            n|dv r/|                     |                     |           d{V            ni|dk    r/|                     |                     |           d{V            n4|dk    r.|                     |                     |           d{V            d                    d |D                       S )u   
        Fetch relevant context data for LLM enrichment.
        v1.8 : NE PAS injecter les comptes de gestion pour les catégories
        non financières. fetch_for_query() fournit le contexte web.
        subventionsN)financesdepensesentreprisesassociationsr   c                     g | ]}||S rl   rl   )rm   ps     r   rp   z+DataFetcher.get_context.<locals>.<listcomp>5  s    :::!:A:::r%   )r   _fetch_subventions_fetch_comptes_fetch_entreprises_fetch_associationsr   )r  rO   r   r  context_partss        r   get_contextzDataFetcher.get_context!  s8      }$$  t'>'>ue'L'L!L!L!L!L!L!LMMMM111  t':':5'A'A!A!A!A!A!A!ABBBB&&  t'>'>u'E'E!E!E!E!E!E!EFFFF''  t'?'?'F'F!F!F!F!F!F!FGGG {{::}:::;;;r%   c                 T  K   d| }t          || j        d         d                   }|rt                              d|           |S t                              |d          }|st                              d|           dS dD ]}d| }d	| d
| d}	 t          j        d          4 d{V }|                    |           d{V }	|		                                 |	
                                }
|
                    dg           }|s	 ddd          d{V  i }|D ]}|                    dd          }|r|d         nd}||vr
ddddd||<   ||         dxx         |                    dd          pdz  cc<   ||         dxx         |                    dd          pdz  cc<   ||         dxx         |                    dd          pdz  cc<   ||         dxx         |                    dd          pdz  cc<   |                    di           }|                    di           }t          d |D                       }|                    dd          }|                    dd          }||z
  }d| d| d| d t          |           d!|d"d#|d"d$|d"d%|                    d&i                               dd          d"d'|                    d&i                               dd          d"d(|d"d)|                    d*i                               dd          d"d+}t          |                                          D ]'}||         }|d,| d-|d         d"d.|d         d"d/z  }(t                              d0|t          |          |           t          ||           |cddd          d{V  c S # 1 d{V swxY w Y   U# t           $ r'}t                              d1||           Y d}~d}~ww xY wt                              d2|           dS )3z4Fetch comptes de gestion from data.economie.gouv.fr.comptes_r  r  u   comptes(%s) — cache hitr   zNo SIREN mapping for INSEE %s)i  i  z$balances-comptables-des-communes-en-z@https://data.economie.gouv.fr/api/explore/v2.1/catalog/datasets/z/records?where=siren%3D%22zE%22%20AND%20cbudg%3D1&select=compte,obnetdeb,obnetcre,sd,sc&limit=100      @r,   Nr   compter   r   )debcresdscr  obnetdebr  obnetcrer  r  67c              3      K   | ]E}|                     d d                              d          +|                     dd          pdV  FdS )r  r   16r  r   N)r   r   )rm   recs     r   r   z-DataFetcher._fetch_comptes.<locals>.<genexpr>e  sk          778R00;;DAA q)).Q           r%   zCOMPTES DE GESTION u    — COMMUNE INSEE z (SIREN z=)
Source: DGFiP via data.economie.gouv.fr
Nombre de comptes: u*   

FONCTIONNEMENT:
  Dépenses (classe 6): z,.2fu    €
  Recettes (classe 7):  u    €
  Épargne brute:        u.    €

INVESTISSEMENT:
  Dépenses (classe 2): 2u    €
  Recettes (classe 2): u%    €

DETTE:
  Encours dette (c.16): u"    €
  Trésorerie (classe 5 sd): 5u    €

CLASSES COMPTABLES:z

  Classe u	   : débit=u   €  crédit=u   €u!   comptes(%s) — %d records for %dzDGFiP fetch %d failed: %szNo DGFiP data found for %s)r   r{  r5   r   INSEE_SIRENr   r6   r0   r1   raise_for_statusr   sumr   sortedkeysr$   r   error)r  r   	cache_keycachedr   anneedatasetapi_urlr   respr   recordsclassesr  r  clsc6c7dette	dep_fonct	rec_fonctepargner4   cls_numvr9   s                             r   r  zDataFetcher._fetch_comptes7  s     &u&&	It|N'CK'PQQ 	HH0%888Mr** 	KK7???2! G	 G	EDUDDGSZ  %*   > ,S999 9  9  9  9  9  9  9 V!'G!4!4444444D))+++99;;D"hhy"55G" ! 9  9  9  9  9  9  9  9  9  9  9  9  9  !G& D D!$2!6!6+1:fQiisg--34Qaq+Q+QGCLU+++swwz1/E/E/JJ+++U+++swwz1/E/E/JJ+++T***cggdA.>.>.C!C***T***cggdA.>.>.C!C**** S"--B S"--B    #*       E !#ua 0 0I "ua 0 0I')3G5  U  \a  LL 
 #   #   "   !S"--11%;;    C,,00::      &kk#r2266tQ??   D$ $*',,..#9#9 o o#G, ng n n% n n n\]^c\d n n n nnHH@%WW\]]]y$///s9  9  9  9  9  9  9  9  9  9  9  9  9  9  9  9  9  9  9  9  9  9  9  9  9  9  9  9  9  9  9 v    7BBB 			.666rsJ   O1AOO JO1O
O	OO	O
P
#PP
c                 f  K   d| dt          |          dz   }t          || j        d         d                   }|rt                              d|           |S |                     |           d{V }d| d	}|r|d
| z  }t                              d|           t          ||           |S )zFetch subventions context.subv__i r  r  u   subventions(%s) — cache hitNu'   CONTEXTE SUBVENTIONS — COMMUNE INSEE u<  
Strate: < 5 000 habitants | Département: Gard (30) | Région: Occitanie

DISPOSITIFS PRINCIPAUX ACCESSIBLES:
- DETR (Dotation d'Équipement des Territoires Ruraux): communes < 2000 hab ou arrondissement éligible
- DSIL (Dotation de Soutien à l'Investissement Local): projets structurants
- FCTVA (Fonds de Compensation de la TVA): remboursement TVA sur investissements
- Fonds Vert: transition écologique (rénovation énergétique, biodiversité)
- DPV (Dotation Politique de la Ville): si quartiers prioritaires
- Aides Région Occitanie: contrats territoriaux, rénovation thermique
- Aides Département Gard: voirie, bâtiments communaux, culture

CALENDRIER INDICATIF:
- DETR/DSIL: dépôt dossiers sept-nov pour l'année suivante
- Fonds Vert: appels à projets continus
- Aides régionales: selon programmes en coursr   u,   subventions(%s) — static context + comptes)hashr   r{  r5   r   r  r$   )r  r   rO   r  r  comptes_ctxr4   s          r   r  zDataFetcher._fetch_subventions  s      :E::DKK&$8::	It|4G'H'UVV 	HH4e<<<M //6666666625 2 2 2"  	)(;(((D?GGG9d###r%   c           
      B  K   d| }t          || j        d         d                   }|rt                              d|           |S t                              ||          }d| d}	 t          j        d          4 d	{V }|                    |           d	{V }|                                 |	                                }|                    d
g           }	|                    dd          }
|	s	 d	d	d	          d	{V  dS t          d |	D                       }d| d|
 dt          |	           d| d	}t          |	d	d         d          D ]\  }}|                    dd          }|                    dd          }|                    d          dk    rdnd}|                    dd          }|                    dd          }|                    dd          }|d | d!| z  }|d"| d#| d$| z  }|d%| d&| z  }t                              d'||
t          |	                     t          ||           |cd	d	d	          d	{V  S # 1 d	{V swxY w Y   d	S # t          $ r&}t                              d(|           Y d	}~dS d	}~ww xY w))z9Fetch entreprises from recherche-entreprises.api.gouv.fr.entreprises_r  r  u   entreprises(%s) — cache hitr   z%&page=1&per_page=25&mtm_campaign=icacr  r  Nr   total_resultsr   r   c              3   L   K   | ]}|                     d           dk    dV   dS )r   r   r   Nrr  )rm   ents     r   r   z1DataFetcher._fetch_entreprises.<locals>.<genexpr>  s:      "`"`377CW;X;X\_;_;_1;_;_;_;_"`"`r%   u   ENTREPRISES — COMMUNE INSEE uF   
Source: recherche-entreprises.api.gouv.fr (SIRENE)
Total résultats: u   
Établissements affichés: z (25 premiers)
Actifs: u   

DÉTAIL (25 premiers):   r   r   r   r   r   r   Actifu   Ferméactivite_principaler   tranche_effectif_salarie
  . 
     SIREN: z | NAF: 
    | État: u   
     Création: z | Effectif: u&   entreprises(%s) — %d total, %d shownzSIRENE fetch failed: %s)r   r{  r5   r   r   r   r0   r1   r  r   r  r   	enumerater$   r   r6   )r  r   r  r  r   r  r   r  r   r   totalactive_countr4   ir  r   r   r   nafr   trancher9   s                         r   r  zDataFetcher._fetch_entreprises  s     *5**	It|H'=k'JKK 	HH4e<<<M044UEBB"+" " " 	(	(555 # # # # # # ##ZZ00000000%%'''yy{{((9b11!44 # # # # # # # # # # # # # #  #"`"`"`"`"```%     LL  
	   (a88 
W 
WFAs''-55CGGGS11E&)gg.B&C&Cs&J&J77PXD''"7==C$'GGOS$A$AM!gg&@#FFG-1-----DQUQQCQQ4QQQDVVVWVVVDDA5%QTU\Q]Q]^^^9d+++G# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #J  	 	 	KK1155522222	sJ   *I. A3I8I. D=II. 
I%%I. (I%)I. .
J8JJc           	        K   d| }t          || j        d         d                   }|rt                              d|           |S t                              ||          }d| d}	 t          j        d          4 d	{V }|                    |           d	{V }|                                 |	                                }|                    d
g           }	|                    dd          }
|	sdD ]}d| d| d}|                    |           d	{V }|j
        dk    rV|	                                }|	                    |                    d
g                      |
|                    dd          z  }
|	s	 d	d	d	          d	{V  dS d |	D             }d| d|
 dt          |           d}t          |	d	d         d          D ]\  }}|                    dd          }|                    dd          }|                    d          dk    rdnd}|                    d d          }|                    d!d          }|d"| d#| z  }|d$| d%| d&| z  }|d'| z  }t                              d(||
           t          ||           |cd	d	d	          d	{V  S # 1 d	{V swxY w Y   d	S # t          $ r&}t                              d)|           Y d	}~dS d	}~ww xY w)*z4Fetch associations from recherche-entreprises (RNA).associations_r  r  u   associations(%s) — cache hitr   r   r  r  Nr   r  r   )9210923092409260z&nature_juridique=z&page=1&per_page=10r/   r   c                 D    g | ]}|                     d           dk    |S )r   r   rr  )rm   r8   s     r   rp   z3DataFetcher._fetch_associations.<locals>.<listcomp>  s/    SSS6J0K0Ks0R0R!0R0R0Rr%   u   ASSOCIATIONS — COMMUNE INSEE z:
Source: RNA via recherche-entreprises.api.gouv.fr
Total: z | Actives: u   

LISTE (25 premières):r  r   r   r   r   r   r   r   r   r   r  r  r  r  r  u    | Création: u   
     Activité (NAF): u   associations(%s) — %d totalzAssociations fetch failed: %s)r   r{  r5   r   r   r   r0   r1   r  r   r2   r  r   r  r$   r   r6   )r  r   r  r  r   r  r   r  r   r   r  njapi_url2resp2d2r   r4   r  r   r   r   r   r   r  r9   s                            r   r  zDataFetcher._fetch_associations  sq     +E++	It|4E'F{'STT 	HH5u===M044UEBB"+" " " 	3	(555 . . . . . . .#ZZ00000000%%'''yy{{((9b11!44 @> @ @3-;3 3133 3 3 ! '-jj&:&: : : : : : : ,33!&B#NN266)R+@+@AAA!RVVOQ%?%??E /. . . . . . . . . . . . . .2 TSWSSS5   v;;    )"q99 	= 	=GAt((=#66C HHWc22E'+xx0D'E'E'L'L88R\D$(HH_c$B$BM((#8#>>C-1-----DaUaadaaR_aaaD<s<<<DD8%GGG9d+++]. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .`  	 	 	KK7;;;22222	sJ   *K C?J0K DJ0K 0
J::K =J:>K 
K3K..K3N)__name__
__module____qualname____doc__r  r   r  r  r  r  r  rl   r%   r   r  r    s        LLU U U<s <3 <# <# < < < <,W# W# W W W Wr c  #  #        D8c 8c 8 8 8 8tDs Ds D D D D D Dr%   r  r   commune_inseec           	      *  K   d| ddddddd}	 t                               ||          }t          j        d          4 d{V }d|  d| d	}|                    |           d{V }|j        d
k    r|                                }|                    dg           }|r|d         }	d|d<   |	                    d|           |d<   |	                    di                               d          |d<   |	                    d          |d<   |	                    di           }
|
r|
                    d          |d<   	 ddd          d{V  n# 1 d{V swxY w Y   n3# t          $ r&}t                              d| |           Y d}~nd}~ww xY w|S )zF
    Recherche dans le RNA via recherche-entreprises.api.gouv.fr.
    FNzRNA/JO)foundr   r   r   r   r   r   sourcer   r  z3https://recherche-entreprises.api.gouv.fr/search?q=z&code_commune=z(&nature_juridique=9220&page=1&per_page=5r/   r   r   Tr  r   r   r   r   r   r   r   adresse_completer   zRNA fetch %s: %s)	r   r   r0   r1   r2   r   r   r5   r6   )r   r  resultr   r   r'   r  r   r   r   r   r9   s               r   fetch_association_rnar  7  s     
 !	 	F1044]MRR$Q/// 	J 	J 	J 	J 	J 	J 	J6&& &!/& & &   C((((((D3&&yy{{((9b11 J"1:D&*F7O%)XXmT%B%BF6N$(HH]B$?$?$C$CD]$^$^F5M.2hh.G.GF?+ HHWb11E J,1II6H,I,Iy)I)	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J*  1 1 1&a000000001Ms<   6E  C6E<E  
EE  EE   
F*FFc                 @   K   ddddd}t          | |           d{V S )up   
    Web fallback legacy — désormais remplacé par fetch_for_query().
    Conservé pour compatibilité.
    r
   rj   r   r8  )r   r   r   r7  N)r  )rO   r   s     r   fetch_web_fallbackr  a  sD        	 K !444444444r%   )r&   )r   )0r  rv  r   loggingrK   r   pathlibr   typingr   r0   bs4r   	getLoggerr5   __file__r   BASE_DIRr   mkdirr  r   r   intr   r$   r:   r3   rt   ry  r   r   r   rz  r  r  r   r$  r(  r*  r/  r1  r3  r5  r  r  r  r  rl   r%   r   <module>r     s   &    				                    g+,,4>> 'w'	 	t , , , [ W 

C 
# 
(3- 
 
 
 
]C ]# ] ] ] ] S S C    " # #     -3 -8C= - - - -, c d    k4 kD k k k k\s S T    &o oS o3 oC od o o o odis i i$ i i i iX+ + + + +\!C !D ! ! ! !HS 3 c d    $ c d    $
S 
T 
 
 
 
# $           	C 	D 	 	 	 	"s s4 sD s s s st[ [ [ [ [ [ [ [D	'c '# '$ ' ' ' 'T5C 5D 5 5 5 5 5 5r%   