CLI tool
boto/botocore avatar
boto/botocore

botocore is the low-level, data-driven core under boto3 and the AWS CLI

The low-level, core functionality of boto3 and the AWS CLI.

1,646 stars1,192 forksPythonApache-2.0

At a glance

What is it?
botocore is the Python package that holds the service models, the credential resolution and the request pipeline for AWS. It is not the API most people call, but every boto3 and AWS CLI request passes through it, and its three dependencies keep it small enough to sit underneath anything.
Who is it for?
Adopt botocore directly when you are building a tool that has to control the wire format, the retry behaviour or the credential chain, such as a proxy, a recorder or a custom signer. Do not adopt it for ordinary service calls, because boto3 is the interface meant for that and botocore exposes the plumbing underneath.
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 last received commits 3 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

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

Editorial analysis

The package underneath boto3 and the AWS CLI

botocore is described as a low-level interface to a growing number of Amazon Web Services, and it is the foundation for the AWS CLI and for boto3. The setup.py description is more blunt about it, calling botocore the low-level, data-driven core of boto 3.

Two different audiences end up here. The first is anyone who wants the full breadth of AWS services with a pleasant interface, and that person should be using boto3, since botocore is deliberately not that layer. The second is anyone building on top of the AWS SDK, a local testing proxy, a request recorder, a tool that signs requests differently, or a program that needs to know exactly what was sent on the wire. That person wants botocore, because it is where the request pipeline, the service models and the credential resolution actually live.

It is maintained and published by Amazon Web Services, so the code is the same code that ships inside the CLI and inside boto3, not a community reimplementation with a different model of the services. That also means the release cadence is tied to the AWS SDK and tools policy rather than to a single project, and the README points at the SDKs and Tools Maintenance Policy and the Version Support Matrix for the details.

Botocore has been generally available since 2015-06-22 and the README states it is currently in the full support phase of the availability life cycle.

Credentials and region come from files in your home directory

The getting started section assumes Python and virtualenv, and gives two routes. For development it clones the repository, creates a virtual environment and installs the requirements and the package in editable mode.

bash
$ git clone https://github.com/boto/botocore.git
$ cd botocore
$ python -m venv .venv
$ source .venv/bin/activate
$ python -m pip install -r requirements.txt
$ python -m pip install -e .

For use, the package comes from pip.

bash
$ pip install botocore

The credential setup is then a file, conventionally at ~/.aws/credentials.

ini
[default]
aws_access_key_id = YOUR_KEY
aws_secret_access_key = YOUR_SECRET

The region goes in a separate file, conventionally at ~/.aws/config, and the README is explicit about the split.

ini
[default]
region=us-east-1

Other credential configuration methods are pointed at the boto3 credentials documentation. That pointer matters for anyone using botocore directly, because botocore implements the resolution chain and the other mechanisms, environment variables, instance metadata, and the rest of the provider chain described there, are part of what the package does.

The credentials file and the config file holding the region is a small thing that trips people up, since the region is not a credential and lives elsewhere.

Using the session and client API directly

The library entry point is a session, and from a session you create a client for a service.

python
>>> import botocore.session
>>> session = botocore.session.get_session()
>>> client = session.create_client('ec2')
>>> print(client.describe_instances())

That is the whole usage example in the README, and it is worth noticing what it lacks. There is no resource abstraction, no convenience methods, and no generated per-service code. create_client returns a client for one service, and the client exposes operations whose names come from the service model, so describe_instances is a method on the client rather than something you look up in a paginator helper.

The data driven part of the design shows up in the packaging. The setup.py package_data entry lists cacert.pem, data/*.json and data/*/*.json as files shipped with the botocore package, and the vendored requests package ships its own pem files. Those JSON files are the service models, the protocol descriptions and the endpoint data, and they are why a new AWS service appears in the SDK without any new Python code being written for it.

The size of that data directory is the practical cost of the approach. You get breadth automatically, and you get it whether you need it or not.

Three dependencies and one optional extra

The dependency list in setup.py is short enough to read in full. It is jmespath with a range of 0.7.1 and above and below 2.0.0, python-dateutil from 2.1 up to but not including 3.0.0, and urllib3 from 1.25.4 with 2.2.0 explicitly excluded and 3 excluded as an upper bound.

jmespath is the query language used to filter responses, python-dateutil handles the timestamp parsing that the protocol requires, and urllib3 is the HTTP transport. That is the whole stack, and the exclusions are the interesting part, since a pinned exclusion of a single urllib3 release indicates a specific incompatibility that was worth encoding in the packaging metadata.

There is exactly one optional extra, crt, which pulls in awscrt at a pinned version of 0.36.0. The AWS Common Runtime is the native library behind the faster transfer and signing paths, and the extra exists so that a project that wants it can ask for it explicitly rather than paying for it by default.

For a package that sits underneath the CLI, boto3 and a lot of internal tooling, a three dependency footprint is a real property. It keeps the install small, and it means the transitive dependency graph of an AWS project stays something a team can read.

The interface you should not use directly

The most common mistake with botocore is using it when boto3 would do. botocore gives you a client whose methods mirror the service API, and for most tasks that is a worse experience than the resource layer and the paginators and the waiters that boto3 builds on top of it.

The second mistake is expecting botocore to be stable in the way a normal library is. It is pinned to the AWS SDK and tools release train, its service models change whenever AWS changes a service, and a new botocore version can therefore change the shape of a response that your code assumed was stable. The changelog is a file in the repository, CHANGELOG.rst, rather than a list of GitHub releases, because the repository has no GitHub releases at all. Tracking what changed means reading that file or watching the .changes/ directory where the fragments are collected.

There is also the version matrix question. The README sends readers to the AWS SDKs and Tools Version Support Matrix and the maintenance policy, and for a project that pins botocore this matters: botocore's own version number does not tell you which SDK generation you are on.

The right question to ask is whether you need the plumbing. If you need the request pipeline, the signing, the credential chain or the service model, use botocore. If you need to call a service, use boto3.

Python 3.9 support ended on 2026-04-29

The README carries a notice about the end of Python 3.9 support for botocore, dated 2026-04-29, and states that it follows the Python Software Foundation end of support for the runtime, which occurred on 2025-10-31. It links to a blog post about the AWS SDKs and tools Python support policy for the full reasoning.

The packaging metadata is consistent with that. The python_requires field says 3.10 and above, the classifiers list 3.10, 3.11 and later, and the ruff configuration sets target-version to py310 with a line length of 79.

The repository is not archived, and the last push was on 2026-10-17, so the code is current. The default branch is develop, which is where the work happens before it is cut into a release.

The licence is Apache-2.0, recorded in setup.py and in the LICENSE.txt file at the top level, with a NOTICE file alongside it. The package classifiers mark it as Production/Stable, and the author field is Amazon Web Services.

What contribution and CI look like in the tree

The repository layout tells you how a change gets made. There is a scripts/ directory, a tests/ directory, a docs/ directory, a .changes/ directory for changelog fragments, a tox.ini for environment management, and a setup.cfg next to the older setup.py and the pyproject.toml.

The testing setup has two custom pytest markers declared in pyproject.toml, slow to mark tests as slow and validates_models to mark the tests that validate the service models. That second marker is a hint about where the risk lives. The service models are data, and the tests that validate them are the ones that catch a model that does not match what the service actually accepts.

There is also a .codecov.yml and a .coveragerc, a .pre-commit-config.yaml for the hook checks, a CODE_OF_CONDUCT.md and a CONTRIBUTING.rst, and requirement lock files for development and for docs, which is the pattern of a project where the dependency set is treated as a supply chain surface.

The README is candid about support. Bug reports and feature requests go to GitHub issues, and the project states it has limited bandwidth to address them, pointing people to Stack Overflow with the boto3 tag and to AWS Support tickets for anything account related.

Editorial conclusion

Adopt botocore directly when you are building a tool that has to control the wire format, the retry behaviour or the credential chain, such as a proxy, a recorder or a custom signer. Do not adopt it for ordinary service calls, because boto3 is the interface meant for that and botocore exposes the plumbing underneath. Verify first that your Python is 3.10 or newer, since support for 3.9 ended on 2026-04-29, and read the AWS SDKs and Tools Maintenance Policy before pinning a version, because botocore has no GitHub releases and the changelog is a file in the repository.

Frequently asked questions

What is botocore and how does it relate to boto3?

botocore is the low-level, data-driven core that holds the AWS service models, the credential resolution and the request pipeline. It is the foundation for boto3 and for the AWS CLI, and it is maintained and published by Amazon Web Services.

How do I install botocore and make a first call?

Run pip install botocore, put your keys in ~/.aws/credentials and the region in ~/.aws/config, then use botocore.session.get_session() and session.create_client('ec2') from a Python interpreter. For development the README clones the repository, creates a virtualenv and installs with pip install -e .

What dependencies does botocore pull in?

Three: jmespath, python-dateutil and urllib3, with urllib3 2.2.0 explicitly excluded. There is one optional extra, crt, which installs awscrt at a pinned version for the faster native transfer and signing paths.

Which Python versions does botocore support?

Support for Python 3.9 ended on 2026-04-29, following the Python Software Foundation end of support for that runtime on 2025-10-31. The package metadata requires 3.10 and above.

Should I use botocore or boto3 for calling AWS services?

Use boto3 for ordinary service calls, since it adds the resource layer, paginators and waiters on top. Reach for botocore when you need the request pipeline, the signing, the credential chain or the service model itself.

Where can I see what changed in a botocore release?

The repository has no GitHub releases. The changelog is the CHANGELOG.rst file, with fragments collected in the .changes/ directory, and the README points to the AWS SDKs and Tools Maintenance Policy and Version Support Matrix for the wider release train.

Official sources

  1. boto/botocore on GitHub
  2. Issues
  3. License: Apache-2.0
  4. README
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-botocore.svg)](https://hysenlabs.com/projects/boto-botocore)

Was this useful?