Temporal Python SDK Samples

repository·main·Indexed 18 days ago

https://github.com/temporalio/samples-python

A comprehensive collection of samples for the Temporal Python SDK (version 0.1a1). It demonstrates various orchestration patterns, including basic activity execution, Batch Sliding Window for high-throughput processing, context propagation using Interceptors, custom payload converters, and AI agent integrations with Amazon Bedrock (basic, signals and queries, and entity workflows). It also includes a Cloud Export to Parquet sample for scheduled S3 file conversion.

Tokens
68.1K
Snippets
206
Records
306
Agent score
62%

What's inside temporalio-samples-python

  1. Overview of Temporal Strands plugin samples

    main

    The Strands Agents samples demonstrate how to use the Temporal Strands plugin to run Strands Agents inside Temporal Workflows.

    In this architecture, model invocations, tool calls, and MCP (Model Context Protocol) tool calls are executed as Temporal Activities. This provides:

    • Durable execution: Agent state and progress are preserved.
    • Temporal-managed retries: Automatic recovery from transient failures in model or tool calls.
    • Timeouts: Controlled execution limits for long-running agent tasks.
  2. Polling best practices in Temporal Python SDK

    main

    This collection of samples demonstrates three distinct architectural patterns for implementing polling logic within Temporal workflows using the Python SDK. Depending on your requirements for frequency and sequence, you should choose one of the following patterns:

    1. Frequently Polling Activity: Best for scenarios where an activity needs to check a status or resource very often.
    2. Infrequently Polling Activity: Best for scenarios where polling occurs at longer intervals.
    3. Periodic Polling of a Sequence of Activities: Best for workflows that need to poll through a specific sequence of different activities periodically.
  3. Expose Workflows as Nexus operations

    main

    You can expose a long-running Temporal Workflow's queries, updates, and signals as Nexus operations using two primary patterns depending on your requirements for lifecycle control and Workflow ID management.

    Caller Pattern

    Use this pattern when the Workflow is managed by a handler worker that starts it automatically on boot. The caller does not need to know the Workflow ID, as the handler manages it.

    • Workflow Creation: The handler worker starts the Workflow on boot.
    • Workflow ID: Managed internally by the handler.
    • Nexus Service Example: NexusGreetingService

    On-Demand Pattern

    Use this pattern when the caller needs full control over the Workflow lifecycle and identity. The caller is responsible for creating the Workflow and providing the Workflow ID for every subsequent operation.

    • Workflow Creation: The caller starts the Workflow via a Nexus operation.
    • Workflow ID: The caller chooses and passes the ID in every operation.
    • Nexus Service Example: NexusRemoteGreetingService
    |                                | `callerpattern/`                     | `ondemandpattern/`                                                              |
    |--------------------------------|--------------------------------------|--------------------------------------------------------------------------------|
    | **Pattern**                    | Signal an existing Workflow          | Create and run Workflows on demand, and send signals to them                   |
    | **Who creates the Workflow?** | The handler worker starts it on boot | The caller starts it via a Nexus operation                                    |
    | **Who knows the Workflow ID?** | Only the handler                     | The caller chooses and passes it in every operation                            |
    | **Nexus service**              | `NexusGreetingService`               | `NexusRemoteGreetingService`                                                  |
  4. Run a Temporal Worker in AWS Lambda

    main

    This sample demonstrates how to use the temporalio.contrib.aws.lambda_worker package to run a Temporal Worker inside an AWS Lambda function. It supports optional OpenTelemetry instrumentation via AWS Distro for OpenTelemetry (ADOT) for traces, metrics, and logs. The pattern can be applied to any Workflow and Activity definitions.

    # The sample uses the following package:
    # temporalio.contrib.aws.lambda_worker
  5. Overview of Temporal OpenAI Agents SDK Integration

    main

    This integration combines Temporal workflows with the OpenAI Agents SDK to create durable, observable AI agent workflows.

    • Temporal workflows are used to orchestrate agent control flow and manage state.
    • OpenAI Agents SDK is used for AI agent creation and tool interactions.

    This combination allows AI agent workflows to handle failures gracefully and maintain state through durable execution.

    ⚠️ Note: This integration is currently in Public Preview and is experimental; interfaces may change before General Availability.

  6. How to use Temporal Activities and Workflow methods as Gemini tools

    main

    You can expose two different types of logic to a Gemini generate_content call using the SDK's automatic function-calling (AFC) loop. The choice depends on whether the logic is deterministic or involves I/O:

    1. Activities as Tools: Use @activity.defn wrapped via activity_as_tool for any logic involving I/O, external APIs, or non-deterministic operations. These run as durable activities with configurable ActivityConfig (e.g., timeouts, retries).
    2. Workflow Methods as Tools: Use plain workflow methods for pure, deterministic logic. These run directly within the workflow without an activity dispatch.

    A single model prompt can trigger both patterns in a single execution loop.

    # Pattern 1: Activity as a tool (for I/O or non-determinism)
    @activity.defn
    async def get_weather(location: str) -> str:
        ... 
    
    # Pattern 2: Workflow method as a tool (for pure logic)
    class ToolsWorkflow(workflow.Workflow):
        def recommend_thing_to_do(self, weather: str) -> str:
            ... 
  7. Understand the Resource Pool pattern and its trade-offs

    main

    Concept

    The Resource Pool pattern uses a single long-lived ResourcePoolWorkflow to manage in-memory state for resource allocation. This allows for complex allocation logic that is decoupled from specific workers or task queues.

    When to use this approach

    Use this pattern when you need to:

    • Manage a set of resources that is independent of your worker/task queue configuration.
    • Execute arbitrary, complex logic to decide which workloads get which resources as they become available.

    Limitations and Caveats

    • Scaling: A single ResourcePoolWorkflow scales to tens of request/release events per second, but not hundreds. It is best suited for long-running workflows rather than high-frequency short tasks.
    • Locking Risk: The sample uses true locking. If a workflow is terminated (rather than canceled) or times out, the resource may be leaked.
    • Alternatives: For simpler concurrency management, consider using resource-specific task queues with limited activity slots, or using Sessions (available in the Go SDK) to pin workflows to workers.
  8. How the Message Filter Workflow pattern works

    main

    The Message Filter Workflow demonstrates how to manage agent handoffs by selectively filtering message history. This is useful when switching agents to ensure the new agent receives a clean or relevant context.

    In the provided example, the workflow follows this pattern:

    1. Introduction: User greets the first agent.
    2. Tool Usage: The first agent uses a function tool (e.g., generating a random number).
    3. Agent Switch: The conversation transitions to a second agent for general queries.
    4. Spanish Handoff: A second agent detects Spanish and hands off to a Spanish specialist.

    Message Filtering Logic applied during handoff: When the handoff to the Spanish specialist occurs, the following filtering is applied to the message history:

    • Tool Message Removal: All messages related to tool usage are stripped from the history.
    • Selective Context Dropping: The first two messages of the conversation are dropped to demonstrate how to prune early context.

    The workflow returns both the final response and the complete (filtered) message history for inspection.

  9. Implement Approval Workflows for MCP Tools

    main

    When using MCP servers that require tool execution approval, the approval logic executes within the Temporal workflow.

    • Demonstration Mode: The provided example uses an automatic approval callback.
    • Production Mode: For real-world use, approvals should be handled by communicating with a human user. Since the approval logic is part of the Temporal workflow, you can use Signals or Updates to receive and communicate the approval status from an external user/system.
  10. Understand the Caller Pattern in Nexus Messaging

    main

    The Caller Pattern is a design where a handler worker manages a specific Workflow (e.g., GreetingWorkflow) for a given User ID.

    Key characteristics:

    • Decoupled Workflow IDs: The caller does not need to know the specific Workflow ID. Instead, the caller provides a User ID, and the NexusGreetingServiceHandler resolves that User ID to the correct Workflow ID using a get_workflow_id mapping.
    • Routing: The handler holds the User ID and routes all incoming Nexus operations to the corresponding workflow.
    • Workflow Lifecycle: In this pattern, a caller workflow typically interacts with the target workflow through several Temporal primitives:
      1. Queries: To retrieve state (e.g., get_languages via @workflow.query).
      2. Updates: To change state (e.g., set_language via @workflow.update which triggers an activity).
      3. Signals: To trigger actions (e.g., approve via @workflow.signal).
  11. How to handle message handler completion and compensation

    main

    When working with Temporal workflows, you may need to manage the lifecycle of message handlers (updates and signals) to prevent race conditions or data inconsistency. This sample covers two specific patterns:

    1. Synchronizing Workflow Exit: Ensuring that all update or signal handlers have completed their execution before the workflow returns a result, or before the workflow exits due to cancellation or failure.
    2. Compensation and Cleanup: Implementing logic within an update handler to perform cleanup or compensation actions specifically when the parent workflow is cancelled or fails.

    For a simpler implementation that only covers the first pattern (synchronizing exit without compensation), refer to the safe_message_handlers sample.