%global _empty_manifest_terminate_build 0 Name: python-temporal-python-sdk Version: 1.0.19 Release: 1 Summary: Unofficial Python SDK for the Temporal Workflow Engine License: MIT License URL: https://github.com/firdaus/temporal-python-sdk Source0: https://mirrors.nju.edu.cn/pypi/web/packages/f9/35/65b712ff6bfaec51f783d3c54228579e0f4900f5f93f82e73b89fe81c1a6/temporal-python-sdk-1.0.19.tar.gz BuildArch: noarch Requires: python3-betterproto-for-temporal-python-sdk Requires: python3-dataclasses-json Requires: python3-grpcio Requires: python3-grpclib Requires: python3-h2 Requires: python3-more-itertools Requires: python3-pytz Requires: python3-tblib %description # Unofficial Python SDK for the Temporal Workflow Engine ## Status This should be considered EXPERIMENTAL at the moment. At the moment, all I can say is that the [test cases](https://gist.github.com/firdaus/4ec442f2c626122ad0c8d379a7ffd8bc) currently pass. I have not tested this for any real world use cases yet. ## Installation ``` pip install temporal-python-sdk ``` ## Sample Code Sample code for using this library can be found in [Workflows in Python Using Temporal](https://onepointzero.app/workflows-in-python-using-temporal/). ## Hello World ```python import asyncio import logging from datetime import timedelta from temporal.activity_method import activity_method from temporal.workerfactory import WorkerFactory from temporal.workflow import workflow_method, Workflow, WorkflowClient logging.basicConfig(level=logging.INFO) TASK_QUEUE = "HelloActivity-python-tq" NAMESPACE = "default" # Activities Interface class GreetingActivities: @activity_method(task_queue=TASK_QUEUE, schedule_to_close_timeout=timedelta(seconds=1000)) async def compose_greeting(self, greeting: str, name: str) -> str: raise NotImplementedError # Activities Implementation class GreetingActivitiesImpl: async def compose_greeting(self, greeting: str, name: str): return greeting + " " + name + "!" # Workflow Interface class GreetingWorkflow: @workflow_method(task_queue=TASK_QUEUE) async def get_greeting(self, name: str) -> str: raise NotImplementedError # Workflow Implementation class GreetingWorkflowImpl(GreetingWorkflow): def __init__(self): self.greeting_activities: GreetingActivities = Workflow.new_activity_stub(GreetingActivities) pass async def get_greeting(self, name): return await self.greeting_activities.compose_greeting("Hello", name) async def client_main(): client = WorkflowClient.new_client(namespace=NAMESPACE) factory = WorkerFactory(client, NAMESPACE) worker = factory.new_worker(TASK_QUEUE) worker.register_activities_implementation(GreetingActivitiesImpl(), "GreetingActivities") worker.register_workflow_implementation_type(GreetingWorkflowImpl) factory.start() greeting_workflow: GreetingWorkflow = client.new_workflow_stub(GreetingWorkflow) result = await greeting_workflow.get_greeting("Python") print(result) print("Stopping workers.....") await worker.stop() print("Workers stopped......") if __name__ == '__main__': asyncio.run(client_main()) ``` ## Roadmap 1.0 - [x] Workflow argument passing and return values - [x] Activity invocation - [x] Activity heartbeat and Activity.getHeartbeatDetails() - [x] doNotCompleteOnReturn - [x] ActivityCompletionClient - [x] complete - [x] complete_exceptionally - [x] Activity get_namespace(), get_task_token() get_workflow_execution() - [x] Activity Retry - [x] Activity Failure Exceptions - [x] workflow_execution_timeout / workflow_run_timeout / workflow_task_timeout - [x] Workflow exceptions - [x] Cron workflows - [x] Workflow static methods: - [x] await_till() - [x] sleep() - [x] current_time_millis() - [x] now() - [x] random_uuid() - [x] new_random() - [x] get_workflow_id() - [x] get_run_id() - [x] get_version() - [x] get_logger() - [x] Activity invocation parameters - [x] Query method - [x] Signal methods - [x] Workflow start parameters - workflow_id etc... - [x] Workflow client - starting workflows synchronously - [x] Workflow client - starting workflows asynchronously (WorkflowClient.start) - [x] Get workflow result after async execution (client.wait_for_close) - [x] Workflow client - invoking signals - [x] Workflow client - invoking queries 1.1 - [x] ActivityStub and Workflow.newUntypedActivityStub - [x] Remove threading, use coroutines for everything all concurrency - [x] Classes as arguments and return values to/from activity and workflow methods (DataConverter) - [x] Type hints for DataConverter - [x] Parallel activity execution (STATUS: there's a working but not finalized API). 1.2 - [x] Timers - [x] Custom workflow ids through start() and new_workflow_stub() - [ ] WorkflowStub and WorkflowClient.newUntypedWorkflowStub - [ ] ContinueAsNew ![status-wip](https://img.shields.io/badge/status-work_in_progress-lightgrey.svg) - [ ] Sticky workflows ![status-wip](https://img.shields.io/badge/status-work_in_progress-lightgrey.svg) - [ ] Child Workflows ![status-wip](https://img.shields.io/badge/status-work_in_progress-lightgrey.svg) 1.3 - [ ] Support for keyword arguments ![](https://img.shields.io/badge/PRs-welcome-informational) 2.0 - [ ] Compatibility with Java client ![](https://img.shields.io/badge/PRs-welcome-informational) - [ ] Compatibility with Golang client ![](https://img.shields.io/badge/PRs-welcome-informational) - [ ] Upgrade python-betterproto ![](https://img.shields.io/badge/PRs-welcome-informational) Post 2.0: - [ ] sideEffect/mutableSideEffect ![](https://img.shields.io/badge/PRs-welcome-informational) - [ ] Local activity ![](https://img.shields.io/badge/PRs-welcome-informational) - [ ] Cancellation Scopes ![](https://img.shields.io/badge/PRs-welcome-informational) - [ ] Explicit activity ids for activity invocations ![](https://img.shields.io/badge/PRs-welcome-informational) %package -n python3-temporal-python-sdk Summary: Unofficial Python SDK for the Temporal Workflow Engine Provides: python-temporal-python-sdk BuildRequires: python3-devel BuildRequires: python3-setuptools BuildRequires: python3-pip %description -n python3-temporal-python-sdk # Unofficial Python SDK for the Temporal Workflow Engine ## Status This should be considered EXPERIMENTAL at the moment. At the moment, all I can say is that the [test cases](https://gist.github.com/firdaus/4ec442f2c626122ad0c8d379a7ffd8bc) currently pass. I have not tested this for any real world use cases yet. ## Installation ``` pip install temporal-python-sdk ``` ## Sample Code Sample code for using this library can be found in [Workflows in Python Using Temporal](https://onepointzero.app/workflows-in-python-using-temporal/). ## Hello World ```python import asyncio import logging from datetime import timedelta from temporal.activity_method import activity_method from temporal.workerfactory import WorkerFactory from temporal.workflow import workflow_method, Workflow, WorkflowClient logging.basicConfig(level=logging.INFO) TASK_QUEUE = "HelloActivity-python-tq" NAMESPACE = "default" # Activities Interface class GreetingActivities: @activity_method(task_queue=TASK_QUEUE, schedule_to_close_timeout=timedelta(seconds=1000)) async def compose_greeting(self, greeting: str, name: str) -> str: raise NotImplementedError # Activities Implementation class GreetingActivitiesImpl: async def compose_greeting(self, greeting: str, name: str): return greeting + " " + name + "!" # Workflow Interface class GreetingWorkflow: @workflow_method(task_queue=TASK_QUEUE) async def get_greeting(self, name: str) -> str: raise NotImplementedError # Workflow Implementation class GreetingWorkflowImpl(GreetingWorkflow): def __init__(self): self.greeting_activities: GreetingActivities = Workflow.new_activity_stub(GreetingActivities) pass async def get_greeting(self, name): return await self.greeting_activities.compose_greeting("Hello", name) async def client_main(): client = WorkflowClient.new_client(namespace=NAMESPACE) factory = WorkerFactory(client, NAMESPACE) worker = factory.new_worker(TASK_QUEUE) worker.register_activities_implementation(GreetingActivitiesImpl(), "GreetingActivities") worker.register_workflow_implementation_type(GreetingWorkflowImpl) factory.start() greeting_workflow: GreetingWorkflow = client.new_workflow_stub(GreetingWorkflow) result = await greeting_workflow.get_greeting("Python") print(result) print("Stopping workers.....") await worker.stop() print("Workers stopped......") if __name__ == '__main__': asyncio.run(client_main()) ``` ## Roadmap 1.0 - [x] Workflow argument passing and return values - [x] Activity invocation - [x] Activity heartbeat and Activity.getHeartbeatDetails() - [x] doNotCompleteOnReturn - [x] ActivityCompletionClient - [x] complete - [x] complete_exceptionally - [x] Activity get_namespace(), get_task_token() get_workflow_execution() - [x] Activity Retry - [x] Activity Failure Exceptions - [x] workflow_execution_timeout / workflow_run_timeout / workflow_task_timeout - [x] Workflow exceptions - [x] Cron workflows - [x] Workflow static methods: - [x] await_till() - [x] sleep() - [x] current_time_millis() - [x] now() - [x] random_uuid() - [x] new_random() - [x] get_workflow_id() - [x] get_run_id() - [x] get_version() - [x] get_logger() - [x] Activity invocation parameters - [x] Query method - [x] Signal methods - [x] Workflow start parameters - workflow_id etc... - [x] Workflow client - starting workflows synchronously - [x] Workflow client - starting workflows asynchronously (WorkflowClient.start) - [x] Get workflow result after async execution (client.wait_for_close) - [x] Workflow client - invoking signals - [x] Workflow client - invoking queries 1.1 - [x] ActivityStub and Workflow.newUntypedActivityStub - [x] Remove threading, use coroutines for everything all concurrency - [x] Classes as arguments and return values to/from activity and workflow methods (DataConverter) - [x] Type hints for DataConverter - [x] Parallel activity execution (STATUS: there's a working but not finalized API). 1.2 - [x] Timers - [x] Custom workflow ids through start() and new_workflow_stub() - [ ] WorkflowStub and WorkflowClient.newUntypedWorkflowStub - [ ] ContinueAsNew ![status-wip](https://img.shields.io/badge/status-work_in_progress-lightgrey.svg) - [ ] Sticky workflows ![status-wip](https://img.shields.io/badge/status-work_in_progress-lightgrey.svg) - [ ] Child Workflows ![status-wip](https://img.shields.io/badge/status-work_in_progress-lightgrey.svg) 1.3 - [ ] Support for keyword arguments ![](https://img.shields.io/badge/PRs-welcome-informational) 2.0 - [ ] Compatibility with Java client ![](https://img.shields.io/badge/PRs-welcome-informational) - [ ] Compatibility with Golang client ![](https://img.shields.io/badge/PRs-welcome-informational) - [ ] Upgrade python-betterproto ![](https://img.shields.io/badge/PRs-welcome-informational) Post 2.0: - [ ] sideEffect/mutableSideEffect ![](https://img.shields.io/badge/PRs-welcome-informational) - [ ] Local activity ![](https://img.shields.io/badge/PRs-welcome-informational) - [ ] Cancellation Scopes ![](https://img.shields.io/badge/PRs-welcome-informational) - [ ] Explicit activity ids for activity invocations ![](https://img.shields.io/badge/PRs-welcome-informational) %package help Summary: Development documents and examples for temporal-python-sdk Provides: python3-temporal-python-sdk-doc %description help # Unofficial Python SDK for the Temporal Workflow Engine ## Status This should be considered EXPERIMENTAL at the moment. At the moment, all I can say is that the [test cases](https://gist.github.com/firdaus/4ec442f2c626122ad0c8d379a7ffd8bc) currently pass. I have not tested this for any real world use cases yet. ## Installation ``` pip install temporal-python-sdk ``` ## Sample Code Sample code for using this library can be found in [Workflows in Python Using Temporal](https://onepointzero.app/workflows-in-python-using-temporal/). ## Hello World ```python import asyncio import logging from datetime import timedelta from temporal.activity_method import activity_method from temporal.workerfactory import WorkerFactory from temporal.workflow import workflow_method, Workflow, WorkflowClient logging.basicConfig(level=logging.INFO) TASK_QUEUE = "HelloActivity-python-tq" NAMESPACE = "default" # Activities Interface class GreetingActivities: @activity_method(task_queue=TASK_QUEUE, schedule_to_close_timeout=timedelta(seconds=1000)) async def compose_greeting(self, greeting: str, name: str) -> str: raise NotImplementedError # Activities Implementation class GreetingActivitiesImpl: async def compose_greeting(self, greeting: str, name: str): return greeting + " " + name + "!" # Workflow Interface class GreetingWorkflow: @workflow_method(task_queue=TASK_QUEUE) async def get_greeting(self, name: str) -> str: raise NotImplementedError # Workflow Implementation class GreetingWorkflowImpl(GreetingWorkflow): def __init__(self): self.greeting_activities: GreetingActivities = Workflow.new_activity_stub(GreetingActivities) pass async def get_greeting(self, name): return await self.greeting_activities.compose_greeting("Hello", name) async def client_main(): client = WorkflowClient.new_client(namespace=NAMESPACE) factory = WorkerFactory(client, NAMESPACE) worker = factory.new_worker(TASK_QUEUE) worker.register_activities_implementation(GreetingActivitiesImpl(), "GreetingActivities") worker.register_workflow_implementation_type(GreetingWorkflowImpl) factory.start() greeting_workflow: GreetingWorkflow = client.new_workflow_stub(GreetingWorkflow) result = await greeting_workflow.get_greeting("Python") print(result) print("Stopping workers.....") await worker.stop() print("Workers stopped......") if __name__ == '__main__': asyncio.run(client_main()) ``` ## Roadmap 1.0 - [x] Workflow argument passing and return values - [x] Activity invocation - [x] Activity heartbeat and Activity.getHeartbeatDetails() - [x] doNotCompleteOnReturn - [x] ActivityCompletionClient - [x] complete - [x] complete_exceptionally - [x] Activity get_namespace(), get_task_token() get_workflow_execution() - [x] Activity Retry - [x] Activity Failure Exceptions - [x] workflow_execution_timeout / workflow_run_timeout / workflow_task_timeout - [x] Workflow exceptions - [x] Cron workflows - [x] Workflow static methods: - [x] await_till() - [x] sleep() - [x] current_time_millis() - [x] now() - [x] random_uuid() - [x] new_random() - [x] get_workflow_id() - [x] get_run_id() - [x] get_version() - [x] get_logger() - [x] Activity invocation parameters - [x] Query method - [x] Signal methods - [x] Workflow start parameters - workflow_id etc... - [x] Workflow client - starting workflows synchronously - [x] Workflow client - starting workflows asynchronously (WorkflowClient.start) - [x] Get workflow result after async execution (client.wait_for_close) - [x] Workflow client - invoking signals - [x] Workflow client - invoking queries 1.1 - [x] ActivityStub and Workflow.newUntypedActivityStub - [x] Remove threading, use coroutines for everything all concurrency - [x] Classes as arguments and return values to/from activity and workflow methods (DataConverter) - [x] Type hints for DataConverter - [x] Parallel activity execution (STATUS: there's a working but not finalized API). 1.2 - [x] Timers - [x] Custom workflow ids through start() and new_workflow_stub() - [ ] WorkflowStub and WorkflowClient.newUntypedWorkflowStub - [ ] ContinueAsNew ![status-wip](https://img.shields.io/badge/status-work_in_progress-lightgrey.svg) - [ ] Sticky workflows ![status-wip](https://img.shields.io/badge/status-work_in_progress-lightgrey.svg) - [ ] Child Workflows ![status-wip](https://img.shields.io/badge/status-work_in_progress-lightgrey.svg) 1.3 - [ ] Support for keyword arguments ![](https://img.shields.io/badge/PRs-welcome-informational) 2.0 - [ ] Compatibility with Java client ![](https://img.shields.io/badge/PRs-welcome-informational) - [ ] Compatibility with Golang client ![](https://img.shields.io/badge/PRs-welcome-informational) - [ ] Upgrade python-betterproto ![](https://img.shields.io/badge/PRs-welcome-informational) Post 2.0: - [ ] sideEffect/mutableSideEffect ![](https://img.shields.io/badge/PRs-welcome-informational) - [ ] Local activity ![](https://img.shields.io/badge/PRs-welcome-informational) - [ ] Cancellation Scopes ![](https://img.shields.io/badge/PRs-welcome-informational) - [ ] Explicit activity ids for activity invocations ![](https://img.shields.io/badge/PRs-welcome-informational) %prep %autosetup -n temporal-python-sdk-1.0.19 %build %py3_build %install %py3_install install -d -m755 %{buildroot}/%{_pkgdocdir} if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi pushd %{buildroot} if [ -d usr/lib ]; then find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst fi if [ -d usr/lib64 ]; then find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst fi if [ -d usr/bin ]; then find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst fi if [ -d usr/sbin ]; then find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst fi touch doclist.lst if [ -d usr/share/man ]; then find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst fi popd mv %{buildroot}/filelist.lst . mv %{buildroot}/doclist.lst . %files -n python3-temporal-python-sdk -f filelist.lst %dir %{python3_sitelib}/* %files help -f doclist.lst %{_docdir}/* %changelog * Tue May 30 2023 Python_Bot - 1.0.19-1 - Package Spec generated