o
    i0                     @  s   d dl mZ d dlZd dlmZmZ d dlmZmZm	Z	m
Z
mZmZmZ d dlmZmZ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mZmZmZm Z m!Z! G d
d dee
eef Z"G dd de"eef Z#d!ddZ$d"ddZ%d#dd Z&dS )$    )annotationsN)ABCabstractmethod)Any	AwaitableCallableGenericOptionalTypeUnion)InputTOperationInfoOutputTServiceHandlerT)	OperationServiceDefinition)get_operation_factoryis_async_callableis_callable
is_subtype   )CancelOperationContextFetchOperationInfoContextFetchOperationResultContextStartOperationContextStartOperationResultAsyncStartOperationResultSyncc                   @  sH   e Zd ZdZeddd	ZedddZedddZedddZdS )OperationHandlera  
    Base class for an operation handler in a Nexus service implementation.

    To define a Nexus operation handler, create a method on your service handler class
    that takes `self` and returns an instance of :py:class:`OperationHandler`, and apply
    the :py:func:`@nexusrpc.handler.operation_handler` decorator.

    To create an operation handler that is limited to returning synchronously, use
    :py:func:`@nexusrpc.handler.SyncOperationHandler` to create the
    instance of :py:class:`OperationHandler` from the start method.
    ctxr   inputr   returnUnion[StartOperationResultSync[OutputT], Awaitable[StartOperationResultSync[OutputT]], StartOperationResultAsync, Awaitable[StartOperationResultAsync]]c                 C     dS )z
        Start the operation, completing either synchronously or asynchronously.

        Returns the result synchronously, or returns an operation token. Which path is
        taken may be decided at operation handling time.
        N selfr   r   r#   r#   i/var/www/html/karishye-ai-python/venv/lib/python3.10/site-packages/nexusrpc/handler/_operation_handler.pystart/   s   zOperationHandler.startr   tokenstr.Union[OperationInfo, Awaitable[OperationInfo]]c                 C  r"   )zO
        Return information about the current status of the operation.
        Nr#   r%   r   r(   r#   r#   r&   
fetch_info@      zOperationHandler.fetch_infor   "Union[OutputT, Awaitable[OutputT]]c                 C  r"   )z5
        Return the result of the operation.
        Nr#   r+   r#   r#   r&   fetch_resultI   r-   zOperationHandler.fetch_resultr   Union[None, Awaitable[None]]c                 C  r"   )z'
        Cancel the operation.
        Nr#   r+   r#   r#   r&   cancelR   r-   zOperationHandler.cancelN)r   r   r   r   r    r!   )r   r   r(   r)   r    r*   )r   r   r(   r)   r    r.   )r   r   r(   r)   r    r0   )	__name__
__module____qualname____doc__r   r'   r,   r/   r1   r#   r#   r#   r&   r   "   s    r   c                   @  sB   e Zd ZdZdddZdddZdddZd ddZd!ddZdS )"SyncOperationHandlerz
    An :py:class:`OperationHandler` that is limited to responding synchronously.

    This version of the class uses `async def` methods. For the syncio version, see
    :py:class:`nexusrpc.handler._syncio.SyncOperationHandler`.
    r'   =Callable[[StartOperationContext, InputT], Awaitable[OutputT]]c                 C  sH   t |st| d|| _|jr t| jdd  }r"|j|_d S d S d S )Nzd is not an `async def` method. SyncOperationHandler must be initialized with an `async def` method. __func__)r   RuntimeError_startr5   getattrr'   )r%   r'   
start_funcr#   r#   r&   __init__d   s   zSyncOperationHandler.__init__r   r   r   r   r    !StartOperationResultSync[OutputT]c                   s   t | ||I dH S )a  
        Start the operation and return its final result synchronously.

        The name 'SyncOperationHandler' means that it responds synchronously in the
        sense that the start method delivers the final operation result as its return
        value, rather than returning an operation token representing an in-progress
        operation. This version of the class uses `async def` methods. For the syncio
        version, see :py:class:`nexusrpc.handler.syncio.SyncOperationHandler`.
        N)r   r:   r$   r#   r#   r&   r'   q   s   zSyncOperationHandler.startr   r(   r)   r   c                   
   t d)NzJCannot fetch operation info for an operation that responded synchronously.NotImplementedErrorr+   r#   r#   r&   r,         zSyncOperationHandler.fetch_infor   r   c                   r?   )NzECannot fetch the result of an operation that responded synchronously.r@   r+   r#   r#   r&   r/      rB   z!SyncOperationHandler.fetch_resultr   Nonec                   r?   )Nz>An operation that responded synchronously cannot be cancelled.r@   r+   r#   r#   r&   r1      s   zSyncOperationHandler.cancelN)r'   r7   )r   r   r   r   r    r>   )r   r   r(   r)   r    r   )r   r   r(   r)   r    r   )r   r   r(   r)   r    rC   )	r2   r3   r4   r5   r=   r'   r,   r/   r1   r#   r#   r#   r&   r6   \   s    



r6   user_service_clsType[ServiceHandlerT]serviceOptional[ServiceDefinition]r    Bdict[str, Callable[[ServiceHandlerT], OperationHandler[Any, Any]]]c                 C  s  i }|rdd |j  D nt }t }t| tD ]f\}}t|\}}|rt|tr|j	|v r=t
d|j	 d| j d|rj|j|vrjddd t|D }	d	|j d
|  d}
|
|	r_|	nd7 }
|
d7 }
t|
|jsuJ d| d|||j< ||j	 q|S )zN
    Collect operation handler methods from a user service handler class.
    c                 S  s   h | ]
}|j d ur|j qS )N)method_name).0opr#   r#   r&   	<setcomp>   s
    
zEcollect_operation_handler_factories_by_method_name.<locals>.<setcomp>Operation '' in service 'z' is defined multiple times., c                 s  s    | ]	}d | d V  qdS )'Nr#   )rJ   sr#   r#   r&   	<genexpr>   s    zEcollect_operation_handler_factories_by_method_name.<locals>.<genexpr>zOperation method name 'z' in service handler zv does not match an operation method name in the service definition. Available method names in the service definition: z[none].z5' method name should not be None. This is an SDK bug.)
operationsvaluessetinspect
getmembersr   r   
isinstancer   namer9   r2   rI   joinsorted	TypeErroradd)rD   rF   	factoriesservice_method_namesseen_methodfactoryop_defn_namesmsgr#   r#   r&   2collect_operation_handler_factories_by_method_name   s:   	


rh   user_methods_by_method_nameservice_definitionr   rC   c                 C  s  |  }|j D ]}|jstd| d| d||jd}|s1td|  d|j d| dt|\}}t|t	sHtd	| d
| j
 d|j|j|jfvretd|j d|  d|j d|j d	|jdur|jdurt|j|jfvr|j|jkst|j|jstd|j d|  d|j d|j d|j d|jdur|jdurt|j|jfvrt|j|jstd|j d|  d|j d|j d| dq	|rtd|  d| ddt|  ddS )a  Validate operation handler methods against a service definition.

    For every operation in ``service_definition``:

    1. There must be a method in ``user_methods`` whose method name matches the method
       name from the service definition.

    2. The input and output types of the user method must be such that the user method
       is a subtype of the operation defined in the service definition, i.e. respecting
       input type contravariance and output type covariance.
    rM   z' in service definition 'z' does not have a method name. Nz	Service 'z4' does not implement an operation with method name 'z0'. But this operation is in service definition 'z'.zMethod 'z' in class 'z' does not have a valid __nexus_operation__ attribute. Did you forget to decorate the operation method with an operation handler decorator such as :py:func:`@nexusrpc.handler.operation_handler`?rN   z' has name 'z.', but the name in the service definition is 'zZ'. Operation handlers may not override the name of an operation in the service definition.z' has input type 'z0', which is not compatible with the input type 'z' in interface 'z]'. The input type must be the same as or a superclass of the operation definition input type.z' has output type 'z1', which is not compatible with the output type 'z' in interface  'z]'. The output type must be the same as or a subclass of the operation definition output type.z1' implements more operations than the interface 'z'. Extra operations: rO   rS   )copyrT   rU   rI   
ValueErrorpopr]   r   rY   r   r2   rZ   
input_typer   r   output_typer[   r\   keys)rD   ri   rj   re   rc   method_op_defnr#   r#   r&   "validate_operation_handler_methods   s   





rr   service_namer)   user_methodsc                 C  sX   i }|  D ]\}}t|\}}t|ts td|  d| d|||j< qt| |dS )ah  
    Create a service definition from operation handler factory methods.

    In general, users should have access to, or define, a service definition, and validate
    their service handler against it by passing the service definition to the
    :py:func:`@nexusrpc.handler.service_handler` decorator. This function is used when
    that is not the case.
    zIn service 'zL', could not locate operation definition for user operation handler method 'z'. Did you forget to decorate the operation method with an operation handler decorator such as :py:func:`@nexusrpc.handler.operation_handler`?)rZ   rT   )itemsr   rY   r   rl   rZ   r   )rs   rt   op_defnsrZ   rc   rb   re   r#   r#   r&   1service_definition_from_operation_handler_methods  s   
rw   )rD   rE   rF   rG   r    rH   )rD   rE   ri   rH   rj   r   r    rC   )rs   r)   rt   rH   r    r   )'
__future__r   rW   abcr   r   typingr   r   r   r   r	   r
   r   nexusrpc._commonr   r   r   r   nexusrpc._servicer   r   nexusrpc._utilr   r   r   r   _commonr   r   r   r   r   r   r   r6   rh   rr   rw   r#   r#   r#   r&   <module>   s    $
 
:
7
/V