
0c@_r                 @   s2  d  Z  d d l Z d d l Z d d l Z d d l m Z d d l m Z d d l m	 Z	 d d l
 m Z m Z m Z m Z m Z d d l m Z m Z m Z m Z d d	 l m Z m Z m Z d d
 l m Z 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& d d l' m( Z( d d l) m* Z* d d l m+ Z+ m, Z, m- Z- m. Z. m/ Z/ m0 Z0 d d l1 m2 Z2 d d l m3 Z3 e j4 d k ry e j5 Z6 Wn e7 k
 re j8 Z6 Yn Xn	 e j Z6 e d d  Z9 e d d  Z: Gd d   d e;  Z< Gd d   d e<  Z= d d   Z> d S)z
requests.session
~~~~~~~~~~~~~~~~

This module provides a Session object to manage and persist settings across
requests (cookies, auth, proxies).
    N)	timedelta)OrderedDict   )_basic_auth_str)	cookielibis_py3urljoinurlparseMapping)cookiejar_from_dictextract_cookies_to_jarRequestsCookieJarmerge_cookies)RequestPreparedRequestDEFAULT_REDIRECT_LIMIT)default_hooksdispatch_hook)to_native_string)to_key_val_listdefault_headersDEFAULT_PORTS)TooManyRedirectsInvalidSchemaChunkedEncodingErrorContentDecodingError)CaseInsensitiveDict)HTTPAdapter)requote_uriget_environ_proxiesget_netrc_authshould_bypass_proxiesget_auth_from_urlrewind_body)codes)REDIRECT_STATIwin32c             C   s   | d k r |  S|  d k r  | St  | t  o; t  |  t  sB |  S| t |   } | j t |    d d   | j   D } x | D] } | | =q W| S)zDetermines appropriate setting for a given request, taking into account
    the explicit setting on that request, and the setting in the session. If a
    setting is a dictionary, they will be merged together using `dict_class`
    Nc             S   s(   g  |  ] \ } } | d  k r |  q S)N ).0kvr'   r'   </tmp/pip-build-jynh7p1z/pip/pip/_vendor/requests/sessions.py
<listcomp>J   s   	 z!merge_setting.<locals>.<listcomp>)
isinstancer
   r   updateitems)request_settingsession_setting
dict_classmerged_setting	none_keyskeyr'   r'   r+   merge_setting2   s    r6   c             C   sZ   | d k s! | j  d  g  k r% |  S|  d k sF |  j  d  g  k rJ | St |  | |  S)zProperly merges both requests and session hooks.

    This is necessary because when request_hooks == {'response': []}, the
    merge breaks Session hooks entirely.
    Nresponse)getr6   )request_hookssession_hooksr2   r'   r'   r+   merge_hooksQ   s
    !!r;   c               @   sj   e  Z d  Z d d   Z d d   Z d d d d d d d d	  Z d
 d   Z d d   Z d d   Z d S)SessionRedirectMixinc             C   s<   | j  r8 | j d } t r+ | j d  } t | d  Sd S)z7Receives a Response. Returns a redirect URI or ``None``locationlatin1utf8N)is_redirectheadersr   encoder   )selfrespr=   r'   r'   r+   get_redirect_targetb   s    	z(SessionRedirectMixin.get_redirect_targetc             C   s   t  |  } t  |  } | j | j k r. d S| j d k rn | j d k rn | j d k rn | j d	 k rn d S| j | j k } | j | j k } t j | j d  d f } | r | j | k r | j | k r d S| p | S)
zFDecide whether Authorization header should be removed when redirectingThttpP   Nhttps  F)rG   N)rI   N)r	   hostnameschemeportr   r8   )rC   Zold_urlnew_urlZ
old_parsedZ
new_parsedZchanged_portZchanged_schemedefault_portr'   r'   r+   should_strip_authw   s    z&SessionRedirectMixin.should_strip_authFNTc	             k   s,  g  }
 |  j  |  } t | j  j } x| r'| j   } |
 j |  |
 d d  | _ y | j Wn. t t	 t
 f k
 r | j j d d  Yn Xt | j  |  j k r t d j |  j  d |  | j   | j d  rt | j  } d j t | j  | g  } t |  } | j d	 k rJ| rJ| j d
 |  } n | j r\| j } | j   } | j st | j t |   } n t |  } t |  | _ |  j | |  | j t j t j f k rd } x! | D] } | j  j! | d  qWd | _" | j  } | j! d d  t# | j$ | | j  t% | j$ |  j&  | j' | j$  |  j( | |  } |  j) | |  | j* d k	 od | k pd | k } | rt+ |  | } | r| Vq* |  j, | d | d | d | d | d | d d |	 } t# |  j& | | j  |  j  |  } | Vq* Wd S)zBReceives a Response. Returns a generator of Responses or Requests.r   Ndecode_contentFzExceeded {} redirects.r7   z//: fragmentContent-LengthContent-TypeTransfer-EncodingCookiestreamtimeoutverifycertproxiesallow_redirects)rT   rU   rV   )-rE   r	   urlrS   copyappendhistorycontentr   r   RuntimeErrorrawreadlenmax_redirectsr   formatclose
startswithjoinr   rK   _replacegeturlnetlocr   r   rebuild_methodstatus_coder$   temporary_redirectpermanent_redirectrA   popbodyr   _cookiesr   cookiesprepare_cookiesrebuild_proxiesrebuild_authZ_body_positionr#   send)rC   rD   reqrX   rY   rZ   r[   r\   yield_requestsadapter_kwargshistr^   Zprevious_fragmentprepared_requestparsed_rurlparsedZpurged_headersheaderrA   Z
rewindabler'   r'   r+   resolve_redirects   sv    	
					
	z&SessionRedirectMixin.resolve_redirectsc             C   su   | j  } | j } d | k r= |  j | j j |  r= | d =|  j rR t |  n d } | d k	 rq | j |  d S)zWhen being redirected we may want to strip authentication from the
        request to avoid leaking credentials. This method intelligently removes
        and reapplies authentication where possible to avoid credential loss.
        AuthorizationN)rA   r^   rO   request	trust_envr    prepare_auth)rC   r   r7   rA   r^   new_authr'   r'   r+   ry      s    		$z!SessionRedirectMixin.rebuild_authc             C   s*  | d k	 r | n i  } | j  } | j } t |  j } | j   } | j d  } t | d | } |  j r | r t | d | }	 |	 j | |	 j d   }
 |
 r | j	 | |
  d | k r | d =y t
 | |  \ } } Wn t k
 rd \ } } Yn X| r&| r&t | |  | d <| S)a  This method re-evaluates the proxy configuration by considering the
        environment variables. If we are redirected to a URL covered by
        NO_PROXY, we strip the proxy configuration. Otherwise, we set missing
        proxy keys for this URL (in case they were stripped by a previous
        redirect).

        This method also replaces the Proxy-Authorization header where
        necessary.

        :rtype: dict
        Nno_proxyallzProxy-Authorization)NN)rA   r^   r	   rK   r_   r8   r!   r   r   
setdefaultr"   KeyErrorr   )rC   r   r\   rA   r^   rK   new_proxiesr   Zbypass_proxyenviron_proxiesproxyusernamepasswordr'   r'   r+   rx     s*    		z$SessionRedirectMixin.rebuild_proxiesc             C   s   | j  } | j t j k r- | d k r- d } | j t j k rQ | d k rQ d } | j t j k ru | d k ru d } | | _  d S)zWhen being redirected we may want to change the method of the request
        based on certain specs or browser behavior.
        HEADGETPOSTN)methodrp   r$   	see_otherfoundmoved)rC   r   r7   r   r'   r'   r+   ro   :  s    	z#SessionRedirectMixin.rebuild_method)	__name__
__module____qualname__rE   rO   r   ry   rx   ro   r'   r'   r'   r+   r<   `   s   m)r<   c               @   sZ  e  Z d  Z d Z d d d d d d d d	 d
 d d d g Z d d   Z d d   Z d d   Z d d   Z d d d d d d d d d d d d d d d d  Z	 d d   Z
 d d   Z d d   Z d d d  d!  Z d d" d#  Z d d$ d%  Z d& d'   Z d( d)   Z d* d+   Z d, d-   Z d. d/   Z d0 d1   Z d2 d3   Z d4 d5   Z d S)6Sessiona  A Requests session.

    Provides cookie persistence, connection-pooling, and configuration.

    Basic Usage::

      >>> import requests
      >>> s = requests.Session()
      >>> s.get('https://httpbin.org/get')
      <Response [200]>

    Or as a context manager::

      >>> with requests.Session() as s:
      ...     s.get('https://httpbin.org/get')
      <Response [200]>
    rA   rv   authr\   hooksparamsrZ   r[   adaptersrX   r   rg   c             C   s   t    |  _ d  |  _ i  |  _ t   |  _ i  |  _ d |  _ d |  _ d  |  _	 t
 |  _ d |  _ t i   |  _ t   |  _ |  j d t    |  j d t    d  S)NFTzhttps://zhttp://)r   rA   r   r\   r   r   r   rX   rZ   r[   r   rg   r   r   rv   r   r   mountr   )rC   r'   r'   r+   __init__j  s    								zSession.__init__c             C   s   |  S)Nr'   )rC   r'   r'   r+   	__enter__  s    zSession.__enter__c             G   s   |  j    d  S)N)ri   )rC   argsr'   r'   r+   __exit__  s    zSession.__exit__c             C   s$  | j  p i  } t | t j  s- t |  } t t t   |  j   |  } | j } |  j r} | r} |  j r} t	 | j
  } t   } | j d | j j   d | j
 d | j d | j d | j d t | j |  j d t d t | j |  j  d	 t | |  j  d
 | d t | j |  j   
| S)a  Constructs a :class:`PreparedRequest <PreparedRequest>` for
        transmission and returns it. The :class:`PreparedRequest` has settings
        merged from the :class:`Request <Request>` instance and those of the
        :class:`Session`.

        :param request: :class:`Request` instance to prepare with this
            session's settings.
        :rtype: requests.PreparedRequest
        r   r^   filesdatajsonrA   r2   r   r   rv   r   )rv   r-   r   	CookieJarr   r   r   r   r   r    r^   r   preparer   upperr   r   r   r6   rA   r   r   r;   r   )rC   r   rv   merged_cookiesr   pr'   r'   r+   prepare_request  s*    
							zSession.prepare_requestNTc             C   s   t  d | j   d | d | d | d | p- i  d | d | p? i  d | d	 | d
 |  
} |  j |  } | po i  } |  j | j | | | |  } d |	 d |
 i } | j |  |  j | |  } | S)a  Constructs a :class:`Request <Request>`, prepares it and sends it.
        Returns :class:`Response <Response>` object.

        :param method: method for the new :class:`Request` object.
        :param url: URL for the new :class:`Request` object.
        :param params: (optional) Dictionary or bytes to be sent in the query
            string for the :class:`Request`.
        :param data: (optional) Dictionary, list of tuples, bytes, or file-like
            object to send in the body of the :class:`Request`.
        :param json: (optional) json to send in the body of the
            :class:`Request`.
        :param headers: (optional) Dictionary of HTTP Headers to send with the
            :class:`Request`.
        :param cookies: (optional) Dict or CookieJar object to send with the
            :class:`Request`.
        :param files: (optional) Dictionary of ``'filename': file-like-objects``
            for multipart encoding upload.
        :param auth: (optional) Auth tuple or callable to enable
            Basic/Digest/Custom HTTP Auth.
        :param timeout: (optional) How long to wait for the server to send
            data before giving up, as a float, or a :ref:`(connect timeout,
            read timeout) <timeouts>` tuple.
        :type timeout: float or tuple
        :param allow_redirects: (optional) Set to True by default.
        :type allow_redirects: bool
        :param proxies: (optional) Dictionary mapping protocol or protocol and
            hostname to the URL of the proxy.
        :param stream: (optional) whether to immediately download the response
            content. Defaults to ``False``.
        :param verify: (optional) Either a boolean, in which case it controls whether we verify
            the server's TLS certificate, or a string, in which case it must be a path
            to a CA bundle to use. Defaults to ``True``.
        :param cert: (optional) if String, path to ssl client cert file (.pem).
            If Tuple, ('cert', 'key') pair.
        :rtype: requests.Response
        r   r^   rA   r   r   r   r   r   rv   r   rY   r]   )r   r   r   merge_environment_settingsr^   r.   rz   )rC   r   r^   r   r   rA   rv   r   r   rY   r]   r\   r   rX   rZ   r[   r   r{   prepsettingssend_kwargsrD   r'   r'   r+   r     s(    )	zSession.requestc             K   s#   | j  d d  |  j d | |  S)zSends a GET request. Returns :class:`Response` object.

        :param url: URL for the new :class:`Request` object.
        :param \*\*kwargs: Optional arguments that ``request`` takes.
        :rtype: requests.Response
        r]   Tr   )r   r   )rC   r^   kwargsr'   r'   r+   r8     s    zSession.getc             K   s#   | j  d d  |  j d | |  S)zSends a OPTIONS request. Returns :class:`Response` object.

        :param url: URL for the new :class:`Request` object.
        :param \*\*kwargs: Optional arguments that ``request`` takes.
        :rtype: requests.Response
        r]   TOPTIONS)r   r   )rC   r^   r   r'   r'   r+   options!  s    zSession.optionsc             K   s#   | j  d d  |  j d | |  S)zSends a HEAD request. Returns :class:`Response` object.

        :param url: URL for the new :class:`Request` object.
        :param \*\*kwargs: Optional arguments that ``request`` takes.
        :rtype: requests.Response
        r]   Fr   )r   r   )rC   r^   r   r'   r'   r+   head,  s    zSession.headc             K   s   |  j  d | d | d | | S)a  Sends a POST request. Returns :class:`Response` object.

        :param url: URL for the new :class:`Request` object.
        :param data: (optional) Dictionary, list of tuples, bytes, or file-like
            object to send in the body of the :class:`Request`.
        :param json: (optional) json to send in the body of the :class:`Request`.
        :param \*\*kwargs: Optional arguments that ``request`` takes.
        :rtype: requests.Response
        r   r   r   )r   )rC   r^   r   r   r   r'   r'   r+   post7  s    zSession.postc             K   s   |  j  d | d | | S)au  Sends a PUT request. Returns :class:`Response` object.

        :param url: URL for the new :class:`Request` object.
        :param data: (optional) Dictionary, list of tuples, bytes, or file-like
            object to send in the body of the :class:`Request`.
        :param \*\*kwargs: Optional arguments that ``request`` takes.
        :rtype: requests.Response
        PUTr   )r   )rC   r^   r   r   r'   r'   r+   putD  s    
zSession.putc             K   s   |  j  d | d | | S)aw  Sends a PATCH request. Returns :class:`Response` object.

        :param url: URL for the new :class:`Request` object.
        :param data: (optional) Dictionary, list of tuples, bytes, or file-like
            object to send in the body of the :class:`Request`.
        :param \*\*kwargs: Optional arguments that ``request`` takes.
        :rtype: requests.Response
        PATCHr   )r   )rC   r^   r   r   r'   r'   r+   patchP  s    
zSession.patchc             K   s   |  j  d | |  S)zSends a DELETE request. Returns :class:`Response` object.

        :param url: URL for the new :class:`Request` object.
        :param \*\*kwargs: Optional arguments that ``request`` takes.
        :rtype: requests.Response
        DELETE)r   )rC   r^   r   r'   r'   r+   delete\  s    zSession.deletec             K   s  | j  d |  j  | j  d |  j  | j  d |  j  | j  d |  j  t | t  rg t d   | j d d  } | j	 d  } | j
 } |  j d | j  } t   } | j | |  } t   | }	 t d	 |	  | _ t d
 | | |  } | j r+x* | j D] }
 t |  j |
 j |
 j  qWt |  j | | j  | rr|  j | | |  } d d   | D } n g  } | r| j d |  | j   } | | _ | sy( t |  j | | d d |  | _ Wn t k
 rYn X| s| j | S)zISend a given PreparedRequest.

        :rtype: requests.Response
        rX   rZ   r[   r\   z#You can only send PreparedRequests.r]   Tr^   secondsr7   c             S   s   g  |  ] } |  q Sr'   r'   )r(   rD   r'   r'   r+   r,     s   	 z Session.send.<locals>.<listcomp>r   r|   )r   rX   rZ   r[   r\   r-   r   
ValueErrorrs   r8   r   get_adapterr^   preferred_clockrz   r   elapsedr   ra   r   rv   r   rd   r   insertnextZ_nextStopIterationrb   )rC   r   r   r]   rX   r   adapterstartrr   rD   genra   r'   r'   r+   rz   f  sF    				(zSession.sendc       
      C   s	  |  j  r | d k	 r$ | j d  n d } t | d | } x* | j   D] \ } }	 | j | |	  qI W| d k s | d k r t j j d  p t j j d  } t | |  j  } t | |  j	  } t | |  j
  } t | |  j  } d | d | d | d	 | i S)
z^
        Check the environment and merge it with some settings.

        :rtype: dict
        Nr   TREQUESTS_CA_BUNDLECURL_CA_BUNDLErZ   r\   rX   r[   )r   r8   r   r/   r   osenvironr6   r\   rX   rZ   r[   )
rC   r^   r\   rX   rZ   r[   r   env_proxiesr)   r*   r'   r'   r+   r     s    	!z"Session.merge_environment_settingsc             C   sX   x< |  j  j   D]+ \ } } | j   j | j    r | Sq Wt d j |    d S)z~
        Returns the appropriate connection adapter for the given URL.

        :rtype: requests.adapters.BaseAdapter
        z*No connection adapters were found for {!r}N)r   r/   lowerrj   r   rh   )rC   r^   prefixr   r'   r'   r+   r     s    zSession.get_adapterc             C   s(   x! |  j  j   D] } | j   q Wd S)z+Closes all adapters and as such the sessionN)r   valuesri   )rC   r*   r'   r'   r+   ri     s    zSession.closec                sW   | |  j    <  f d d   |  j  D } x' | D] } |  j  j |  |  j  | <q0 Wd S)zwRegisters a connection adapter to a prefix.

        Adapters are sorted in descending order by prefix length.
        c                s.   g  |  ]$ } t  |  t     k  r |  q Sr'   )rf   )r(   r)   )r   r'   r+   r,     s   	 z!Session.mount.<locals>.<listcomp>N)r   rs   )rC   r   r   keys_to_mover5   r'   )r   r+   r     s    zSession.mountc                s      f d d     j  D } | S)Nc                s%   i  |  ] } t    | d   |  q S)N)getattr)r(   attr)rC   r'   r+   
<dictcomp>  s   	 z(Session.__getstate__.<locals>.<dictcomp>)	__attrs__)rC   stater'   )rC   r+   __getstate__  s    zSession.__getstate__c             C   s1   x* | j    D] \ } } t |  | |  q Wd  S)N)r/   setattr)rC   r   r   valuer'   r'   r+   __setstate__  s    zSession.__setstate__)r   r   r   __doc__r   r   r   r   r   r   r8   r   r   r   r   r   r   rz   r   r   ri   r   r   r   r'   r'   r'   r+   r   Q  s2   	7)D
Kr   c               C   s   t    S)aZ  
    Returns a :class:`Session` for context-management.

    .. deprecated:: 1.0.0

        This method has been deprecated since version 1.0.0 and is only kept for
        backwards compatibility. New code should use :class:`~requests.sessions.Session`
        to create a session. This may be removed at a future date.

    :rtype: Session
    )r   r'   r'   r'   r+   session  s    r   )?r   r   systimedatetimer   collectionsr   r   r   compatr   r   r   r	   r
   rv   r   r   r   r   modelsr   r   r   r   r   r   Z_internal_utilsr   utilsr   r   r   
exceptionsr   r   r   r   
structuresr   r   r   r   r   r    r!   r"   r#   status_codesr$   r%   platformperf_counterr   AttributeErrorclockr6   r;   objectr<   r   r   r'   r'   r'   r+   <module>	   s<   ("".	 