s3transfer
s3transfer is an Amazon S3 Transfer Manager for Python, maintained by Amazon Web Services. It provides managed multipart uploads and downloads, automatic retries, progress callbacks, bandwidth throttling, and optional AWS CRT-accelerated transfers. As of version 0.16.0 it defaults to CRC32 checksums and supports user-provided full-object checksums. The project is NOT yet generally available (GA); minor-version bumps may contain breaking interface changes, so production deployments must pin to a minor version. It is bundled as a dependency of boto3 and botocore and is typically consumed indirectly through those SDKs.
Warnings
- breaking s3transfer is explicitly NOT GA. Interfaces can break between minor versions (e.g. 0.x.0 → 0.y.0). Always pin to a minor version in production requirements (e.g. s3transfer>=0.16.0,<0.17.0).
- breaking Mismatched awscrt version causes ImportError at import time. If awscrt is installed (e.g. pulled in by boto3[crt]) but is not at the version expected by the installed s3transfer/boto3, 'from boto3.s3.transfer import TransferConfig' raises ImportError: cannot import name 'S3ResponseError' from 'awscrt.s3'.
- breaking TransferConfig parameter names differ between s3transfer.manager.TransferConfig and boto3.s3.transfer.TransferConfig. The boto3 version maps max_concurrency→max_request_concurrency and max_io_queue→max_io_queue_size. Passing the raw s3transfer config to boto3 code (or vice versa) silently ignores aliased parameters.
- gotcha S3Transfer requires either a boto3 client OR a TransferManager instance — not both, not neither. Passing manager together with client, config, or osutil raises ValueError. Passing nothing also raises ValueError.
- gotcha CRC32 is now the default checksum algorithm for uploads. If the receiving side or downstream tooling does not handle the x-amz-checksum-crc32 header (e.g., some S3-compatible stores), uploads may fail or produce unexpected validation errors.
- gotcha Thread-local context (AWS X-Ray segments, OpenTelemetry spans, contextvars) is lost inside transfer worker threads. The transfer manager uses a ThreadPoolExecutor internally; tracing SDKs that rely on thread-local or context-variable storage will not see the parent trace context in worker threads.
- gotcha download_file and upload_file require filename to be a str or os.PathLike. Passing a raw bytes path or any other object raises ValueError immediately without touching S3.
Install
-
pip install s3transfer -
pip install "s3transfer" "boto3[crt]"
Imports
- TransferManager
from s3transfer.manager import TransferManager
- TransferConfig
from boto3.s3.transfer import TransferConfig
- S3Transfer
from boto3.s3.transfer import S3Transfer
- BaseSubscriber
from s3transfer.subscribers import BaseSubscriber
- RetriesExceededError
from boto3.exceptions import RetriesExceededError
Quickstart
import os
import boto3
from boto3.s3.transfer import TransferConfig, S3Transfer
# Credentials resolved from env, ~/.aws/credentials, or IAM role
aws_access_key = os.environ.get('AWS_ACCESS_KEY_ID', '')
aws_secret_key = os.environ.get('AWS_SECRET_ACCESS_KEY', '')
region = os.environ.get('AWS_DEFAULT_REGION', 'us-east-1')
bucket = os.environ.get('S3_BUCKET', 'my-bucket')
client = boto3.client(
's3',
region_name=region,
aws_access_key_id=aws_access_key or None,
aws_secret_access_key=aws_secret_key or None,
)
config = TransferConfig(
multipart_threshold=8 * 1024 * 1024, # 8 MB
max_concurrency=10,
num_download_attempts=5,
use_threads=True,
# Force classic manager; use 'auto' to allow CRT when awscrt is installed
preferred_transfer_client='classic',
)
transfer = S3Transfer(client, config)
# Upload
transfer.upload_file(
'/tmp/example.txt',
bucket,
'uploads/example.txt',
extra_args={'ContentType': 'text/plain'},
)
# Download
transfer.download_file(
bucket,
'uploads/example.txt',
'/tmp/example_downloaded.txt',
)
print('Transfer complete')