+
    #i                         R t ^ RIHt ^ RIt^ RIHt ^ RIHt ^ RIt^ RI	H
t
 RtRt ! R R	]4      t ! R
 R]4      t ! R R]4      t ! R R4      tR R ltR R ltR R ltR R ltR# )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                      ] tR t^tRtRtR# )EspacenetErroru2   EPO OPS API hatası (HTTP 4xx/5xx, parse hatası). N__name__
__module____qualname____firstlineno____doc____static_attributes__r       b/Users/zincirx/Documents/projelerim/patentyazar/backend-python/app/services/prior_art/espacenet.pyr   r      s    <r   r   c                      ] tR t^!tRtRtR# )EspacenetAuthErroruH   OAuth token alınamadı — credentials yanlış veya EPO rate-limit'te.r   Nr	   r   r   r   r   r   !   s    Rr   r   c                      ] tR t^%tRtRtR# )EspacenetNotConfiguredz)EPO_OPS_KEY / EPO_OPS_SECRET .env'de yok.r   Nr	   r   r   r   r   r   %   s    3r   r   c                  f    ] tR t^)tRtRR/R R lltR R ltR R	 ltR
 R ltR^
/R R llt	Rt
R# )EspacenetClientu#   EPO OPS REST API wrapper — async.http_clientNc               (    V ^8  d   QhRRRRRRRR/# )   consumer_key
str | Noneconsumer_secretr   zhttpx.AsyncClient | NonereturnNoner   )formats   "r   __annotate__EspacenetClient.__annotate__,   s2     , , , $,
 ., 
,r   c               	    Wn         W n        VR JV n        T;'       g    \        P                  ! RR7      V n        R V n        RV n        R # )Ng      >@)timeoutg        )_key_secret_external_clienthttpxAsyncClient_http_token_token_expires_at)selfr   r   r   s   &&&$r   __init__EspacenetClient.__init__,   sD     !	& +4 7 CCE$5$5d$C
"&(+r   c                   V ^8  d   QhRR/# )r   r   boolr   )r    s   "r   r!   r"   :   s     0 0t 0r   c                	T    \        V P                  ;'       d    V P                  4      # N)r1   r%   r&   r-   s   &r   is_configuredEspacenetClient.is_configured:   s    DII..$,,//r   c                   V ^8  d   QhRR/# )r   r   r   r   )r    s   "r   r!   r"   =   s     & &T &r   c                	~   "   V P                   '       g%   V P                  P                  4       G R j  xL
  R # R #  L5ir3   )r'   r*   acloser4   s   &r   closeEspacenetClient.close=   s/     $$$**##%%% %%s   0=;	=c                   V ^8  d   QhRR/# )r   r   strr   )r    s   "r   r!   r"   A   s       r   c                  "   V P                  4       '       g   \        R4      hV P                  '       d8   \        P                  ! 4       V P                  ^<,
          8  d   V P                  # V P
                  P                  \        RR/V P                  ;'       g    RV P                  ;'       g    R3R7      G Rj  xL
 pVP                  ^8w  d-   \        RVP                   RVP                  R	,           24      hVP                  4       pVR
,          V n        \        P                  ! 4       \        VP                  RR4      4      ,           V n        V P                  #  L5i)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authNu   EPO token alınamadı (HTTP ): :N   Naccess_token
expires_ini  )r5   r   r+   timer,   r*   post
_TOKEN_URLr%   r&   status_coder   textjsonintget)r-   responserB   s   &  r   _get_access_token!EspacenetClient._get_access_tokenA   s    !!##()abb;;;499;)?)?")DD;; 45))//r4<<#5#526 ) 
 

 3&$.x/C/C.DCVZH[G\]  }}>*!%s488L$3O/P!P{{
s$   3E&A&E&E&2E&>E$?B&E&limitc               $    V ^8  d   QhRRRRRR/# )r   queryr=   rS   rN   r   list[PriorArtHit]r   )r    s   "r   r!   r"   X   s(     #2 #2#2 	#2
 
#2r   c               
  "   V P                  4       G Rj  xL
 p\         R\        V4       R\        V^d4       2pV P                  P                  VRRV 2RR/R7      G Rj  xL
 pVP                  R	8X  d   . # VP                  R
8  d-   \        RVP                   RVP                  R,           24      h VP                  4       p\        \        T4      4      #  L L{  \         d   p\        RT 24      ThRp?ii ; i5i)u  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-AuthorizationzBearer Acceptzapplication/json)headersi  i  u   EPO search hatası (HTTP rD   :Ni,  Nu   EPO JSON parse hatası: )rQ   	_BASE_URLr   minr*   rO   rK   r   rL   rM   
ValueErrorlist_parse_biblio_response)r-   rU   rS   tokenurlrP   rB   excs   &&$     r   searchEspacenetClient.searchX   s      ,,..;E%L>SVW\^aSbRcd$w&7CUV ( 
 
 3&I3& +H,@,@+AX]]SWEXDYZ 	L==?D *4011' /
  	L #;C5!ABK	LsG   DCAD#C$AD9C! 	DD!D ,C;;D  D)r'   r*   r%   r&   r+   r,   )r
   r   r   r   r   r.   r5   r:   rQ   rc   r   r   r   r   r   r   )   s7    -,
 15,0&.#2 	#2 #2r   r   c                    V ^8  d   QhRRRR/# )r   valuer   r   z	list[Any]r   )r    s   "r   r!   r!      s      C I r   c                D    V f   . # \        V \        4      '       d   V # V .# )uI   EPO response'unda tek öğe bazen dict, bazen list olur — normalize et.)
isinstancer^   rf   s   &r   _as_listrj      s%    }	%7Nr   c                    V ^8  d   QhRRRR/# )r   rf   r   r   r   r   )r    s   "r   r!   r!      s     
 
s 
z 
r   c                    V f   R# \        V \        4      '       d   V # \        V \        4      '       d   V P                  R4      # \        V \        4      '       d   V '       d   \        V ^ ,          4      # R# )u;   EPO '$' field'i ile text'i çıkar (dict or list of dicts).N$)rh   r=   dictrO   r^   _first_textri   s   &r   ro   ro      sX    }%%yy~%558$$r   c                    V ^8  d   QhRRRR/# )r   rB   rn   r   rV   r   )r    s   "r   r!   r!      s       *; r   c                J    V R,          R,          p\        VP                  R/ 4      P                  R4      4      p. pT FL  p\        TP                  R4      4      pT F)  p\        T4      pT'       g   K  TP	                  T4       K+  	  KN  	  T#   \         d    . u # i ; i)u?   EPO /published-data/search/biblio JSON → PriorArtHit listesi.zops:world-patent-datazops:biblio-searchzops:search-resultzexchange-documentszexchange-document)rj   rO   KeyError_parse_single_documentappend)rB   search_resultentrieshitsentry_wrapperexchange_docsdochits   &       r   r_   r_      s    456IJ=,,-@"EIIJ^_` !D  !2!23F!GH C(-CsC  ! ! K  	s   :B B"!B"c                    V ^8  d   QhRRRR/# )r   rz   rn   r   zPriorArtHit | Noner   )r    s   "r   r!   r!      s     H H H); Hr   c                   V P                  RR4      pV P                  RR4      pV P                  RR4      pV'       d	   V'       g   R# V V V 2pV P                  R/ 4      pRp\        VP                  R4      4       F>  p\        V\        4      '       g   K  VP                  R4      R	8X  g   K3  \	        V4      p M	  V'       g   \	        VP                  R4      4      pRp\        VP                  R
4      4      p	V	 F  p
\        V
P                  R4      4      pV FX  p\	        VP                  R4      4      pV'       g   K'  \        V4      ^8X  g   K9  VR,           RVR,           RVR,           2p M	  V'       g   K   M	  RpVP                  R/ 4      p\        VP                  R/ 4      P                  R4      4      pV F9  p\	        VP                  R/ 4      P                  R4      4      pV'       g   K7  Tp M	  . p\        VP                  R/ 4      P                  R4      4      pV EF  p\	        VP                  R4      4      pV'       g   K(  RV9   g   K1  \	        VP                  R4      4      ;'       g    Rp\	        VP                  R4      4      ;'       g    Rp\	        VP                  R4      4      ;'       g    Rp\	        VP                  R4      4      ;'       g    Rp\	        VP                  R4      4      ;'       g    RpV V V V RV 2P                  R4      pV'       g   EK  VP                  V4       EK   	  R V 2p\        R!TTRTRTRT;'       g    RVR"7
      # )#u2   Tek bir exchange-document'ı PriorArtHit'e çevir.z@countryrA   z@doc-numberz@kindNzbibliographic-datazinvention-titlez@langenzapplication-referencezdocument-iddate:N   N-:r      N:r      N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abstractr   	inventorsfiling_datepublication_datecpc_classesra   )	rO   rj   rh   rn   ro   lenstriprt   r   )rz   country
doc_numberkindr   biblio
title_texttitle_entryr   app_refsrefdoc_id_listdiddate_valapplicant_textr   r   apr   r   	pat_classpcschemer   clsr   
main_groupr   codera   s   &                             r   rs   rs      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xCMQ.!)"aaO	 
 ;  "&NjjB'G'++lB7;;KHIJ266"2B7;;FCD4!N	   K$<bAEEF]^_IRVV$;<=6evo!"&&"34::GbffWo.44"C"266*#56<<"H$RVVL%9:@@bJ"266*#56<<"HYseH:j\8*EKKCPDt""4(  Gyk
RC ''4 r   )r   
__future__r   rH   typingr   urllib.parser   r(   app.services.prior_art.modelsr   rJ   r[   RuntimeErrorr   r   r   r   rj   ro   r_   rs   r   r   r   <module>r      sp    #     57
3	=\ =S S4^ 4R2 R2t
$Hr   