aioboto3 Documentation

repository·main·Indexed 21 days ago

https://github.com/terricain/aioboto3

An asynchronous wrapper for the AWS SDK for Python that combines the high-level APIs of boto3 with the low-level async client commands of aiobotocore. It provides an async Session class for managing credentials and creating service resources for AWS services like S3, DynamoDB, and EC2. Features include S3 Client-Side Encryption (CSE) via KMS, asymmetric, and symmetric contexts, as well as an experimental integration with AWS Chalice for async HTTP routes.

Tokens
6.9K
Snippets
25
Records
31
Agent score
75%

What's inside aioboto3

  1. How to instantiate clients and resources in aioboto3

    main

    In aioboto3, you must use aioboto3.Session() to create a session, and then instantiate clients or resources using async context managers. You can no longer call aioboto3.client() or aioboto3.resource() directly. This pattern ensures that the session lifecycle is correctly managed within the event loop.

    To access a resource, use the async with session.resource(...) as resource_name: syntax. Note that accessing properties on resource objects (like an S3 Bucket) is also asynchronous; these properties are coroutines that load metadata on the first await and cache it thereafter.

    async def main():
        session = aioboto3.Session()
        async with session.resource("s3") as s3:
            bucket = await s3.Bucket('mybucket')
            async for s3_object in bucket.objects.all():
                print(s3_object)
  2. Core Usage Patterns in aioboto3

    main

    The usage of aioboto3 closely mimics boto3, with the primary difference being that most operations must be prefixed with await.

    Key differences from boto3:

    • aioboto3.resource returns a resource object that is an async context manager (supports async with) and has an awaitable .close() method.
    • Service resources (e.g., s3.Bucket, dynamodb.Table) must be instantiated using await.
    • Standard client connections also work using the async with session.client(...) pattern.
    import asyncio
    import aioboto3
    from boto3.dynamodb.conditions import Key
    
    async def main():
        session = aioboto3.Session()
        # Use async with for resources
        async with session.resource('dynamodb', region_name='eu-central-1') as dynamo_resource:
            # Service resources must be awaited
            table = await dynamo_resource.Table('test_table')
    
            await table.put_item(
                Item={'pk': 'test1', 'col1': 'some_data'}
            )
    
            result = await table.query(
                KeyConditionExpression=Key('pk').eq('test1')
            )
            print(result['Items'])
    
    asyncio.run(main())
  3. Pull Request guidelines for aioboto3

    main

    When submitting a pull request, ensure the following requirements are met:

    • Tests: The PR must include tests.
    • Documentation: If adding functionality, update the documentation. New functionality should be placed in a function with a docstring, and the feature should be added to the list in README.rst.
    • Compatibility: The code must work for Python versions 3.7 through 3.11.
    • CI Status: Verify that the GitHub Actions workflows pass at https://github.com/terrycain/aioboto3/actions/workflows/CI.yml.
  4. Implement AWS S3 Client-Side Encryption (CSE)

    main

    AWS S3 Client-Side Encryption (CSE) allows you to encrypt data before it is sent to S3, ensuring that sensitive information is never unencrypted in transit or at rest on the S3 server.

    aioboto3 provides the S3CSE class and several CryptoContext implementations to manage this process. You wrap your S3 operations (like put_object and get_object) using an S3CSE instance initialized with a specific CryptoContext.

    import asyncio
    import aioboto3
    from aioboto3.s3.cse import S3CSE, KMSCryptoContext
    
    async def main():
        # 1. Initialize the CryptoContext (e.g., KMS)
        ctx = KMSCryptoContext(keyid='alias/someKey', kms_client_args={'region_name': 'eu-central-1'})
    
        some_data = b'Some sensitive data for S3'
    
        # 2. Use S3CSE as an async context manager
        async with S3CSE(crypto_context=ctx, s3_client_args={'region_name': 'eu-central-1'}) as s3_cse:
            # 3. Perform encrypted uploads
            await s3_cse.put_object(
                Body=some_data,
                Bucket='some-bucket',
                Key='encrypted_file',
            )
    
            # 4. Perform encrypted downloads
            response = await s3_cse.get_object(
                Bucket='some-bucket',
                Key='encrypted_file'
            )
            data = await response['Body'].read()
            print(data)
    
    asyncio.run(main())
  5. Set up aioboto3 for local development

    main

    To contribute to aioboto3, follow these steps to set up your local environment:

    1. Fork the repository on GitHub.
    2. Clone your fork locally.
    3. Install the local copy into a virtual environment using uv sync.
    4. Create a new development branch.
    5. After making changes, verify them using make lint (for flake8) and make test (to run tests, including tox for multiple Python versions).
    6. Commit and push your changes to your GitHub fork.
    7. Submit a pull request via the GitHub website.
    git clone git@github.com:your_name_here/aioboto3.git
    cd aioboto3/
    uv sync
    git checkout -b name-of-your-bugfix-or-feature
    
    # After making changes
    make lint
    make test
    
    git add .
    git commit -m "Your detailed description of your changes."
    git push origin name-of-your-bugfix-or-feature
  6. Integrate aioboto3 with AWS Chalice (EXPERIMENTAL)

    main

    You can use aioboto3.experimental.async_chalice.AsyncChalice as the main application entrypoint for an AWS Chalice app. This integration provides shims that allow you to use async def functions for HTTP routes.

    Key features:

    • Async Routes: Define routes using async def to handle asynchronous logic.
    • aioboto3 Session: The app.aioboto3 attribute contains an aioboto3.Session object, which you can use to create clients (e.g., app.aioboto3.client('s3')).
    • Custom Sessions: You can pass a custom session to AsyncChalice to override the default empty session.

    Warning: This integration is EXPERIMENTAL. It is not recommended for critical production use. Due to how Chalice manages the event loop (which can disappear between invocations), you should not cache aioboto3 clients or resources.

    from aioboto3.experimental.async_chalice import AsyncChalice
    
    # Initialize the app
    app = AsyncChalice(app_name='testclient')
    
    # Define an async route
    @app.route('/hello/{name}')
    async def hello(name):
        return {'hello': name}
    
    # Use the integrated aioboto3 session to create clients
    @app.route('/list_buckets')
    async def get_list_buckets():
        async with app.aioboto3.client("s3") as s3:
            resp = await s3.list_buckets()
    
        return {"buckets": [bucket['Name'] for bucket in resp['Buckets']]}
  7. Upload and stream files from S3

    main

    You can upload files to S3 using upload_fileobj and stream them back using the get_object method. When streaming, the Body of the S3 object is an async stream that can be read in chunks.

    async def upload(filename: str, staging_path: Path, bucket: str):
        session = aioboto3.Session()
        async with session.client("s3") as s3:
            with staging_path.open("rb") as spfp:
                await s3.upload_fileobj(spfp, bucket, filename)
    
    async def stream_download(bucket: str, key: str, chunk_size: int = 69 * 1024):
        session = aioboto3.Session()
        async with session.client("s3") as s3:
            s3_ob = await s3.get_object(Bucket=bucket, Key=key)
            stream = s3_ob["Body"]
            while file_data := await stream.read(chunk_size):
                # Process or yield file_data
                pass
  8. Manage aioboto3 sessions in long-running processes (e.g. AioHTTP)

    main

    Since aioboto3 v8.0.0, .client and .resource are async context managers. In long-running applications like aiohttp servers, you should use contextlib.AsyncExitStack to manage the lifecycle of these resources during application startup and shutdown to avoid unclosed session warnings.

    import contextlib
    import aioboto3
    from aiohttp import web
    
    session = aioboto3.Session()
    routes = web.RouteTableDef()
    
    async def startup_tasks(app: web.Application) -> None:
        context_stack = contextlib.AsyncExitStack()
        app['context_stack'] = context_stack
    
        # Enter the resource context and save it in the stack
        app['dynamo_resource'] = await context_stack.enter_async_context(
            session.resource('dynamodb', region_name='eu-west-1')
        )
        # Await the service resource
        app['table'] = await app['dynamo_resource'].Table('my_table')
    
    async def shutdown_tasks(app: web.Application) -> None:
        # Clean up all managed contexts
        await app['context_stack'].aclose()
    
    _app = web.Application()
    _app.on_startup.append(startup_tasks)
    _app.on_shutdown.append(shutdown_tasks)
  9. Install aioboto3 from source

    main

    If you need to install from source, you can clone the GitHub repository or download the source tarball. Once the source is on your local machine, use setup.py to perform the installation.

    # Clone the repository
    $ git clone git://github.com/terrycain/aioboto3
    
    # OR download the tarball
    $ curl -OL https://github.com/terrycain/aioboto3/tarball/master
    
    # Install from the source directory
    $ python setup.py install