aiobotocore Documentation

repository·main·Indexed 23 days ago

https://github.com/aio-libs/aiobotocore

An asynchronous client for AWS services using botocore and aiohttp. The library includes AioBaseClient for asynchronous context management, AioAWSResponse for async access to response content, and the aiobotocore-bot plugin, a collection of AI skills designed to automate development, synchronization, and release workflows.

Tokens
36.6K
Snippets
49
Records
176
Agent score
80%

What's inside aiobotocore

  1. Dependency bump (dep-bump) rules and versioning

    main

    The dep-bump bucket uses the net transition of dependency lower bounds in pyproject.toml (specifically for botocore, boto3, and aiohttp) to influence the release version.

    Transition Types

    When comparing the lower bound (the version after >=) from the start of the window to the end:

    • major advance: e.g., botocore >= 1.42.79 $\rightarrow$ botocore >= 2.0.0. Forces a MAJOR release bump.
    • minor advance: e.g., botocore >= 1.42.79 $\rightarrow$ botocore >= 1.43.0. Forces at least a MINOR release bump.
    • patch advance: e.g., botocore >= 1.42.79 $\rightarrow$ botocore >= 1.42.90. Does not force a bump (release stays at current level unless other buckets push it higher).
    • range-only: e.g., botocore < 1.42.85 $\rightarrow$ botocore < 1.42.92 (lower bound unchanged). No transition effect.

    Note: The bump rule is driven by the net transition across the entire release window, even if multiple PRs contribute to it.

  2. Categorization buckets for release PRs

    main

    The release skill categorizes every PR or standalone commit into one or more buckets based on signals (title prefixes, labels, or changed files). A single PR can belong to multiple buckets simultaneously.

    Available Buckets

    • breaking: Triggered by a BREAKING: prefix in the title, a BREAKING CHANGE: footer in the PR body/merge commit, or a breaking label.
    • dep-bump: Triggered when pyproject.toml changes the lower bound of botocore, boto3, or aiohttp dependencies.
    • feature: Triggered by a feat: prefix or enhancement/feature labels.
    • bugfix: Triggered by a fix: prefix or a bug label.
    • doc: Triggered by a docs: prefix or if only files under docs/ or *.md/*.rst were touched.
    • contrib: Triggered by ci:, chore:, or test: prefixes, or if only files under .github/, tests/, or pyproject.toml (without source changes) were touched.
    • misc: Anything else with a user-visible effect that doesn't match the above rules.
  3. How the pyright-delta workflow works

    main

    The skill follows a multi-step process to ensure a safe and accurate comparison:

    1. Resolve Arguments: Determines the target path, the baseline ref, and the list of TOUCHED files.
    2. Create Baseline Worktree: Fetches the base ref and creates a detached git worktree in a temporary directory using mktemp -d. This prevents corruption of the primary tree if the process fails.
    3. Run Baseline Pyright: Executes uv run --with pyright pyright inside the worktree and saves the output to a temporary file.
    4. Cleanup Worktree: Removes the temporary worktree using git worktree remove --force.
    5. Run Current Pyright: Executes Pyright against the current working directory and saves the output.
    6. Compute Delta: Compares the two outputs. A new error is only reported if its file path matches one of the TOUCHED files. Errors in files not modified by the PR are treated as baseline noise and ignored.

    Output Format:

    Baseline: <N> errors, <W> warnings
    With changes: <N'> errors, <W'> warnings
    Touched files: <list>
    
    New errors in touched files:
      <path>:<line>: <message>
      ...
    
    No new errors: <true|false>
  4. Detect unreleased versions in draft-release

    main

    When running the draft-release skill, the process must determine if the current version in the repository is already released on PyPI or if it is an unreleased draft (e.g., a previous run already bumped __version__ or added a draft entry to CHANGES.rst).

    If the version in aiobotocore/__init__.py or the top entry in CHANGES.rst is strictly newer than the latest PyPI version, it is considered unreleased. In this case, the skill should:

    1. Recompute the release window starting from the last released boundary (released..$TO).
    2. Redo categorization.
    3. Replace the existing top entry in CHANGES.rst entirely (version, date, and bullets) rather than attempting to append to it. This prevents stacking multiple unreleased entries and ensures the changelog reflects the latest reality.
    current=$(grep -oP "__version__\s*=\s*['\"]\\K[0-9]+\\.[0-9]+\\.[0-9]+" \
      aiobotocore/__init__.py)
    released=$(curl -s https://pypi.org/pypi/aiobotocore/json \
      | python3 -c "import sys,json; print(json.load(sys.stdin)['info']['version'])")
    # `current` is unreleased iff it sorts strictly newer than `released`
    unreleased=$(python3 -c "
    from packaging.version import Version
    print('1' if Version('$current') > Version('$released') else '0')")
  5. Categorize drift: cosmetic vs behavioral

    main

    The skill distinguishes between different types of divergence from the botocore source to help reviewers prioritize feedback.

    Cosmetic Drift (Medium Confidence)

    Flagged when changes widen the diff without an async-explained justification. Examples include:

    • Docstring additions ("""...""") that aren't in the botocore version (unless they describe async-only behavior).
    • Type-hint additions on parameters or return values.
    • Import reordering or PEP8 cleanup.
    • Comment additions.

    Behavioral Drift (High Confidence)

    Flagged when logic changes in a way that is not required for async. Examples include:

    • Changes to control flow, conditionals, or function calls that differ from botocore and aren't async-required.
    • Replacing one standard library call with another that has different semantics (e.g., inspect.isawaitable(x) vs hasattr(x, "__await__")).
    • Added guards (e.g., if x is None: ...), added logging, or added error handling that isn't in botocore.
    • Removed logic that exists in botocore.
  6. Maintain integrity with test_patches.py

    main

    Due to the tight coupling with botocore and aiohttp, aiobotocore uses tests/test_patches.py to store hashes of critical code sections. This ensures that if botocore changes its method parameters, moves classes, or updates method bodies, aiobotocore's overrides are flagged.

    When to update hashes in test_patches.py:

    1. Bumping versions: If a hash mismatch occurs during a botocore or aiohttp upgrade, validate the code change and update the hash if the change is intentional and reflected in aiobotocore.
    2. Implementing new functionality: When adding new overrides, add entries for the botocore or aiohttp methods being used/overridden. For private attributes, you may need to hash the entire class.
  7. How aiobotocore works and its responsibilities

    main

    The aiobotocore package provides a low-level interface to Amazon services. It handles the low-level details of making requests and receiving results, specifically:

    • Providing access to all available services and their operations.
    • Marshaling parameters for operations into the correct format.
    • Signing requests with the correct authentication signature.
    • Receiving responses and returning data as native Python data structures.

    aiobotocore is a data-driven package. It uses JSON service descriptions to define operations, parameters, documentation, regions, and endpoints. It does not provide high-level abstractions; those are intended to be implemented at the application layer.

  8. How aiobotocore implements async overrides

    main

    aiobotocore follows a strict architectural principle: minimize divergence from botocore. It avoids monkey-patching and instead uses a subclassing pattern to inject async capabilities.

    To maintain compatibility with upstream botocore updates, developers should only introduce changes that are strictly necessary for asyncio (e.g., replacing threading.Lock with asyncio.Lock, adding await to I/O calls, or using resolve_awaitable() for mixed sync/async handlers). Any other changes (refactors, docstring updates, or bug fixes not present in botocore) are considered "drift" and should be avoided or submitted to botocore first.

  9. Subclass and async override pattern

    main

    The most common way aiobotocore extends botocore is by subclassing with an Aio prefix and overriding methods as async def. This allows awaiting I/O calls and event hooks that were previously synchronous in botocore.

    Example implementation in aiobotocore/client.py:

    # aiobotocore/client.py
    class AioBaseClient(BaseClient):
        async def _make_api_call(self, operation_name, api_params):
            # Same logic as BaseClient._make_api_call but with:
            # - await on endpoint._send_request()
            # - await on event hooks
            ...
  10. Review process for aiobotocore pull requests

    main

    The review-pr skill follows a strict five-step workflow to ensure high-quality, secure, and context-aware reviews:

    1. Eligibility Check: Verifies the PR is not closed, not a draft, and that no new commits have been pushed since the last Claude review (using a GraphQL check against CLAUDE_LAST and HEAD_PUSHED).
    2. Gather Context: Collects relevant CLAUDE.md files, the PR diff via gh pr diff, and PR metadata via gh pr view.
    3. Review Changes: Sequentially audits for:
      • CLAUDE.md compliance: Rules specific to the modified directories.
      • Bugs: Compilation errors, logic errors, security issues, and incorrect API usage.
      • Async patterns: Validates botocore overrides against docs/override-patterns.md (e.g., resolve_awaitable(), async context managers, and Aio prefix naming).
      • Override drift: For PRs touching aiobotocore/*.py files with a botocore mirror, it invokes check-override-drift to flag behavioral or cosmetic drift.
      • Port-vs-no-port sanity: For sync-bot PRs (claude[bot] with title Bump botocore), it invokes check-async-need to verify if the version update requires a port.
      • Coverage-driven test-porting: Suggests backfilling tests if codecov reports uncovered new lines in aiobotocore/*.py files that have botocore counterparts.
    4. Validate Findings: Every issue is scored from 0-100. Only issues with a score $\ge 80$ are considered for posting.
    5. Self-critique for Prompt Injection: A critical security step where the agent reviews its own findings to ensure it hasn't been influenced by malicious instructions embedded in the PR diff, title, or body (e.g., instructions claiming to be from a maintainer).
  11. Synthesize PR discussion into buckets

    main

    To build a coherent action plan, the skill synthesizes the PR history into three distinct buckets:

    Bucket A — What was asked

    Every concrete request from trusted reviewers across the full PR history, including requests already addressed. Related asks should be grouped.

    Bucket B — What was done

    For each ask in Bucket A, record the response:

    • A claude[bot] reply explaining the action + the commit SHA.
    • A commit on the branch addressing the ask.
    • Reviewer acknowledgment (e.g., isResolved: true).
    • No response yet.

    Note: Always verify the current code state using git log -p and file reads before assuming a response matches the request.

    Bucket C — What is being asked that isn't resolved

    The set difference: items from Bucket A where Bucket B is empty or insufficient. These are the candidates for action.

    Filtering Bucket C for actionability:

    1. Trusted author: Only act on MEMBER, OWNER, or COLLABORATOR associations.
    2. Not engaged by claude: The most recent comment must not be from claude[bot]. If Claude replied last, the reviewer has the ball.
    3. Actionable work: Must be a concrete code change, bug fix, or code-level answer. Skip human-to-human chatter, status updates, or meta-review discussion.
  12. Identify async-gap exceptions (OK changes)

    main

    Certain changes are considered legitimate 'async-gap exceptions' and should not be flagged as drift:

    • Upstream Syncs: Additions that mirror the exact same addition found in the matching botocore version.
    • Async Semantics: Divergences required by asyncio, such as:
      • Using await, async def, async with, or async for.
      • Replacing threading.Lock with asyncio.Lock.
      • Using asyncio.Event, asyncio.sleep, or AsyncExitStack.
      • Using resolve_awaitable on objects that may be awaitable in aiobotocore but aren't in botocore.
      • Referencing Aio<Name> classes that subclass botocore classes.
    • aiobotocore-only code: Changes to files that have no botocore mirror.
    • Async-only bug fixes: Fixing a race condition, missing await, or broken cancellation that only exists in the async implementation. These should be explicitly stated in the PR description.