o
    ib                     @  sx  d Z 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	m
Z
 ddlmZmZmZmZmZmZmZmZmZmZ ddlZddlmZ ddlZddlZddlZddlZddlZddl Zddl!Zddl"Zddl#Zddl$Ze%e&Z'G dd	 d	Z(G d
d de(Z)G dd dej*j+ej,j+Z-G dd dej,j.Z/G dd dej*j+Z0G dd dej*j1Z2G dd dej*j3Z4dddZ5dS )zWorkflow test environment.    )annotationsN)asynccontextmanagercontextmanager)datetime	timedeltatimezone)
AnyAsyncIteratorIteratorListMappingOptionalSequenceTypeUnioncast)Selfc                   @  s   e Zd ZdZedUddZedejjj	g g d	d	i d	d
dd	d	d
d	dd	d	dddg d	ddVd5d6Z
eejjj	g g d	d	i d	d	d	d	d	dg d	d7dWd<d=ZdXd?d@ZdYdAdBZdZdCdDZed[dEdFZdZdGdHZd\dKdLZd]dNdOZed^dPdQZed_dSdTZd	S )`WorkflowEnvironmenta  Workflow environment for testing workflows.

    Most developers will want to use the static :py:meth:`start_time_skipping`
    to start a test server process that automatically skips time as needed.
    Alternatively, :py:meth:`start_local` may be used for a full, local Temporal
    server with more features. To use an existing server, use
    :py:meth:`from_client`.

    This environment is an async context manager, so it can be used with
    ``async with`` to make sure it shuts down properly. Otherwise,
    :py:meth:`shutdown` can be manually called.

    To use the environment, simply use the :py:attr:`client` on it.

    Workflows invoked on the workflow environment are automatically configured
    to have ``assert`` failures fail the workflow with the assertion error.
    clienttemporalio.client.Clientreturnr   c                 C  s   | t |t S )a  Create a workflow environment from the given client.

        :py:attr:`supports_time_skipping` will always return ``False`` for this
        environment. :py:meth:`sleep` will sleep the actual amount of time and
        :py:meth:`get_current_time` will return the current time.

        Args:
            client: The client to use for the environment.

        Returns:
            The workflow environment that runs against the given client.
        )_client_with_interceptors_AssertionErrorInterceptor)clsr    r   b/var/www/html/karishye-ai-python/venv/lib/python3.10/site-packages/temporalio/testing/_workflow.pyfrom_client:   s   zWorkflowEnvironment.from_clientdefaultNFz	127.0.0.1r   prettywarn)	namespacedata_converterinterceptorsplugins'default_workflow_query_reject_conditionretry_configrpc_metadataidentitytlsipportdownload_dest_diruiruntimesearch_attributesdev_server_existing_pathdev_server_database_filenamedev_server_log_formatdev_server_log_leveldev_server_download_versiondev_server_extra_argsdev_server_download_ttlr    strr!   "temporalio.converter.DataConverterr"   'Sequence[temporalio.client.Interceptor]r#   "Sequence[temporalio.client.Plugin]r$   0Optional[temporalio.common.QueryRejectCondition]r%   'Optional[temporalio.client.RetryConfig]r&   Mapping[str, Union[str, bytes]]r'   Optional[str]r(   "bool | temporalio.client.TLSConfigr)   r*   Optional[int]r+   r,   boolr-   $Optional[temporalio.runtime.Runtime]r.   .Sequence[temporalio.common.SearchAttributeKey]r/   r0   r1   r2   r3   r4   Sequence[str]r5   Optional[timedelta]c                  sj  |s)t tjrd}nt tjrd}nt tjrd}nt tjr'd}nd}|rIg }|D ]}|d ||j d|j	  q/||7 }|}|pPt
jj }d}|dur_t| d	 }t
jjj|jt
jjj|d
t
jj||||
|||||||dI dH }ztt
jjj|j||||||	||||dI dH |W S    z	| I dH  W     t jddd Y  )a  Start a full Temporal server locally, downloading if necessary.

        This environment is good for testing full server capabilities, but does
        not support time skipping like :py:meth:`start_time_skipping` does.
        :py:attr:`supports_time_skipping` will always return ``False`` for this
        environment. :py:meth:`sleep` will sleep the actual amount of time and
        :py:meth:`get_current_time` will return the current time.

        Internally, this uses the Temporal CLI dev server from
        https://github.com/temporalio/cli. This is a self-contained binary for
        Temporal using Sqlite persistence. This call will download the CLI to a
        temporary directory by default if it has not already been downloaded
        before and ``dev_server_existing_path`` is not set.

        In the future, the dev server implementation may be changed to another
        implementation. Therefore, all ``dev_server_`` prefixed parameters are
        dev-server specific and may not apply to newer versions.

        Args:
            namespace: Namespace name to use for this environment.
            data_converter: See parameter of the same name on
                :py:meth:`temporalio.client.Client.connect`.
            interceptors: See parameter of the same name on
                :py:meth:`temporalio.client.Client.connect`.
            default_workflow_query_reject_condition: See parameter of the same
                name on :py:meth:`temporalio.client.Client.connect`.
            retry_config: See parameter of the same name on
                :py:meth:`temporalio.client.Client.connect`.
            rpc_metadata: See parameter of the same name on
                :py:meth:`temporalio.client.Client.connect`.
            identity: See parameter of the same name on
                :py:meth:`temporalio.client.Client.connect`.
            tls: See parameter of the same name on
                :py:meth:`temporalio.client.Client.connect`.
            ip: IP address to bind to, or 127.0.0.1 by default.
            port: Port number to bind to, or an OS-provided port by default.
            download_dest_dir: Directory to download binary to if a download is
                needed. If unset, this is the system's temporary directory.
            ui: If ``True``, will start a UI in the dev server.
            runtime: Specific runtime to use or default if unset.
            search_attributes: Search attributes to register with the dev
                server.
            dev_server_existing_path: Existing path to the CLI binary.
                If present, no download will be attempted to fetch the binary.
            dev_server_database_filename: Path to the Sqlite database to use
                for the dev server. Unset default means only in-memory Sqlite
                will be used.
            dev_server_log_format: Log format for the dev server.
            dev_server_log_level: Log level to use for the dev server. Default
                is ``warn``, but if set to ``None`` this will translate the
                Python logger's level to a dev server log level.
            dev_server_download_version: Specific CLI version to download.
                Defaults to ``default`` which downloads the version known to
                work best with this SDK.
            dev_server_extra_args: Extra arguments for the CLI binary.
            dev_server_download_ttl: TTL for the downloaded CLI binary. If unset, it will be
                cached indefinitely.

        Returns:
            The started CLI dev server workflow environment.
        debuginfor   errorfatalz--search-attribute=N  
sdk-python)existing_pathsdk_namesdk_versiondownload_versionr+   r    r)   r*   database_filenamer,   
log_format	log_level
extra_argsdownload_ttl_ms)
r    r!   r"   r#   r$   r(   r%   r&   r'   r-   z9Failed stopping local server on client connection failureTexc_info)loggerisEnabledForloggingDEBUGINFOWARNINGERRORappendname_metadata_type
temporalior-   Runtimer   inttotal_secondsbridgetestingEphemeralServerstart_dev_server_core_runtimeDevServerConfigservice__version__#_EphemeralServerWorkflowEnvironmentr   Clientconnecttargetshutdownr   )r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   new_argsattrrT   serverr   r   r   start_localK   s   [



zWorkflowEnvironment.start_local)r!   r"   r#   r$   r%   r&   r'   r*   r+   r-   test_server_existing_pathtest_server_download_versiontest_server_extra_argstest_server_download_ttlrv   rw   rx   ry   c                  s   |
pt jj }
d}|rt| d }t jjj	|
j
t jjj|dt jj||	|||dI dH }ztt jjj|j||||||||
d	I dH |W S    z	| I dH  W     tjddd Y  )	ae  Start a time skipping workflow environment.

        By default, this environment will automatically skip to the next events
        in time when a workflow's
        :py:meth:`temporalio.client.WorkflowHandle.result` is awaited on (which
        includes :py:meth:`temporalio.client.Client.execute_workflow`). Before
        the result is awaited on, time can be manually skipped forward using
        :py:meth:`sleep`. The currently known time can be obtained via
        :py:meth:`get_current_time`.

        Internally, this environment lazily downloads a test-server binary for
        the current OS/arch into the temp directory if it is not already there.
        Then the executable is started and will be killed when
        :py:meth:`shutdown` is called (which is implicitly done if this is
        started via
        ``async with await WorkflowEnvironment.start_time_skipping()``).

        Users can reuse this environment for testing multiple independent
        workflows, but not concurrently. Time skipping, which is automatically
        done when awaiting a workflow result and manually done on
        :py:meth:`sleep`, is global to the environment, not to the workflow
        under test.

        In the future, the test server implementation may be changed to another
        implementation. Therefore, all ``test_server_`` prefixed parameters are
        test server specific and may not apply to newer versions.

        Args:
            data_converter: See parameter of the same name on
                :py:meth:`temporalio.client.Client.connect`.
            interceptors: See parameter of the same name on
                :py:meth:`temporalio.client.Client.connect`.
            default_workflow_query_reject_condition: See parameter of the same
                name on :py:meth:`temporalio.client.Client.connect`.
            retry_config: See parameter of the same name on
                :py:meth:`temporalio.client.Client.connect`.
            rpc_metadata: See parameter of the same name on
                :py:meth:`temporalio.client.Client.connect`.
            identity: See parameter of the same name on
                :py:meth:`temporalio.client.Client.connect`.
            port: Port number to bind to, or an OS-provided port by default.
            download_dest_dir: Directory to download binary to if a download is
                needed. If unset, this is the system's temporary directory.
            runtime: Specific runtime to use or default if unset.
            test_server_existing_path: Existing path to the test server binary.
                If present, no download will be attempted to fetch the binary.
            test_server_download_version: Specific test server version to
                download. Defaults to ``default`` which downloads the version
                known to work best with this SDK.
            test_server_extra_args: Extra arguments for the test server binary.
            test_server_download_ttl: TTL for the downloaded test server binary. If unset, it
                will be cached indefinitely.

        Returns:
            The started workflow environment with time skipping.
        NrJ   rK   )rL   rM   rN   rO   r+   rT   r*   rS   )r!   r"   r#   r$   r%   r&   r'   r-   z8Failed stopping test server on client connection failureTrU   )ra   r-   rb   r   rc   rd   re   rf   rg   start_test_serverri   TestServerConfigrk   rl   rm   r   rn   ro   rp   rq   rW   r   )r   r!   r"   r#   r$   r%   r&   r'   r*   r+   r-   rv   rw   rx   ry   rT   rt   r   r   r   start_time_skipping   sV   N


z'WorkflowEnvironment.start_time_skippingNonec                 C  s
   || _ dS )zoCreate a workflow environment from a client.

        Most users would use a factory methods instead.

        N_client)selfr   r   r   r   __init__f  s   
zWorkflowEnvironment.__init__c                   s   | S )z Noop for ``async with`` support.r   r   r   r   r   
__aenter__n     zWorkflowEnvironment.__aenter__c                   s   |   I dH  dS )z<For ``async with`` support to just call :py:meth:`shutdown`.N)rq   )r   argsr   r   r   	__aexit__r  s   zWorkflowEnvironment.__aexit__c                 C     | j S )zClient to this environment.r~   r   r   r   r   r   v  s   zWorkflowEnvironment.clientc                   s   dS )zShut down this environment.Nr   r   r   r   r   rq   {  r   zWorkflowEnvironment.shutdowndurationUnion[timedelta, float]c                   s(   t t|tr| n|I dH  dS )zSleep in this environment.

        This awaits a regular :py:func:`asyncio.sleep` in regular environments,
        or manually skips time in time-skipping environments.

        Args:
            duration: Amount of time to sleep.
        N)asynciosleep
isinstancer   rd   )r   r   r   r   r   r     s   	zWorkflowEnvironment.sleepr   c                   s   t tjS )zGet the current time known to this environment.

        For non-time-skipping environments this is simply the system time. For
        time-skipping environments this is whatever time has been skipped to.
        )r   nowr   utcr   r   r   r   get_current_time  s   z$WorkflowEnvironment.get_current_timec                 C  s   dS )z0Whether this environment supports time skipping.Fr   r   r   r   r   supports_time_skipping     z*WorkflowEnvironment.supports_time_skippingIterator[None]c                 c  s    dV  dS )a  Disable any automatic time skipping if this is a time-skipping
        environment.

        This is a context manager for use via ``with``. Usually in time-skipping
        environments, waiting on a workflow result causes time to automatically
        skip until the next event. This can disable that. However, this only
        applies to results awaited inside this context. This will not disable
        automatic time skipping on previous results.

        This has no effect on non-time-skipping environments.
        Nr   r   r   r   r   auto_time_skipping_disabled  s   
z/WorkflowEnvironment.auto_time_skipping_disabled)r   r   r   r   ).r    r6   r!   r7   r"   r8   r#   r9   r$   r:   r%   r;   r&   r<   r'   r=   r(   r>   r)   r6   r*   r?   r+   r=   r,   r@   r-   rA   r.   rB   r/   r=   r0   r=   r1   r6   r2   r=   r3   r6   r4   rC   r5   rD   r   r   )r!   r7   r"   r8   r#   r9   r$   r:   r%   r;   r&   r<   r'   r=   r*   r?   r+   r=   r-   rA   rv   r=   rw   r6   rx   rC   ry   rD   r   r   )r   r   r   r}   )r   r   r   r}   )r   r   r   r   r   r}   r   r   r   r@   r   r   )__name__
__module____qualname____doc__classmethodr   ra   	converterDataConverterr   ru   r|   r   r   r   propertyr   rq   r   r   r   r   r   r   r   r   r   r   '   sr     "
x




r   c                      sn   e Zd Zd fddZdd	d
Zd fddZd fddZedddZe	d ddZ
ed!ddZ  ZS )"rm   r   r   rt   )temporalio.bridge.testing.EphemeralServerr   r}   c                   sL   |j | _t g}| jr|t|  t t|g|R   || _d| _	d S )NT)
has_test_service_supports_time_skippingr   r^   _TimeSkippingClientInterceptorsuperr   r   _server_auto_time_skipping)r   r   rt   r"   	__class__r   r   r     s   
z,_EphemeralServerWorkflowEnvironment.__init__c                   s   | j  I d H  d S N)r   rq   r   r   r   r   rq     s   z,_EphemeralServerWorkflowEnvironment.shutdownr   r   c                   s`   | j st |I d H S tjjj }|j	t
|tr|nt|d | jj|I d H  d S )N)seconds)r   r   r   ra   apitestservicev1SleepRequestr   FromTimedeltar   r   r   test_serviceunlock_time_skipping_with_sleep)r   r   reqr   r   r   r     s   z)_EphemeralServerWorkflowEnvironment.sleepr   c                   sH   | j st  I d H S | jjtjj I d H }|j	
 jtjdS )N)tzinfo)r   r   r   r   r   googleprotobuf	empty_pb2Emptytime
ToDatetimereplacer   r   )r   respr   r   r   r     s   

z4_EphemeralServerWorkflowEnvironment.get_current_timer@   c                 C  r   r   )r   r   r   r   r   r     s   z:_EphemeralServerWorkflowEnvironment.supports_time_skippingr   c                 c  s8    | j  }d| _ zd V  W |sd| _ d S d S |sd| _ w )NFT)r   )r   already_disabledr   r   r   r     s   
z?_EphemeralServerWorkflowEnvironment.auto_time_skipping_disabledAsyncIterator[None]c              	   C s   | j r| jsd V  d S | jjtjjj	 I d H  zd V  | jj
tjjj I d H  W d S    z| jj
tjjj I d H  W     td Y  )Nz(Failed locking time skipping after error)r   r   r   r   unlock_time_skippingra   r   r   r   UnlockTimeSkippingRequestlock_time_skippingLockTimeSkippingRequestrW   	exceptionr   r   r   r   time_skipping_unlocked  s*   
z:_EphemeralServerWorkflowEnvironment.time_skipping_unlocked)r   r   rt   r   r   r}   r   r   r   r   r   )r   r   )r   r   r   r   rq   r   r   r   r   r   r   r   r   __classcell__r   r   r   r   rm     s    

		rm   c                   @  s   e Zd ZdddZdS )	r   input/temporalio.worker.WorkflowInterceptorClassInputr   <Optional[Type[temporalio.worker.WorkflowInboundInterceptor]]c                 C  s   t S r   ))_AssertionErrorWorkflowInboundInterceptorr   r   r   r   r   workflow_interceptor_class  r   z5_AssertionErrorInterceptor.workflow_interceptor_classN)r   r   r   r   )r   r   r   r   r   r   r   r   r     s    r   c                      s:   e Zd Zd fddZd fd	d
ZedddZ  ZS )r   r   &temporalio.worker.ExecuteWorkflowInputr   r   c                   @   |    t |I d H W  d    S 1 sw   Y  d S r   )assert_error_as_app_errorr   execute_workflowr   r   r   r   r     s   
$z:_AssertionErrorWorkflowInboundInterceptor.execute_workflow#temporalio.worker.HandleSignalInputr}   c                   r   r   )r   r   handle_signalr   r   r   r   r     s   
$z7_AssertionErrorWorkflowInboundInterceptor.handle_signalr   c              
   c  sL    zd V  W d S  t y% } ztjjt|ddd}|j|_|d d }~ww )NAssertionErrorT)typenon_retryable)r   ra   
exceptionsApplicationErrorr6   __traceback__)r   errapp_errr   r   r   r     s   
zC_AssertionErrorWorkflowInboundInterceptor.assert_error_as_app_error)r   r   r   r   )r   r   r   r}   r   )r   r   r   r   r   r   r   r   r   r   r   r   r     s
    r   c                   @  s    e Zd ZdddZdd	d
ZdS )r   envrm   r   r}   c                 C  s
   || _ d S r   )r   )r   r   r   r   r   r     s   
z'_TimeSkippingClientInterceptor.__init__next%temporalio.client.OutboundInterceptorc                 C  s   t || jS r   )&_TimeSkippingClientOutboundInterceptorr   )r   r   r   r   r   intercept_client"  s   z/_TimeSkippingClientInterceptor.intercept_clientN)r   rm   r   r}   )r   r   r   r   )r   r   r   r   r   r   r   r   r   r     s    
r   c                      s,   e Zd Zd fddZd fddZ  ZS )r   r   r   r   rm   r   r}   c                   s   t  | || _d S r   )r   r   r   )r   r   r   r   r   r   r   )  s   
z/_TimeSkippingClientOutboundInterceptor.__init__r   $temporalio.client.StartWorkflowInput*temporalio.client.WorkflowHandle[Any, Any]c                   s,   t tt |I d H }t|_| j|_|S r   )r   _TimeSkippingWorkflowHandler   start_workflowr   r   )r   r   handler   r   r   r   1  s
   z5_TimeSkippingClientOutboundInterceptor.start_workflow)r   r   r   rm   r   r}   )r   r   r   r   )r   r   r   r   r   r   r   r   r   r   r   (  s    r   c                      s2   e Zd ZU ded< di ddd fddZ  ZS )r   rm   r   TNfollow_runsr&   rpc_timeoutr   r@   r&   r<   r   rD   r   r   c             	     s\   | j  4 I d H  t j|||dI d H W  d   I d H  S 1 I d H s'w   Y  d S )Nr   )r   r   r   result)r   r   r&   r   r   r   r   r   >  s   
0z"_TimeSkippingWorkflowHandle.result)r   r@   r&   r<   r   rD   r   r   )r   r   r   __annotations__r   r   r   r   r   r   r   ;  s   
 r   r   r   r"   temporalio.client.Interceptorr   c                 G  s8   |   }t|d }|| ||d< tjjdi |S )Nr"   r   )configlistextendra   r   rn   )r   r"   r   config_interceptorsr   r   r   r   M  s
   
r   )r   r   r"   r   r   r   )6r   
__future__r   r   rY   
contextlibr   r   r   r   r   typingr   r	   r
   r   r   r   r   r   r   r   google.protobuf.empty_pb2r   typing_extensionsr   temporalio.api.testservice.v1ra   temporalio.bridge.testingtemporalio.clienttemporalio.commontemporalio.convertertemporalio.exceptionstemporalio.runtimetemporalio.servicetemporalio.typestemporalio.worker	getLoggerr   rW   r   rm   r   Interceptorworkerr   WorkflowInboundInterceptorr   r   OutboundInterceptorr   WorkflowHandler   r   r   r   r   r   <module>   sF    0
   
R
	
