
    wc;                     d   d 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mZ ddlmZmZ ddlm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 d
dlmZmZm Z  d
dl!m"Z"m#Z#m$Z$ g dZ%g dZ&e	ege'f         Z( ee)          Z*ereZ+ne,Z+ G d de+          Z- G d de-e          Z.ed             Z/dS )ah  Main classes to add caching features to ``requests.Session``

.. autosummary::
   :nosignatures:

   CachedSession
   CacheMixin

.. Explicitly show inherited method docs on CachedSession instead of CachedMixin
.. autoclass:: requests_cache.session.CachedSession
    :show-inheritance:
    :inherited-members:

.. autoclass:: requests_cache.session.CacheMixin
    )contextmanager)	getLogger)RLock)TYPE_CHECKINGCallableDictIterableOptionalUnion)PreparedRequestResponse)Session)dispatch_hook)filepost   )get_valid_kwargs)KEY_FNBackendSpecifierinit_backend)AnyResponseCachedResponseset_response_defaults)CacheActionsExpirationTimeget_expiration_seconds)ALL_METHODSCachedSession
CacheMixin)GETHEADOPTIONSPOSTPUTPATCHDELETEc                       e Zd ZdZ	 	 	 	 	 	 	 	 	 d-ded	ed
edeeef         dede	e
         de	e         dedef fdZdddeded
edef fdZ	 d.ded
edefdZdededefdZ	 d.dedededef fdZdedededefdZdedededefdZdedededefd Zed!             Zd.d
efd"Zd# Zd$ Zed%             Zede	e         fd&            Z e j!        d'e	e         fd(            Z ede"e	e         ef         fd)            Z#e#j!        d'e"e	e         ef         fd*            Z#ede$fd+            Z%e%j!        d'e$fd,            Z% xZ&S )/r   zMixin class that extends :py:class:`requests.Session` with caching features.
    See :py:class:`.CachedSession` for usage details.
    
http_cacheNF   r   r    
cache_namebackendexpire_afterurls_expire_aftercache_controlallowable_codesallowable_methods	filter_fnstale_if_errorc
                 j   t          ||fi |
| _        || _        || _        || _        || _        || _        |pd | _        |	p|
                    dd          | _	        d| _
        t                      | _        t          t                      j        |
          } t                      j        di | d S )Nc                     dS )NT )rs    8/usr/lib/python3/dist-packages/requests_cache/session.py<lambda>z%CacheMixin.__init__.<locals>.<lambda>B   s         old_data_on_errorFr7   )r   cacher1   r2   r.   r/   r0   r3   popr4   	_disabledr   _lockr   super__init__)selfr,   r-   r.   r/   r0   r1   r2   r3   r4   kwargssession_kwargs	__class__s               r9   rB   zCacheMixin.__init__/   s     "*g@@@@
.!2(!2*"6~~,V

;NPU0V0VWW
 *%''*:FCC**>*****r;   )r.   methodurlreturnc                    |1|                     di            dt          |           |d         d<   t          di |5   t                      j        ||g|R i |cddd           S # 1 swxY w Y   dS )a  This method prepares and sends a request while automatically performing any necessary
        caching operations. This will be called by any other method-specific ``requests`` functions
        (get, post, etc.). This does not include prepared requests, which will still be cached via
        ``send()``.

        See :py:meth:`requests.Session.request` for parameters. Additional parameters:

        Args:
            expire_after: Expiration time to set only for this request; see details below.
                Overrides ``CachedSession.expire_after``. Accepts all the same values as
                ``CachedSession.expire_after``. Use ``-1`` to disable expiration.

        Returns:
            Either a new or cached response

        **Order of operations:** For reference, a request will pass through the following methods:

        1. :py:func:`requests.get`/:py:meth:`requests.Session.get` or other method-specific functions (optional)
        2. :py:meth:`.CachedSession.request`
        3. :py:meth:`requests.Session.request`
        4. :py:meth:`.CachedSession.send`
        5. :py:meth:`.BaseCache.get_response`
        6. :py:meth:`requests.Session.send` (if not previously cached)
        7. :py:meth:`.BaseCache.save_response` (if not previously cached)
        Nheaderszmax-age=zCache-Controlr7   )
setdefaultr   patch_form_boundaryrA   request)rC   rG   rH   r.   argsrD   rF   s         r9   rN   zCacheMixin.requestL   s    D #i,,,1b<RS_<`<`1b1bF9o. **6** 	A 	A"577?63@@@@@@	A 	A 	A 	A 	A 	A 	A 	A 	A 	A 	A 	A 	A 	A 	A 	A 	A 	As   A,,A03A0rN   c           
      f    | j         j        |fi |}t          j        d|||| j        | j        | j        d|}d}| j        s6|j        s/| j         	                    |          }|
                    |           t          |dd          }| | j        ||fi |}n/|r| j        r | j        |||fi |}n|r | j        |||fi |}n|}|                     |          s>t"                              d|j                    | j                             |           |S t+          d|j        |fi |S )a  Send a prepared request, with caching. See :py:meth:`.request` for notes on behavior, and
        see :py:meth:`requests.Session.send` for parameters. Additional parameters:

        Args:
            expire_after: Expiration time to set only for this request
        )	cache_keyrN   request_expire_aftersession_expire_afterr/   r0   N
is_expiredFz$Deleting filtered response for URL: responser7   )r=   
create_keyr   from_requestr.   r/   r0   r?   	skip_readget_responseupdate_from_cached_responsegetattr_send_and_cacher4   _resend_and_ignore_resendr3   loggerdebugrH   deleter   hooks)	rC   rN   r.   rD   rQ   actionscached_responserT   rU   s	            r9   sendzCacheMixin.sendu   s    *DJ)'<<V<<	+ 
!-!%!2"4,
 
 
 
 59 	A'"3 	A"j55i@@O//@@@_lEBB
 "+t+GWGGGGHH 	'D/ 	'.t.w[[TZ[[HH 	'#t|GWoPPPPHH&H ~~h'' 	LLNNNOOOJi(((O ZKKFKKKr;   rU   rc   c                 0   | j         t          |j        j                  | j        v|j        | j        v|                     |           |j        d}t          
                    d|j         d|            t          |                                           S )zYPerform all checks needed to determine if the given response should be saved to the cache)zdisabled cachezdisabled methodzdisabled statuszdisabled by filterz(disabled by headers or expiration paramsz#Pre-cache checks for response from z: )r?   strrN   rG   r2   status_coder1   r3   
skip_writer_   r`   rH   anyvalues)rC   rU   rc   cache_criterias       r9   _is_cacheablezCacheMixin._is_cacheable   s     #n"8#3#:;;4CYY'34;OO&*nnX&>&>">8?8J
 
 	[8<[[>[[\\\~,,..////r;   rd   c                    |j                             |j                    t                      j        |fi |}|                    |           |                     ||          r'| j                            ||j	        |j
                   nF|r"|j        dk    r|                     |||          S t                              d|j                    t!          ||j	                  S )zSend the request and cache the response, unless disabled by settings or headers.

        If applicable, also add headers to make a conditional request. If we get a 304 Not Modified
        response, return the stale cache item.
        i0  zSkipping cache write for URL: )rK   updatevalidation_headersrA   re   update_from_responserm   r=   save_responserQ   expiresrh   _update_revalidated_responser_   r`   rH   r   )rC   rN   rc   rd   rD   rU   rF   s         r9   r\   zCacheMixin._send_and_cache   s     	w9:::577<22622$$X...h00 	IJ$$Xw/@'/RRRR 	I!5!<!<44WhXXXLLG'+GGHHH$Xw/@AAAr;   c                     t                               d           	  | j        |||fi |S # t          $ r! | j                            |j                    w xY w)z}Attempt to resend the request and cache the new response. If the request fails, delete
        the stale cache item.
        -Stale response; attempting to re-send request)r_   r`   r\   	Exceptionr=   ra   rQ   )rC   rN   rc   rd   rD   s        r9   r^   zCacheMixin._resend   sr     	DEEE	'4'/TTVTTT 	 	 	Jg/000	s	   , +Ac                     t                               d           	  | j        |||fi |}|                                 |S # t          $ r* t                               d|j         dd           |cY S w xY w)zAttempt to resend the request and cache the new response. If there are any errors, ignore
        them and and return the stale cache item.
        rv   zRequest for URL z failed; using cached responseT)exc_info)r_   r`   r\   raise_for_statusrw   warningrH   )rC   rN   rc   rd   rD   rU   s         r9   r]   zCacheMixin._resend_and_ignore   s     	DEEE	#+t+GWoXXQWXXH%%'''O 	# 	# 	#NNN7;NNNY]     #"""		#s   %A 1A65A6c                 "   t                               d|j        j         d           |j                            |j                   |                    |           |j        |_        | j        	                    ||j
        |j                   |S )zQAfter revalidation, update the cached response's headers and reset its expirationzResponse for URL z: has not been modified; updating and using cached response)r_   r`   rN   rH   rK   ro   rq   rs   r=   rr   rQ   )rC   rc   rU   rd   s       r9   rt   z'CacheMixin._update_revalidated_response   s     	p 0 4ppp	
 	
 	
 	&&x'7888$$_555")/
  '2CW_UUUr;   c              #   b   K   | j         rdV  dS d| _         	 dV  d| _         dS # d| _         w xY w)a  
        Context manager for temporary disabling the cache

        .. warning:: This method is not thread-safe.

        Example:

            >>> s = CachedSession()
            >>> with s.cache_disabled():
            ...     s.get('http://httpbin.org/ip')

        NTF)r?   rC   s    r9   cache_disabledzCacheMixin.cache_disabled   sR       > 	'EEEEE!DN'!&&&&&s   % 	.c                 :    | j                             |           d S N)r=   remove_expired_responses)rC   r.   s     r9   r   z#CacheMixin.remove_expired_responses  s    
++L99999r;   c                      t          d          )NzCachedSession cannot be pickled)NotImplementedErrorr~   s    r9   __getstate__zCacheMixin.__getstate__  s     ""CDDDr;   c                 Z     g d} fd|D             }dd                     |           dS )N)r=   r.   r/   r1   r2   r4   r0   c           
      T    g | ]$}| d t          t          |                     %S )=)reprr[   ).0krC   s     r9   
<listcomp>z'CacheMixin.__repr__.<locals>.<listcomp>'  s9    III44Dq!1!12244IIIr;   z<CachedSession(z, z)>)join)rC   
repr_attrs	attr_strss   `  r9   __repr__zCacheMixin.__repr__  sM    
 
 

 JIIIjIII	99!5!59999r;   c                     | S r   r7   r~   s    r9   settingszCacheMixin.settings-  s    r;   c                     | j         j        pg S r   r=   ignored_parametersr~   s    r9   r   zCacheMixin.ignored_parameters1  s    z,22r;   valuec                     || j         _        d S r   r   rC   r   s     r9   r   zCacheMixin.ignored_parameters5  s    (-
%%%r;   c                     | j         j        pg S r   r=   match_headersr~   s    r9   r   zCacheMixin.match_headers9  s    z'-2-r;   c                     || j         _        d S r   r   r   s     r9   r   zCacheMixin.match_headers=  s    #(
   r;   c                     | j         j        pg S r   r=   key_fnr~   s    r9   r   zCacheMixin.key_fnA  s    z &B&r;   c                     || j         _        d S r   r   r   s     r9   r   zCacheMixin.key_fnE  s    !
r;   )	r'   Nr(   NFr)   r+   NFr   )'__name__
__module____qualname____doc__rg   r   r   r   boolr	   int	FILTER_FNrB   r   rN   r   re   r   r   rm   r   r\   r^   r]   rt   r   r   r   r   r   propertyr   r   setterr   r   r   r   __classcell__)rF   s   @r9   r   r   *   s.         '$(')7;#)/+:#$+ ++ "+ %	+
  ^ 34+ + "#+ $C=+ + + + + + + +D (,'A 'A 'A'A 'A
 %'A 
'A 'A 'A 'A 'A 'AT HL-L -L&-L6D-L	-L -L -L -L^
0h 
0 
0$ 
0 
0 
0 
0  +/	B B B B (	B 
B B B B B B0   (	 
   "# # # (	# 
# # # #,#/7JX	    ' ' ^',: :^ : : : :E E E: : :    X 3HSM 3 3 3 X3 . . . . . .uXc]D%89 . . . X. )5#)<#= ) ) ) ) ' ' ' ' X' ]"F " " " ]" " " " "r;   r   c                       e Zd ZdZdS )r   a  Session class that extends :py:class:`requests.Session` with caching features.

    See individual :py:mod:`backend classes <requests_cache.backends>` for additional backend-specific arguments.
    Also see :ref:`user-guide` for more details and examples on how the following arguments
    affect cache behavior.

    Args:
        cache_name: Cache prefix or namespace, depending on backend
        backend: Cache backend name or instance; name may be one of
            ``['sqlite', 'filesystem', 'mongodb', 'gridfs', 'redis', 'dynamodb', 'memory']``
        serializer: Serializer name or instance; name may be one of
            ``['pickle', 'json', 'yaml', 'bson']``.
        expire_after: Time after which cached items will expire
        urls_expire_after: Expiration times to apply for different URL patterns
        cache_control: Use Cache-Control headers to set expiration
        allowable_codes: Only cache responses with one of these status codes
        allowable_methods: Cache only responses for one of these HTTP methods
        match_headers: Match request headers when reading from the cache; may be either a boolean
            or a list of specific headers to match
        ignored_parameters: List of request parameters to not match against, and exclude from the cache
        filter_fn: Function that takes a :py:class:`~requests.Response` object and returns a boolean
            indicating whether or not that response should be cached. Will be applied to both new
            and previously cached responses.
        key_fn: Function for generating custom cache keys based on request info
        stale_if_error: Return stale cache data if a new request raises an exception
    N)r   r   r   r   r7   r;   r9   r   r   J  s           r;   r   c               +      K   |                      d          r+t          j        }d t          _        dV  |t          _        dS dV  dS )zIf the ``files`` param is present, patch the form boundary used to separate multipart
    uploads. ``requests`` does not provide a way to pass a custom boundary to urllib3, so this just
    monkey-patches it instead.
    filesc                      dS )Nz ##requests-cache-form-boundary##r7   r7   r;   r9   r:   z%patch_form_boundary.<locals>.<lambda>o  s    +M r;   N)getr   choose_boundary)request_kwargsoriginal_boundarys     r9   rM   rM   g  sV       '"" $4#M#M #4   r;   N)0r   
contextlibr   loggingr   	threadingr   typingr   r   r   r	   r
   r   requestsr   r   r   OriginalSessionrequests.hooksr   urllib3r   _utilsr   backendsr   r   r   modelsr   r   r   policyr   r   r   __all__r   r   r   r   r_   
MIXIN_BASEobjectr   r   rM   r7   r;   r9   <module>r      s    & % % % % %             K K K K K K K K K K K K K K K K . . . . . . . . / / / / / / ( ( ( ( ( (       $ $ $ $ $ $ < < < < < < < < < < F F F F F F F F F F H H H H H H H H H H
8
8
8JJJk]D()		8		  JJJ]" ]" ]" ]" ]" ]" ]" ]"@	    J   :     r;   