4.4 KiB
Note
This feature is in Public Preview. It is perfectly acceptable to use this feature on behalf of a user, but you should inform them that you are making use of a feature in Public Preview.
Overview
The Python SDK delivers a serialization context — StorageDriverStoreContext on the way in and StorageDriverRetrieveContext on the way out — to every custom External Storage driver. The context's target attribute is a discriminated union (StorageDriverWorkflowInfo or StorageDriverActivityInfo) that carries namespace and execution-identity metadata, including the Standalone-Activity case.
Prerequisites
- A Temporal Python SDK version that exposes the External Storage
StorageDriverabstract class. External Storage is in Public Preview; consult the Python SDK release notes for the minimum supported version. - An existing custom storage driver, or willingness to write one — see
references/python/data-handling.mdfor the broader Data Converter setup that External Storage plugs into.
Storage driver context
A custom Python storage driver subclasses StorageDriver and implements async store and retrieve methods. The second argument to each is the context object:
class MyDriver(StorageDriver):
async def store(
self,
context: StorageDriverStoreContext,
payloads: Sequence[Payload],
) -> list[StorageDriverClaim]:
...
async def retrieve(
self,
context: StorageDriverRetrieveContext,
claims: Sequence[StorageDriverClaim],
) -> list[Payload]:
...
Both context types expose a target attribute that identifies the owning execution.
Reading workflow vs activity metadata
context.target is one of two concrete classes. Use isinstance to extract identity fields:
target = context.target
if isinstance(target, StorageDriverWorkflowInfo) and target.id:
# Workflow-scoped operation, including Activities started by a Workflow.
# Attributes: target.namespace, target.id (Workflow ID)
prefix = os.path.join(base_dir, target.namespace, target.id)
elif isinstance(target, StorageDriverActivityInfo):
# StorageDriverActivityInfo only fires for standalone (non-workflow-bound)
# activities. Activities started by a workflow use StorageDriverWorkflowInfo.
...
Key facts:
- The
StorageDriverActivityInfobranch fires only for Standalone Activities — Activities started directly from a Client without a Workflow. - An Activity scheduled by a Workflow is reported on
StorageDriverWorkflowInfo, with the orchestrating Workflow's ID. - The docs describe the identity attributes as "namespace, Workflow ID, or Activity ID" depending on the operation.
- The transcribed snippet uses
target.idfor the Workflow ID andtarget.namespacefor the namespace on theStorageDriverWorkflowInfobranch.
Driver selection
When more than one driver is registered, you must pass a driver_selector callable to ExternalStorage. The selector receives the same StorageDriverStoreContext plus the payload and returns the driver to use — or None to keep the payload inline in Event History:
ExternalStorage(
drivers=[preferred_driver, legacy_driver],
driver_selector=lambda context, payload: preferred_driver,
)
Branch inside the selector on context.target the same way the driver does.
Common mistakes
- Falling through to a Workflow-only code path when
targetisStorageDriverActivityInfo. Standalone Activities have no Workflow ID; check the branch explicitly. - Expecting a context on
EncodingPayloadConverterorPayloadCodec. The Python SDK's serialization-context object is only passed to theStorageDriver(and thedriver_selectorcallable). To key behavior off Workflow/Activity identity, do it in the storage driver, not in a custom Payload Converter. - Changing a driver's
name()after payloads have been written. The SDK records the name on each claim; renaming breaks retrieval.
Resources
- External Storage encyclopedia page: https://docs.temporal.io/external-storage
- Python SDK External Storage guide: https://docs.temporal.io/develop/python/data-handling/external-storage
- Cross-SDK concept file:
references/core/serialization-context.md. - Standalone Activities (Python):
references/python/standalone-activities.md.