
    dh                         S r SSKrSSKJrJrJrJrJr  SSKJ	r	  SSK
Jr  \R                  " \5      r SSKJr   " S S\5      r " S	 S
\	5      rg! \ a    Sr N!f = f)z0Ratelimiting Handler to limit requests or tokens    N)AnyDictListLiteralOptional)BaseCallbackHandler)	LLMResult)	Ratelimitc            
       Z   ^  \ rS rSrSr  S
S\S\S   S\\   S\\	   4U 4S jjjr
S	rU =r$ )UpstashRatelimitError   z]
Upstash Ratelimit Error

Raised when the rate limit is reached in `UpstashRatelimitHandler`
messagetype)tokenrequestlimitresetc                 H   > [         TU ]  U5        X l        X0l        X@l        g)aZ  
Args:
    message (str): error message
    type (str): The kind of the limit which was reached. One of
        "token" or "request"
    limit (Optional[int]): The limit which was reached. Passed when type
        is request
    reset (Optional[int]): unix timestamp in milliseconds when the limits
        are reset. Passed when type is request
N)super__init__r   r   r   )selfr   r   r   r   	__class__s        p/var/www/html/shao/venv/lib/python3.13/site-packages/langchain_community/callbacks/upstash_ratelimit_callback.pyr   UpstashRatelimitError.__init__   s!    $ 	!	

    )r   r   r   )NN)__name__
__module____qualname____firstlineno____doc__strr   r   intfloatr   __static_attributes____classcell__)r   s   @r   r   r      sN      $!% () }	
  r   r   c            	           \ rS rSr% SrSr\\S'   Sr\\S'   SSSS.S	\	S
\
\   S\
\   S\4S jjrS\\	\4   S\\	\4   S\S\4S jrS\\	\4   S\\	   S\SS4S jrS\S\SS4S jrSS	\
\	   SS 4S jjrSrg)UpstashRatelimitHandler/   a  
Callback to handle rate limiting based on the number of requests
or the number of tokens in the input.

It uses Upstash Ratelimit to track the ratelimit which utilizes
Upstash Redis to track the state.

Should not be passed to the chain when initialising the chain.
This is because the handler has a state which should be fresh
every time invoke is called. Instead, initialise and pass a handler
every time you invoke.
Traise_errorF_checkedN)token_ratelimitrequest_ratelimitinclude_output_tokens
identifierr+   r,   r-   c                l    [        X#/5      (       d  [        S5      eXl        X l        X0l        X@l        g)a   
Creates UpstashRatelimitHandler. Must be passed an identifier to
ratelimit like a user id or an ip address.

Additionally, it must be passed at least one of token_ratelimit
or request_ratelimit parameters.

Args:
    identifier Union[int, str]: the identifier
    token_ratelimit Optional[Ratelimit]: Ratelimit to limit the
        number of tokens. Only works with OpenAI models since only
        these models provide the number of tokens as information
        in their output.
    request_ratelimit Optional[Ratelimit]: Ratelimit to limit the
        number of requests
    include_output_tokens bool: Whether to count output tokens when
        rate limiting based on number of tokens. Only used when
        `token_ratelimit` is passed. False by default.

Example:
    .. code-block:: python

        from upstash_redis import Redis
        from upstash_ratelimit import Ratelimit, FixedWindow

        redis = Redis.from_env()
        ratelimit = Ratelimit(
            redis=redis,
            # fixed window to allow 10 requests every 10 seconds:
            limiter=FixedWindow(max_requests=10, window=10),
        )

        user_id = "foo"
        handler = UpstashRatelimitHandler(
            identifier=user_id,
            request_ratelimit=ratelimit
        )

        # Initialize a simple runnable to test
        chain = RunnableLambda(str)

        # pass handler as callback:
        output = chain.invoke(
            "input",
            config={
                "callbacks": [handler]
            }
        )

zhYou must pass at least one of input_token_ratelimit or request_ratelimit parameters for handler to work.N)any
ValueErrorr.   r+   r,   r-   )r   r.   r+   r,   r-   s        r   r    UpstashRatelimitHandler.__init__@   s?    t O788E 
 %.!2%:"r   
serializedinputskwargsreturnc                 
   U R                   (       ar  U R                  (       d`  U R                   R                  U R                  5      nUR                  (       d"  [        SSUR                  UR                  5      eSU l        ggg)a,  
Run when chain starts running.

on_chain_start runs multiple times during a chain execution. To make
sure that it's only called once, we keep a bool state `_checked`. If
not `self._checked`, we call limit with `request_ratelimit` and raise
`UpstashRatelimitError` if the identifier is rate limited.
zRequest limit reached!r   TN)r,   r*   r   r.   allowedr   r   )r   r3   r4   r5   responses        r   on_chain_start&UpstashRatelimitHandler.on_chain_start   se     !!$----33DOODH##+,i  !DM +8!r   promptsc                     U R                   (       a8  U R                   R                  U R                  5      nUS::  a  [        SS5      egg)z
Run when LLM starts running
r   zToken limit reached!r   N)r+   get_remainingr.   r   )r   r3   r<   r5   	remainings        r   on_llm_start$UpstashRatelimitHandler.on_llm_start   sF     ,,::4??KIA~+,BGLL   r   r9   c                    U R                   (       a[   UR                  =(       d    0 nUS   nU R                  (       a  US   OUS   nU R                   R                  U R                  US9  gg! [         a    [	        S5      ef = f)z
Run when LLM ends running

If the `include_output_tokens` is set to True, number of tokens
in LLM completion are counted for rate limiting
token_usagetotal_tokensprompt_tokenszLLM response doesn't include `token_usage: {total_tokens: int, prompt_tokens: int}`  field. To use UpstashRatelimitHandler with token_ratelimit, either use a model which returns token_usage (like  OpenAI models) or rate limit only with request_ratelimit.)rateN)r+   
llm_outputr-   KeyErrorr1   r   r.   )r   r9   r5   rG   rC   token_counts         r   
on_llm_end"UpstashRatelimitHandler.on_llm_end   s     %006B
(7 11  /$_5 "   &&t[&I+     Q s   5A. .Bc                 |    [        U=(       d    U R                  U R                  U R                  U R                  S9$ )z
Creates a new UpstashRatelimitHandler object with the same
ratelimit configurations but with a new identifier if it's
provided.

Also resets the state of the handler.
)r.   r+   r,   r-   )r'   r.   r+   r,   r-   )r   r.   s     r   r   UpstashRatelimitHandler.reset   s8     '!4T__ 00"44"&"<"<	
 	
r   )r*   r.   r-   r,   r+   )N)r   r   r   r   r    r)   bool__annotations__r*   r!   r   r
   r   r   r   r:   r   r@   r	   rJ   r   r$    r   r   r'   r'   /   s	    KHd 0415&+C;C; "),	C;
 $I.C;  $C;J!sCx.!26sCx.!LO!	!&	MsCx.	M379	MHK	M		MJ9 J J J<
 
9R 
 
r   r'   )r    loggingtypingr   r   r   r   r   langchain_core.callbacksr   langchain_core.outputsr	   	getLoggerr   loggerupstash_ratelimitr
   ImportError	Exceptionr   r'   rP   r   r   <module>rZ      sa    6  5 5 8 ,			8	$+
I >_
1 _
G  Is   A AA