+
    qmj"                       ^ RI Ht ^ RIt^ RIt^ RIHt ^ RIHt ^ RIH	t	H
t
HtHt ^ RIHt ^RIHt ^RIHt ^R	IHtHt ^R
IHtHt ]P2                  ! ]P4                  RR7       ]P6                  ! R4      t]R R l4       t]! ^R7      R R l4       t]! ^R7      R R l4       t]	! R]RR]R7      tR R lt ]PC                  R4      R R l4       t"]PG                  R4      ]
! RR7      3R R ll4       t$R  R! lt%R# )"    )annotationsN)asynccontextmanager)	lru_cache)FastAPIHeaderHTTPExceptionRequest)
UploadFile)__version__)Settings)EngineInputDocument)OllamaClientOllamaErrorz%%(asctime)s %(levelname)s %(message)s)levelformat
pataniscaic                   V ^8  d   QhRR/# )   _r    )r   s   "src/pataniscai/api.py__annotate__r      s     
 
g 
    c                  "    \        4       P                  P                  4        \        P	                  R 4       R5x  R#   \
         d    \        P                  R4        L)i ; i5i)zmodel preload completedzFmodel preload failed; health remains unavailable until Ollama recoversN)engineclientloadloggerinfor   warning)r   s   &r   lifespanr"      sN     a-. 
  a_`as'   A(7A A( A%"A($A%%A()maxsizec                   V ^8  d   QhRR/# )r   returnr   r   )r   s   "r   r   r      s      ( r   c                 ,    \         P                  ! 4       # N)r   from_envr   r   r   settingsr)      s    r   c                   V ^8  d   QhRR/# )r   r%   r   r   )r   s   "r   r   r   $   s     P P Pr   c                 ~    \        4       p \        \        V P                  V P                  V P
                  4      4      # r'   )r)   r   r   
ollama_urlmodelrequest_timeout)cfgs    r   r   r   #   s+    
*C,s~~syy#:M:MNOOr   
pataniscAI)titleversiondocs_url	redoc_urlr"   c               $    V ^8  d   QhRRRRRR/# )r   requestr	   token
str | Noner%   Noner   )r   s   "r   r   r   .   s&     F F F
 Ft Fr   c                   \        4       pV P                  '       d   V P                  P                  MR pW2P                  9  d   \	        RRR7      hVP
                  '       d   WP
                  8w  d   \	        RRR7      hR# )   Cliente nao autorizadostatus_codedetaili  zToken invalidoN)r)   r   hostallowed_ipsr   r7   )r6   r7   r/   	client_ips   &&  r   
_authorizerD   .   s_    
*C'.~~~##2I'4LMM999*4DEE +r   z/healthc                    V ^8  d   QhRRRR/# )r   r6   r	   r%   dictr   )r   s   "r   r   r   8   s      G  r   c                   \        4       pV P                  '       d   V P                  P                  MR pW!P                  9  d   \	        RRR7      h \        4       P                  P                  4       p\        VR,          4      pRR	R\        R
R\         2RVP                  RVRVP                  RRRR^ /4      RV/#   \         d    RR RRR^ /pRp LPi ; i)r;   r<   r=   r>   model_availabler2   Fmodels_countservicer0   engine_versionzpataniscAI-r-   readygpumodel_loaded
vram_bytesbackend)r)   r   rA   rB   r   r   healthboolr   r   r-   get)r6   r/   rC   rP   rL   s   &    r   rQ   rQ   7   s    
*C'.~~~##2I'4LMM(//((*W./0
 	<;K}5w{{5>5,"JK7   b"3UNANs   4C   CCz/v1/extract)defaultc               $    V ^8  d   QhRRRRRR/# )r   r6   r	   x_pataniscai_tokenr8   r%   rF   r   )r   s   "r   r   r   O   s&     / //"/ 
/r   c                  "   \        W4       \        4       pV P                  4       G R j  xL
 pVP                  R4      p\	        V\
        4      '       g   \        RRR7      h \        P                  ! V4      p\	        T\        4      '       d   TP                  R. 4      M. p\	        T\        4      '       g   \        RRR7      hT'       g   \        RRR7      h\        T4      TP                  8  d   \        R	R
R7      h. pT EF  p	\	        T	\        4      '       g   \        RRR7      hTP                  \        T	P                  RR4      4      4      p
\	        T
\        4      '       g   \        RRR7      hT
P                  TP                   ^,           4      G R j  xL
 pT
P#                  4       G R j  xL
  T'       d   \        T4      TP                   8  d   \        R	RR7      hT
P$                  '       d/   T
P$                  P'                  R4      '       g   \        RRR7      hTP)                  \+        \        T	P                  RR4      4      \        T	P                  RT
P,                  ;'       g    R4      4      \        T	P                  RR4      4      TR7      4       EK  	  \.        P1                  RT P2                  '       d   T P2                  P4                  MR\        T4      4       \7        4       P9                  T4      p\.        P1                  RTR,          \        T4      TR,          4       T#  EL  \        P                   d   p\        RRR7      ThR p?ii ; i EL EL5i)Nmanifesti  zManifesto em faltar>   zManifesto JSON invalido	documentsz!Documentos invalidos no manifestoz!O manifesto nao contem documentosi  zDemasiados ficheiroszDocumento invalido no manifesto
upload_keyr;   z'Manifesto nao corresponde aos ficheirosz"Ficheiro vazio ou demasiado grandezimage/i  z(A API aceita apenas paginas rasterizadasidnamepaginatype)document_idr\   document_typecontentz$extract start client=%s documents=%dz2extract end success=%s documents=%d duration_ms=%dsuccessduration_ms)rD   r)   formrS   
isinstancestrr   jsonloadsJSONDecodeErrorrF   listlen	max_filesr
   readmax_file_bytesclosecontent_type
startswithappendr   filenamer   r    r   rA   r   extract)r6   rV   r/   rd   rX   decodedexcdefinitionsrY   
definitionuploadra   results   &&           r   rt   rt   N   s    
 w+
*CDxx
#Hh$$4HIIX**X& 3=Wd2K2K'++k2.QSKk4((4WXX4WXX
;#--'4JKK%'I!
*d++C8YZZ#jnn\2>?@&*--C8abbC$6$6$:;;lln#g,););;C8\]]v':':'E'Eh'O'OC8bcc
tR 890K0K8LM!*.."<=		
 "* KK6w~~~8K8KcegjktguvXi(F
KKDfYFWY\]fYgiop}i~MS    X4MNTWWX" <ss   )M5M8M5%M ;AM5CM5!M/"M59M2:M58M5? M5 B0M5A1M5M,M''M,,M52M5c                   V ^8  d   QhRR/# )r   r%   r9   r   )r   s   "r   r   r      s     S Sd Sr   c                 8    ^ RI p V P                  RRRRR7       R# )r   Nzpataniscai.api:appz0.0.0.0i@  r    )rA   port	log_level)uvicornrun)r   s    r   mainr      s    KK$946KRr   )&
__future__r   rg   logging
contextlibr   	functoolsr   fastapir   r   r   r	   starlette.datastructuresr
   r;   r   configr   r   r   r   ollamar   r   basicConfigINFO	getLoggerr   r"   r)   apprD   rS   rQ   postrt   r   r   r   r   <module>r      s    "   *  ; ; /   ) -   ',,/V W			<	( 
 
 1  1P P
 
ddU]
F  , - &,D%9/ /dSr   