
    5j4K              	          S SK Jr  S SKrS SKrS SKrS SKJrJr  S SKJ	r	J
r
Jr  S SKJrJrJr  S SKJr  \" S5      r\" S5      r\" S	S
9\" SSS9 " S S\\	\
5      5       5       rg)    )annotationsN)versionaddedversionchanged)MovingWindowSupportSlidingWindowCounterSupportStorage)	ParamSpecTypeVarcast)get_dependencyPRz2.1)versionz3.14.0zEAdded option to select custom collection names for windows & counters)r   reasonc                  b  ^  \ rS rSrSrSS/r SS/r    S             SU 4S jjjr\  SS j5       r	\S	 5       r
SS
 jrSS jrSS jrSS jrSS jrS S!S jjrS"S jr        S#S jr S          S$S jjr S          S$S jjr      S%S jrS&S jrSS jrSrU =r$ )'MongoDBStorage   zG
Rate limit storage with MongoDB as backend.

Depends on :pypi:`motor`
async+mongodbzasync+mongodb+srvmotor.motor_asynciopymongoc                  > UR                  SSS5      n[        TU ]  " U4SU0UD6  U R                  S   U l        U R                  S   U l        [        S5      u  U l        nU R                  R                  R                  " U40 UD6U l
        [        R                  U R                  l        X l        UUS.U l        S	U l        g
)a  
:param uri: uri of the form ``async+mongodb://[user:password]@host:port?...``,
 This uri is passed directly to :class:`~motor.motor_asyncio.AsyncIOMotorClient`
: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:`~motor.motor_asyncio.AsyncIOMotorClient`
:raise ConfigurationError: when the :pypi:`motor` or :pypi:`pymongo` are
 not available
r   mongodb   wrap_exceptionsr   r   zpymongo.errors)counterswindowsFN)replacesuper__init__dependencies
dependencyproxy_dependencyr   
lib_errorsmoduleAsyncIOMotorClientstorageasyncioget_running_loopget_io_loop_MongoDBStorage__database_name#_MongoDBStorage__collection_mapping _MongoDBStorage__indices_created)	selfuridatabase_namecounter_collection_namewindow_collection_namer   options_	__class__s	           Y/root/lseg-credit/backend/venv/lib/python3.13/site-packages/limits/aio/storage/mongodb.pyr   MongoDBStorage.__init__,   s    4 kk/9a8IoII++,AB $ 1 1) <+,<=--@@PP $+#;#; ,/-%
! "'    c                .    U R                   R                  $ N)r#   PyMongoErrorr-   s    r5   base_exceptionsMongoDBStorage.base_exceptions[   s     +++r7   c                L    U R                   R                  U R                  5      $ r9   )r&   get_databaser*   r;   s    r5   databaseMongoDBStorage.databasea   s    ||(()=)=>>r7   c                  #    U R                   (       do  [        R                  " U R                  U R                  S      R                  SSS9U R                  U R                  S      R                  SSS95      I S h  vN   SU l         g  N7f)Nr   expireAtr   )expireAfterSecondsr   T)r,   r'   gatherr@   r+   create_indexr;   s    r5   create_indicesMongoDBStorage.create_indicese   s     %%..d77
CDQQ1 R  d77	BCPP1 Q 	   "&s   A<B>B?Bc                  #    [        [        R                  " U R                  U R                  S      R                  0 5      U R                  U R                  S      R                  0 5      5      I Sh  vN 5      n[        R                  " U R                  U R                  S      R                  5       U R                  U R                  S      R                  5       5      I Sh  vN   [        [        U5      $  N N7f)zN
Delete all rate limit keys in the rate limit collections (counters, windows)
r   r   N)	sumr'   rE   r@   r+   count_documentsdropr   int)r-   num_keyss     r5   resetMongoDBStorage.resetq   s      ..d77
CDTT d77	BCSSTVW	 
 nnMM$33J?@EEGMM$33I>?DDF
 	
 	

 C""	
s%   A2D 4C<5A2D 'C>(D >D c                   #    [         R                  " U R                  U R                  S      R	                  SU05      U R                  U R                  S      R	                  SU05      5      I Sh  vN   g N7f)z.
:param key: the key to clear rate limits for
r   _idr   N)r'   rE   r@   r+   find_one_and_delete)r-   keys     r5   clearMongoDBStorage.clear   sq      nnMM$33J?@TT MM$33I>?SS	
 	
 	
s   A1A;3A94A;c                2  #    U R                   U R                  S      R                  SU05      I Sh  vN nU(       a  US   O[        R                  R	                  5       R                  [        R                  R                  S9R                  5       $  Na7f)z+
:param key: the key to get the expiry for
r   rR   NrC   tzinfo)	r@   r+   find_onedatetimenowr   timezoneutc	timestampr-   rT   counters      r5   
get_expiryMongoDBStorage.get_expiry   s}      d&?&?
&KLUUCL
 
 %,WZ 1B1B1F1F1HWH--11W2Y[	

s   1BBA"Bc                  #    U R                   U R                  S      R                  US[        R                  R	                  [        R
                  R                  5      0S.S/S9I Sh  vN nU=(       a    US   =(       d    S$  N7f)z2
:param key: the key to get the counter value for
r   $gte)rR   rC   count)
projectionNr   )r@   r+   rZ   r[   r\   r]   r^   r`   s      r5   getMongoDBStorage.get   s      d&?&?
&KLUU#X%6%6%:%:8;L;L;P;P%QR  y V 
 
 +77+0q0
s   A)B	+B,B	c           
       #    U R                  5       I Sh  vN   [        R                  R                  [        R                  R                  5      [        R
                  " US9-   nU R                  U R                  S      R                  SU0SSSSS	/0US
SU/0S.0SSSS	/0USS.0S.0/SS/U R                  R                  R                  R                  S9I Sh  vN n[        US   5      $  N N7f)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
Nsecondsr   rR   $set$condz$lt	$expireAt$$NOW$addz$countifthenelse)rf   rC   Trf   )upsertrg   return_document)rG   r[   r\   r]   r^   	timedeltar@   r+   find_one_and_updater"   r$   ReturnDocumentAFTERrM   )r-   rT   expiryamount
expirationresponses         r5   incrMongoDBStorage.incr   s-     !!###&&**8+<+<+@+@AHDVDVE
 

 %%j1


CL #',{G.D&E(.)/(F1C(D&" $',{G.D&E(2(3&%( y 1188GGMM1  

: 8G$%%G 	$
s"   C7C3C	C7 C5!C75C7c                d   #     U R                   R                  5       I Sh  vN   g N!    g= f7f)zc
Check if storage is healthy by calling
:meth:`motor.motor_asyncio.AsyncIOMotorClient.server_info`
NTF)r&   server_infor;   s    r5   checkMongoDBStorage.check   s1     
	,,**,,, -	s    0) ') 0) -0c                .  #    [         R                   " 5       nU R                  U R                  S      R                  SSU00SSSSSS	S
XC-
  /0S.000SSS0SS0S.0/5      R	                  SS9I Sh  vN =n(       a  US   S   US   S   4$ US4$  N7f)z
returns the starting point and the number of entries in the moving
window

:param str key: rate limit key
:param int expiry: expiry of entry
:return: (start of window, number of acquired entries)
r   z$matchrR   z$projectfilteredEntriesz$filterz$entriesentryre   z$$entry)inputascondz$minz$filteredEntriesz$size)minrf   r   )lengthNr   r   rf   )timer@   r+   	aggregateto_list)r-   rT   limitr|   r_   results         r5   get_moving_window MongoDBStorage.get_moving_window   s      IIK	 MM$*C*CI*NOYs|,"- )-7*1-3iAS5T,U,"0%
 #$*,>#?&-/A%B%, WAW/ F 2 !9U#VAYw%777!|5s   A1B3B4 Bc           	       #    U R                  5       I Sh  vN   XB:  a  g[        R                  " 5       n SU/U-  SUS.0S[        R                  R                  [        R                  R
                  5      [        R                  " US9-   0S.nU R                  U R                  S	      R                  S
USX$-
   3SSXS-
  000USS9I Sh  vN   g N N! U R                  R                  R                  R                   a     gf = f7f)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
NFentriesr   )z$eachz	$positionz$slicerC   rk   )z$pushrm   r   rR   zentries.z$notre   T)rv   )rG   r   r[   r\   r]   r^   rx   r@   r+   
update_oner"   r$   errorsDuplicateKeyError)r-   rT   r   r|   r}   r_   updatess          r5   acquire_entryMongoDBStorage.acquire_entry  s4     !!###>IIK		 "+v!5%&"'   ))--h.?.?.C.CD",,V<= & -- 9 9) DEPP3u~./&69CU:V1W  Q    G 	$4 $$++22DD 		sE   DCDBC CC DC .D
D	D

Dc                j  #    U R                  5       I S h  vN   US-  nU R                  U R                  S      R                  SU0SSSSSS	S
/0U/0SSS/0SSS/0S.000SSSSS	S
/0U/0SSSS/0S.0SSSS	S
/0U/0SSS	S/0SS	U/0SS
SU-  /0S.0S	S.0S.0SSSSSSSSSSS	SS
U/0/0/0U/0/0S/0000SSSSSSU/0U/0SSU/0SS.000SSSSSU/0U/000SS/0/U R                  R
                  R                  R                  SS9I S h  vN n[        [        US   5      $  GN N7f)N  r   rR   rm   previousCountrn   $lte	$subtractro   rp   $ifNull$currentCountr   $previousCountrr   z$gtrq      )currentCountrC   curWeightedCountz$floorz	$multiplyz$dividez$maxr   z$curWeightedCount	_acquiredz$unsetT)rw   rv   )
rG   r@   r+   ry   r"   r$   rz   r{   r   bool)r-   rT   r   r|   r}   	expiry_msr   s          r5   acquire_sliding_window_entry+MongoDBStorage.acquire_sliding_window_entry?  s     !!###TM	}}%%i0


CL '#$*)4{G6L(M(1-&'" *3_a4H(I)25Eq4I(J	&*" #$*)4{G6L(M(1-&'" )*)2_a4H(I	&) $$*)4{G6L(M(1-&'" %,/4{A6F.G17+y9Q0R17'1y=9Q0R.&)" )4&%!F *$ &(3,<098><=@KDOHNLSLUQJEFNB
=>A:56  5>#<2-.6*%&4 %47)"' -"$L &#$*)/2Ev1N(O(--&'" *0/61J(K(7	&)" #"f/BF.K%Le$T& ./0_pb !1188GGMMi  u
w
r D&-..w 	$w
s"   D3D.C?D3D1D31D3c                  #    US-  nU R                   U R                  S      R                  SU0SSSSSS	/0U/0S
SS/0S
SS/0S.0SSSSS	/0U/0SS
SS/0S.0SSSSS	/0U/0SSU/0SS.0S.0/U R                  R                  R
                  R                  / SQS9I S h  vN =n(       a  UR                  S5      (       a8  US   R                  [        R                  R                  S9R                  5       O[        R                  " 5       n[        SU[        R                  " 5       -
  5      n[        SUS   (       a  Xb-
  OS5      nUS   UUS   U4$ g N7f)Nr   r   rR   rm   rn   r   r   ro   rp   r   r   r   r   rr   rq   )r   r   rC   )r   r   rC   )rw   rg   rC   rX   r   r   )r           r   r   )r@   r+   ry   r"   r$   rz   r{   rh   r   r[   r]   r^   r_   r   max)r-   rT   r|   r   r   
expires_atcurrent_ttlprev_ttls           r5   get_sliding_window!MongoDBStorage.get_sliding_window  s     TM	==%%i0


CL #$*)4{G6L(M(1-&'" *3_a4H(I)25Eq4I(J	&* $$*)4{G6L(M(1-&'" )*)2_a4H(I	&) $$*)4{G6L(M(1-&'" *0+y1I(J(3	&%3%')T !1188GGMMD[  .
0
 0
6 0
f ::j)) 
#++83D3D3H3H+ISSUYY[ 
 adiik!9:K1f_6Mk2STUH '~&	  0
s   B"E$E%B8Ec                @   #    U R                  U5      I S h  vN $  N7fr9   )rU   )r-   rT   r|   s      r5   clear_sliding_window#MongoDBStorage.clear_sliding_window  s     ZZ_$$$s   c                b    U R                   =(       a    U R                   R                  5         g   g r9   )r&   closer;   s    r5   __del__MongoDBStorage.__del__  s    -++--r7   )__collection_mapping__database_name__indices_createdr!   r#   r"   r&   )limitsr   r   F)r.   strr/   r   r0   r   r1   r   r   r   r2   zfloat | str | boolreturnNone)r   z-type[Exception] | tuple[type[Exception], ...])r   r   )r   z
int | None)rT   r   r   r   )rT   r   r   float)rT   r   r   rM   )r   )rT   r   r|   rM   r}   rM   r   rM   )r   r   )rT   r   r   rM   r|   rM   r   ztuple[float, int])
rT   r   r   rM   r|   rM   r}   rM   r   r   )rT   r   r|   rM   r   ztuple[int, float, int, float])rT   r   r|   rM   r   r   )__name__
__module____qualname____firstlineno____doc__STORAGE_SCHEMEDEPENDENCIESr   propertyr<   r@   rG   rO   rU   rb   rh   r   r   r   r   r   r   r   r   __static_attributes____classcell__)r4   s   @r5   r   r      s    &':;N *95L
 &'1&/ %-'-' -' "%	-'
 !$-' -' &-' 
-' -'^ ,	6, ,
 ? ?
&#&

1+&Z
(("(,/(	(V @A..".,/.9<.	.b @A~/~/"~/,/~/9<~/	~/@CC #C	&CJ%. .r7   r   )
__future__r   r'   r[   r   deprecated.sphinxr   r   limits.aio.storage.baser   r   r   limits.typingr	   r
   r   limits.utilr   r   r   r    r7   r5   <module>r      s{    "    : 
 
 'cNCL eRj.W13N j.	 
j.r7   