o
    KDiF                     @  s   d dl mZ d dlZd dlZd dlmZmZ d dl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mZmZ G d
d deeeeZedde	dddG dd deZdS )    )annotationsN)ABCabstractmethod)versionaddedversionchanged)MongoClientMongoCollectionMongoDatabasecast   )get_dependency   )MovingWindowSupportSlidingWindowCounterSupportStoragec                      s  e Zd ZdZdgZ				dIdJ fddZedKddZedLddZedMddZ	edMddZ
edNd d!ZedOd#d$ZdPd%d&ZdQd(d)ZdRd+d,ZdSd.d/ZdTd1d2ZdUdVd6d7ZdWd8d9ZdXd<d=ZdUdYd>d?ZdZdAdBZ	3dUdYdCdDZd[dEdFZdPdGdHZ  ZS )\MongoDBStorageBasezV
    Rate limit storage with MongoDB as backend.

    Depends on :pypi:`pymongo`.
    pymongolimitscounterswindowsFuristrdatabase_namecounter_collection_namewindow_collection_namewrap_exceptionsbooloptionsint | str | boolreturnNonec                   s\   t  j|fd|i| || _||d| _| jd j| _td\| _}|| _	|| _
d| _dS )ai  
        :param uri: uri of the form ``mongodb://[user:password]@host:port?...``,
         This uri is passed directly to :class:`~pymongo.mongo_client.MongoClient`
        :param database_name: The database to use for storing the rate limit
         collections.
        :param counter_collection_name: The collection name to use for individual counters
         used in fixed window strategies
        :param window_collection_name: The collection name to use for sliding & moving window
         storage
        :param wrap_exceptions: Whether to wrap storage exceptions in
         :exc:`limits.errors.StorageError` before raising it.
        :param options: all remaining keyword arguments are passed to the
         constructor of :class:`~pymongo.mongo_client.MongoClient`
        :raise ConfigurationError: when the :pypi:`pymongo` library is not available
        r   )r   r   r   zpymongo.errorsN)super__init___database_name_collection_mappingdependenciesmodulelibr   
lib_errors_storage_uri_storage_options_storage)selfr   r   r   r   r   r   _	__class__ O/var/www/Datamplify/venv/lib/python3.10/site-packages/limits/storage/mongodb.pyr"      s   
zMongoDBStorageBase.__init__r   c                 C  s0   | j d u r| j| jfi | j| _ |   | j S N)r+   _init_mongo_clientr)   r*   (_MongoDBStorageBase__initialize_databaser,   r0   r0   r1   storageD   s   
zMongoDBStorageBase.storager	   c                 C  s   | j | j S r2   )r6   r#   r5   r0   r0   r1   	_databaseM   s   zMongoDBStorageBase._databaser   c                 C     | j | jd  S )Nr   r7   r$   r5   r0   r0   r1   r   Q      zMongoDBStorageBase.countersc                 C  r8   )Nr   r9   r5   r0   r0   r1   r   U   r:   zMongoDBStorageBase.windows
str | Nonec                 K  s   t  r2   )NotImplementedErrorr,   r   r   r0   r0   r1   r3   Y   s   z%MongoDBStorageBase._init_mongo_client-type[Exception] | tuple[type[Exception], ...]c                 C  s   | j jS r2   )r(   PyMongoErrorr5   r0   r0   r1   base_exceptions_   s   z"MongoDBStorageBase.base_exceptionsc                 C  s$   | j jddd | jjddd d S )NexpireAtr   )expireAfterSeconds)r   create_indexr   r5   r0   r0   r1   __initialize_databasee   s   z(MongoDBStorageBase.__initialize_database
int | Nonec                 C  s4   | j i | ji  }| j   | j  t|S )z^
        Delete all rate limit keys in the rate limit collections (counters, windows)
        )r   count_documentsr   dropint)r,   num_keysr0   r0   r1   reseti   s   

zMongoDBStorageBase.resetkeyc                 C  s$   | j d|i | jd|i dS )z>
        :param key: the key to clear rate limits for
        _idN)r   find_one_and_deleter   )r,   rK   r0   r0   r1   clears   s   zMongoDBStorageBase.clearfloatc                 C  s6   | j d|i}|r|d ntj jtjjd S )z;
        :param key: the key to get the expiry for
        rL   rA   tzinfo)r   find_onedatetimenowreplacetimezoneutc	timestampr,   rK   counterr0   r0   r1   
get_expiryz   s   zMongoDBStorageBase.get_expiryrH   c                 C  s8   | j j|dtjtjjiddgd}|r|d pdS )zB
        :param key: the key to get the counter value for
        $gte)rL   rA   count)
projectionr   )r   rR   rS   rT   rV   rW   rY   r0   r0   r1   get   s   zMongoDBStorageBase.getr   expiryamountc              
   C  s   t j t jjt j|d }t| jjd|idddddgi|dd	|gid
iddddgi|dd
idigddg| jj	j
dd S )z
        increments the counter for a given rate limit key

        :param key: the key to increment
        :param expiry: amount in seconds for the key to expire in
        :param amount: the number to increment by
        secondsrL   $set$condz$lt	$expireAt$$NOW$addz$countifthenelse)r]   rA   Tr]   )upsertr^   return_document)rS   rT   rV   rW   	timedeltarH   r   find_one_and_updater'   ReturnDocumentAFTER)r,   rK   r`   ra   
expirationr0   r0   r1   incr   s:   


zMongoDBStorageBase.incrc                 C  s   z| j   W dS    Y dS )zm
        Check if storage is healthy by calling :meth:`pymongo.mongo_client.MongoClient.server_info`
        TF)r6   server_infor5   r0   r0   r1   check   s
   
zMongoDBStorageBase.checklimittuple[float, int]c                 C  s|   t   }t| jdd|iiddddddd	|| gid
iiidddiddidig }r:|d d |d d fS |dfS )z
        returns the starting point and the number of entries in the moving
        window

        :param key: rate limit key
        :param expiry: expiry of entry
        :return: (start of window, number of acquired entries)
        z$matchrL   z$projectfilteredEntriesz$filterz$entriesentryr\   z$$entry)inputascondz$minz$filteredEntriesz$size)minr]   r   r~   r]   )timelistr   	aggregate)r,   rK   rw   r`   rX   resultr0   r0   r1   get_moving_window   s0   	
z$MongoDBStorageBase.get_moving_windowc                 C  s   ||krdS t   }z7d|g| d|didtjtjjtj|d id}| jjd|d	||  d
d|| iii|dd W dS  | jj	j
yN   Y dS w )z
        :param key: rate limit key to acquire an entry in
        :param limit: amount of entries allowed
        :param expiry: expiry of the entry
        :param amount: the number of entries to acquire
        Fentriesr   )z$eachz	$positionz$slicerA   rb   )z$pushrd   rL   zentries.z$notr\   T)rm   )r   rS   rT   rV   rW   ro   r   
update_oner'   errorsDuplicateKeyError)r,   rK   rw   r`   ra   rX   updatesr0   r0   r1   acquire_entry   s8   
	z MongoDBStorageBase.acquire_entrytuple[int, float, int, float]c              
   C  s  |d }| j jd|iddddddgi|gid	d
dgid	ddgididddddgi|gidd	d
dgididddddgi|gidd|giddidig| jjjg dd }r|dri|d jtjj	d
 nt }td|t  }td|d r|| nd}|d ||d |fS dS )N  rL   rd   re   $lte	$subtractrf   rg   $ifNull$currentCountr   $previousCountri   rh   )previousCountcurrentCountrA   )r   r   rA   )rn   r^   rA   rP   r   r   )r           r   r   )r   rp   r'   rq   rr   r_   rU   rS   rV   rW   rX   r   max)r,   rK   r`   	expiry_msr   
expires_atcurrent_ttlprev_ttlr0   r0   r1   get_sliding_window  sj   





,
3z%MongoDBStorageBase.get_sliding_windowc                 C  sl  |d }| j jd|iddddddd	gi|gid
ddgid
ddgidiiidddddd	gi|gidd
ddgididdddd	gi|giddddgidd|gidd	d| gididdididdddddddddddd	|gigigi|gigidgiiiidddddd|gi|gidd|giddiiiddddd|gi|giiiddgig| jjjdd}tt|d S )Nr   rL   rd   r   re   r   r   rf   rg   r   r   r   r   ri   z$gtrh   r   )r   rA   curWeightedCountz$floorz	$multiplyz$dividez$maxr   z$curWeightedCount	_acquiredz$unsetT)rn   rm   )r   rp   r'   rq   rr   r
   r   )r,   rK   rw   r`   ra   r   r   r0   r0   r1   acquire_sliding_window_entry]  s   







#&

qvz/MongoDBStorageBase.acquire_sliding_window_entryc                 C  s
   |  |S r2   )rN   )r,   rK   r`   r0   r0   r1   clear_sliding_window  s   
z'MongoDBStorageBase.clear_sliding_windowc                 C  s   | j r
| j   d S d S r2   )r6   closer5   r0   r0   r1   __del__  s   zMongoDBStorageBase.__del__)r   r   r   F)r   r   r   r   r   r   r   r   r   r   r   r   r   r    )r   r   )r   r	   )r   r   r   r;   r   r   r   r   )r   r>   )r   r    )r   rE   )rK   r   r   r    )rK   r   r   rO   )rK   r   r   rH   )r   )rK   r   r`   rH   ra   rH   r   rH   )r   r   )rK   r   rw   rH   r`   rH   r   rx   )
rK   r   rw   rH   r`   rH   ra   rH   r   r   )rK   r   r`   rH   r   r   )rK   r   r`   rH   r   r    )__name__
__module____qualname____doc__DEPENDENCIESr"   propertyr6   r7   r   r   r   r3   r@   r4   rJ   rN   r[   r_   rt   rv   r   r   r   r   r   r   __classcell__r0   r0   r.   r1   r      sD    %






)
%
,F
|r   z2.1)versionz3.14.0zEAdded option to select custom collection names for windows & counters)r   reasonc                   @  s   e Zd ZddgZdd	d
ZdS )MongoDBStoragemongodbzmongodb+srvr   r;   r   r   r   r   c                 K  s   t t| jj|fi |S r2   )r
   r   r'   r=   r0   r0   r1   r3     s   z!MongoDBStorage._init_mongo_clientNr   )r   r   r   STORAGE_SCHEMEr3   r0   r0   r0   r1   r     s    r   )
__future__r   rS   r   abcr   r   deprecated.sphinxr   r   limits.typingr   r   r	   r
   utilr   baser   r   r   r   r   r0   r0   r0   r1   <module>   s(    
   P