|
| 1 | +# AWS Integration for Temporal Python SDK |
| 2 | + |
| 3 | +> ⚠️ **This package is currently at an experimental release stage.** ⚠️ |
| 4 | +
|
| 5 | +This package provides AWS integrations for the Temporal Python SDK, including an Amazon S3 driver for [external storage](../../../README.md#external-storage). |
| 6 | + |
| 7 | +## Install Dependencies |
| 8 | + |
| 9 | + python -m pip install "temporalio[aws-s3]" |
| 10 | + |
| 11 | +## S3 Driver |
| 12 | + |
| 13 | +`temporalio.contrib.aws.s3driver.S3StorageDriver` stores and retrieves Temporal payloads in Amazon S3. It requires an [`aioboto3`](https://github.com/terrycain/aioboto3) S3 client and a `bucket` — either a static name or a callable for dynamic per-payload selection. |
| 14 | + |
| 15 | +```python |
| 16 | +import aioboto3 |
| 17 | +import dataclasses |
| 18 | +from temporalio.client import Client |
| 19 | +from temporalio.contrib.aws.s3driver import S3StorageDriver |
| 20 | +from temporalio.converter import DataConverter, ExternalStorage |
| 21 | + |
| 22 | +session = aioboto3.Session() |
| 23 | +# Credentials and region are resolved automatically from the standard AWS credential |
| 24 | +# chain e.g. environment variables, ~/.aws/config, IAM instance profile, and so on. |
| 25 | +async with session.client("s3") as s3_client: |
| 26 | + driver = S3StorageDriver(client=s3_client, bucket="my-temporal-payloads") |
| 27 | + |
| 28 | + client = await Client.connect( |
| 29 | + "localhost:7233", |
| 30 | + data_converter=dataclasses.replace( |
| 31 | + DataConverter.default, |
| 32 | + external_storage=ExternalStorage(drivers=[driver]), |
| 33 | + ), |
| 34 | + ) |
| 35 | +``` |
| 36 | + |
| 37 | +Payloads are stored under content-addressable keys derived from a SHA-256 hash of the serialized payload bytes, segmented by namespace and workflow/activity identifiers when serialization context is available, e.g.: |
| 38 | + |
| 39 | + v0/ns/my-namespace/wfi/my-workflow-id/d/sha256/<hash> |
| 40 | + |
| 41 | +Some things to note about the S3 driver: |
| 42 | + |
| 43 | +* Any driver used to store payloads must also be configured on the component that retrieves them. If the client stores workflow inputs using this driver, the worker must include it in its `ExternalStorage.drivers` list to retrieve them. |
| 44 | +* Credentials, region, endpoint, and other AWS settings are configured on the `aioboto3` client directly. |
| 45 | +* The target S3 bucket must already exist; the driver will not create it. |
| 46 | +* Identical serialized bytes within the same namespace and workflow (or activity) share the same S3 object — the key is content-addressable within that scope. The same bytes used across different workflows or namespaces produce distinct S3 objects because the key includes the namespace and workflow/activity identifiers. |
| 47 | +* Only payloads at or above `ExternalStorage.payload_size_threshold` (default: 256 KiB) are offloaded; smaller payloads are stored inline. Set `payload_size_threshold=None` to offload every payload regardless of size. |
| 48 | +* `max_payload_size` (default: 50 MiB) sets a hard upper limit on the serialized size of any single payload. A `ValueError` is raised at store time if a payload exceeds this limit. Increase it if your workflows produce payloads larger than 50 MiB. |
| 49 | +* Override `driver_name` only when registering multiple `S3StorageDriver` instances with distinct configurations under the same `ExternalStorage.drivers` list. |
| 50 | + |
| 51 | +### Dynamic Bucket Selection |
| 52 | + |
| 53 | +To select the S3 bucket per payload, pass a callable as `bucket`: |
| 54 | + |
| 55 | +```python |
| 56 | +from temporalio.contrib.aws.s3driver import S3StorageDriver |
| 57 | + |
| 58 | +driver = S3StorageDriver( |
| 59 | + client=s3_client, |
| 60 | + bucket=lambda context, payload: ( |
| 61 | + "large-payloads" if payload.ByteSize() > 10 * 1024 * 1024 else "small-payloads" |
| 62 | + ), |
| 63 | +) |
| 64 | +``` |
| 65 | + |
| 66 | +### Required IAM permissions |
| 67 | + |
| 68 | +The AWS credentials used by the `aioboto3` client must have the following S3 permissions on the target bucket and its objects: |
| 69 | + |
| 70 | +```json |
| 71 | +{ |
| 72 | + "Effect": "Allow", |
| 73 | + "Action": [ |
| 74 | + "s3:PutObject", |
| 75 | + "s3:GetObject" |
| 76 | + ], |
| 77 | + "Resource": "arn:aws:s3:::my-temporal-payloads/*" |
| 78 | +} |
| 79 | +``` |
| 80 | + |
| 81 | +`s3:PutObject` is required by components that store payloads (typically the Temporal client and worker sending workflow/activity inputs), and `s3:GetObject` is required by components that retrieve them (typically workers and clients reading results). Components that only retrieve payloads do not need `s3:PutObject`, and vice versa. |
0 commit comments