Skip to main content

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.Session Creates a new boto3 session, optionally using a named CLI profile and/or region.

  • client(service_name, sess=None, profile=None, region=None, **kwargs) -> Any Creates a client for the given AWS service, reusing sess if provided, otherwise creating a new session from profile/region. Extra kwargs are passed through to Session.client().

  • assumeRoleClient(service_name, role_arn, role_session_name, sess=None, profile=None, region=None, duration_seconds=3600, **kwargs) -> Any Calls STS AssumeRole for role_arn and returns a client for service_name built from the resulting temporary credentials. Extra kwargs are passed through to Session.client().

  • assumeRoleSession(role_arn, role_session_name, sess=None, profile=None, region=None, duration_seconds=3600) -> boto3.Session Calls STS AssumeRole for role_arn and returns a boto3.Session built from the resulting temporary credentials. Use this instead of assumeRoleClient when many different clients need to be created from the same assumed role.

  • getAccountId(sess=None, profile=None, region=None) -> str Returns 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) -> str Reads a parameter (including SecureString secrets) from SSM Parameter Store and returns its value.

  • getSecret(secretId, sess=None, profile=None, region=None, **kwargs) -> str Reads a secret value from AWS Secrets Manager.

  • s3GetJson(bucket, key, sess=None, profile=None, region=None, **kwargs) -> Any Reads an S3 object and parses its body as JSON, returning a python object (typically a dict).

  • s3PutJson(bucket, key, data, sess=None, profile=None, region=None, **kwargs) -> Any Writes a python object to S3, encoded as JSON.

  • paginate(client, operationName, resultKey, **kwargs) -> Iterator[Any] Universal pagination helper: yields every item under resultKey across all pages of the paginated operationName call on client, passing kwargs through to paginate().

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 own session(); threading primitives (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

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ccaaws-1.1.0.tar.gz (4.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ccaaws-1.1.0-py3-none-any.whl (6.6 kB view details)

Uploaded Python 3

File details

Details for the file ccaaws-1.1.0.tar.gz.

File metadata

  • Download URL: ccaaws-1.1.0.tar.gz
  • Upload date:
  • Size: 4.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for ccaaws-1.1.0.tar.gz
Algorithm Hash digest
SHA256 b2f4c2b46b0e2381bef2b7ad8e87b6ed5485def231fec721ca5898c806ed22d1
MD5 bd6c3565e1f90412dc8843625147473d
BLAKE2b-256 9e16bac6b924cbee53c35b93fa93fd1cdb72c12ee5f09ab37138c9784423257f

See more details on using hashes here.

Provenance

The following attestation bundles were made for ccaaws-1.1.0.tar.gz:

Publisher: release.yaml on ccdale/ccaaws

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ccaaws-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: ccaaws-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 6.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for ccaaws-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9cf7dc030bbe9570169fce3e78a898190c823ebd5b06eb39fa5d96a93fa95fff
MD5 9d8b8cdfc57d705b6d0a44c510c12022
BLAKE2b-256 470ac3299ce9811caf7d3c49e665e21896d8df009eba2ba9b69d1d0060a101d9

See more details on using hashes here.

Provenance

The following attestation bundles were made for ccaaws-1.1.0-py3-none-any.whl:

Publisher: release.yaml on ccdale/ccaaws

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

1.1.0 This release

2 files

1.0.0

2 files

0.4.8

2 files

0.4.7

2 files

0.4.6

2 files

0.4.5

2 files

0.4.4

2 files

0.4.3

2 files

0.4.2

2 files

0.4.1

2 files

0.4.0

2 files

0.3.6

2 files

0.3.3

2 files

0.3.2

2 files

0.3.1

2 files

0.3.0

2 files

0.2.3

2 files

0.2.2

2 files

0.2.1

2 files

0.2.0

2 files

0.1.8

2 files

0.1.7

2 files

0.1.6

2 files

0.1.5

2 files

0.1.4

2 files

0.1.3

2 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