Install & Compatibility
Where this runs
tested against v1.32.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
py 3.9
✕ build_error
✓ 3.8s
75MB installed
● package 75MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
Client
✓ from temporalio.client import Client
Used to connect to a Temporal Cluster and interact with workflows (start, signal, query).
Worker
✓ from temporalio.worker import Worker
Used to host workflow and activity implementations and poll task queues.
workflow
✓ from temporalio import workflow
Provides decorators like `@workflow.defn` for defining workflows and functions like `workflow.execute_activity` for orchestrating activities.
activity
✓ from temporalio import activity
Provides decorators like `@activity.defn` for defining activities.
workflow.unsafe.imports_passed_through
✓ from temporalio import workflow
with workflow.unsafe.imports_passed_through():
from my_app import my_activity_module
Crucial for importing activity modules into workflow files when those activity modules have non-deterministic or non-standard library imports, to prevent sandbox errors.
This quickstart demonstrates how to define an activity and a workflow, configure and start a Temporal worker to process tasks, and execute a workflow. It connects to a local Temporal server (defaulting to `localhost:7233`) and includes `os.environ.get` for flexible configuration.
import asyncio
from datetime import timedelta
from temporalio.client import Client
from temporalio.worker import Worker
from temporalio import activity, workflow
# Define an activity
@activity.defn
async def say_hello(name: str) -> str:
return f"Hello, {name}!"
# Define a workflow
@workflow.defn
class GreetingWorkflow:
@workflow.run
async def run(self, name: str) -> str:
return await workflow.execute_activity(
say_hello,
name,
schedule_to_close_timeout=timedelta(seconds=5),
)
async def main():
# Connect to Temporal server (default to localhost:7233)
# Use os.environ.get('TEMPORAL_HOST_PORT', 'localhost:7233') for dynamic connection
client = await Client.connect(os.environ.get('TEMPORAL_HOST_PORT', 'localhost:7233'))
# Run a worker
task_queue_name = "my-task-queue"
worker = Worker(
client,
task_queue=task_queue_name,
workflows=[GreetingWorkflow],
activities=[say_hello],
)
# Start worker in background
worker_task = asyncio.create_task(worker.run())
print(f"Worker started on task queue '{task_queue_name}'...")
# Start a workflow execution
result = await client.execute_workflow(
GreetingWorkflow.run,
"Temporal",
id="greeting-workflow-id",
task_queue=task_queue_name,
)
print(f"Workflow result: {result}") # Expected: "Hello, Temporal!"
# Clean up worker
worker_task.cancel()
await worker_task
if __name__ == "__main__":
import os
asyncio.run(main())
Debug
Known issues
breakingPython 3.9 support was removed in version 1.19.0 as it reached End-of-Life. Users on Python 3.9 must upgrade to Python 3.10 or newer.fixUpgrade Python environment to 3.10 or a later supported version.
affects: >=1.19.0
breakingIn version 1.23.0, fields `workflow_id`, `workflow_namespace`, `workflow_run_id`, and `workflow_type` within `activity.Info` were made optional. Additionally, `converter.BaseWorkflowSerializationContext` was removed.fixAdjust code that manually accesses `activity.Info` fields to handle potential `None` values. Refactor any custom `BaseWorkflowSerializationContext` subclasses.
affects: >=1.23.0
breakingVersion 1.24.0 introduces general availability for Nexus and OpenAI Agents SDK Integration. It also includes new OpenTelemetry integration for OpenAI Agents, which may cause conflicts or require adjustments for existing custom OpenTelemetry setups.fixReview and update OpenTelemetry tracing configurations if using OpenAI Agents with custom instrumentation. Leverage the GA features of Nexus and OpenAI Agents.
affects: >=1.24.0
gotchaBeginning with version 1.21.0, providing an `api_key` to `Client.connect` automatically enables TLS.fixIf you wish to use an `api_key` without TLS, explicitly pass `tls=False` to `Client.connect`.
affects: >=1.21.0
gotchaThe Workflow Sandbox isolates workflow code to ensure determinism. Importing non-standard library or non-`temporalio` modules directly into workflow files can lead to `RestrictedWorkflowAccessError` or non-determinism.fixFor modules needed only by activities, import them within the activity function, or use `with workflow.unsafe.imports_passed_through(): import my_module` when importing them into workflow files. For performance, pass through any side-effect-free third-party libraries explicitly.
affects: All versions with sandbox enabled (default)
breakingInstalling `temporalio` on Alpine Linux (especially with newer Python versions for which pre-built wheels may not exist) can fail due to missing build dependencies like `libgcc_s.so.1` or incompatible Rust compilation. Alpine's musl libc often requires specific system packages or a different Rust target to successfully compile native extensions.fixOn Alpine Linux, ensure `build-base`, `gcc`, `g++`, and `rustup` (with the `x86_64-unknown-linux-musl` target) are installed in the build environment. For simpler deployments, consider using a glibc-based Python image (e.g., Debian-based) where pre-built `temporalio` wheels are more commonly available.
affects: All versions when attempting to build from source on Alpine Linux without necessary system dependencies.
Errors
Common errors & fixes
grpc._channel._MultiThreadedRendezvous: <_MultiThreadedRendezvous of RPC that terminated with: status = StatusCode.UNAVAILABLE
The Temporal client cannot establish a connection with the Temporal server, usually because the server is not running or is unreachable at the specified address.
fixEnsure the Temporal server is running and confirm the `target_host` (e.g., `localhost:7233`) used in `Client.connect()` matches the server's address and port.
ApplicationError: type='temporal.workflow.NotFound', message='Workflow with name "MyWorkflow" is not registered on the worker.'
The worker instance has not been configured to register the workflow class, or the task queue used to start the workflow does not match the worker's task queue.
fixAdd the workflow class to the worker's `workflows` list and ensure the worker's `task_queue` argument matches the task queue specified when starting the workflow. Example: `Worker(client, task_queue='my-task-queue', workflows=[MyWorkflow])`.
RuntimeError: Workflow must not 'await' non-Temporal futures. Instead, use 'temporalio.workflow.asyncio.sleep', 'temporalio.workflow.asyncio.wait', etc.
Temporal workflows require deterministic execution and cannot directly await arbitrary Python `asyncio` futures or blocking calls; they must use Temporal's specific asynchronous primitives or delegate to activities.
fixReplace non-Temporal `await` calls (e.g., `await asyncio.sleep()`, `await aiohttp.get()`) with their deterministic Temporal counterparts (e.g., `await workflow.sleep()`) or encapsulate the non-deterministic logic within a Temporal Activity.
ModuleNotFoundError: No module named 'temporalio'
The `temporalio` Python SDK library has not been installed in the current Python environment.
fixInstall the library using pip: `pip install temporalio`.
Upgrade
Version history
1.32.0latest on PyPI · released Aug 24, 2026
Audit
Dependencies
PythonrequiredRuntime requirement
openai-agentsoptionalOptional integration for OpenAI Agent SDK
google-adkoptionalOptional integration for Google ADK agents
opentelemetryoptionalOptional integration for OpenTelemetry tracing
pydanticoptionalOptional support for Pydantic models in data conversion
grpcoptionalOptional gRPC dependency for advanced use cases