Library / SDK
boto/boto3 avatar
boto/boto3

Boto3: the AWS SDK for Python, and when it is the wrong layer

AWS SDK for Python (Boto3)

9,910 stars1,996 forksPythonApache-2.0

At a glance

What is it?
Boto3 is Amazon's own Python client for AWS, pinned at install time to a narrow botocore range. This review covers the install path, the client/resource split, the version coupling that shapes upgrades, and the cases where a declarative tool fits better.
Who is it for?
Adopt boto3 when you need imperative AWS calls from Python and want the SDK published by AWS itself. Do not adopt it as a provisioning layer: it has no state file and no plan step, so infrastructure that must be reproducible belongs in a declarative tool.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What boto3 is for, and who ends up using it

Boto3 is the Amazon Web Services Software Development Kit for Python. The README describes it as allowing Python developers to write software that makes use of services such as Amazon S3 and Amazon EC2, and states that it is maintained and published by Amazon Web Services. That matters for adoption decisions: the SDK is not a community wrapper around undocumented HTTP endpoints, it is the vendor's own client, and the credential and configuration conventions it follows are the same ones documented across the AWS SDK family.

The audience is Python developers who need to call AWS APIs from application code, scripts, or automation. A data engineer listing the contents of a bucket, a backend service writing objects to S3, a scheduled job reading from DynamoDB: all of these are imperative, per-call operations, and that is the shape boto3 is built for. It is a library, not a service and not a deployment tool. Nothing runs in the background, and there is no daemon to operate.

The name is not an acronym. The README says Boto was named after the fresh water dolphin native to the Amazon river, chosen by the author of the original Boto library, Mitch Garnaat, as a reference to the company. The "3" distinguishes this generation from the earlier boto library, which the README points to separately at docs.pythonboto.org.

Clients, resources and sessions: how a call actually reaches AWS

Boto3 exposes two programming styles over the same underlying API surface. The resource interface is the object-oriented one shown in the README, where you obtain a resource object and iterate over collections: s3.buckets.all() yields bucket objects with a name attribute. The client interface is the lower-level one, generated per service, where method names map directly onto API operations and responses come back as dictionaries. The repository ships a data/aws/resources JSON directory as package data, which is what backs the resource layer's model of services and their relationships.

Sessions sit underneath both. A session carries configuration and credentials, and clients and resources are created from it. If you call boto3.resource or boto3.client directly, you get the default session, which reads credentials from the locations the README links to in the credentials guide, including the shared file at ~/.aws/credentials. Creating an explicit session is how you point at a different region or a different set of credentials within one process, and it is the usual fix when a long-running process needs to assume a role partway through.

Dependencies are pinned tightly. The install requires botocore between 1.43.98 and 1.44.0, jmespath between 0.7.1 and 2.0.0, and s3transfer between 0.19.0 and 0.20.0. Botocore is where the service definitions and request signing live, so the boto3 version you install largely determines the API surface you get. The requirements.txt in the repository is not a release manifest; it points at the develop branches of botocore, jmespath and s3transfer as editable installs, which is how the maintainers develop against unreleased dependencies.

Installing boto3 and listing buckets from a script

The README's Getting Started section assumes a supported version of Python is already present and begins with a virtual environment. The package metadata is stricter than the README prose: setup.py declares python_requires of 3.10 or higher, and the classifiers list 3.10 through 3.14. The README's Notices section states that support for Python 3.9 ended on 2026-04-29, following the Python Software Foundation's end of support for that runtime on 2025-10-31.

Create and activate the environment, then install from PyPI:

bash
python -m venv .venv
. .venv/bin/activate
python -m pip install boto3

The README also documents a source install, which clones the repository, installs requirements.txt, then installs the package in editable mode with python -m pip install -e . Note that requirements.txt resolves botocore and the other dependencies from their develop branches, so a source install from that file is not the same dependency set as a PyPI install.

Credentials go in ~/.aws/credentials, and a default region in ~/.aws/config, using the ini format the README gives. The README notes that other credential configuration methods are documented in the credentials guide.

ini
[default]
aws_access_key_id = YOUR_KEY
aws_secret_access_key = YOUR_SECRET

The first real use is the README's own example. From a Python interpreter, import boto3, build the S3 resource, and iterate the bucket collection, printing each bucket name. What you should see is one line per bucket in the account the credentials belong to. If the region is not set and the service requires one, the call fails before it reaches S3, which is the most common first-run problem.

The botocore pin is the real upgrade cost

Because setup.py constrains botocore to a range narrower than a single minor version, boto3 releases and botocore releases move together. You cannot independently hold botocore at an older revision to keep a service definition stable while taking a newer boto3. In practice this means an upgrade to boto3 is an upgrade to the service models, the request signing code, and the retry behaviour that botocore implements, whether or not you wanted any of those changes.

For teams with a lockfile this is manageable, because the resolver will refuse an incompatible pair rather than silently mixing them. For teams that install without a lock, the failure mode is drift: different machines resolve to different botocore versions over time, and a call that works on one host fails on another with a parameter validation error. The pin is a deliberate coupling, not an oversight, but it does mean boto3 upgrades deserve the same review as any dependency bump that changes request serialization.

The repository's own tooling gives a sense of the supported matrix. tox.ini and the README's testing section describe running the suite across supported Python versions with tox, and pyproject.toml targets py310 for linting with ruff while pytest is configured with a slow marker. The README also notes that running the full tox matrix requires all supported Python versions to be installed locally, and that you can run pytest tests/unit against just your default interpreter instead.

Where boto3 is the wrong tool

Boto3 is an imperative client, and that is a hard boundary. It has no state file, no plan phase, and no notion of desired configuration. If you use it to create infrastructure, then run the script twice, you get two of whatever it creates, or an error, depending on the service. There is no record of what was created last time and no diff to review before applying. Terraform and similar declarative tools exist precisely for that job: they record state, compute a plan, and reconcile drift. Choosing boto3 for account-level provisioning means rebuilding those guarantees yourself.

The second boundary is scope. The README says the project uses GitHub issues for tracking bugs and feature requests and has limited bandwidth to address them, directing users to Stack Overflow with the boto3 tag, AWS Support, or an issue for confirmed bugs. If your problem is an AWS service behaving unexpectedly rather than the Python SDK misbehaving, the SDK issue tracker is the wrong channel and the support ticket is the right one.

Python version support is a third constraint that catches people late. Support for 3.9 ended on 2026-04-29. If you are pinned to an older interpreter by a managed runtime or a base image, you are outside the supported range regardless of what the SDK can technically still do, and the README points to AWS's Python support policy blog post for the schedule.

Terraform and boto3 solve different halves of the problem

The comparison that comes up most often is boto3 against Terraform, and the difference is not language preference. Terraform describes the desired end state of resources in configuration files, stores what it believes exists in a state file, and computes the difference before making changes. Boto3 executes the calls you write, in the order you write them, with no memory between runs. One is a control loop, the other is a remote control.

That said, the two are not mutually exclusive, and the split is usually clean. Provision the bucket, the role, and the policy with a declarative tool, then use boto3 inside the application to read and write objects in that bucket at runtime. Application code that needs to put a file in S3 should not be shelling out to a provisioning tool, and account setup that needs to be reproducible should not be a Python script someone runs by hand.

If you want a declarative layer written in Python specifically, that is a different comparison again, and it is worth being explicit that boto3 is not trying to be one. Its job is to be the vendor's Python binding to the AWS APIs, and it does that job without opinion about how you organize the calls.

Licence, maintenance and what the repository tells you

Boto3 is licensed under Apache-2.0, declared in setup.py and referenced from the README badge to the LICENSE file on the develop branch. Apache-2.0 is a permissive licence with an explicit patent grant, which is generally the least contentious option for commercial use, but the specifics of your obligations, including NOTICE file handling, are a matter for your own legal review rather than something to infer from a badge.

The repository is not archived, and the last push was on 2026-09-18. The README states that boto3 was made generally available on 06/22/2015 and is currently in the full support phase of the availability life cycle, with pointers to the AWS SDKs and Tools Maintenance Policy and Version Support Matrix for the details of what full support means for major versions. The release list shown in the repository metadata stops at 0.0.14 from April 2015, which does not reflect the current version; the authoritative version is the one read from boto3/__init__.py by setup.py at build time, and the changelog at CHANGELOG.rst is where release history actually lives.

Upgrade cost is dominated by the botocore coupling described above. There is no separate migration tooling to budget for, but every boto3 bump carries a botocore bump with it, so the practical cost is the review and testing of your AWS-calling code paths against the new service models.

Editorial conclusion

Adopt boto3 when you need imperative AWS calls from Python and want the SDK published by AWS itself. Do not adopt it as a provisioning layer: it has no state file and no plan step, so infrastructure that must be reproducible belongs in a declarative tool. Before committing, verify which Python versions your runtime supports, since support for 3.9 ended on 2026-04-29, and check the botocore pin in setup.py against the botocore version already in your lockfile.

Frequently asked questions

Why is boto3 called Boto3?

The README states that Boto was named after the fresh water dolphin native to the Amazon river, a name chosen by the author of the original Boto library, Mitch Garnaat, as a reference to the company. The 3 distinguishes this SDK from the earlier boto library.

Is boto3 deprecated?

No. The README states that boto3 was made generally available on 06/22/2015 and is currently in the full support phase of the availability life cycle. It directs readers to the AWS SDKs and Tools Maintenance Policy and Version Support Matrix for details on major version support.

How do I install boto3?

The README's Getting Started section sets up a virtual environment with python -m venv .venv and then installs from PyPI with python -m pip install boto3. A source install is also documented, using git clone followed by pip install -r requirements.txt and pip install -e .

How do I use boto3 to access S3?

The README example creates the S3 resource with boto3.resource('s3') and iterates s3.buckets.all(), printing each bucket's name. Credentials and a default region must be configured first, in ~/.aws/credentials and ~/.aws/config respectively.

How do I use a boto3 client or session?

A session carries configuration and credentials, and clients and resources are created from it; calling boto3.resource or boto3.client directly uses the default session. The client interface returns dictionaries and maps methods onto API operations, while the resource interface returns objects and collections.

What are the key differences between boto3 and Terraform?

Boto3 is an imperative Python SDK: it executes the API calls you write, in order, with no state file and no plan step. Terraform describes desired end state, records what exists in state, and computes a plan before applying, which is why provisioning is usually left to a declarative tool and runtime calls to boto3.

Official sources

  1. boto/boto3 on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/boto-boto3.svg)](https://hysenlabs.com/projects/boto-boto3)