botocore
botocore is the low-level, data-driven core of boto3 and the AWS CLI, providing a direct interface to Amazon Web Services APIs. It handles request signing (AWS Signature Version 4), credential resolution, retry logic, pagination, and service model loading. Current version is 1.42.77, released by Amazon Web Services. Releases are extremely frequent — often multiple times per week — tracking new and updated AWS service APIs. Most users interact with botocore indirectly via boto3, but direct use is common for fine-grained control, event hooks, custom credential providers, and low-overhead Lambda code.
Warnings
- breaking Python 3.9 support ends 2026-04-29. After that date botocore will require Python 3.10+. Plan runtime upgrades now, especially for AWS Lambda functions still on the Python 3.9 runtime.
- breaking botocore.vendored.requests and botocore.vendored.requests.packages.urllib3 were removed. Any import from botocore.vendored.* raises ImportError at runtime.
- breaking The old Service/Operation object interface (session.get_service(), service.get_operation()) was fully removed. Only the client interface is supported.
- breaking The event system emits events keyed by service_id (hyphenated), not by endpoint prefix. Handlers registered against e.g. `before-call.autoscaling` may silently stop firing or start firing for unintended services when endpoint prefixes are shared.
- gotcha All AWS service exceptions are raised as `ClientError`, not as typed subclasses. You cannot catch service-specific errors by exception type alone — you must inspect `e.response['Error']['Code']` (a string) to branch on specific error codes.
- gotcha urllib3 v2 is only supported on Python 3.10+. On Python 3.9, botocore pins urllib3<1.27, which conflicts with packages that require urllib3>=2. Installing both in the same environment silently pins you to the older urllib3 or raises a ResolutionImpossible error.
- gotcha Credentials are resolved lazily at first API call, not at client creation. Missing or expired credentials raise `NoCredentialsError` or `ClientError` (ExpiredTokenException) only when a request is made, making silent misconfiguration easy to overlook during startup.
Install
-
pip install botocore -
pip install boto3
Imports
- get_session
import botocore.session; session = botocore.session.get_session()
- ClientError
from botocore.exceptions import ClientError
- BotoCoreError
from botocore.exceptions import BotoCoreError
- Config
from botocore.config import Config
- Session (low-level)
import botocore.session; s = botocore.session.Session()
Quickstart
import os
import botocore.session
from botocore.config import Config
from botocore.exceptions import ClientError, BotoCoreError
# Build session — credentials resolved from env, ~/.aws/credentials, or IAM role
session = botocore.session.get_session()
client = session.create_client(
's3',
region_name=os.environ.get('AWS_DEFAULT_REGION', 'us-east-1'),
aws_access_key_id=os.environ.get('AWS_ACCESS_KEY_ID', ''),
aws_secret_access_key=os.environ.get('AWS_SECRET_ACCESS_KEY', ''),
config=Config(
retries={'max_attempts': 5, 'mode': 'adaptive'},
connect_timeout=5,
read_timeout=10,
),
)
try:
response = client.list_buckets()
for bucket in response.get('Buckets', []):
print(bucket['Name'])
except ClientError as e:
# AWS service-side error — inspect the structured code, NOT the string message
code = e.response['Error']['Code']
msg = e.response['Error']['Message']
print(f'AWS error [{code}]: {msg}')
if code == 'AccessDenied':
raise PermissionError('Check IAM permissions') from e
except BotoCoreError as e:
# Client-side error (bad config, network, credential resolution)
print(f'botocore client error: {e}')
raise