bucket_helper package
Submodules
Module contents
Bucket Helper
Utility functions for AWS S3 and any S3-compatible object storage
(MinIO, Backblaze B2 S3 API, DigitalOcean Spaces, Cloudflare R2,
Wasabi, …) via boto3. Same shape as sftp-helper:
credentials() loader + upload / download / delete /
exists / list_prefix / make_bucket + a remote_tempfile
context manager for stage-and-share flows.
Also exposes multi-surface entry points:
Library (this module) — the pure functions.
CLI —
bucket_helper.cli(bucket-helper), built with click.FastAPI HTTP —
bucket_helper.api(uvicorn bucket_helper.api:app).
Usage Example
>>> import bucket_helper as bh
>>> cred = bh.credentials("path/to/settings.yaml")
>>> uri = bh.upload("local.txt", cred, "folder/uploaded.txt")
>>> assert bh.exists(uri, cred)
>>> bh.download(uri, "back.txt", cred)
>>> bh.delete(uri, cred)
- bucket_helper.credentials(config_path=None)[source]
Retrieve S3 credentials from a configuration file, folder, or environment.
Loads (in this precedence order) from JSON / YAML files,
.env, then environment variables — seeos_helper.get_config().Required keys
s3_access_key: your access key IDs3_secret_key: your secret access keys3_bucket: default bucket names3_https: base public URL for built objects, e.g."https://my-bucket.s3.eu-west-3.amazonaws.com"or"https://cdn.example.com"(used byremote_tempfileto build the public URL handed back to the caller)
Optional keys
s3_region: AWS region (defaults to"us-east-1"if absent, mostly irrelevant for path-style MinIO etc.)s3_endpoint_url: custom endpoint for S3-compatible storage (MinIO, R2, B2, Spaces, Wasabi). Empty / missing → AWS S3.s3_prefix: default key prefix (path-like, e.g."uploads")s3_use_path_style:"true"to force path-style addressing (typical for MinIO with custom domains). Default"false"(uses virtual-hosted style).s3_verify_ssl:"false"to disable TLS verification (use sparingly — e.g. dev MinIO with self-signed cert).
- returns:
Credentials dict.
- rtype:
dict
- bucket_helper.delete(s3_address, cred)[source]
Delete an S3 object. Returns True if the object is gone after the call (including the case where it never existed — S3’s delete is idempotent).
- bucket_helper.download(s3_address, local_path, cred)[source]
Download an S3 object to a local path. Returns
local_pathon success.
- bucket_helper.exists(s3_address, cred)[source]
Return True if the object at
s3_addressexists, False otherwise.
- bucket_helper.get_client_s3(cred)[source]
Open a boto3 S3 client honoring
credconfiguration.The client is configured per AWS S3 (no
endpoint_url) or per the S3-compatible endpoint whencred["s3_endpoint_url"]is set.
- bucket_helper.list_prefix(prefix, cred, *, max_keys=1000)[source]
List the object keys under
prefixin the default bucket.Returns at most
max_keyskeys, ordered by S3’s lexicographic response (no client-side sort). For very large prefixes, paginate via boto3 directly withget_client_s3.
- bucket_helper.list_prefix_page(prefix, cred, *, max_keys=1000)[source]
List keys under
prefix, and say whether more were left behind.list_prefix()returns at mostmax_keyskeys and cannot tell the caller whether that was all of them. For a human reading a terminal that is a mild annoyance; for a program it is a correctness problem, because a response of 1000 keys looks identical whether the prefix holds exactly 1000 objects or fifty thousand.This asks S3 for one key more than it will return. If that extra key arrives, there is more behind it. The cost is a single additional key, and it turns an ambiguous answer into a definite one.
- Parameters:
prefix (str) – Key prefix to list under, in the credentials’ default bucket.
cred (dict) – Credentials, as accepted by
get_client_s3().max_keys (int, default 1000) – Maximum number of keys to return.
- Returns:
The keys (at most
max_keysof them), andTruewhen S3 held more than that under the prefix.- Return type:
Examples
>>> keys, truncated = list_prefix_page("logs/", cred, max_keys=10) >>> if truncated: ... print("there are more than 10 objects under logs/")
- bucket_helper.make_bucket(bucket, cred)[source]
Create a bucket if it doesn’t exist.
Honors
cred["s3_region"]for the LocationConstraint. No-op when the bucket already exists and is owned by the credentials.
- bucket_helper.remote_tempfile(cred, *, ext='', prefix='')[source]
Yield
(s3_address, public_url)for a unique key, deleted on exit.Useful for stage-and-share flows: upload a generated file, hand the public URL to whoever needs it (a downstream worker, a webhook target, a test fixture), and let the context manager clean up the remote artifact at the end of the block — even on exception.
- Parameters:
cred (dict) – Credentials dict from
credentials(). The object goes undercred["s3_bucket"]; the public URL is built fromcred["s3_https"].ext (str, optional) – Extension to append to the random name (with or without leading
.). Default empty.prefix (str, optional) – Extra path segment under the bucket / default prefix. Default empty.
- Yields:
(s3_address, public_url) (tuple of str) –
s3_addressis"s3://bucket/key";public_urlis thehttps://...URL built fromcred["s3_https"].- Return type:
Example
>>> import bucket_helper as bh >>> cred = bh.credentials("path/to/settings.yaml") >>> with bh.remote_tempfile(cred, ext="json") as (addr, url): ... bh.upload("payload.json", cred, addr, content_type="application/json") ... # publish `url` somewhere, e.g. trigger a webhook >>> # the object is gone after the block — even if the body raised.
- bucket_helper.strip_s3_path(s3_address, cred)[source]
Return the key part of
s3_address(compat with sftp-helper’sstrip_sftp_path).
- bucket_helper.upload(local_path, cred, s3_address='', content_type=None)[source]
Upload a local file to S3.
- Parameters:
local_path (str) – Path to the local file.
cred (dict) – Credentials dict from
credentials().s3_address (str, optional) – Destination — either
"s3://bucket/key"or a key under the default bucket. If empty, a random unique hex name is generated (not derived from the file’s content) undercred["s3_prefix"](if set) of the default bucket.content_type (str, optional) – Override the MIME
Content-Typeheader. If None, boto3 lets the server default (typicallyapplication/octet-stream).
- Returns:
The full
s3://bucket/keyURI of the uploaded object.- Return type:
- Raises:
botocore.exceptions.ClientError – If the upload fails (permissions, bucket missing, network).
AssertionError – If
local_pathdoes not exist or is empty.