+
    jej                        a  R t0 t R t^ RIt^ RIt^ RIHt ^ RIt^ RIHt ]P                  ! ]
4      tRt]P                  ! RRR7      t/ t] ^ k RtR	 R
 ltR R ltR R ltRR R lltR# )u  Consulta de empresa por NIF: VIES + SICAE.

Substitui `app/scrapers/ptdata.py`. O ptdata.org devolve 503 desde meados de
julho de 2026 e era de onde vinha o CAE.

Cada fonte dá o que faz melhor, em paralelo:

* **VIES** (UE, oficial, sem chave nem quota) — nome legal e morada.
* **SICAE** (consórcio IRN/AT/INE/IAPMEI, gratuito) — CAE Rev.4 principal e
  secundários. Não devolve morada.

Há ainda uma terceira fonte melhor para nome/morada/natureza jurídica: as
publicações do registo comercial (ver `mj_irn_sync`). Mas essa é por empresa
monitorizada e assíncrona; isto é o caminho rápido para quando alguém escreve
um NIF num formulário.
N)Any)is_valid_nifzChttps://ec.europa.eu/taxation_customs/vies/rest-api/ms/PT/vat/{nif}g      @g      @)connecti   c                `    V ^8  d   QhR\         R\        \         \        3,          R,          /#    nifreturnNstrdictr   )formats   "app/services/nif_lookup.py__annotate__r   %   s'       c3h$!6     c                 f  "    \         P                  ! \        R 7      ;_uu_4       GRj  xL
 pVP                  \        P                  V R7      RR/R7      G Rj  xL
 pRRR4      GRj  xL
  XP                  ^8w  d   R# VP                  4       pVP                  R4      '       g   R# VP                  R4      ;'       g    RP                  4       pV'       d7   VP                  R	4      '       d    R
P                  VP                  4       4      MRpRVP                  R4      ;'       g    RP                  4       ;'       g    RRVRV/#  EL$ L L  + GRj  xL 
 '       g   i     L; i  \         P                  \        3 d"   p\        P                  RY4        Rp?R# Rp?ii ; i5i))timeoutN)r   Acceptzapplication/json)headersisValidaddress z-  namerawzVIES lookup falhou para %s: %s)httpxAsyncClientVIES_TIMEOUTgetVIES_URLr   status_codejsonstripjoinsplit	HTTPError
ValueErrorloggerwarning)r   crdataaddr_rawaddres   &      r   	_try_viesr/   %   s>    $$\:::aeeHOOO4xI[>\e]]A ;:==Cvvxxx	""HHY'--2446-5(..:N:Nsxx()TXTXXf%++224<<t4
 	
 ;] ;::: OOZ( 7@s   F1'E2 EE2 -EEE!E2 ,E-E2 F1&E2 +F1-E2 E2 E2 59E2 /E2 E2 F1E2 EE2 E/	E
E/	(E/	*E2 2F.F)#F1)F..F1c                `    V ^8  d   QhR\         R\        \         \        3,          R,          /# r   r
   )r   s   "r   r   r   ;   s'      # $sCx.4"7 r   c                    "   ^ RI Hp  V! V 4      G Rj  xL
 #  L  \         d"   p\        P	                  RY4        Rp?R# Rp?ii ; i5i)    )lookup_by_nipcNu   SICAE indisponível para %s: %s)app.scrapers.sicaer3   	Exceptionr'   info)r   r3   r.   s   &  r   
_try_sicaer7   ;   s?     1#C(((( 5s>s5   A  A AAAAAc                R    V ^8  d   QhR\         R\        \         \        3,          /# )r   r   r	   r
   )r   s   "r   r   r   E   s"     6 6# 6$sCx. 6r   c                t  "   \         P                  V 4      pVe   \        V4      # RV R\        V 4      RRRRRRRRR	RR
RRR/	pVR,          '       g   V# \        P
                  ! \        V 4      \        V 4      4      G Rj  xL
 w  r4/ p. pV'       dN   VP                  R4       VP                  R4      VR&   VP                  R	4      VR	&   VP                  R4      VR&   V'       dV   VP                  R4       VR,          '       g   VP                  R4      VR&   VP                  R4      pV'       d   WrR&   WER&   V'       d   RP                  V4      VR&   WRR&   \        \         4      \        8  d,   \         P                  \        \        \         4      4      4       \        V4      \         V &   V#  EL45i)u   Consulta um NIF português.

Devolve sempre — cai para `source='local'` com validação mod-11 quando
ambas as fontes falham. Mantém a assinatura e o formato do antigo
`ptdata.lookup_nif` para os chamadores não terem de mudar.
Nr   validsourcelocal
legal_name
trade_namecaer   statusr   viesr   sicaedenominacao+)_CACHEr   r   r   asynciogatherr/   r7   appendr#   len
_CACHE_MAXpopnextiter)r   cachedresultrA   rB   r   sourcesr?   s   &       r   
lookup_nifrQ   E   s     ZZ_FF| 	sc"'ddt4$t
F '??  y~z#GGKDCGv#xx/| HHY/yhhuoFwl###(99]#;F< ii5MG88G,xu
6{j 

4V%&v,F3KM9 Hs,   A?F8F5A&F8)F8	,F86F8A0F8c          	      t    V ^8  d   QhR\         R\        R\        \        \         \        3,          ,          /# )r   r   limitr	   )r   intlistr   r   )r   s   "r   r   r   ~   s.      s 3 T#s(^8L r   c                   "   ^ RI Hp  V! WR7      G Rj  xL
 #  L  \         d#   p\        P	                  RY4       . u Rp?# Rp?ii ; i5i)z)Pesquisa inversa nome -> NIPC, via SICAE.)search_by_name)rS   Nzpesquisa por nome %r falhou: %s)r4   rW   r5   r'   r6   )r   rS   rW   r.   s   &&  r   lookup_by_namerX   ~   sA     1#D6666 5t?	s;   A  A A
AA
 AA

Ac                    V ^8  d   Qh/ ^ \         9   d,   \        \        \        \        \        3,          3,          ;R&   # )r   rE   )__conditional_annotations__r   r   r   )r   s   "r   r   r      s2      @ ' &S$sCx. ! &Ar   )
   )rZ   __doc__rF   loggingtypingr   r   app.services.nifr   	getLogger__name__r'   r   Timeoutr   rE   rJ   r/   r7   rQ   rX   r   )rZ   s   @r   <module>rc      sj         )			8	$P}}S#.
 %' &
,6r r   