AWS SDK for Python (boto3)

raw JSON →
1.42.59 verified Mon May 11 auth: no python install: verified quickstart: verified

Official AWS SDK for Python. Extremely stable API — no breaking changes since v1.0. Two client styles: low-level client (boto3.client()) and high-level resource (boto3.resource()). Credential resolution follows a fixed chain. Region must be specified or set in environment — no global default. Released daily with new AWS service additions.

pip install boto3
error ModuleNotFoundError: No module named 'boto3'
cause The boto3 library is not installed in the Python environment where the code is being executed, or the active Python interpreter does not have access to it.
fix
Install boto3 using pip: pip install boto3 (or python -m pip install boto3 to ensure it's installed for the correct Python interpreter).
error botocore.exceptions.NoCredentialsError: Unable to locate credentials
cause boto3 cannot find the necessary AWS credentials to authenticate requests to AWS services. This occurs when credentials are not configured via environment variables, the AWS credentials file (~/.aws/credentials), or IAM roles.
fix
Configure your AWS credentials using the AWS CLI (aws configure), by setting AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables, or by ensuring the application runs on an EC2 instance with an appropriate IAM role.
error botocore.exceptions.ParamValidationError: Parameter validation failed: Invalid type for parameter ...
cause A parameter passed to a boto3 client method does not meet the expected type, format, or value required by the AWS service API.
fix
Review the boto3 documentation for the specific service and operation to ensure all parameters are of the correct data type, format, and within valid ranges. Upgrade boto3 if using an older version that might not support newer parameters.
error AttributeError: 'S3' object has no attribute 'Bucket'
cause This error typically occurs when attempting to use high-level resource-style methods (like `.Bucket()`) on a low-level client object (created with `boto3.client('s3')`) instead of a high-level resource object (created with `boto3.resource('s3')`).
fix
Instantiate an S3 resource object using s3 = boto3.resource('s3') to access high-level abstractions like s3.Bucket('your-bucket-name').objects.all(). If low-level API calls are needed, use s3_client = boto3.client('s3') and call methods like s3_client.list_buckets().
error botocore.exceptions.NoRegionError: You must specify a region.
cause Boto3 requires an AWS region to be specified but could not find one through environment variables, configuration files, or direct parameter.
fix
client = boto3.client('s3', region_name='us-east-1') # Or export AWS_REGION=us-east-1
gotcha Region is not globally defaulted. Calling boto3.client('s3') without region_name and without AWS_DEFAULT_REGION raises botocore.exceptions.NoRegionError. This is the most common source of 'it works on my machine' failures when deploying to CI/CD.
fix Always pass region_name= explicitly, or set AWS_DEFAULT_REGION in the environment.
gotcha NoCredentialsError means the credential chain was exhausted — no credentials found anywhere. Common in CI/CD when AWS_ACCESS_KEY_ID is set but AWS_SECRET_ACCESS_KEY is missing, or when ~/.aws/credentials exists locally but not in the deployment environment.
fix Check all chain links: env vars (both KEY and SECRET required), ~/.aws/credentials format, IAM instance role attachment.
gotcha boto3.client() and boto3.resource() return different objects with different APIs. S3 client uses client.put_object(), resource uses s3.Object().put(). Mixing client and resource patterns causes AttributeError.
fix Choose one pattern per codebase. boto3.resource() is higher-level but covers fewer services. boto3.client() covers all services.
gotcha Pinning boto3 without pinning botocore (or vice versa) causes version conflicts. boto3 and botocore ship together daily and must stay version-compatible.
fix Pin both: boto3==X.Y.Z botocore==A.B.C. Check boto3's setup.py for the exact botocore version it requires.
gotcha ClientError contains all AWS service errors. The error code is at e.response['Error']['Code'], not as a Python exception type. Catching specific AWS errors requires checking this string.
fix except ClientError as e: if e.response['Error']['Code'] == 'NoSuchBucket': ...
gotcha boto3.setup_default_session() modifies global state and is not thread-safe. In multi-threaded or async applications, concurrent calls with different credentials will interfere.
fix Use boto3.Session() to create isolated sessions per thread/coroutine.
pip install boto3[crt]
python os / libc variant status wheel install import disk
3.10 alpine (musl) boto3 - - 1.26s 50.3M
3.10 alpine (musl) crt - - 1.30s 61.7M
3.10 slim (glibc) boto3 - - 0.94s 51M
3.10 slim (glibc) crt - - 1.03s 63M
3.11 alpine (musl) boto3 - - 1.55s 53.2M
3.11 alpine (musl) crt - - 1.69s 64.7M
3.11 slim (glibc) boto3 - - 1.26s 54M
3.11 slim (glibc) crt - - 1.51s 66M
3.12 alpine (musl) boto3 - - 1.42s 44.8M
3.12 alpine (musl) crt - - 1.49s 56.3M
3.12 slim (glibc) boto3 - - 1.31s 45M
3.12 slim (glibc) crt - - 1.46s 57M
3.13 alpine (musl) boto3 - - 1.52s 44.5M
3.13 alpine (musl) crt - - 1.47s 55.8M
3.13 slim (glibc) boto3 - - 1.35s 45M
3.13 slim (glibc) crt - - 1.50s 57M
3.9 alpine (musl) boto3 - - 0.96s 49.8M
3.9 alpine (musl) crt - - 1.01s 61.2M
3.9 slim (glibc) boto3 - - 0.76s 50M
3.9 slim (glibc) crt - - 0.89s 62M

Credential chain order: (1) explicit in code, (2) env vars AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY, (3) ~/.aws/credentials, (4) ~/.aws/config, (5) EC2/ECS instance metadata.

import boto3
from botocore.exceptions import ClientError, NoCredentialsError

# Credential chain: env vars → ~/.aws/credentials → IAM role → ...
# Set AWS_DEFAULT_REGION or pass region_name explicitly
client = boto3.client('s3', region_name='us-east-1')

try:
    # List buckets
    response = client.list_buckets()
    for bucket in response['Buckets']:
        print(bucket['Name'])
except NoCredentialsError:
    print('No AWS credentials found')
except ClientError as e:
    print(f"Error: {e.response['Error']['Code']}: {e.response['Error']['Message']}")