+
    2jY                     .   R t ^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	H
t
Ht ^ RIHt ^ RIt^ RIt^ RIHt ^RIHtHtHt ^RIHtHtHtHtHtHt ]
'       d   ^ RIHt R	.tR
t  ! R R]PB                  4      t"R R lt# ! R R4      t$ ! R R	4      t%R# )a,  urllib3-based async HTTP transport for nab-index.

urllib3 is sync. To present an async surface we run each request
in a worker thread via ``asyncio.to_thread``. This is useful for
benchmarking against the natively-async backends, and for cases
where users already have urllib3 in their environment.
)annotationsN)TYPE_CHECKINGAny)urljoin)override)	GET_RETRYMAX_RETRIES
next_delay)DEFAULT_HEADERSContentDecodingError	HttpErroraccepts_gzipdecode_bodyraise_for_error_status)MappingUrllib3AsyncTransportg      @c                  0    ] tR t^-tRt]R R l4       tRtR# )_SSLContexta  truststore SSLContext that answers urllib3-future's cert probe.

urllib3-future removed the ``ssl_context is None`` guard from
``ssl_wrap_socket`` in commit ``23d13d6`` (Jun 2025) and now calls
``context.cert_store_stats()`` whenever no ``ca_certs`` is supplied;
truststore's ``cert_store_stats`` raises ``NotImplementedError`` by
design (``sethmlarson/truststore`` commit ``63dc9e1``, Feb 2023).
Returning a non-empty count tells urllib3-future the context already
has trust roots, which is true: truststore delegates verification to
the OS framework. Upstream ``urllib3`` 2.x is unaffected because PR
1566 (Apr 2019) left the guard in place. Drop this subclass once
urllib3-future restores the guard.
c                   V ^8  d   QhRR/# )   returnzdict[str, int] )formats   "l/home/user/billing-ledger-validation/.venv/lib/python3.14/site-packages/nab_index/urllib3_async_transport.py__annotate___SSLContext.__annotate__=   s     3 3. 3    c                	    R ^R^R^ /# )x509_cax509crlr   selfs   &r   cert_store_stats_SSLContext.cert_store_stats<   s    1fa22r   r   N)__name__
__module____qualname____firstlineno____doc__r   r#   __static_attributes__r   r   r   r   r   -   s     3 3r   r   c               $    V ^8  d   QhRRRRRR/# )r   responseurllib3.BaseHTTPResponserequested_urlstrr   r   )r   s   "r   r   r   A   s"      1 # # r   c                    V P                   e   V P                   P                  MRpTpV FA  pVP                  '       g   K  \        VP                  ;'       g    TVP                  4      pKC  	  V# )aw  Return the absolute URL ``response`` was retrieved from.

urllib3 records status, connect, and read retries in the same history as
redirects, and records them with the request path alone, so only a hop
carrying a ``Location`` moves the URL. A ``Location`` is reported verbatim
and may be relative, so each is resolved against the URL that served it
(RFC 3986 section 5.1.3).
r   )retrieshistoryredirect_locationr   url)r,   r.   r2   r4   hops   &&   r   
_final_urlr6   A   s`     +3*:*:*Fh&&BG
C   #''..S#*?*?@C  Jr   c                      ] tR t^StRtRtR R lt]R R l4       t]R R l4       t	]R R	 l4       t
]R
 R l4       t]R R l4       tR R ltR R ltRtR# )_Urllib3Responsea  Adapter that gives a urllib3 response the HttpResponse shape.

The body is fetched undecoded, and decoded by the transport when the
request asked for gzip (see :func:`~nab_index.transport.decode_body`),
so it is carried here rather than read from the urllib3 response.
c               (    V ^8  d   QhRRRRRRRR/# )	r   r,   r-   contentbytesr.   r/   r   Noner   )r   s   "r   r   _Urllib3Response.__annotate__]   s,     , ,0,;@,QT,	,r   c                	*    Wn         W n        W0n        R # N)	_response_content_requested_url)r"   r,   r:   r.   s   &&&&r   __init___Urllib3Response.__init__]   s     "+r   c                   V ^8  d   QhRR/# )r   r   intr   )r   s   "r   r   r=   e   s     % %S %r   c                	.    V P                   P                  # r?   )r@   statusr!   s   &r   status_code_Urllib3Response.status_coded   s    ~~$$$r   c                   V ^8  d   QhRR/# r   r   r/   r   )r   s   "r   r   r=   i   s     ? ?S ?r   c                	B    \        V P                  V P                  4      # r?   )r6   r@   rB   r!   s   &r   r4   _Urllib3Response.urlh   s    $..$*=*=>>r   c                   V ^8  d   QhRR/# )r   r   zMapping[str, str]r   )r   s   "r   r   r=   m   s     & &* &r   c                	.    V P                   P                  # r?   )r@   headersr!   s   &r   rQ   _Urllib3Response.headersl   s    ~~%%%r   c                   V ^8  d   QhRR/# )r   r   r;   r   )r   s   "r   r   r=   q   s       r   c                	    V P                   # r?   )rA   r!   s   &r   r:   _Urllib3Response.contentp   s    }}r   c                   V ^8  d   QhRR/# rL   r   )r   s   "r   r   r=   u   s     - -c -r   c                	8    V P                   P                  R 4      # )zutf-8)rA   decoder!   s   &r   text_Urllib3Response.textt   s    }}##G,,r   c                   V ^8  d   QhRR/# )r   r   r   r   )r   s   "r   r   r=   x   s     * *c *r   c                	B    \         P                  ! V P                  4      # r?   )_jsonloadsrA   r!   s   &r   json_Urllib3Response.jsonx   s    {{4==))r   c                   V ^8  d   QhRR/# r   r   r<   r   )r   s   "r   r   r=   {   s     @ @$ @r   c                	Z    \        V P                  P                  V P                  4       R # r?   )r   r@   rH   r4   r!   s   &r   raise_for_status!_Urllib3Response.raise_for_status{   s    t~~44dhh?r   )rA   rB   r@   N)r%   r&   r'   r(   r)   	__slots__rC   propertyrI   r4   rQ   r:   rY   r_   rd   r*   r   r   r   r8   r8   S   s     <I, % % ? ? & &   - -*@ @r   r8   c                  n    ] tR t^tRtR^
R^2R]/R R lltR R ltR	 R
 ltRR/R R llt	R R lt
RtR# )r   a^  Async HTTP transport using urllib3 (sync) wrapped in to_thread.

Each ``get`` runs the underlying sync request on the asyncio default
executor.  A separate :class:`~urllib3.PoolManager` (and truststore
SSLContext) is kept per worker thread: truststore toggles the
context's ``verify_mode`` to ``CERT_NONE`` for the duration of each
``wrap_socket`` (truststore#209), so sharing one context across the
executor threads races that toggle and trips spurious
``InsecureRequestWarning``s.  One context per thread means no two
threads ever touch the same context; connections are still reused
within each thread.
	num_poolsmaxsizetimeoutc               (    V ^8  d   QhRRRRRRRR/# )r   ri   rF   rj   rk   floatr   r<   r   )r   s   "r   r   "Urllib3AsyncTransport.__annotate__   s4     , , , 	,
 , 
,r   c                   Wn         W n        W0n        \        P                  ! 4       V n        . V n        \        P                  ! 4       V n        R# )zCreate a transport.N)	
_num_pools_maxsize_timeout	threadinglocal_local_poolsLock_pools_lock)r"   ri   rj   rk   s   &$$$r   rC   Urllib3AsyncTransport.__init__   s7     $oo'13$>>+r   c                   V ^8  d   QhRR/# )r   r   zurllib3.PoolManagerr   )r   s   "r   r   rn      s      * r   c                   \        V P                  RR4      pVf   \        P                  ! V P                  V P
                  \        \        P                  4      R7      pWP                  n	        V P                  ;_uu_ 4        V P                  P                  V4       RRR4       V# V#   + '       g   i     T# ; i)z;Return this worker thread's pool, creating it on first use.poolN)ri   rj   ssl_context)getattrru   urllib3PoolManagerrp   rq   r   sslPROTOCOL_TLS_CLIENTr|   rx   rv   append)r"   r|   s   & r   _poolUrllib3AsyncTransport._pool   s    +24;;+M<&&//'(?(?@D
  $KK!!!""4( "t "!s   B,,B=	c               $    V ^8  d   QhRRRRRR/# )r   r4   r/   rQ   zdict[str, str]r   r8   r   )r   s   "r   r   rn      s"     $< $<C $<. $<=M $<r   c           	        V P                  4       p\        V4      p^ p VP                  RVVV P                  \        RR7      pV'       g   \        WfP                  V4      #  \        VP                  VP                  P                  R4      4      p\        YgT4      #   \         d9    T^,          pT\        8  d   h \        P                  ! \        T4      4        K  i ; i)a&  Issue the GET on this worker thread, retrying a truncated body.

The body is fetched raw, and decoded with ``decode_body`` when the
request asked for gzip. urllib3's retries cover connection errors and
statuses, not a body that decodes short, so that case is retried here
on the same schedule.
GETF)rQ   rk   r1   decode_contentzContent-Encoding)r   r   requestrr   r   r8   datar   rQ   getr   r   timesleepr	   )r"   r4   rQ   r|   rX   failuresr,   r:   s   &&&     r   _requestUrllib3AsyncTransport._request   s     zz|g&||!$ $ H '--EE	%MM8#3#3#7#78J#K $Hs;; ( Ak)

:h/0s   #/B ?C! C!rQ   Nc               $    V ^8  d   QhRRRRRR/# )r   r4   r/   rQ   zdict[str, str] | Noner   r8   r   )r   s   "r   r   rn      s$     * **$9*	*r   c                  "   \        \        4      pVe   VP                  V4        \        P                  ! V P
                  W4      G Rj  xL
 #  L  \         d   pRT RT 2p\        T4      ThRp?ii ; i5i)a  Send a GET request, off-loaded to a worker thread.

``headers`` overrides entries of
:data:`~nab_index.transport.DEFAULT_HEADERS`, so a caller can pass
:data:`~nab_index.transport.IDENTITY_HEADERS` to get the body
undecoded. Requesting gzip matters here: without it urllib3's stdlib
base sends ``Accept-Encoding: identity``, which disables compression.
The defaults go on the request rather than on the pool because urllib3
replaces the pool's headers with a request's own instead of merging.
NzGET z	 failed: )dictr
   updateasyncio	to_threadr   	Exceptionr   )r"   r4   rQ   request_headersexcmsgs   &&$   r   r   Urllib3AsyncTransport.get   sv      /""7+	* **4==#OOOO 	* Yse,CC.c)	*s:   %A:$A AA A:A A7A22A77A:c                   V ^8  d   QhRR/# rb   r   )r   s   "r   r   rn      s     0 0d 0r   c                   "   V P                   ;_uu_ 4        \        V P                  4      pRRR4       X F+  p\        P                  ! VP
                  4      G Rj  xL
  K-  	  R#   + '       g   i     LC; i L5i)zClose every per-thread pool.N)rx   listrv   r   r   clear)r"   poolsr|   s   &  r   acloseUrllib3AsyncTransport.aclose   sT     %E D##DJJ///   0s'   A=A(0A=A;
A=(A8	3	A=)ru   rq   rp   rv   rx   rr   )r%   r&   r'   r(   r)   _DEFAULT_TIMEOUT_SECONDSrC   r   r   r   r   r*   r   r   r   r   r      sL    , , 	,
 2,$<L*<@*20 0r   )&r)   
__future__r   r   r_   r]   r   rs   r   typingr   r   urllib.parser   
truststorer   typing_extensionsr   retryr   r   r	   	transportr
   r   r   r   r   r   collections.abcr   __all__r   
SSLContextr   r6   r8   r   r   r   r   <module>r      s    #   
   %     & 5 5  '   3*'' 3($)@ )@Xo0 o0r   