
    f3fiQb              
         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	  ej                  de	j                        Z ej                  de	j                        Z G d d	      Z ej                  d
d      Z G d dej"                  e         Z ej                  dd      Z G d dej(                  e         Z ej                  dd      Z ej                  dd      Z ej                  dd      Z ej                  dd      Z ej                  dd      Z G d dej(                  eeeeef         Z G d dee	j8                  e	j:                  e	j<                  e	j>                  e	j@                  f         Z! G d dee	jD                  e	jF                  e	jH                  e	jJ                  e	jL                  f         Z' G d dee	jP                  e	jR                  e	jT                  e	jV                  e	jX                  f         Z- G d  d!      Z. ej                  d"ee/e0ejb                  f            Z2 G d# d$      Z3	 	 	 	 	 	 	 	 	 	 d)d%Z4d*d&Z5	 	 	 	 d+d'Z6g d(Z7y),    )annotationsN)CallableSequence)
exceptionstypesTH)boundAHc                  0    e Zd ZdZdZeZ	 eZ	 ddZddZy)Autha  Add custom authentication and authorization management to your LangGraph application.

    The Auth class provides a unified system for handling authentication and
    authorization in LangGraph applications. It supports custom user authentication
    protocols and fine-grained authorization rules for different resources and
    actions.

    To use, create a separate python file and add the path to the file to your
    LangGraph API configuration file (`langgraph.json`). Within that file, create
    an instance of the Auth class and register authentication and authorization
    handlers as needed.

    Example `langgraph.json` file:

    ```json
    {
      "dependencies": ["."],
      "graphs": {
        "agent": "./my_agent/agent.py:graph"
      },
      "env": ".env",
      "auth": {
        "path": "./auth.py:my_auth"
      }
    ```

    Then the LangGraph server will load your auth file and run it server-side whenever a request comes in.

    ???+ example "Basic Usage"

        ```python
        from langgraph_sdk import Auth

        my_auth = Auth()

        async def verify_token(token: str) -> str:
            # Verify token and return user_id
            # This would typically be a call to your auth server
            return "user_id"

        @auth.authenticate
        async def authenticate(authorization: str) -> str:
            # Verify token and return user_id
            result = await verify_token(authorization)
            if result != "user_id":
                raise Auth.exceptions.HTTPException(
                    status_code=401, detail="Unauthorized"
                )
            return result

        # Global fallback handler
        @auth.on
        async def authorize_default(params: Auth.on.value):
            return False # Reject all requests (default behavior)

        @auth.on.threads.create
        async def authorize_thread_create(params: Auth.on.threads.create.value):
            # Allow the allowed user to create a thread
            assert params.get("metadata", {}).get("owner") == "allowed_user"

        @auth.on.store
        async def authorize_store(ctx: Auth.types.AuthContext, value: Auth.types.on):
            assert ctx.user.identity in value["namespace"], "Not authorized"
        ```

    ???+ note "Request Processing Flow"

        1. Authentication (your `@auth.authenticate` handler) is performed first on **every request**
        2. For authorization, the most specific matching handler is called:
            * If a handler exists for the exact resource and action, it is used (e.g., `@auth.on.threads.create`)
            * Otherwise, if a handler exists for the resource with any action, it is used (e.g., `@auth.on.threads`)
            * Finally, if no specific handlers match, the global handler is used (e.g., `@auth.on`)
            * If no global handler is set, the request is accepted

        This allows you to set default behavior with a global handler while
        overriding specific routes as needed.
    )_authenticate_handler_global_handlers_handler_cache	_handlersonc                ^    t        |       | _        	 i | _        g | _        d | _        i | _        y N)_Onr   r   r   r   r   )selfs    Y/var/www/auto_recruiter/arenv/lib/python3.12/site-packages/langgraph_sdk/auth/__init__.py__init__zAuth.__init__p   s7    d)C	L FH57AE"DF    c                ^    | j                   t        d| j                    d      || _         |S )a
  Register an authentication handler function.

        The authentication handler is responsible for verifying credentials
        and returning user scopes. It can accept any of the following parameters
        by name:

            - request (Request): The raw ASGI request object
            - path (str): The request path, e.g., "/threads/abcd-1234-abcd-1234/runs/abcd-1234-abcd-1234/stream"
            - method (str): The HTTP method, e.g., "GET"
            - path_params (dict[str, str]): URL path parameters, e.g., {"thread_id": "abcd-1234-abcd-1234", "run_id": "abcd-1234-abcd-1234"}
            - query_params (dict[str, str]): URL query parameters, e.g., {"stream": "true"}
            - headers (dict[bytes, bytes]): Request headers
            - authorization (str | None): The Authorization header value (e.g., "Bearer <token>")

        Args:
            fn: The authentication handler function to register.
                Must return a representation of the user. This could be a:
                    - string (the user id)
                    - dict containing {"identity": str, "permissions": list[str]}
                    - or an object with identity and permissions properties
                Permissions can be optionally used by your handlers downstream.

        Returns:
            The registered handler function.

        Raises:
            ValueError: If an authentication handler is already registered.

        ???+ example "Examples"

            Basic token authentication:

            ```python
            @auth.authenticate
            async def authenticate(authorization: str) -> str:
                user_id = verify_token(authorization)
                return user_id
            ```

            Accept the full request context:

            ```python
            @auth.authenticate
            async def authenticate(
                method: str,
                path: str,
                headers: dict[str, bytes]
            ) -> str:
                user = await verify_request(method, path, headers)
                return user
            ```

            Return user name and permissions:

            ```python
            @auth.authenticate
            async def authenticate(
                method: str,
                path: str,
                headers: dict[str, bytes]
            ) -> Auth.types.MinimalUserDict:
                permissions, user = await verify_request(method, path, headers)
                # Permissions could be things like ["runs:read", "runs:write", "threads:read", "threads:write"]
                return {
                    "identity": user["id"],
                    "permissions": permissions,
                    "display_name": user["name"],
                }
            ```
        z&Authentication handler already set as .)r   
ValueErrorr   fns     r   authenticatezAuth.authenticate   sA    N %%189S9S8TTUV  &("	r   N)returnNone)r   r
   r   r
   )	__name__
__module____qualname____doc__	__slots__r   r   r   r    r   r   r   r      s6    L\I E0
 JKGZLr   r   VT)contravariantc                       e Zd Z	 	 	 	 	 	 ddZy)_ActionHandlerc                  K   y wr   r&   )r   ctxvalues      r   __call__z_ActionHandler.__call__  s	     !s   N)r,   ztypes.AuthContextr-   r'   r   ztypes.HandlerResult)r!   r"   r#   r.   r&   r   r   r*   r*     s    "'"01"	"r   r*   T)	covariantc                  0    e Zd Z	 	 	 	 	 	 	 	 	 	 ddZddZy)_ResourceActionOnc                <    || _         || _        || _        || _        y r   )authresourceactionr-   )r   r4   r5   r6   r-   s        r   r   z_ResourceActionOn.__init__  s      	 
r   c                t    t        |       t        | j                  | j                  | j                  |       |S r   )_validate_handler_register_handlerr4   r5   r6   r   s     r   r.   z_ResourceActionOn.__call__)  s)    "$))T]]DKKD	r   N)
r4   r   r5   0typing.Literal['threads', 'crons', 'assistants']r6   zLtyping.Literal['create', 'read', 'update', 'delete', 'search', 'create_run']r-   ztype[T]r   r    )r   _ActionHandler[T]r   r;   )r!   r"   r#   r   r.   r&   r   r   r2   r2     s=     C
	  
r   r2   VCreateVUpdateVReadVDeleteVSearchc                      e Zd ZU dZded<   ded<   ded<   ded	<   d
ed<   ded<   	 	 	 	 	 	 ddZej                  	 	 	 	 dd       Zej                  dd	 	 	 	 	 dd       Z	 dddd	 	 	 	 	 	 	 ddZy)_ResourceOnz<
    Generic base class for resource-specific handlers.
    z3type[VCreate | VUpdate | VRead | VDelete | VSearch]r-   ztype[VCreate]Createztype[VRead]Readztype[VUpdate]Updateztype[VDelete]Deleteztype[VSearch]Searchc                B   || _         || _        t        ||d| j                        | _        t        ||d| j
                        | _        t        ||d| j                        | _        t        ||d| j                        | _
        t        ||d| j                        | _        y )Ncreatereadupdatedeletesearch)r4   r5   r2   rC   rI   rD   rJ   rE   rK   rF   rL   rG   rM   )r   r4   r5   s      r   r   z_ResourceOn.__init__C  s    
 	 2C(Hdkk3
 /@(FDII/
	 3D(Hdkk3
 3D(Hdkk3
 3D(Hdkk3
r   c                     y r   r&   r   s     r   r.   z_ResourceOn.__call__Z  s	     ILr   Nactionsc                    y r   r&   r   	resourcesrP   s      r   r.   z_ResourceOn.__call__c  s     r   rS   rP   c          	          |At        |       t        j                  dt         j                   j
                  d|            S 	 	 	 	 d fd}||f}|S )N=_ActionHandler[VCreate | VUpdate | VRead | VDelete | VSearch]*c           	         t        |        t        j                  dt        j                  j
                  d|             S )NrV   rW   r8   typingcastr9   r4   r5   )handlerr   s    r   	decoratorz'_ResourceOn.__call__.<locals>.decorator  s7     g&;;O!$))T]]CI r   )r\   rV   r   rV   rY   )r   r   rS   rP   r]   _s   `     r   r.   z_ResourceOn.__call__n  sc    " >b!;;O!$))T]]CD 
	R	J	 wr   r4   r   r5   r:   r   r    )r   ze_ActionHandler[VCreate | VUpdate | VRead | VDelete | VSearch] | _ActionHandler[dict[str, typing.Any]]r   rV   )rS   str | Sequence[str]rP   str | Sequence[str] | Noner   zCallable[[_ActionHandler[VCreate | VUpdate | VRead | VDelete | VSearch]], _ActionHandler[VCreate | VUpdate | VRead | VDelete | VSearch]]r   )r   zl_ActionHandler[VCreate | VUpdate | VRead | VDelete | VSearch] | _ActionHandler[dict[str, typing.Any]] | NonerS   ra   rP   ra   r   z_ActionHandler[VCreate | VUpdate | VRead | VDelete | VSearch] | Callable[[_ActionHandler[VCreate | VUpdate | VRead | VDelete | VSearch]], _ActionHandler[VCreate | VUpdate | VRead | VDelete | VSearch]])	r!   r"   r#   r$   __annotations__r   rZ   overloadr.   r&   r   r   rB   rB   6  s     ?>


 C
 
	
. __L4L 
GL L __
 /3	 ' ,	

   # 15.2## .# ,#	
#r   rB   c                     e Zd Zej                  ej
                  z  ej                  z  ej                  z  ej                  z  Z	ej                  Z
ej
                  Zej                  Zej                  Zej                  Zy)_AssistantsOnN)r!   r"   r#   r   AssistantsCreateAssistantsReadAssistantsUpdateAssistantsDeleteAssistantsSearchr-   rC   rD   rE   rF   rG   r&   r   r   re   re     s     	


	

 
 	! 
 
 	! 
 
 		! 
 ##FD##F##F##Fr   re   c                  V    e Zd Zej                  ej
                  z  ej                  z  ej                  z  ej                  z  ej                  z  Z
ej                  Zej
                  Zej                  Zej                  Zej                  Zej                  Z	 	 	 	 	 	 d fdZ xZS )
_ThreadsOnc                `    t         |   ||       t        ||d| j                        | _        y )N
create_run)superr   r2   	CreateRunrn   )r   r4   r5   	__class__s      r   r   z_ThreadsOn.__init__  s.    
 	x(?P(L$..@
r   r_   )r!   r"   r#   r   ThreadsCreateThreadsReadThreadsUpdateThreadsDeleteThreadsSearch
RunsCreater-   rC   rD   rE   rF   rG   rp   r   __classcell__)rq   s   @r   rl   rl     s     	


	


	 

	 

		
 

	 
   FD  F  F  F  I

 C
 
	
 
r   rl   c                  
   e Zd Zeej
                  ej                  z  ej                  z  ej                  z  ej                  z     Z
ej
                  Zej                  Zej                  Zej                  Zej                  Zy)_CronsOnN)r!   r"   r#   typer   CronsCreate	CronsReadCronsUpdateCronsDeleteCronsSearchr-   rC   rD   rE   rF   rG   r&   r   r   rz   rz     s     
//	


	 

	 

		E F??DFFFr   rz   c                      e Zd ZddZej
                  dd	 	 	 dd       Zej
                  d	d       Z	 d
dd	 	 	 	 	 ddZy)_StoreOnc                    || _         y r   )_authr   r4   s     r   r   z_StoreOn.__init__  s	    
r   NrO   c                    y r   r&   )r   rP   s     r   r.   z_StoreOn.__call__  s      #r   c                     y r   r&   r   s     r   r.   z_StoreOn.__call__      (+r   c               X     |t         j                  dd|       |S 	 	 	 	 d fd}|S )a  Register a handler for specific resources and actions.

        Can be used as a decorator or with explicit resource/action parameters:

        @auth.on.store
        async def handler(): ... # Handle all store ops

        @auth.on.store(actions=("put", "get", "search", "delete"))
        async def handler(): ... # Handle specific store ops

        @auth.on.store.put
        async def handler(): ... # Handle store.put ops
        Nstorec                    t        t              rg}nt              ndg}|D ]  }t        j                  d||         | S )NrW   r   
isinstancestrlistr9   r   )r\   action_listr6   rP   r   s      r   r]   z$_StoreOn.__call__.<locals>.decorator  sP     '3'&i/6/Bd7m% H!$**gvwGHNr   r\   AHOr   r   r9   r   )r   r   rP   r]   s   ` ` r   r.   z_StoreOn.__call__  s>    2 >djj'4<I						 r   r4   r   r   r    )rP   typing.Literal['put', 'get', 'search', 'list_namespaces', 'delete'] | Sequence[typing.Literal['put', 'get', 'search', 'list_namespaces', 'delete']] | Noner   Callable[[AHO], AHO]r   r   r   r   r   )r   
AHO | NonerP   r   r   AHO | Callable[[AHO], AHO])r!   r"   r#   r   rZ   rc   r.   r&   r   r   r   r     s|     __ 
#	
# 

# 
# __+ + * **
* 
$*r   r   r   c                      e Zd ZdZdZd
dZej                  dd	 	 	 	 	 dd       Zej                  dd       Z	 dddd	 	 	 	 	 	 	 dd	Zy)r   a  Entry point for authorization handlers that control access to specific resources.

    The _On class provides a flexible way to define authorization rules for different resources
    and actions in your application. It supports three main usage patterns:

    1. Global handlers that run for all resources and actions
    2. Resource-specific handlers that run for all actions on a resource
    3. Resource and action specific handlers for fine-grained control

    Each handler must be an async function that accepts two parameters:
    - ctx (AuthContext): Contains request context and authenticated user info
    - value: The data being authorized (type varies by endpoint)

    The handler should return one of:
        - None or True: Accept the request
        - False: Reject with 403 error
        - FilterType: Apply filtering rules to the response

    ???+ example "Examples"

        Global handler for all requests:

        ```python
        @auth.on
        async def log_all_requests(ctx: AuthContext, value: Any) -> None:
            print(f"Request to {ctx.path} by {ctx.user.identity}")
            return True
        ```

        Resource-specific handler:

        ```python
        @auth.on.threads
        async def check_thread_access(ctx: AuthContext, value: Any) -> bool:
            # Allow access only to threads created by the user
            return value.get("created_by") == ctx.user.identity
        ```

        Resource and action specific handler:

        ```python
        @auth.on.threads.delete
        async def prevent_thread_deletion(ctx: AuthContext, value: Any) -> bool:
            # Only admins can delete threads
            return "admin" in ctx.user.permissions
        ```

        Multiple resources or actions:

        ```python
        @auth.on(resources=["threads", "runs"], actions=["create", "update"])
        async def rate_limit_writes(ctx: AuthContext, value: Any) -> bool:
            # Implement rate limiting for write operations
            return await check_rate_limit(ctx.user.identity)
        ```
    )r   
assistantscronsrunsr   threadsr-   c                    || _         t        |d      | _        t        |d      | _        t        |d      | _        t        |      | _        t        t        t        j                  f   | _        y )Nr   r   r   )r   re   r   rl   r   rz   r   r   r   dictr   rZ   Anyr-   r   s     r   r   z_On.__init__n  sR    
'l;!$	2dG,
d^
#vzz/*
r   NrO   c                    y r   r&   rR   s      r   r.   z_On.__call__v  s      #r   c                     y r   r&   r   s     r   r.   z_On.__call__~  r   r   rT   c               \     |t         j                  dd|       |S 	 	 	 	 d fd}|S )a  Register a handler for specific resources and actions.

        Can be used as a decorator or with explicit resource/action parameters:

        @auth.on
        async def handler(): ...  # Global handler

        @auth.on(resources="threads")
        async def handler(): ...  # types.Handler for all thread actions

        @auth.on(resources="threads", actions="create")
        async def handler(): ...  # types.Handler for thread creation
        Nc                    t        t              rg}nt              ndg}t        t              rg}nt              ndg}|D ]!  }|D ]  }t        j                  |||         # | S )NrW   r   )r\   resource_listr   r5   r6   rP   rS   r   s        r   r]   z_On.__call__.<locals>.decorator  s     )S)!*3<3HYse'3'&i/6/Bd7m) M) MF%djj(FGLMM Nr   r   r   )r   r   rS   rP   r]   s   ` `` r   r.   z_On.__call__  s>    ( >djj$b9I			" r   r   )rS   r`   rP   ra   r   r   r   r   )r   r   rS   ra   rP   ra   r   r   )	r!   r"   r#   r$   r%   r   rZ   rc   r.   r&   r   r   r   r   *  s    7rI+ __
 /3	# '# ,	#
 
# # __+ + + 15.2++ .	+
 ,+ 
$+r   r   c                0   t        |       |xs d}|xs d}|dk(  r9|dk(  r4| j                  rt        d      | j                  j                  |       |S ||nd}||nd}||f| j                  v rt        d| d| d      |g| j                  ||f<   |S )NrW   zGlobal handler already set.ztypes.Handler already set for z, r   )r8   r   r   appendr   )r4   r5   r6   r   ras         r   r9   r9     s     b3H]sF36S=  :;;$$R( I !,H#(Fcq6T^^#=aS1#QGHH"$1vIr   c                ,   t        j                  |       st        dt        | d|        d      t        j                  |       }d|j
                  vrt        dt        | d|        d      d|j
                  vrt        dt        | d|        d      y)	zValidates that an auth handler function meets the required signature.

    Auth handlers must:
    1. Be async functions
    2. Accept a ctx parameter of type AuthContext
    3. Accept a value parameter for the data being authorized
    zAuth handler 'r!   z|' must be an async function. Add 'async' before 'def' to make it asynchronous and ensure any IO operations are non-blocking.r,   zm' must have a 'ctx: AuthContext' parameter. Update the function signature to include this required parameter.r-   z' must have a 'value' parameter.  The value contains the mutable data being sent to the endpoint.Update the function signature to include this required parameter.N)inspectiscoroutinefunctionr   getattr	signature
parameters)r   sigs     r   r8   r8     s     &&r*WRR89 :3 3
 	
 

B
CCNN"WRR89 :P P
 	
 cnn$WRR89 :P P
 	
 %r   c                    t        | t        j                        xs& t        | t              xr | j	                  d      dk(  S )Nkind
StudioUser)r   r   r   r   get)users    r   is_studio_userr     s<     	4))* 	ItT"Gtxx'7<'Gr   )r   r   r   )
r4   r   r5   
str | Noner6   r   r   types.Handlerr   r   )r   zCallable[..., typing.Any]r   r    )r   z:types.MinimalUser | types.BaseUser | types.MinimalUserDictr   bool)8
__future__r   r   rZ   collections.abcr   r   langgraph_sdk.authr   r   TypeVarHandlerr   Authenticatorr
   r   r'   Protocolr*   r/   Genericr2   r<   r=   r>   r?   r@   rB   rf   rg   rh   ri   rj   re   rr   rs   rt   ru   rv   rl   r|   r}   r~   r   r   rz   r   r   r   r   r   r   r9   r8   r   __all__r&   r   r   <module>r      s}   "   . 0V^^D.V^^D 3 34| |B FNN3d+"V__Q' " FNN3$'q) * &..d
3
&..d
3w$/
&..d
3
&..d
3[&..%'7!JK [|$		 $. 
		 
F		0> >B fnnU.c6::o1F"GHB BJ
  		
 ,
:
D	 *r   