Ë
    }D™j›<  ã                  óp  — d 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	 ddl
mZ ddlmZmZmZmZ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 m!Z! ddl"m#Z#m$Z$m%Z% ddl&m'Z'm(Z( e)e*ee+e,fZ- e	e.«      Z/ G d„ d«      Z0 ed«      Z1 ed«      Z2 G d„ dee1e2f   e«      Z3 G d„ dee3«      Z4y)zwBase classes for all cache backends

.. automodsumm:: requests_cache.backends.base
   :classes-only:
   :nosignatures:
é    )Úannotations)ÚABC)ÚUserDict)Údatetime)Ú	getLogger)ÚPickleError)ÚTYPE_CHECKINGÚIterableÚIteratorÚListÚMutableMappingÚOptionalÚTypeVarÚUnion)Úwarn)ÚPath)ÚRequestÚResponseé   )Ú
create_keyÚredact_response)Ú
AnyRequestÚCachedResponse)ÚDEFAULT_CACHE_NAMEÚCacheSettingsÚExpirationTime)ÚSerializerTypeÚinit_serializerc                  ó$  — e Zd ZdZefdd„Zedd„«       Zddd„Z	 	 d	 	 	 	 	 dd„Z	d„ Z
d„ Z	 d	 	 	 	 	 dd	„Z	 	 	 	 d	 	 	 	 	 	 	 d d„Zdddddd
dœ	 	 	 	 	 	 	 	 	 	 	 	 	 d!d„Zd„ Z	 	 	 	 d"	 	 	 	 	 	 	 	 	 d#d„Zd„ Zdd$d„Zdd$d„Zd%d„Zd&d„Zd„ Zd„ Zy)'Ú	BaseCachea®  Base class for cache backends. Can be used as a non-persistent, in-memory cache.

    This manages higher-level cache operations, including:

    * Saving and retrieving responses
    * Managing redirect history
    * Convenience methods for general cache info
    * Dict-like wrapper methods around the underlying storage

    Notes:

    * Lower-level storage operations are handled by :py:class:`.BaseStorage`.
    * To extend this with your own custom backend, see :ref:`custom-backends`.

    Args:
        cache_name: Cache prefix or namespace, depending on backend
        serializer: Serializer name or instance
        kwargs: Additional backend-specific keyword arguments
    c                ól   — || _         t        «       | _        t        «       | _        t	        «       | _        y ©N)Ú
cache_nameÚDictStorageÚ	responsesÚ	redirectsr   Ú	_settings)Úselfr#   Úkwargss      úh/var/www/html/Astrologybackend/backend/venv/lib/python3.12/site-packages/requests_cache/backends/base.pyÚ__init__zBaseCache.__init__6   s$   € Ø$ˆŒÜ;F»=ˆŒÜ0;³ˆŒÜ&›ˆ�ó    c                ó   — t         ‚)z�Path to the cache database file.

        Raises:
            NotImplementedError: For backends that do not use a file-based database.
        )ÚNotImplementedError©r(   s    r*   Údb_pathzBaseCache.db_path<   s
   € ô "Ð!r,   Nc                ó¨   — 	 | j                   j                  |«      }|€| j                   | j                  |      }|S # t        t        f$ r |cY S w xY w)z¶Retrieve a response from the cache, if it exists

        Args:
            key: Cache key for the response
            default: Value to return if `key` is not in the cache
        )r%   Úgetr&   ÚAttributeErrorÚKeyError)r(   ÚkeyÚdefaultÚresponses       r*   Úget_responsezBaseCache.get_responseH   sV   € ð	Ø—~‘~×)Ñ)¨#Ó.ˆHØÐØŸ>™>¨$¯.©.¸Ñ*=Ñ>�ØˆOøÜ¤Ð)ò 	ØŠNð	ús   ‚:= ½AÁAc                ót  — |xs | j                  |j                  «      }t        j                  ||¬«      }t	        || j
                  j                  «      }|| j                  |<   |j                  rG|j                  s:|j                  D ]*  }|| j                  | j                  |j                  «      <   Œ, yyy)züSave a response to the cache

        Args:
            cache_key: Cache key for this response; will otherwise be generated based on request
            response: Response to save
            expires: Absolute expiration time for this response
        )ÚexpiresN)r   Úrequestr   Úfrom_responser   r'   Úignored_parametersr%   ÚhistoryÚrevalidatedr&   )r(   r7   Ú	cache_keyr:   Úcached_responseÚrs         r*   Úsave_responsezBaseCache.save_responseW   s¡   € ð ÒB §¡°×1AÑ1AÓ!Bˆ	Ü(×6Ñ6°xÈÔQˆÜ)¨/¸4¿>¹>×;\Ñ;\Ó]ˆØ$3ˆ�‰�yÑ!ð ×Ò O×$?Ò$?Ø×%Ñ%ò G�Ø=F�—‘˜tŸ™¨q¯y©yÓ9Ò:ñGð %@Ðr,   c                ó–   — t         j                  d«       | j                  j                  «        | j                  j                  «        y)zDelete all items from the cachez!Clearing all items from the cacheN)ÚloggerÚinfor%   Úclearr&   r/   s    r*   rG   zBaseCache.clearn   s/   € ä�‰Ð7Ô8Ø�‰×ÑÔØ�‰×ÑÕr,   c                ó–   — t         j                  d«       | j                  j                  «        | j                  j                  «        y)ú"Close any open backend connectionszClosing backend connectionsN)rE   Údebugr%   Úcloser&   r/   s    r*   rK   zBaseCache.closet   s/   € ä�‰Ð2Ô3Ø�‰×ÑÔØ�‰×ÑÕr,   c           	     ó*  — | j                   j                  �| j                   j                  nt        } |d|| j                   j                  | j                   j                  |xs | j                   j
                  | j                  j                  dœ|¤ŽS )z3Create a normalized cache key from a request object)r;   r=   Úcontent_root_keyÚmatch_headersÚ
serializer© )r'   Úkey_fnr   r=   rM   rN   r%   rO   )r(   r;   rN   r)   rQ   s        r*   r   zBaseCache.create_keyz   s}   € ð +/¯.©.×*?Ñ*?Ð*K�—‘×&Ò&ÔQ[ˆÙð 
ØØ#Ÿ~™~×@Ñ@Ø!Ÿ^™^×<Ñ<Ø'ÒG¨4¯>©>×+GÑ+GØ—~‘~×0Ñ0ñ
ð ñ
ð 	
r,   Tc                óˆ   — |rt        d|«      }|r|s| j                  ||¬«      }|| j                  v xs || j                  v S )ac  Check if the specified request is cached

        Args:
            key: Check for a specific cache key
            request: Check for a matching request, according to current request matching settings
            url: Check for a matching GET request with the specified URL
            verify: Check for requests with or without SSL verification
        ÚGET©Úverify)r   r   r%   r&   )r(   r5   r;   ÚurlrU   s        r*   ÚcontainszBaseCache.containsŽ   sG   € ñ Ü˜e SÓ)ˆGÙ™3Ø—/‘/ '°&�/Ó9ˆCØ�d—n‘nÐ$Ò=¨¨t¯~©~Ð(=Ð=r,   F)ÚexpiredÚinvalidÚ
older_thanÚrequestsÚurlsrU   c               óX  — |rt        |«      ng }|r8t        |xs g «      |D �	cg c]  }	t        d|	«      j                  «       ‘Œ c}	z   }|r$||D �
cg c]  }
| j                  |
|¬«      ‘Œ c}
z  }| j	                  d|||¬«      D ]  }|j                  |j                  «       Œ t        j                  dt        |«      › d�«       t        |«      dk(  r	 | j                  |d   = n| j                  j                  |«       | j                  «        y	c c}	w c c}
w # t        $ r Y Œ&w xY w)
a‡  Remove responses from the cache according one or more conditions.

        Args:
            keys: Remove responses with these cache keys
            expired: Remove all expired responses
            invalid: Remove all invalid responses (that can't be deserialized with current settings)
            older_than: Remove responses older than this value, relative to ``response.created_at``
            requests: Remove matching responses, according to current request matching settings
            urls: Remove matching GET requests for the specified URL(s)
            verify: Set to ``False`` to remove responses without SSL verification
        rS   rT   F)ÚvalidrX   rY   rZ   zDeleting up to z
 responsesé   r   N)Úlistr   Úpreparer   ÚfilterÚappendr@   rE   rJ   Úlenr%   r4   Úbulk_deleteÚ_prune_redirects)r(   rX   rY   rZ   r[   r\   rU   ÚkeysÚdelete_keysrV   r;   r7   s               r*   ÚdeletezBaseCache.delete£   s"  € ñ* 04¤ d¤¸ˆÙÜ˜HšN¨Ó+ÐX\Ö.]ÐQT¬w°u¸cÓ/B×/JÑ/JÕ/LÒ.]Ñ]ˆHÙØÐS[Ö\È˜DŸO™O¨G¸F˜OÕCÒ\Ñ\ˆKàŸ™Ø °'Àjð $ó 
ò 	3ˆHð ×Ñ˜x×1Ñ1Õ2ð	3ô
 	�‰�¤s¨;Ó'7Ð&8¸
ÐCÔDäˆ{Ó˜qÒ ðØ—N‘N ;¨q¡>Ñ2ð �N‰N×&Ñ& {Ô3Ø×ÑÕùò% /^ùâ\øô ò Ùðús   ¤!DÁDÃD Ä	D)Ä(D)c                ó¼   — | j                   j                  «       D ��cg c]  \  }}|| j                  vsŒ|‘Œ }}}| j                   j                  |«       yc c}}w )zARemove any redirects that no longer point to an existing responseN)r&   Úitemsr%   re   )r(   ÚkÚvÚinvalid_redirectss       r*   rf   zBaseCache._prune_redirectsÎ   sK   € à+/¯>©>×+?Ñ+?Ó+A×]¡4 1 aÀQÈdÏnÉnÒE\šQÐ]ÐÑ]Ø�‰×"Ñ"Ð#4Õ5ùó ^s
   žAµAc              #  ó4  K  — t        ||||g«      sy| j                  j                  «       D ]g  }| j                  |«      }|r|€t	        d¬«      }||_        |–— Œ0|€Œ3|r|j                  r#|r|j                  s|sŒR|j                  |«      sŒd|–— Œi y­w)aÔ  Get responses from the cache, with optional filters for which responses to include:

        Args:
            valid: Include valid and unexpired responses; set to ``False`` to get **only**
                expired/invalid/old responses
            expired: Include expired responses
            invalid: Include invalid responses (as an empty ``CachedResponse``)
            older_than: Get responses older than this value, relative to ``response.created_at``
        Niø  )Ústatus_code)Úanyr%   rg   r8   r   r@   Ú
is_expiredÚis_older_than)r(   r^   rX   rY   rZ   r5   r7   s          r*   rb   zBaseCache.filterÓ   sš   è ø€ ô  �E˜7 G¨ZÐ8Ô9ØØ—>‘>×&Ñ&Ó(ò 	ˆCØ×(Ñ(¨Ó-ˆHñ ˜8Ð+Ü)°cÔ:�Ø%(�Ô"Ø“ØÑ%Ù˜x×2Ò2Ù × 3Ò 3Ú 8×#9Ñ#9¸*Õ#Eà“ñ	ùs   ‚ABÁ BÁ?BÂBc                ón  — t         j                  d«       t        | j                  j	                  «       «      }|D ]x  }| j                  |   }|j
                  j                  dk(  rd|j
                  _        | j                  |j
                  «      }||k7  sŒ]|| j                  |<   | j                  |= Œz y)z7Recreate cache keys for all previously cached responseszRecreating all cache keyss   Noner,   N)rE   rJ   r`   r%   rg   r;   Úbodyr   )r(   Úold_keysÚold_cache_keyr7   Únew_cache_keys        r*   Úrecreate_keyszBaseCache.recreate_keysô   s›   € ä�‰Ð0Ô1Ü˜Ÿ™×+Ñ+Ó-Ó.ˆà%ò 	2ˆMØ—~‘~ mÑ4ˆHà×Ñ×$Ñ$¨Ò/Ø(+�× Ñ Ô%Ø ŸO™O¨H×,<Ñ,<Ó=ˆMØ Ó-Ø08�—‘˜}Ñ-Ø—N‘N =Ñ1ñ	2r,   c                ót   — t        dt        d¬«       |r| j                  |«       | j                  dd¬«       y )NzQremove_expired_responses() is deprecated; please use delete(expired=True) insteadr   )Ú
stacklevelT)rX   rY   )r   ÚDeprecationWarningÚreset_expirationri   )r(   Úexpire_afters     r*   Úremove_expired_responsesz"BaseCache.remove_expired_responses  s6   € ÜØ_ÜØõ	
ñ
 Ø×!Ñ! ,Ô/Ø�‰˜D¨$ˆÕ/r,   c                ó²   — t         j                  d|› �«       | j                  «       D ],  }|j                  |«       || j                  |j
                  <   Œ. y)z¢Set a new expiration value to set on existing cache items

        Args:
            expire_after: New expiration value, **relative to the current time**
        zResetting expiration with: N)rE   rF   rb   r}   r%   r@   )r(   r~   r7   s      r*   r}   zBaseCache.reset_expiration  sO   € ô 	�‰Ð1°,°Ð@ÔAØŸ™›ò 	:ˆHØ×%Ñ% lÔ3Ø19ˆD�N‰N˜8×-Ñ-Ò.ñ	:r,   c           
     ó  — t         j                  dt        |j                  «      › dt	        |«      › dt	        | «      › �«       | j                  j                  |j                  «       | j                  j                  |j                  «       y)z4Update this cache with the contents of another cachezCopying z responses from z to N)rE   rJ   rd   r%   ÚreprÚupdater&   )r(   Úothers     r*   rƒ   zBaseCache.update  se   € ä�‰�x¤ E§O¡OÓ 4Ð5Ð5EÄdÈ5ÃkÀ]ÐRVÔW[Ð\`ÓWaÐVbÐcÔdØ�‰×Ñ˜eŸo™oÔ.Ø�‰×Ñ˜eŸo™oÕ.r,   c                ór   — t         | j                  di |¤ŽD �ch c]  }|j                  ’Œ c}«      S c c}w )zVGet all unique cached URLs. Optionally takes keyword arguments for :py:meth:`.filter`.rP   )Úsortedrb   rV   )r(   r)   r7   s      r*   r\   zBaseCache.urls   s-   € ä°K°D·K±KÑ4IÀ&Ñ4IÖJ¨�x—|“|ÒJÓKÐKùÒJs   š4c                óP   — d| j                   j                  › d| j                  › d�S )Nú<z(name=z)>)Ú	__class__Ú__name__r#   r/   s    r*   Ú__str__zBaseCache.__str__$  s'   € Ø�4—>‘>×*Ñ*Ð+¨6°$·/±/Ð1BÀ"ÐEÐEr,   c                ó   — t        | «      S r"   )Ústrr/   s    r*   Ú__repr__zBaseCache.__repr__'  s   € Ü�4‹yÐr,   )r#   r�   )ÚreturnzUnion[str, Path]r"   )r5   r�   r�   zOptional[CachedResponse])NN)r7   r   r@   úOptional[str]r:   zOptional[datetime])r;   r   rN   úOptional[Iterable[str]]r�   r�   )NNNT)r5   r�   r;   zOptional[AnyRequest]rV   r�   rU   Úbool)rg   r�   rX   r’   rY   r’   rZ   r   r[   zOptional[Iterable[AnyRequest]]r\   r‘   rU   r’   )TTFN)
r^   r’   rX   r’   rY   r’   rZ   r   r�   zIterator[CachedResponse])r~   r   )r„   z'BaseCache')r�   z	List[str])rŠ   Ú
__module__Ú__qualname__Ú__doc__r   r+   Úpropertyr0   r8   rC   rG   rK   r   rW   ri   rf   rb   ry   r   r}   rƒ   r\   r‹   rŽ   rP   r,   r*   r    r    !   sŒ  „ ñð( *<ô )ð ò"ó ð"ôð$ $(Ø&*ð	GàðGð !ðGð $ó	Gò.òð 26ð
àð
ð /ð
ð
 
ó
ð, "Ø(,Ø!Øð>àð>ð &ð>ð ð	>ð
 ó>ð0 ØØ%)Ø37Ø(,Øñ) àð) ð ð) ð ð	) ð
 #ð) ð 1ð) ð &ð) ð ó) òV6ð ØØØ%)ðàðð ðð ð	ð
 #ðð 
"óòB2ô"0ô	:ó/óLòFór,   r    ÚKTÚVTc                  óH   — e Zd ZdZ	 	 d		 	 	 d
d„Zdd„Zd„ Zdd„Zdd„Zd„ Z	y)ÚBaseStorageaé  Base class for client-agnostic storage implementations. Notes:

    * This provides a common dictionary-like interface for the underlying storage operations
      (create, read, update, delete).
    * One ``BaseStorage`` instance corresponds to a single table/hash/collection, or whatever the
      backend-specific equivalent may be.
    * ``BaseStorage`` subclasses contain no behavior specific to ``requests``, which are handled by
      :py:class:`.BaseCache` subclasses.
    * ``BaseStorage`` also contains a serializer object (defaulting to :py:mod:`pickle`), which
      determines how :py:class:`.CachedResponse` objects are saved internally. See :ref:`serializers`
      for details.

    Args:
        serializer: Custom serializer that provides ``loads`` and ``dumps`` methods.
            If not provided, values will be written as-is.
        decode_content: Decode response body JSON or text into a human-readable format
        kwargs: Additional backend-specific keyword arguments
    Nc                ó–   — t        ||«      | _        t        j                  dt	        | «      j
                  › d| j                  › �«       y )NzInitialized z with serializer: )r   rO   rE   rJ   ÚtyperŠ   )r(   rO   Údecode_contentr)   s       r*   r+   zBaseStorage.__init__C  s<   € ô *¨*°nÓEˆŒÜ�‰�|¤D¨£J×$7Ñ$7Ð#8Ð8JÈ4Ï?É?ÐJ[Ð\Õ]r,   c                ó8   — |D ]  }	 | |= Œ y# t         $ r Y Œw xY w)zóDelete multiple keys from the cache, without raising errors for missing keys.

        This is a naive, generic implementation that subclasses should override with a more
        efficient backend-specific implementation, if possible.
        N)r4   )r(   rg   rl   s      r*   re   zBaseStorage.bulk_deleteL  s3   € ð ò 	ˆAðØ˜‘Gñ	øô ò Ùðús   ‡�	˜c                 ó   — y)rI   NrP   r/   s    r*   rK   zBaseStorage.closeX  s   � r,   c                ó�   — t         rt        | j                  d«      sJ ‚| j                  r| j                  j                  |«      S |S )z/Serialize a value, if a serializer is availableÚdumps)r	   ÚhasattrrO   r¡   )r(   Úvalues     r*   Ú	serializezBaseStorage.serialize[  s9   € åÜ˜4Ÿ?™?¨GÔ4Ð4Ð4Ø/3¯ªˆt�‰×$Ñ$ UÓ+ÐIÀEÐIr,   c                ób  — | j                   s|S t        rt        | j                   d«      sJ ‚	 | j                   j                  |«      }	 ||_        |S # t
        $ r Y |S w xY w# t        $ rB}t        j                  dt        |«      › �«       t        j                  |d¬«       Y d}~yd}~ww xY w)zÃDeserialize a value, if a serializer is available.

        If deserialization fails (usually due to a value saved in an older requests-cache version),
        ``None`` will be returned.
        Úloadsz Unable to deserialize response: T)Úexc_infoN)rO   r	   r¢   r¦   r@   r3   ÚDESERIALIZE_ERRORSrE   Úerrorr�   rJ   )r(   r5   r£   ÚobjÚes        r*   ÚdeserializezBaseStorage.deserializea  s¨   € ð �ŠØˆLÝÜ˜4Ÿ?™?¨GÔ4Ð4Ð4ð	Ø—/‘/×'Ñ'¨Ó.ˆCðØ #�”ð ˆJøô "ò ØØˆJðûô "ò 	Ü�L‰LÐ;¼CÀ»F¸8ÐDÔEÜ�L‰L˜ TˆLÔ*Üûð	ús;   ®A# Á
A ÁA# Á	A ÁA# ÁA Á A# Á#	B.Á,8B)Â)B.c                óF   — t        t        | j                  «       «      «      S r"   )r�   r`   rg   r/   s    r*   r‹   zBaseStorage.__str__y  s   € Ü”4˜Ÿ	™	›Ó$Ó%Ð%r,   )NF)rO   zOptional[SerializerType]r�   r’   )rg   zIterable[KT])r£   r˜   )
rŠ   r“   r”   r•   r+   re   rK   r¤   r¬   r‹   rP   r,   r*   rš   rš   /  sC   „ ñð* 04Ø$ð^à,ð^ð ó^ó
ò1óJóó0&r,   rš   c                  ó,   ‡ — e Zd ZdZˆ fd„Zˆ fd„Zˆ xZS )r$   a7  A basic dict wrapper class for non-persistent, in-memory storage

    .. note::
        This is mostly a placeholder for when no other backends are available. For in-memory
        caching, either :py:class:`.SQLiteCache` (with `use_memory=True`) or :py:class:`.RedisCache`
        is recommended instead.

    c                ó2   •— t        ‰| �  |i |¤Ž d | _        y r"   )Úsuperr+   rO   )r(   Úargsr)   r‰   s      €r*   r+   zDictStorage.__init__‡  s   ø€ Ü‰Ñ˜$Ð) &Ò)Øˆ�r,   c                ó¤   •— t         ‰| �  |«      }t        |dd«      r|j                  j	                  «        	 ||_        |S # t        $ r Y |S w xY w)a  An additional step is needed here for response data. The original response object
        is still in memory, and hasn't gone through a serialize/deserialize loop. So, the file-like
        response body has already been read, and needs to be reset.
        ÚrawN)r°   Ú__getitem__Úgetattrr³   Úresetr@   r3   )r(   r5   Úitemr‰   s      €r*   r´   zDictStorage.__getitem__‹  sZ   ø€ ô
 ‰wÑ" 3Ó'ˆÜ�4˜ Ô%Ø�H‰H�N‰NÔð	Ø ˆDŒNð ˆøô ò 	ØØˆð	ús   ¹A Á	AÁA)rŠ   r“   r”   r•   r+   r´   Ú__classcell__)r‰   s   @r*   r$   r$   }  s   ø„ ñô÷ð r,   r$   N)5r•   Ú
__future__r   Úabcr   Úcollectionsr   r   Úloggingr   Úpickler   Útypingr	   r
   r   r   r   r   r   r   Úwarningsr   Úpathlibr   r[   r   r   Ú
cache_keysr   r   Úmodelsr   r   Úpolicyr   r   r   Úserializersr   r   r3   ÚImportErrorÚ	TypeErrorÚ
ValueErrorr¨   rŠ   rE   r    r—   r˜   rš   r$   rP   r,   r*   ú<module>rÈ      s¥   ðñõ #å Ý  Ý Ý Ý ß d× dÓ dÝ å ç &ç 4ß /ß FÑ Fß 9ð % k°;À	È:ÐVÐ á	�8Ó	€÷Gñ GñT ˆTƒ]€ÙˆTƒ]€ôK&�.  R Ñ(¨#ô K&ô\�(˜Kõ r,   