S3-compatible storage
forze[s3] implements object storage — upload, download, list, delete — on AWS
S3 or any S3-compatible endpoint (MinIO, Yandex, …), behind the storage
contracts.
Install¶
uv add 'forze[s3]'
Needs an S3-compatible store. Forze uses existing buckets; it doesn't create them.
The client¶
from forze_s3 import S3Client
s3 = S3Client()
RoutedS3Client (with S3RoutingCredentials) resolves per-tenant endpoints and
keys.
Wire it¶
Each storage route names a bucket and is keyed by StorageSpec.name:
from forze.application.execution import DepsRegistry, LifecyclePlan
from forze_s3 import S3Client, S3DepsModule, S3StorageConfig, s3_lifecycle_step
deps = DepsRegistry.from_modules(
S3DepsModule(client=s3, storages={"assets": S3StorageConfig(bucket="my-assets")}),
)
lifecycle = LifecyclePlan.from_steps(
s3_lifecycle_step(endpoint="https://s3.amazonaws.com", access_key_id="…", secret_access_key="…"),
)
What it provides¶
| Contract | Operations | Keyed by |
|---|---|---|
| Storage query | download, list |
StorageSpec.name (storages) |
| Storage command | upload, delete |
StorageSpec.name (storages) |
Notes¶
- A bucket is required per route —
S3StorageConfig(bucket=...); an empty static bucket name is a configuration error. - Forze never creates or deletes buckets — provision them out of band.
- The bucket can be a static name or a per-tenant resolver;
RoutedS3Client+S3RoutingCredentialscover per-tenant endpoints/credentials. - Downloads return raw bytes — register the FastAPI exception handlers so a missing object maps to a 404.