AWS SDK Signers
The aws-sdk-signers library provides standalone HTTP request signers for Amazon Web Services, primarily focusing on SigV4 signing. It's part of the wider smithy-python ecosystem, offering a low-level interface for integrating AWS signature logic into any HTTP client. As a 0.x.x release, it is under active development with an irregular release cadence.
Common errors
-
ModuleNotFoundError: No module named 'botocore'
cause The `botocore` library, commonly used for resolving AWS credentials and region, is not installed.fixInstall `botocore`: `pip install botocore`. -
RuntimeError: AWS credentials or region not found. Set AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN (optional) and AWS_DEFAULT_REGION.
cause The quickstart code or your application could not find valid AWS credentials or a default region in environment variables, AWS config files, or an assumed IAM role.fixConfigure your AWS credentials and region. This can be done via environment variables (e.g., `export AWS_ACCESS_KEY_ID=...`, `export AWS_DEFAULT_REGION=us-east-1`), `~/.aws/credentials` file, or by running in an environment with an IAM role. -
AttributeError: 'dict' object has no attribute 'headers'
cause You are passing a plain Python dictionary as the request object to the signer instead of an `HttpRequest` object.fixImport `HttpRequest` from `aws_sdk_http` and use it to construct your request object. Ensure `aws-sdk-http` is installed: `pip install aws-sdk-http`.
Warnings
- breaking As a 0.x.x library, the API is subject to frequent and breaking changes without prior notice. Semantic versioning guarantees do not apply, and minor version increments may introduce incompatible changes.
- gotcha This library provides signing logic but does not handle AWS credential or region resolution by itself. For typical AWS environments, you'll need to use `botocore` or manually provide `AWSCredentials` and `region`.
- gotcha The signer expects an `HttpRequest` object from `aws-sdk-http` (or a compatible type) and will not work with a plain Python dictionary or other HTTP request objects directly without custom adaptation.
Install
-
pip install aws-sdk-signers aws-sdk-http botocore
Imports
- HTTPSigner
from aws_sdk_signers import HTTPSigner
- SigV4Signer
from aws_sdk_signers import SigV4Signer
- HttpRequest
from aws_sdk_http import HttpRequest
Quickstart
import os
from datetime import datetime, timezone
from aws_sdk_signers import SigV4Signer
from aws_sdk_http import HttpRequest
import botocore.session
# 1. Resolve AWS credentials and region (e.g., from environment variables, ~/.aws/credentials)
session = botocore.session.get_session()
credentials = session.get_credentials()
# Use os.environ.get for region, falling back to botocore config or a default
region = os.environ.get('AWS_DEFAULT_REGION', session.get_config_variable('region') or 'us-east-1')
# Ensure credentials and region are found
if not credentials or not credentials.access_key or not region:
raise RuntimeError("AWS credentials or region not found. Set AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN (optional) and AWS_DEFAULT_REGION.")
# 2. Create an HTTP Request object
# For an empty body, x-amz-content-sha256 must be the SHA256 hash of an empty string.
request = HttpRequest(
method="GET",
scheme="https",
host="example.s3.amazonaws.com",
path="/myobject.txt",
headers={
"Host": "example.s3.amazonaws.com",
"x-amz-content-sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
body=b''
)
# 3. Create a SigV4Signer instance
signer = SigV4Signer(
credentials=credentials,
service_id="s3",
region=region,
)
# 4. Sign the request
signing_date = datetime.now(timezone.utc) # Use a timezone-aware datetime for signing
signed_request = signer.sign(request, signing_date)
print("--- Original Request Headers ---")
for k, v in request.headers.items():
print(f"{k}: {v}")
print("\n--- Signed Request Headers ---")
for k, v in signed_request.headers.items():
print(f"{k}: {v}")
print(f"\nSigned Authorization header: {signed_request.headers.get('Authorization')}")