ccaaws
A small uv-managed Python library for creating boto3 sessions and clients,
including assumed-role clients.
Requires Python >= 3.14.
Install
uv add ccaaws
Usage
import ccaaws
# a plain boto3 session, optionally with a named CLI profile and/or region
sess = ccaaws.session(profile="myprofile", region="eu-west-1")
# a client for any AWS service, reusing a session if one is given
s3 = ccaaws.client("s3", sess=sess)
# or let it create its own session
ec2 = ccaaws.client("ec2", profile="myprofile", region="eu-west-1")
# a client built from temporary assumed-role credentials
sts_client = ccaaws.assumeRoleClient(
"s3",
"arn:aws:iam::123456789012:role/myrole",
"mysession",
profile="myprofile",
region="eu-west-1",
)
# a session built from temporary assumed-role credentials, for creating
# many different clients from the same assumed role
assumedSess = ccaaws.assumeRoleSession(
"arn:aws:iam::123456789012:role/myrole",
"mysession",
)
s3 = ccaaws.client("s3", sess=assumedSess)
ec2 = ccaaws.client("ec2", sess=assumedSess)
# which AWS account the current (or assumed) session's credentials belong to
accountId = ccaaws.getAccountId(sess=assumedSess)
# read a parameter (or SecureString secret) from SSM Parameter Store
value = ccaaws.getParameter("/my/param")
# read a secret from Secrets Manager
secret = ccaaws.getSecret("mySecretId")
# read/write a python dict as a JSON object in S3
data = ccaaws.s3GetJson("mybucket", "mykey.json")
ccaaws.s3PutJson("mybucket", "mykey.json", data)
# yield every item across all pages of a paginated client call
for bucket in ccaaws.paginate(s3, "list_buckets", "Buckets"):
print(bucket["Name"])
API
-
session(profile=None, region=None) -> boto3.SessionCreates a new boto3 session, optionally using a named CLI profile and/or region. -
client(service_name, sess=None, profile=None, region=None, **kwargs) -> AnyCreates a client for the given AWS service, reusingsessif provided, otherwise creating a new session fromprofile/region. Extrakwargsare passed through toSession.client(). -
assumeRoleClient(service_name, role_arn, role_session_name, sess=None, profile=None, region=None, duration_seconds=3600, **kwargs) -> AnyCalls STSAssumeRoleforrole_arnand returns a client forservice_namebuilt from the resulting temporary credentials. Extrakwargsare passed through toSession.client(). -
assumeRoleSession(role_arn, role_session_name, sess=None, profile=None, region=None, duration_seconds=3600) -> boto3.SessionCalls STSAssumeRoleforrole_arnand returns aboto3.Sessionbuilt from the resulting temporary credentials. Use this instead ofassumeRoleClientwhen many different clients need to be created from the same assumed role. -
getAccountId(sess=None, profile=None, region=None) -> strReturns the AWS account id that the given (or newly created) session's credentials belong to. Useful when working with multiple assumed roles to know which account you are currently in. -
getParameter(name, sess=None, profile=None, region=None, withDecryption=True, **kwargs) -> strReads a parameter (includingSecureStringsecrets) from SSM Parameter Store and returns its value. -
getSecret(secretId, sess=None, profile=None, region=None, **kwargs) -> strReads a secret value from AWS Secrets Manager. -
s3GetJson(bucket, key, sess=None, profile=None, region=None, **kwargs) -> AnyReads an S3 object and parses its body as JSON, returning a python object (typically adict). -
s3PutJson(bucket, key, data, sess=None, profile=None, region=None, **kwargs) -> AnyWrites a python object to S3, encoded as JSON. -
paginate(client, operationName, resultKey, **kwargs) -> Iterator[Any]Universal pagination helper: yields every item underresultKeyacross all pages of the paginatedoperationNamecall onclient, passingkwargsthrough topaginate().
Thread safety (AWS Lambda usage)
boto3 sessions are not thread-safe: a boto3.Session (and anything created
from it, like credential resolution state) must not be shared across threads.
boto3 clients created from a session, however, are thread-safe and can be
shared and reused across threads once created.
This matters for Lambda functions that use threads (for example, to fan out
concurrent I/O within a single invocation): create one session() per thread,
but a client() built from that session can be handed to, or shared with,
other threads that need to call the same service.
Recommended patterns for Lambda:
-
Single-threaded handler (the common case): create the session and client(s) once at module scope, outside the handler function, so they are reused across warm invocations of the same execution environment.
import ccaaws # module scope - created once per execution environment, reused across # warm invocations s3 = ccaaws.client("s3") def handler(event, context): return s3.list_buckets()
-
Multi-threaded handler: create a separate
session()per thread (for example, in the thread's target function or via thread-local storage). Clients built from those sessions can then be shared across threads if needed, since clients are thread-safe.import threading import ccaaws threadLocal = threading.local() def getClient(): if not hasattr(threadLocal, "s3"): sess = ccaaws.session() threadLocal.s3 = ccaaws.client("s3", sess=sess) return threadLocal.s3
-
concurrent.futures.ThreadPoolExecutor: the cleaner, more modern way to fan out work across threads. Since a worker function may run on any thread in the pool, each call must create its ownsession();threadingprimitives (locks, thread-local storage) are still useful when workers need to share or protect other state.from concurrent.futures import ThreadPoolExecutor import ccaaws def fetchBucketTags(bucketName: str) -> dict: # one session per call, since this runs on a pool thread s3 = ccaaws.client("s3", sess=ccaaws.session()) return s3.get_bucket_tagging(Bucket=bucketName) def handler(event, context): bucketNames = event["bucketNames"] with ThreadPoolExecutor(max_workers=len(bucketNames)) as pool: return list(pool.map(fetchBucketTags, bucketNames))
Do not store a session() on a module-level variable and then use it from
multiple threads; create one session per thread instead.
Development
uv sync
uv run pytest
Metadata
Release files for ccaaws 1.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| ccaaws-1.1.0.tar.gz | 4.5 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ccaaws-1.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 11.1 kB
Release files / ccaaws-1.1.0.tar.gz
| Download URL | ccaaws-1.1.0.tar.gz |
|---|---|
| Size | 4.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b2f4c2b46b0e2381bef2b7ad8e87b6ed5485def231fec721ca5898c806ed22d1
|
|
BLAKE2b-256 checksum How to use checksums |
9e16bac6b924cbee53c35b93fa93fd1cdb72c12ee5f09ab37138c9784423257f
|
| 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 Sep 6, 2026.
Transparency logRelease files / ccaaws-1.1.0-py3-none-any.whl
| Download URL | ccaaws-1.1.0-py3-none-any.whl |
|---|---|
| Size | 6.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9cf7dc030bbe9570169fce3e78a898190c823ebd5b06eb39fa5d96a93fa95fff
|
|
BLAKE2b-256 checksum How to use checksums |
470ac3299ce9811caf7d3c49e665e21896d8df009eba2ba9b69d1d0060a101d9
|
| 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 Sep 6, 2026.
Transparency logSecurity for ccaaws 1.1.0
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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for ccaaws-1.1.0.tar.gz
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 Sep 6, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.