Skip to main content

Toolframe S3 object storage

object-store-s3 keeps private Toolframe files in an existing S3-compatible bucket. It implements toolframe.object_store v1, matching the local provider's SDK client and Dashboard image workflow. RustFS is the local integration target.

Quick start

Use Toolframe Core 0.6.2 and SDK 0.3.0 with object-storage support. Create a private bucket first. Supply credentials through the standard AWS chain in the environment that starts Core (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, optional AWS_SESSION_TOKEN, or a supported AWS profile/role).

With the plugin installed but disabled, set its configuration in toolframe.toml:

[plugins.object-store-s3]
source = "pypi:toolframe-object-store-s3==0.1.0"
enabled = false

[plugins.object-store-s3.config]
bucket = "toolframe-images"
endpoint_url = "http://127.0.0.1:9000"
region = "us-east-1"
prefix = "toolframe"
addressing_style = "path"
max_object_bytes = 67108864

Core downloads the pinned package from PyPI when applying this configuration. Omit endpoint_url for AWS S3. TLS verification stays enabled for HTTPS endpoints. Use addressing_style = "virtual" when required by your service. Do not put access keys, secrets or URL credentials in plugin configuration.

toolframe-core --home APP plugin enable object-store-s3

Disable the local object-store provider before enabling S3; each application selects one provider. Existing local files do not migrate automatically. Business code continues to use self.context.object_store() unchanged.

Storage and permissions

Objects live under <prefix>/<sha256(application-id)>/<plugin-id>/<key>. The provider only accesses the existing bucket; it never creates buckets, changes ACLs or enables public access. Grant ListBucket on the configured prefix and GetObject, PutObject and DeleteObject for its objects. Keep application IDs and prefixes stable across restarts. Use bucket backup/versioning policies for recovery.

Core inherits the AWS environment into trusted workers. Use an application-scoped credential/profile; this is not a credential sandbox between untrusted plugins. head_bucket checks access during activation. Service errors do not return SDK exception text, credentials or endpoints to callers.

Uploads stage in bounded local temporary files before one atomic PutObject. Content type and SHA-256 metadata are retained. Range reads use S3 conditional requests to reject concurrent replacement. The common limit is 64 MiB per object, 256 KiB per wire chunk, 32 unfinished uploads and 256 MiB staging per worker; max_object_bytes may lower the object limit. Sessions expire after ten minutes. Completed data survives plugin removal; unfinished uploads do not survive restart. There is no cross-resource transaction, durable upload resumption, presigned URL, public download endpoint or automatic migration in this version.

Test with RustFS

Follow the official RustFS container instructions. Use a dedicated test bucket and credentials. Example local-only container:

# rustfs.env contains private RUSTFS_ACCESS_KEY and RUSTFS_SECRET_KEY values.
docker run -d --name toolframe-rustfs --env-file ./rustfs.env \
  -p 127.0.0.1:9000:9000 -p 127.0.0.1:9001:9001 \
  -v toolframe-rustfs-data:/data -v toolframe-rustfs-logs:/logs \
  rustfs/rustfs:latest

For sibling development checkouts with the matching SDK:

uv sync --group dev
uv run pytest -q                     # stub tests; live test explicitly skips
export TOOLFRAME_TEST_S3_ENDPOINT=http://127.0.0.1:9000
export TOOLFRAME_TEST_S3_BUCKET=toolframe-test
# Set AWS credentials separately, then create this dedicated bucket once.
uv run pytest -q                     # includes the live integration test
uv run ruff check src tests
uv build --no-sources

The integration test uses a unique prefix and removes only the objects it created. It checks a >1 MiB upload, exact download, empty files, restart, application isolation, replacement detection, pagination and deletion. Record the container image digest with acceptance evidence. Runtime validation requires a separate application because a scratch home does not isolate the remote bucket. AWS S3 and other compatible services require their own acceptance run; RustFS coverage does not establish compatibility with every S3 extension.

Licensed under Apache-2.0; see LICENSE.

For release validation and Trusted Publisher setup, see releasing.

Metadata

Release files for toolframe-object-store-s3 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for toolframe-object-store-s3 0.1.0
File Size Uploaded
toolframe_object_store_s3-0.1.0.tar.gz 34.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for toolframe-object-store-s3 0.1.0
File Interpreter ABI Platform
toolframe_object_store_s3-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 45.5 kB

Release files / toolframe_object_store_s3-0.1.0.tar.gz

Download URL toolframe_object_store_s3-0.1.0.tar.gz
Size 34.9 kB
Tags Source
SHA-256 checksum
How to use checksums
a4767cc13f79f296bf07491c0f786e8dfc11ff5124e67647553389b47b53f9a1
BLAKE2b-256 checksum
How to use checksums
96f8489274b34ea58c8a7364f8cf472866c6ca40c975a9b8f3556fc3c55bd3c6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Release files / toolframe_object_store_s3-0.1.0-py3-none-any.whl

Download URL toolframe_object_store_s3-0.1.0-py3-none-any.whl
Size 10.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f3c3a430b7469f0d7df1083141d0d3f61901a0c0da24cf87272ed21a67577f80
BLAKE2b-256 checksum
How to use checksums
8c83678ef50e7554a8b55764e11171d3e10e8f76689b6a696cfd19eae8805b2d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page