U
    dd+
                    @   sD  d dl Z d dlZd dlZd dlZd dlZd dlmZmZ d dlm	Z	 ddl
m
Z
 ddlmZmZmZ ddlmZmZmZmZmZmZ ddlmZ dd	lmZmZmZmZ dd
lmZmZm Z m!Z! ddl"m#Z# ddl$m%Z% ddl&m'Z'm(Z( ddl)m*Z*m+Z+ ddl,m-Z- ddl.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z= ddl>m?Z?m@Z@ ddlAmBZBmCZCmDZDmEZEmFZF ejGdddZHejGdddZIG dd dZJeJ ZKeLdZMde
 ZNdOdd eP D ZQG dd  d ejRZSG d!d" d"e:ZTG d#d$ d$e/ZUejVd%ejWf ZXG d&d' d'ZYG d(d deYZZG d)d deYZ[dS )*    N)asynccontextmanagercontextmanager)TracebackType   )__version__)Auth	BasicAuthFunctionAuth)DEFAULT_LIMITSDEFAULT_MAX_REDIRECTSDEFAULT_TIMEOUT_CONFIGLimitsProxyTimeout)SUPPORTED_DECODERS)
InvalidURLRemoteProtocolErrorTooManyRedirectsrequest_context)CookiesHeadersRequestResponse)codes)ASGITransport)AsyncBaseTransportBaseTransport)AsyncHTTPTransportHTTPTransport)WSGITransport)AsyncByteStream	AuthTypes	CertTypesCookieTypesHeaderTypesProxiesTypesQueryParamTypesRequestContentRequestDataRequestExtensionsRequestFilesSyncByteStreamTimeoutTypesURLTypesVerifyTypes)URLQueryParams)Timer
URLPatternget_environment_proxiesis_https_redirectsame_originTClient)boundUAsyncClientc                   @   s   e Zd ZdZdS )UseClientDefaulta<  
    For some parameters such as `auth=...` and `timeout=...` we need to be able
    to indicate the default "unset" state, in a way that is distinctly different
    to using `None`.

    The default "unset" state indicates that whatever default is set on the
    client should be used. This is different to setting `None`, which
    explicitly disables the parameter, possibly overriding a client default.

    For example we use `timeout=USE_CLIENT_DEFAULT` in the `request()` signature.
    Omitting the `timeout` parameter will send a request using whatever default
    timeout has been configured on the client. Including `timeout=None` will
    ensure no timeout is used.

    Note that user code shouldn't need to use the `USE_CLIENT_DEFAULT` constant,
    but it is used internally when a parameter is not included.
    N)__name__
__module____qualname____doc__ r@   r@   1/tmp/pip-unpacked-wheel-fkuvgui5/httpx/_client.pyr;   @   s   r;   Zhttpxzpython-httpx/z, c                 C   s   g | ]}|d kr|qS )identityr@   ).0keyr@   r@   rA   
<listcomp>[   s      rE   c                   @   s   e Zd ZdZdZdZdS )ClientStater         N)r<   r=   r>   UNOPENEDOPENEDCLOSEDr@   r@   r@   rA   rF   _   s   rF   c                   @   sF   e Zd ZdZeeeddddZej	e
 dddZddd	d
ZdS )BoundSyncStreamz
    A byte stream that is bound to a given response instance, and that
    ensures the `response.elapsed` is set once the response is closed.
    Nstreamresponsetimerreturnc                 C   s   || _ || _|| _d S N_stream	_response_timerselfrN   rO   rP   r@   r@   rA   __init__s   s    zBoundSyncStream.__init__rQ   c                 c   s   | j D ]
}|V  qd S rR   rT   rX   chunkr@   r@   rA   __iter__z   s    
zBoundSyncStream.__iter__c                 C   s(   | j  }tj|d| j_| j  d S N)seconds)rV   Zsync_elapseddatetime	timedeltarU   elapsedrT   closerX   r`   r@   r@   rA   rd   ~   s    
zBoundSyncStream.close)r<   r=   r>   r?   r+   r   r1   rY   typingIteratorbytesr^   rd   r@   r@   r@   rA   rL   m   s     rL   c                   @   sF   e Zd ZdZeeeddddZej	e
 dddZddd	d
ZdS )BoundAsyncStreamz
    An async byte stream that is bound to a given response instance, and that
    ensures the `response.elapsed` is set once the response is closed.
    NrM   c                 C   s   || _ || _|| _d S rR   rS   rW   r@   r@   rA   rY      s    zBoundAsyncStream.__init__rZ   c                 C  s    | j 2 z3 d H W }|V  q6 d S rR   r[   r\   r@   r@   rA   	__aiter__   s    zBoundAsyncStream.__aiter__c                    s4   | j  I d H }tj|d| j_| j I d H  d S r_   )rV   Zasync_elapsedra   rb   rU   rc   rT   aclosere   r@   r@   rA   rk      s    zBoundAsyncStream.aclose)r<   r=   r>   r?   r    r   r1   rY   rf   AsyncIteratorrh   rj   rk   r@   r@   r@   rA   ri      s     ri   .c                   @   s  e Zd Zddddededddddeje eje eje	 eje
 eeeejejeeje f  eeejeejegef f dddZeed	d
dZeed	ddZeedddZeje eejeeje f dddZee d	ddZ!e!j"eddddZ!eejeeje f d	ddZ#e#j"ejeeje f ddddZ#eeje$ d	ddZ%e%j"eddddZ%eed	d d!Z&e&j"eddd"d!Z&ee'd	d#d$Z(e(j"e	dd%d&d$Z(ee)d	d'd(Z*e*j"e
dd)d*d(Z*ee+d	d+d,Z,e,j"edd-d.d,Z,ddddddde-dd/	eeeje. eje/ eje0 ejej1 eje eje	 eje
 ejee2f eje3 e4d0d1d2Z5eedd3d4Z6dMeje
 eje
 d)d5d6Z7dNeje	 eje	 d%d7d8Z8dOeje eje d-d9d:Z9eje eje$ dd;d<Z:e-fe4ejee2df e$d=d>d?Z;e4e<e4d@dAdBZ=e4e<ed@dCdDZ>e4e<ed@dEdFZ?e4eee'dGdHdIZ@e4eejejeAeBf  dJdKdLZCdS )P
BaseClientNF Tutf-8authparamsheaderscookiestimeoutfollow_redirectsmax_redirectsevent_hooksbase_url	trust_envdefault_encodingc                C   s   |d kri n|}|  t|	| _| || _t|| _t|| _t	|| _
t|| _|| _|| _t|dg t|dg d| _|
| _|| _tj| _d S NrequestrO   )r}   rO   )_enforce_trailing_slashr/   	_base_url_build_auth_authr0   _paramsr   rs   r   _cookiesr   _timeoutrv   rw   listget_event_hooks
_trust_env_default_encodingrF   rI   _state)rX   rq   rr   rs   rt   ru   rv   rw   rx   ry   rz   r{   r@   r@   rA   rY      s    



zBaseClient.__init__rZ   c                 C   s   | j tjkS )z2
        Check if the client being closed
        )r   rF   rK   rX   r@   r@   rA   	is_closed   s    zBaseClient.is_closedc                 C   s   | j S rR   )r   r   r@   r@   rA   rz      s    zBaseClient.trust_envurlrQ   c                 C   s"   |j dr|S |j|j d dS )N   /raw_path)r   endswith	copy_withrX   r   r@   r@   rA   r~      s    z"BaseClient._enforce_trailing_slash)proxiesallow_env_proxiesrQ   c                 C   s   |d kr$|r dd t   D S i S t|trpi }| D ]0\}}t|ttfrZt|dn|}||t|< q:|S t|ttfrt|dn|}d|iS d S )Nc                 S   s(   i | ] \}}||d krd nt |dqS )Nr   )r   )rC   rD   r   r@   r@   rA   
<dictcomp>   s    z-BaseClient._get_proxy_map.<locals>.<dictcomp>r   zall://)r3   items
isinstancedictstrr/   r   )rX   r   r   new_proxiesrD   valueproxyr@   r@   rA   _get_proxy_map   s    
zBaseClient._get_proxy_mapc                 C   s   | j S rR   )r   r   r@   r@   rA   ru      s    zBaseClient.timeout)ru   rQ   c                 C   s   t || _d S rR   )r   r   )rX   ru   r@   r@   rA   ru      s    c                 C   s   | j S rR   )r   r   r@   r@   rA   rx      s    zBaseClient.event_hooks)rx   rQ   c                 C   s(   t |dg t |dg d| _d S r|   )r   r   r   )rX   rx   r@   r@   rA   rx      s    c                 C   s   | j S )z
        Authentication class used when none is passed at the request-level.

        See also [Authentication][0].

        [0]: /quickstart/#authentication
        )r   r   r@   r@   rA   rq      s    	zBaseClient.auth)rq   rQ   c                 C   s   |  || _d S rR   )r   r   rX   rq   r@   r@   rA   rq     s    c                 C   s   | j S )zK
        Base URL to use when sending requests with relative URLs.
        )r   r   r@   r@   rA   ry     s    zBaseClient.base_urlc                 C   s   |  t|| _d S rR   )r~   r/   r   r   r@   r@   rA   ry     s    c                 C   s   | j S )z@
        HTTP headers to include when sending requests.
        )_headersr   r@   r@   rA   rs     s    zBaseClient.headers)rs   rQ   c                 C   s2   t dtddtdd}|| || _d S )Ns   */*asciis
   keep-alive)s   Accepts   Accept-Encodings
   Connections
   User-Agent)r   ACCEPT_ENCODINGencode
USER_AGENTupdater   )rX   rs   Zclient_headersr@   r@   rA   rs     s    
c                 C   s   | j S )zA
        Cookie values to include when sending requests.
        )r   r   r@   r@   rA   rt   *  s    zBaseClient.cookies)rt   rQ   c                 C   s   t || _d S rR   )r   r   )rX   rt   r@   r@   rA   rt   1  s    c                 C   s   | j S )zO
        Query parameters to include in the URL when sending requests.
        )r   r   r@   r@   rA   rr   5  s    zBaseClient.params)rr   rQ   c                 C   s   t || _d S rR   )r0   r   )rX   rr   r@   r@   rA   rr   <  s    )	contentdatafilesjsonrr   rs   rt   ru   
extensions)methodr   r   r   r   r   rr   rs   rt   ru   r   rQ   c       	         C   s   |  |}| |}| |	}	| |}|dkr4i n|}d|krnt|
trP| jnt|
}
tf |d|
	 i}t
|||||||||	|d
S )aJ  
        Build and return a request instance.

        * The `params`, `headers` and `cookies` arguments
        are merged with any values set on the client.
        * The `url` argument is merged with any `base_url` set on the client.

        See also: [Request instances][0]

        [0]: /advanced/#request-instances
        Nru   )r   r   r   r   rr   rs   rt   r   )
_merge_url_merge_headers_merge_cookies_merge_queryparamsr   r;   ru   r   r   Zas_dictr   )rX   r   r   r   r   r   r   rr   rs   rt   ru   r   r@   r@   rA   build_request@  s.    



zBaseClient.build_requestc                 C   s4   t |}|jr0| jj|jd }| jj|dS |S )z
        Merge a URL argument together with any 'base_url' on the client,
        to create the URL used for the outgoing request.
        r   r   )r/   is_relative_urlry   r   lstripr   )rX   r   Z	merge_urlZmerge_raw_pathr@   r@   rA   r   s  s
    zBaseClient._merge_urlc                 C   s&   |s
| j r"t| j }|| |S |S )z
        Merge a cookies argument together with any cookies on the client,
        to create the cookies used for the outgoing request.
        )rt   r   r   )rX   rt   merged_cookiesr@   r@   rA   r     s
    


zBaseClient._merge_cookiesc                 C   s   t | j}|| |S )z
        Merge a headers argument together with any headers on the client,
        to create the headers used for the outgoing request.
        )r   rs   r   )rX   rs   Zmerged_headersr@   r@   rA   r     s    

zBaseClient._merge_headersc                 C   s"   |s
| j rt| j }||S |S )z
        Merge a queryparams argument together with any queryparams on the client,
        to create the queryparams used for the outgoing request.
        )rr   r0   merge)rX   rr   Zmerged_queryparamsr@   r@   rA   r     s    


zBaseClient._merge_queryparamsc                 C   s\   |d krd S t |tr*t|d |d dS t |tr8|S t|rJt|dS td|d S )Nr   r   usernamepassword)funczInvalid "auth" argument: )r   tupler   r   callabler	   	TypeErrorr   r@   r@   rA   r     s    


zBaseClient._build_auth)r}   rq   rQ   c                 C   sR   t |tr| jn| |}|d k	r&|S |jj|jj }}|s@|rLt||dS t S )Nr   )	r   r;   r   r   r   r   r   r   r   )rX   r}   rq   r   r   r@   r@   rA   _build_request_auth  s    zBaseClient._build_request_auth)r}   rO   rQ   c                 C   sR   |  ||}| ||}| |||}| ||}t| j}t||||||jdS )z
        Given a request and a redirect response, return a new request that
        should be used to effect the redirect.
        )r   r   rs   rt   rN   r   )_redirect_method_redirect_url_redirect_headers_redirect_streamr   rt   r   r   )rX   r}   rO   r   r   rs   rN   rt   r@   r@   rA   _build_redirect_request  s    
z"BaseClient._build_redirect_requestc                 C   sR   |j }|jtjkr|dkrd}|jtjkr6|dkr6d}|jtjkrN|dkrNd}|S )z
        When being redirected we may want to change the method of the request
        based on certain specs or browser behavior.
        HEADGETPOST)r   status_coder   	SEE_OTHERFOUNDMOVED_PERMANENTLY)rX   r}   rO   r   r@   r@   rA   r     s    zBaseClient._redirect_methodc              
   C   s   |j d }zt|}W n8 tk
rN } ztd| d|ddW 5 d}~X Y nX |jrl|jsl|j|jjd}|jr~|j	|}|jj
r|j
s|j|jj
d}|S )z<
        Return the URL for the redirect to follow.
        ZLocationz Invalid URL in location header: .r}   N)host)fragment)rs   r/   r   r   schemer   r   r   r   joinr   )rX   r}   rO   locationr   excr@   r@   rA   r     s"    

 zBaseClient._redirect_url)r}   r   r   rQ   c                 C   sx   t |j}t||js>t|j|s.|dd |jd|d< ||jkrh|dkrh|dd |dd |dd |S )	zR
        Return the headers that should be used for the redirect request.
        AuthorizationNr   Hostr   zContent-LengthzTransfer-EncodingCookie)	r   rs   r5   r   r4   popnetlocdecoder   )rX   r}   r   r   rs   r@   r@   rA   r     s    
zBaseClient._redirect_headers)r}   r   rQ   c                 C   s   ||j kr|dkrdS |jS )zO
        Return the body that should be used for the redirect request.
        r   N)r   rN   )rX   r}   r   r@   r@   rA   r   -  s    zBaseClient._redirect_stream)N)N)N)Dr<   r=   r>   r   r   rf   Optionalr!   r&   r$   r#   r,   boolintMappingr   List	EventHookr-   UnionCallablerh   rY   propertyr   rz   r/   r~   r%   Dictr   r   r   ru   setterrx   r   rq   ry   r   rs   r   rt   r0   rr   USE_CLIENT_DEFAULTr'   r(   r*   Anyr;   r)   r   r   r   r   r   r   r   r   r   r   r   r   r   r+   r    r   r@   r@   r@   rA   rm      s   $  

3    rm   c                       s  e Zd ZdZddddddddddedeedddddddeje	 eje
 eje eje eeje eeeje ejejeef  eeeeejejeeje f  eeje ejejdejf  eejeejegef f d fd	d
Zddddedddfeeje eeeeje ejejdejf  eed	ddZddddedfe eeje eeeeedddZ!e"edddZ#ddddddde$e$e$ddeeeje% eje& eje' ejej eje
 eje eje eje	e(df ejee(f ejee(f eje) e*dddZ+e,ddddddde$e$e$ddeeeje% eje& eje' ejej eje
 eje eje eje	e(df ejee(f ejee(f eje) ej-e* dddZ.de$e$de/eeje	e(df ejee(f e*dddZ0e/e1eeje* e*ddd Z2e/eeje* e*d!d"d#Z3e/e*d$d%d&Z4ddde$e$e$dd'eeje
 eje eje eje	e(f ejee(f ejee(f eje) e*d(	d)d*Z5ddde$e$e$dd'eeje
 eje eje eje	e(f ejee(f ejee(f eje) e*d(	d+d,Z6ddde$e$e$dd'eeje
 eje eje eje	e(f ejee(f ejee(f eje) e*d(	d-d.Z7ddddddde$e$e$ddeeje% eje& eje' ejej eje
 eje eje eje	e(f ejee(f ejee(f eje) e*d/d0d1Z8ddddddde$e$e$ddeeje% eje& eje' ejej eje
 eje eje eje	e(f ejee(f ejee(f eje) e*d/d2d3Z9ddddddde$e$e$ddeeje% eje& eje' ejej eje
 eje eje eje	e(f ejee(f ejee(f eje) e*d/d4d5Z:ddde$e$e$dd'eeje
 eje eje eje	e(f ejee(f ejee(f eje) e*d(	d6d7Z;dd8d9d:Z<e=e=d;d<d=Z>dAejej?e@  eje@ ejeA dd>d?d@ZB  ZCS )Br7   a  
    An HTTP client, with connection pooling, HTTP/2, redirects, cookie persistence, etc.

    It can be shared between threads.

    Usage:

    ```python
    >>> client = httpx.Client()
    >>> response = client.get('https://example.org')
    ```

    **Parameters:**

    * **auth** - *(optional)* An authentication class to use when sending
    requests.
    * **params** - *(optional)* Query parameters to include in request URLs, as
    a string, dictionary, or sequence of two-tuples.
    * **headers** - *(optional)* Dictionary of HTTP headers to include when
    sending requests.
    * **cookies** - *(optional)* Dictionary of Cookie items to include when
    sending requests.
    * **verify** - *(optional)* SSL certificates (a.k.a CA bundle) used to
    verify the identity of requested hosts. Either `True` (default CA bundle),
    a path to an SSL certificate file, an `ssl.SSLContext`, or `False`
    (which will disable verification).
    * **cert** - *(optional)* An SSL certificate used by the requested host
    to authenticate the client. Either a path to an SSL certificate file, or
    two-tuple of (certificate file, key file), or a three-tuple of (certificate
    file, key file, password).
    * **proxies** - *(optional)* A dictionary mapping proxy keys to proxy
    URLs.
    * **timeout** - *(optional)* The timeout configuration to use when sending
    requests.
    * **limits** - *(optional)* The limits configuration to use.
    * **max_redirects** - *(optional)* The maximum number of redirect responses
    that should be followed.
    * **base_url** - *(optional)* A URL to use as the base when building
    request URLs.
    * **transport** - *(optional)* A transport class to use for sending requests
    over the network.
    * **app** - *(optional)* An WSGI application to send requests to,
    rather than sending actual network requests.
    * **trust_env** - *(optional)* Enables or disables usage of environment
    variables for configuration.
    * **default_encoding** - *(optional)* The default encoding to use for decoding
    response text, if no charset information is included in a response Content-Type
    header. Set to a callable for automatic character set detection. Default: "utf-8".
    NTFrn   ro   rq   rr   rs   rt   verifycerthttp1http2r   mountsru   rv   limitsrw   rx   ry   	transportapprz   r{   .c                   s   t  j||||||||||d rRzdd l}W n tk
rP   tdd Y nX od|d kod|d k}|	|}j ||d_ fdd| D _|
d k	rԈj	dd |
 D  t
tj _d S )Nrp   r   uUsing http2=True, but the 'h2' package is not installed. Make sure to install httpx using `pip install httpx[http2]`.r   r   r   r   r   r   r   rz   c                    s:   i | ]2\}}t ||d krd nj| dqS Nr   r   r   r   r   rz   r2   _init_proxy_transportrC   rD   r   r   r   r   r   rX   rz   r   r@   rA   r     s   z#Client.__init__.<locals>.<dictcomp>c                 S   s   i | ]\}}t ||qS r@   r2   rC   rD   r   r@   r@   rA   r     s      superrY   h2ImportErrorr   _init_transport
_transportr   _mountsr   r   sortedrX   rq   rr   rs   rt   r   r   r   r   r   r   ru   rv   r   rw   rx   ry   r   r   rz   r{   r   r   Z	proxy_map	__class__r   rA   rY   l  sT    
zClient.__init__	r   r   r   r   r   r   r   rz   rQ   c	           	      C   s2   |d k	r|S |d k	rt |dS t||||||dS N)r   r   )r   r   	rX   r   r   r   r   r   r   r   rz   r@   r@   rA   r     s    
zClient._init_transportr   r   r   r   r   r   rz   rQ   c              	   C   s   t |||||||dS )N)r   r   r   r   r   rz   r   )r   rX   r   r   r   r   r   r   rz   r@   r@   rA   r     s    
zClient._init_proxy_transportr   c                 C   s:   | j  D ](\}}||r
|dkr*| jn|  S q
| jS z
        Returns the transport instance that should be used for a given URL.
        This will either be the standard connection pool, or a proxy.
        Nr   r   matchesr   rX   r   patternr   r@   r@   rA   _transport_for_url  s    
zClient._transport_for_urlr   r   r   r   rr   rs   rt   rq   rv   ru   r   r   r   r   r   r   r   rr   rs   rt   rq   rv   ru   r   rQ   c                C   sH   |	dk	rd}t |t | j|||||||||	||d}| j||
|dS )a  
        Build and send a request.

        Equivalent to:

        ```python
        request = client.build_request(...)
        response = client.send(request, ...)
        ```

        See `Client.build_request()`, `Client.send()` and
        [Merging of configuration][0] for how the various parameters
        are merged with client-level configuration.

        [0]: /advanced/#merging-of-configuration
        NzSetting per-request cookies=<...> is being deprecated, because the expected behaviour on cookie persistence is ambiguous. Set cookies directly on the client instance instead.r   r   r   r   r   r   rr   rs   rt   ru   r   rq   rv   )warningswarnDeprecationWarningr   send)rX   r   r   r   r   r   r   rr   rs   rt   rq   rv   ru   r   messager}   r@   r@   rA   r}     s$    !zClient.requestc                c   sL   | j |||||||||	||d}| j||
|dd}z
|V  W 5 |  X dS a  
        Alternative to `httpx.request()` that streams the response body
        instead of loading it into memory at once.

        **Parameters**: See `httpx.request`.

        See also: [Streaming Responses][0]

        [0]: /quickstart#streaming-responses
        r  T)r}   rq   rv   rN   N)r   r  rd   rX   r   r   r   r   r   r   rr   rs   rt   rq   rv   ru   r   r}   rO   r@   r@   rA   rN   0  s,    
zClient.streamrN   rq   rv   r}   rN   rq   rv   rQ   c             
   C   s   | j tjkrtdtj| _ t|tr,| jn|}| ||}| j	|||g d}z|s\|
  |W S  tk
r } z|  |W 5 d}~X Y nX dS )a  
        Send a request.

        The request is sent as-is, unmodified.

        Typically you'll want to build one with `Client.build_request()`
        so that any client-level configuration is merged into the request,
        but passing an explicit `httpx.Request()` is supported as well.

        See also: [Request instances][0]

        [0]: /advanced/#request-instances
        5Cannot send a request, as the client has been closed.rq   rv   historyN)r   rF   rK   RuntimeErrorrJ   r   r;   rv   r   _send_handling_authreadBaseExceptionrd   rX   r}   rN   rq   rv   rO   r   r@   r@   rA   r  d  s*    zClient.sendr}   rq   rv   r  rQ   c           	   
   C   s   | |}zt|}| j|||d}zRz||}W n tk
rR   | Y W W \S X t||_|  |}|	| W q t
k
r } z|  |W 5 d }~X Y qX qW 5 |  X d S N)rv   r  )Zsync_auth_flowrd   next_send_handling_redirectsr  StopIterationr   r  r!  appendr"  	rX   r}   rq   rv   r  Z	auth_flowrO   next_requestr   r@   r@   rA   r     s*    

zClient._send_handling_authr}   rv   r  rQ   c              
   C   s   t || jkrtd|d| jd D ]}|| q$| |}zb| jd D ]}|| qHt||_|jsl|W S | ||}||g }|r|	  n||_
|W S W q  tk
r } z|  |W 5 d }~X Y q X q d S Nz#Exceeded maximum allowed redirects.r   r}   rO   )lenrw   r   r   _send_single_requestr   r  has_redirect_locationr   r!  r+  r"  rd   rX   r}   rv   r  hookrO   r   r@   r@   rA   r'    s.     






zClient._send_handling_redirectsr}   rQ   c              	   C   s   |  |j}t }|  t|jts.tdt|d |	|}W 5 Q R X t|jts^t
||_t|j||d|_| j| | j|_td|j|j|j|j|j |S )L
        Sends a single request, without handling any redirections.
        z?Attempted to send an async request with a sync Client instance.r   rO   rP   zHTTP Request: %s %s "%s %d %s")r  r   r1   Z
sync_startr   rN   r+   r  r   handle_requestAssertionErrorr}   rL   rt   extract_cookiesr   r{   loggerinfor   http_versionr   reason_phrase)rX   r}   r   rP   rO   r@   r@   rA   r/    s6      	zClient._send_single_requestrr   rs   rt   rq   rv   ru   r   	r   rr   rs   rt   rq   rv   ru   r   rQ   c          	      C   s   | j d||||||||d	S )U
        Send a `GET` request.

        **Parameters**: See `httpx.request`.
        r   r=  r   	rX   r   rr   rs   rt   rq   rv   ru   r   r@   r@   rA   r      s    z
Client.getc          	      C   s   | j d||||||||d	S )Z
        Send an `OPTIONS` request.

        **Parameters**: See `httpx.request`.
        OPTIONSr=  r   r@  r@   r@   rA   options  s    zClient.optionsc          	      C   s   | j d||||||||d	S )V
        Send a `HEAD` request.

        **Parameters**: See `httpx.request`.
        r   r=  r   r@  r@   r@   rA   head:  s    zClient.headr   r   r   r   r   rr   rs   rt   rq   rv   ru   r   rQ   c                C   s$   | j d|||||||||	|
||dS )V
        Send a `POST` request.

        **Parameters**: See `httpx.request`.
        r   r  r   rX   r   r   r   r   r   rr   rs   rt   rq   rv   ru   r   r@   r@   rA   postW  s    zClient.postc                C   s$   | j d|||||||||	|
||dS )U
        Send a `PUT` request.

        **Parameters**: See `httpx.request`.
        PUTr  r   rH  r@   r@   rA   put|  s    z
Client.putc                C   s$   | j d|||||||||	|
||dS )W
        Send a `PATCH` request.

        **Parameters**: See `httpx.request`.
        PATCHr  r   rH  r@   r@   rA   patch  s    zClient.patchc          	      C   s   | j d||||||||d	S )X
        Send a `DELETE` request.

        **Parameters**: See `httpx.request`.
        DELETEr=  r   r@  r@   r@   rA   delete  s    zClient.deleterZ   c                 C   sB   | j tjkr>tj| _ | j  | j D ]}|dk	r(|  q(dS z.
        Close transport and proxies.
        N)r   rF   rK   r   rd   r   values)rX   r   r@   r@   rA   rd     s    
zClient.closerX   rQ   c                 C   s`   | j tjkr*tjdtjdi| j  }t|tj| _ | j  | j	 D ]}|d k	rF|  qF| S Nz-Cannot open a client instance more than once.z9Cannot reopen a client instance, once it has been closed.)
r   rF   rI   rJ   rK   r  r   	__enter__r   rT  )rX   msgr   r@   r@   rA   rW    s      

zClient.__enter__exc_type	exc_value	tracebackrQ   c                 C   sB   t j| _| j||| | j D ]}|d k	r"|||| q"d S rR   )rF   rK   r   r   __exit__r   rT  )rX   rZ  r[  r\  r   r@   r@   rA   r]    s
    zClient.__exit__)NNN)Dr<   r=   r>   r?   r   r
   r   rf   r   r!   r&   r$   r#   r.   r"   r   r%   r   r   r   r,   r   r   r   r   r-   r   r   r   rh   rY   r   r   r   r/   r  r   r'   r(   r*   r;   r)   r   r}   r   rg   rN   r   r  r   r   r'  r/  r   rC  rE  rI  rL  rO  rR  rd   r6   rW  Typer"  r   r]  __classcell__r@   r@   r  rA   r7   9  s~  5U
8
73$%(!!!
)
)
)   c                       s  e Zd ZdZddddddddddedeedddddddeje	 eje
 eje eje eeje eeeje ejejeef  eeeeejejeejejdejf  f  eeje ejejdejf  eejeejegef f d fd	d
Zddddedddfeeje eeeeje ejejdejf  eed	ddZddddedfeeeje eeeeedddZ e!edddZ"ddddddde#e#e#ddeeeje$ eje% eje& ejej eje
 eje eje eje	e'df ejee'f ejee'f eje( e)dddZ*e+ddddddde#e#e#ddeeeje$ eje% eje& ejej eje
 eje eje eje	e'f ejee'f ejee'f eje( ej,e) dddZ-de#e#de.eeje	e'df ejee'f e)dddZ/e.e0eeje) e)ddd Z1e.eeje) e)d!d"d#Z2e.e)d$d%d&Z3ddde#e#e#dd'eeje
 eje eje eje	e'df ejee'f ejee'f eje( e)d(	d)d*Z4ddde#e#e#dd'eeje
 eje eje eje	e'f ejee'f ejee'f eje( e)d(	d+d,Z5ddde#e#e#dd'eeje
 eje eje eje	e'f ejee'f ejee'f eje( e)d(	d-d.Z6ddddddde#e#e#ddeeje$ eje% eje& ejej eje
 eje eje eje	e'f ejee'f ejee'f eje( e)d/d0d1Z7ddddddde#e#e#ddeeje$ eje% eje& ejej eje
 eje eje eje	e'f ejee'f ejee'f eje( e)d/d2d3Z8ddddddde#e#e#ddeeje$ eje% eje& ejej eje
 eje eje eje	e'f ejee'f ejee'f eje( e)d/d4d5Z9ddde#e#e#dd'eeje
 eje eje eje	e'f ejee'f ejee'f eje( e)d(	d6d7Z:dd8d9d:Z;e<e<d;d<d=Z=dAejej>e?  eje? eje@ dd>d?d@ZA  ZBS )Br:   aC	  
    An asynchronous HTTP client, with connection pooling, HTTP/2, redirects,
    cookie persistence, etc.

    Usage:

    ```python
    >>> async with httpx.AsyncClient() as client:
    >>>     response = await client.get('https://example.org')
    ```

    **Parameters:**

    * **auth** - *(optional)* An authentication class to use when sending
    requests.
    * **params** - *(optional)* Query parameters to include in request URLs, as
    a string, dictionary, or sequence of two-tuples.
    * **headers** - *(optional)* Dictionary of HTTP headers to include when
    sending requests.
    * **cookies** - *(optional)* Dictionary of Cookie items to include when
    sending requests.
    * **verify** - *(optional)* SSL certificates (a.k.a CA bundle) used to
    verify the identity of requested hosts. Either `True` (default CA bundle),
    a path to an SSL certificate file, an `ssl.SSLContext`, or `False`
    (which will disable verification).
    * **cert** - *(optional)* An SSL certificate used by the requested host
    to authenticate the client. Either a path to an SSL certificate file, or
    two-tuple of (certificate file, key file), or a three-tuple of (certificate
    file, key file, password).
    * **http2** - *(optional)* A boolean indicating if HTTP/2 support should be
    enabled. Defaults to `False`.
    * **proxies** - *(optional)* A dictionary mapping HTTP protocols to proxy
    URLs.
    * **timeout** - *(optional)* The timeout configuration to use when sending
    requests.
    * **limits** - *(optional)* The limits configuration to use.
    * **max_redirects** - *(optional)* The maximum number of redirect responses
    that should be followed.
    * **base_url** - *(optional)* A URL to use as the base when building
    request URLs.
    * **transport** - *(optional)* A transport class to use for sending requests
    over the network.
    * **app** - *(optional)* An ASGI application to send requests to,
    rather than sending actual network requests.
    * **trust_env** - *(optional)* Enables or disables usage of environment
    variables for configuration.
    * **default_encoding** - *(optional)* The default encoding to use for decoding
    response text, if no charset information is included in a response Content-Type
    header. Set to a callable for automatic character set detection. Default: "utf-8".
    NTFrn   ro   r   .c                   s   t  j||||||||||d rRzdd l}W n tk
rP   tdd Y nX od|d kod|d k}|	|}j ||d_ fdd| D _|
d k	rԈj	dd |
 D  t
tj _d S )Nrp   r   r   r   c                    s:   i | ]2\}}t ||d krd nj| dqS r   r   r   r   r@   rA   r     s   z(AsyncClient.__init__.<locals>.<dictcomp>c                 S   s   i | ]\}}t ||qS r@   r   r   r@   r@   rA   r     s      r   r  r  r   rA   rY   A  sT    zAsyncClient.__init__r  c	           	      C   s2   |d k	r|S |d k	rt |dS t||||||dS r  )r   r   r  r@   r@   rA   r     s    
zAsyncClient._init_transportr  c                 C   s   t ||||||dS )N)r   r   r   r   rz   r   )r   r  r@   r@   rA   r     s    
z!AsyncClient._init_proxy_transportr   c                 C   s:   | j  D ](\}}||r
|dkr*| jn|  S q
| jS r	  r
  r  r@   r@   rA   r    s    
zAsyncClient._transport_for_urlr  r  c                   s6   | j |||||||||	||d}| j||
|dI dH S )a  
        Build and send a request.

        Equivalent to:

        ```python
        request = client.build_request(...)
        response = await client.send(request, ...)
        ```

        See `AsyncClient.build_request()`, `AsyncClient.send()`
        and [Merging of configuration][0] for how the various parameters
        are merged with client-level configuration.

        [0]: /advanced/#merging-of-configuration
        r  r  N)r   r  )rX   r   r   r   r   r   r   rr   rs   rt   rq   rv   ru   r   r}   r@   r@   rA   r}     s    !zAsyncClient.requestc                C  sX   | j |||||||||	||d}| j||
|ddI dH }z
|V  W 5 | I dH  X dS r  )r   r  rk   r  r@   r@   rA   rN     s,    
zAsyncClient.streamr  r  c             
      s   | j tjkrtdtj| _ t|tr,| jn|}| ||}| j	|||g dI dH }z|sh|
 I dH  |W S  tk
r } z| I dH  |W 5 d}~X Y nX dS )a  
        Send a request.

        The request is sent as-is, unmodified.

        Typically you'll want to build one with `AsyncClient.build_request()`
        so that any client-level configuration is merged into the request,
        but passing an explicit `httpx.Request()` is supported as well.

        See also: [Request instances][0]

        [0]: /advanced/#request-instances
        r  r  N)r   rF   rK   r  rJ   r   r;   rv   r   r   areadr"  rk   r#  r@   r@   rA   r  0  s*    zAsyncClient.sendr$  c           	   
      s   | |}z| I d H }| j|||dI d H }z^z||I d H }W n tk
rd   | Y W W hS X t||_| I d H  |}|	| W q t
k
r } z| I d H  |W 5 d }~X Y qX qW 5 | I d H  X d S r%  )Zasync_auth_flowrk   	__anext__r'  asendStopAsyncIterationr   r  r`  r)  r"  r*  r@   r@   rA   r   a  s*    

zAsyncClient._send_handling_authr,  c              
      s   t || jkrtd|d| jd D ]}||I d H  q$| |I d H }zn| jd D ]}||I d H  qTt||_|js~|W S | ||}||g }|r|	 I d H  n||_
|W S W q  tk
r } z| I d H  |W 5 d }~X Y q X q d S r-  )r.  rw   r   r   r/  r   r  r0  r   r`  r+  r"  rk   r1  r@   r@   rA   r'    s.     


z$AsyncClient._send_handling_redirectsr3  c              	      s   |  |j}t }| I dH  t|jts4tdt|d |	|I dH }W 5 Q R X t|jtsjt
||_t|j||d|_| j| | j|_|j d|j }|j d| }td|j|j| |S )r4  Nz?Attempted to send an sync request with an AsyncClient instance.r   r5   zHTTP Request: %s %s "%s")r  r   r1   Zasync_startr   rN   r    r  r   Zhandle_async_requestr7  r}   ri   rt   r8  r   r{   r   r<  r;  r9  debugr   )rX   r}   r   rP   rO   statusZresponse_liner@   r@   rA   r/    s6         z AsyncClient._send_single_requestr=  r>  c          	         s"   | j d||||||||d	I dH S )r?  r   r=  Nr   r@  r@   r@   rA   r     s    zAsyncClient.getc          	         s"   | j d||||||||d	I dH S )rA  rB  r=  Nr   r@  r@   r@   rA   rC    s    zAsyncClient.optionsc          	         s"   | j d||||||||d	I dH S )rD  r   r=  Nr   r@  r@   r@   rA   rE    s    zAsyncClient.headrF  c                   s*   | j d|||||||||	|
||dI dH S )rG  r   r  Nr   rH  r@   r@   rA   rI     s    zAsyncClient.postc                   s*   | j d|||||||||	|
||dI dH S )rJ  rK  r  Nr   rH  r@   r@   rA   rL  E  s    zAsyncClient.putc                   s*   | j d|||||||||	|
||dI dH S )rM  rN  r  Nr   rH  r@   r@   rA   rO  j  s    zAsyncClient.patchc          	         s"   | j d||||||||d	I dH S )rP  rQ  r=  Nr   r@  r@   r@   rA   rR    s    zAsyncClient.deleterZ   c                    sN   | j tjkrJtj| _ | j I dH  | j D ]}|dk	r.| I dH  q.dS rS  )r   rF   rK   r   rk   r   rT  )rX   r   r@   r@   rA   rk     s    zAsyncClient.acloserU  c                    sl   | j tjkr*tjdtjdi| j  }t|tj| _ | j I d H  | j	 D ]}|d k	rL| I d H  qL| S rV  )
r   rF   rI   rJ   rK   r  r   
__aenter__r   rT  )rX   rX  r   r@   r@   rA   rg    s      zAsyncClient.__aenter__rY  c                    sN   t j| _| j|||I d H  | j D ] }|d k	r(||||I d H  q(d S rR   )rF   rK   r   r   	__aexit__r   rT  )rX   rZ  r[  r\  r   r@   r@   rA   rh    s
    zAsyncClient.__aexit__)NNN)Cr<   r=   r>   r?   r   r
   r   rf   r   r!   r&   r$   r#   r.   r"   r   r%   r   r   r   r,   r   r   r   r   r   r-   r   rh   rY   r   r   r   r/   r  r   r'   r(   r*   r;   r)   r   r}   r   rl   rN   r   r  r   r   r'  r/  r   rC  rE  rI  rL  rO  rR  rk   r9   rg  r^  r"  r   rh  r_  r@   r@   r  rA   r:     s~  6U
0
73$&$!!!
)
)
)   )\ra   enumloggingrf   r  
contextlibr   r   typesr   r   r   r   r   r	   _configr
   r   r   r   r   r   	_decodersr   _exceptionsr   r   r   r   Z_modelsr   r   r   r   Z_status_codesr   Z_transports.asgir   Z_transports.baser   r   Z_transports.defaultr   r   Z_transports.wsgir   _typesr    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   Z_urlsr/   r0   _utilsr1   r2   r3   r4   r5   TypeVarr6   r9   r;   r   	getLoggerr9  r   r   keysr   EnumrF   rL   ri   r   r   r   rm   r7   r:   r@   r@   r@   rA   <module>   sX    D


        Y