Every time I write boto3 code I end up with the AWS docs open in another tab. My editor has no idea what put_object accepts, what comes back is a plain dict, and if I misspell a parameter I find out when the request fails. You can fix part of this with stub packages, but it's still a sync library, and the async options (aioboto3, aiobotocore) get there by patching botocore's internals, which isn't a reliable base to build on.
So I started generating my own SDK from the same Smithy models AWS uses to describe its APIs. It's called capo, and it's at the point where I think other people can try it.
Here's what using it looks like:
from capo_s3 import AsyncS3Client
async with AsyncS3Client() as s3:
await s3.create_bucket(
bucket="my-bucket",
create_bucket_configuration={"location": {"name": "eu-central-1"}},
)
async with s3.get_object("my-bucket", "report.csv") as response:
async for chunk in response["body"]:
...
Everything you pass in and get back is a TypedDict, so autocomplete works all the way down the nested parameters, and you don't import a separate class for each one. If you don't want async, drop the Async prefix and the await and it's the same API.
Errors are actual exception classes, so you write except NoSuchKey: instead of digging through ClientError.response["Error"]["Code"]. Paginated operations get an iter_ method and waiters get a wait_until_ method, so there's no separate paginator object to set up.
Each service is its own package (capo-s3, capo-ec2, capo-lambda, and 400+ more), so installing S3 doesn't pull in EC2's huge model. Import time also stays flat even for EC2, because the serialization code is generated for each operation instead of looked up at runtime.
Credentials and config work the way you'd expect: env vars, ~/.aws/config profiles, SSO, AssumeRole, IRSA, and instance metadata. If your boto3 setup works, this should pick it up with no changes.
It's all pure Python, so it also runs in the browser through Pyodide.
The API is mostly stable, but the project is still pre-1.0, so pin your versions for now. If you try it and something behaves differently from boto3, please open an issue. That's the kind of feedback I need most right now.
Docs: https://capo-sdk.dev
GitHub: https://github.com/kap-sh/capo
Top comments (0)