
    0i                         d Z ddlmZ ddlZddlmZ ddlmZ ddlZddl	m
Z
 dZdZ G d	 d
e      Z G d de      Z G d de      Z G d d      ZddZddZddZddZy)u  Espacenet OPS (EPO Open Patent Services) client.

https://developers.epo.org/ops-v3-2
- OAuth 2.0 client_credentials — 20dk access_token
- Published data search: /rest-services/published-data/search
- 500 sorgu/hafta ücretsiz (IP başına)
- Response JSON (Accept: application/json)

Tasarım:
- Global singleton (lru_cache) — credentials .env'den
- Token cache + proaktif yenileme (60s buffer)
- Response → PriorArtHit listesi (biblio + abstract yalın)
    )annotationsN)Any)quote)PriorArtHitz(https://ops.epo.org/3.2/auth/accesstokenz%https://ops.epo.org/3.2/rest-servicesc                      e Zd ZdZy)EspacenetErroru2   EPO OPS API hatası (HTTP 4xx/5xx, parse hatası).N__name__
__module____qualname____doc__     ?/var/www/ai.patentyazar.com/app/services/prior_art/espacenet.pyr   r      s    <r   r   c                      e Zd ZdZy)EspacenetAuthErroruH   OAuth token alınamadı — credentials yanlış veya EPO rate-limit'te.Nr	   r   r   r   r   r   !   s    Rr   r   c                      e Zd ZdZy)EspacenetNotConfiguredz)EPO_OPS_KEY / EPO_OPS_SECRET .env'de yok.Nr	   r   r   r   r   r   %   s    3r   r   c                  \    e Zd ZdZdd	 	 	 	 	 	 	 ddZddZddZddZdd		 	 	 	 	 dd
Zy)EspacenetClientu#   EPO OPS REST API wrapper — async.N)http_clientc                   || _         || _        |d u| _        |xs t        j                  d      | _        d | _        d| _        y )Ng      >@)timeoutg        )_key_secret_external_clienthttpxAsyncClient_http_token_token_expires_at)selfconsumer_keyconsumer_secretr   s       r   __init__zEspacenetClient.__init__,   sE     !	& +4 7 CE$5$5d$C
"&(+r   c                H    t        | j                  xr | j                        S N)boolr   r   r"   s    r   is_configuredzEspacenetClient.is_configured:   s    DII.$,,//r   c                n   K   | j                   s#| j                  j                          d {    y y 7 wr'   )r   r   acloser)   s    r   closezEspacenetClient.close=   s-     $$**##%%% %%s   *535c                t  K   | j                         st        d      | j                  r0t        j                         | j                  dz
  k  r| j                  S | j
                  j                  t        ddi| j                  xs d| j                  xs df       d{   }|j                  dk7  r(t        d	|j                   d
|j                  dd        |j                         }|d   | _        t        j                         t        |j                  dd            z   | _        | j                  S 7 w)u>   OAuth client_credentials — token 60s buffer ile cache'lenir.u6   EPO_OPS_KEY / EPO_OPS_SECRET .env'de tanımlı değil.<   
grant_typeclient_credentials )dataauthN   u   EPO token alınamadı (HTTP ): access_token
expires_ini  )r*   r   r    timer!   r   post
_TOKEN_URLr   r   status_coder   textjsonintget)r"   responser3   s      r   _get_access_tokenz!EspacenetClient._get_access_tokenA   s    !!#()abb;;499;)?)?")DD;; 45))/r4<<#526 ) 
 

 3&$.x/C/C.DCVZWZH[G\]  }}>*!%s488L$3O/P!P{{
s   BD8D6 BD8
   )limitc                 K   | j                          d{   }t         dt        |       dt        |d       }| j                  j                  |d| dd       d{   }|j                  d	k(  rg S |j                  d
k\  r(t        d|j                   d|j                  dd        	 |j                         }t        t        |            S 7 7 s# t        $ r}t        d|       |d}~ww xY ww)uT  Espacenet CQL arama — basit keyword/boolean destekli.

        Args:
            query: CQL (ör. 'txt="post-kuantum kriptografi"' veya
                'cpc=H04L9/08 AND ta="gateway"'). Basit keyword de kabul eder.
            limit: Maks. 100.

        Returns:
            PriorArtHit listesi (her biri EP/US/WO patent no ile).
        Nz /published-data/search/biblio?q=z	&Range=1-d   zBearer zapplication/json)AuthorizationAccept)headersi  i  u   EPO search hatası (HTTP r6   i,  u   EPO JSON parse hatası: )rB   	_BASE_URLr   minr   r@   r<   r   r=   r>   
ValueErrorlist_parse_biblio_response)r"   queryrD   tokenurlrA   r3   excs           r   searchzEspacenetClient.searchX   s      ,,..;E%L>SVW\^aSbRcd(/w&7CUV ( 
 
 3&I3& +H,@,@+AX]]SWTWEXDYZ 	L==?D *4011' /
  	L #;C5!ABK	LsG   C8CAC8"C#AC80C  C8C8	C5!C00C55C8)r#   
str | Noner$   rT   r   zhttpx.AsyncClient | NonereturnNone)rU   r(   )rU   rV   )rU   str)rO   rW   rD   r?   rU   list[PriorArtHit])	r
   r   r   r   r%   r*   r-   rB   rS   r   r   r   r   r   )   sj    - 15, , $,
 ., 
,0&6 	#2#2 	#2
 
#2r   r   c                4    | g S t        | t              r| S | gS )uI   EPO response'unda tek öğe bazen dict, bazen list olur — normalize et.)
isinstancerM   values    r   _as_listr]      s"    }	%7Nr   c                    | yt        | t              r| S t        | t              r| j                  d      S t        | t              r| rt        | d         S y)u;   EPO '$' field'i ile text'i çıkar (dict or list of dicts).N$r   )rZ   rW   dictr@   rM   _first_textr[   s    r   ra   ra      sO    }%%yy~%558$$r   c                    	 | d   d   }t        |j                  di       j                  d            }g }|D ]B  }t        |j                  d            }|D ]!  }t        |      }|s|j	                  |       # D |S # t        $ r g cY S w xY w)u?   EPO /published-data/search/biblio JSON → PriorArtHit listesi.zops:world-patent-datazops:biblio-searchzops:search-resultzexchange-documentszexchange-document)r]   r@   KeyError_parse_single_documentappend)r3   search_resultentrieshitsentry_wrapperexchange_docsdochits           r   rN   rN      s    456IJ=,,-@"EIIJ^_` !D  ! !2!23F!GH  	!C(-CC 	!! K  	s   2A? ?BBc                   | j                  dd      }| j                  dd      }| j                  dd      }|r|sy| | | }| j                  di       }d}t        |j                  d            D ]4  }t        |t              s|j                  d      d	k(  s)t	        |      } n |st	        |j                  d            }d}t        |j                  d
            }	|	D ]g  }
t        |
j                  d            }|D ]B  }t	        |j                  d            }|s t        |      dk(  s/|dd  d|dd  d|dd  } n |sg n d}|j                  di       }t        |j                  di       j                  d            }|D ]2  }t	        |j                  di       j                  d            }|s0|} n g }t        |j                  di       j                  d            }|D ]  }t	        |j                  d            }|s d|v s%t	        |j                  d            xs d}t	        |j                  d            xs d}t	        |j                  d            xs d}t	        |j                  d            xs d}t	        |j                  d            xs d}| | | | d| j                  d      }|s|j                  |        d | }t        d!||d|d|d|xs d|"
      S )#u2   Tek bir exchange-document'ı PriorArtHit'e çevir.z@countryr2   z@doc-numberz@kindNzbibliographic-datazinvention-titlez@langenzapplication-referencezdocument-iddate      -   parties
applicants	applicantzapplicant-namenamezpatent-classificationszpatent-classificationzclassification-schemeCPCsectionclasssubclassz
main-groupsubgroup/z:https://worldwide.espacenet.com/patent/search/publication/epo)
source	patent_notitleabstractrv   	inventorsfiling_datepublication_datecpc_classesrQ   )	r@   r]   rZ   r`   ra   lenstripre   r   )rk   country
doc_numberkindr   biblio
title_texttitle_entryr   app_refsrefdoc_id_listdiddate_valapplicant_textrt   ru   aprw   r   	pat_classpcschemery   clsr{   
main_groupr|   coderQ   s                                 r   rd   rd      s   ggj"%G+J777BD
)J<v.IWW)2.F "J

+< => k4([__W-E-M$[1J  ,=!>?
 #K

#:;<H sww}56 	C"3776?3HCMQ.!)"1a1a1O		
  "&NjjB'G'++lB7;;KHIJ 266"2B7;;FCD!N	  K$<bAEEF]^_I 
)RVV$;<=evo!"&&"34:GbffWo.4"C"266*#56<"H$RVVL%9:@bJ"266*#56<"HYseH:j\8*EKKCPD""4(
) Gyk
RC '4 r   )r\   r   rU   z	list[Any])r\   r   rU   rT   )r3   r`   rU   rX   )rk   r`   rU   zPriorArtHit | None)r   
__future__r   r9   typingr   urllib.parser   r   app.services.prior_art.modelsr   r;   rJ   RuntimeErrorr   r   r   r   r]   ra   rN   rd   r   r   r   <module>r      sp    #     57
3	=\ =S S4^ 4R2 R2t
$Hr   