Remote-backed workspace sync for Temporal activities
Project description
Workspace Sync for Temporal Activities
Sync a local directory with remote storage before and after a Temporal activity. Enables file-based activities to work across distributed workers where disk is not shared.
Problem
Temporal activities that read/write files on local disk break when you scale to multiple worker instances. Each worker has its own disk. This module syncs a remote storage location to a local temp directory before the activity runs, and pushes changes back after.
Install
pip install temporal-workdir
# With a specific cloud backend:
pip install temporal-workdir gcsfs # Google Cloud Storage
pip install temporal-workdir s3fs # Amazon S3
pip install temporal-workdir adlfs # Azure Blob Storage
Usage
As a context manager (generic, works anywhere)
from temporal_workdir import Workspace
async with Workspace("gs://my-bucket/pipeline/component-x") as ws:
# ws.path is a local Path — read and write files normally
data = json.loads((ws.path / "component.json").read_text())
(ws.path / "result.csv").write_text("col1,col2\nval1,val2")
# On clean exit: local dir is archived and uploaded
# On exception: no upload (remote state unchanged)
As a Temporal activity decorator
from temporalio import activity
from temporal_workdir import workspace, get_workspace_path
@workspace("gs://my-bucket/{workflow_id}/{activity_type}")
@activity.defn
async def extract(input: ExtractInput) -> ExtractOutput:
ws = get_workspace_path()
# Template vars resolved from activity.info()
source = (ws / "source.json").read_text()
(ws / "output.csv").write_text(process(source))
return ExtractOutput(success=True)
Custom template variables
@workspace(
"gs://my-bucket/{workflow_id}/components/{component}",
key_fn=lambda input: {"component": input.component_name},
)
@activity.defn
async def register(input: RegisterInput) -> RegisterOutput:
ws = get_workspace_path()
...
How It Works
- Pull: On entry, downloads
{remote_url}.tar.gzand unpacks to a temp directory - Execute: Your activity reads/writes files in the local directory
- Push: On clean exit, packs the directory into
tar.gzand uploads
If the archive doesn't exist yet (first run), the local directory starts empty. If the activity raises an exception, no push happens. Remote state is untouched.
Storage Backends
Any backend supported by fsspec:
| Scheme | Backend | Extra package |
|---|---|---|
gs:// |
Google Cloud Storage | gcsfs |
s3:// |
Amazon S3 | s3fs |
az:// |
Azure Blob Storage | adlfs |
file:// |
Local filesystem | (none) |
memory:// |
In-memory (testing) | (none) |
Pass backend-specific options as keyword arguments:
Workspace("gs://bucket/key", project="my-gcp-project", token="cloud")
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file temporal_workdir-0.2.1.tar.gz.
File metadata
- Download URL: temporal_workdir-0.2.1.tar.gz
- Upload date:
- Size: 9.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2dc52f534c510fc3e0de5febe4e5720afeb521488a5909575dffda7d806e114d
|
|
| MD5 |
ccc81b7ddc5fa8904c44b11545436196
|
|
| BLAKE2b-256 |
c5ac6f80ce9c2b14da17b983ed0d57807654f267b04528e1d104364c339775e5
|
Provenance
The following attestation bundles were made for temporal_workdir-0.2.1.tar.gz:
Publisher:
release.yml on saeedseyfi/temporal-workdir
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
temporal_workdir-0.2.1.tar.gz -
Subject digest:
2dc52f534c510fc3e0de5febe4e5720afeb521488a5909575dffda7d806e114d - Sigstore transparency entry: 1151112914
- Sigstore integration time:
-
Permalink:
saeedseyfi/temporal-workdir@37a818593cc072f81d9f412ca99e94106ab82dd7 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/saeedseyfi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@37a818593cc072f81d9f412ca99e94106ab82dd7 -
Trigger Event:
push
-
Statement type:
File details
Details for the file temporal_workdir-0.2.1-py3-none-any.whl.
File metadata
- Download URL: temporal_workdir-0.2.1-py3-none-any.whl
- Upload date:
- Size: 8.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fdc5d71a6e773bf0ccaeecd8a3e891b1dd01d1f9987e418f3b0c29fa747b5355
|
|
| MD5 |
e76a11130fa7ea240eda6686986c7bd0
|
|
| BLAKE2b-256 |
a26baf991f5165b973c6194ce53b3c6543e6bb045b27d18e854ad2f8f179fa63
|
Provenance
The following attestation bundles were made for temporal_workdir-0.2.1-py3-none-any.whl:
Publisher:
release.yml on saeedseyfi/temporal-workdir
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
temporal_workdir-0.2.1-py3-none-any.whl -
Subject digest:
fdc5d71a6e773bf0ccaeecd8a3e891b1dd01d1f9987e418f3b0c29fa747b5355 - Sigstore transparency entry: 1151112965
- Sigstore integration time:
-
Permalink:
saeedseyfi/temporal-workdir@37a818593cc072f81d9f412ca99e94106ab82dd7 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/saeedseyfi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@37a818593cc072f81d9f412ca99e94106ab82dd7 -
Trigger Event:
push
-
Statement type: