mrkeyoor.com_
Sat 08 Aug 21:01 UTC
PyPIInfraupdated 08 Aug 2026

aws-requests-auth

aws-requests-auth is a small requests authentication adapter that calculates AWS Signature Version 4 headers for an outgoing Python HTTP request. You give it the AWS host, region, service name, and credentials, then pass the resulting object through requests' auth parameter. Its original focus was Amazon Elasticsearch Service, now called Amazon OpenSearch Service, but the signer can work with other AWS HTTPS endpoints that accept header-based SigV4 authentication.

Verdict

Keep it only for a tested legacy requests integration. New AWS code should generally use a service client or botocore signer because this package's examples and release cadence are far behind current AWS practice.

API stability4/5The public surface is essentially two constructors, AWSRequestsAuth and the optional BotoAWSRequestsAuth, plus requests' standard auth hook. Version 0.4.3 has not changed since May 2020, so existing calls are unlikely to break. That stability mostly comes from inactivity, however, and the narrow implementation does not cover newer signing modes such as SigV4a or presigned URLs.
Docs2/5The README explains direct keys, STS session tokens, Lambda environment variables, botocore credential discovery, API Gateway, and an Elasticsearch client example. It also says Python 2.7 is tested, uses Python 2 print syntax and old Amazon Elasticsearch names, links to dated integrations, and provides no maintained API reference or troubleshooting guide for canonicalization failures.
Maintenance1/5PyPI 0.4.3 was uploaded in May 2020 and the GitHub repository's last code push was May 2023. The repository is not archived and the package is not formally deprecated, but 22 open issues and pull requests sit against a 509-star project with no current release activity. Treat it as effectively frozen and own compatibility testing if you keep it.
Ecosystem2/5The adapter fits requests cleanly and its optional botocore helper can use the standard AWS credential provider chain. Its README's elasticsearch-py example targets an API that has since changed, it has no plugin system, and modern AWS libraries already carry their own signing path. High transitive download volume does not create a broad integration ecosystem around this two-class package.

Use it if

  • You maintain an existing requests-based integration that already uses AWSRequestsAuth and only needs SigV4 header signing
  • You call an AWS-style endpoint that has no suitable boto3 client and need to retain the requests API
  • You need a tiny adapter whose signing code is short enough to audit locally
  • You can pin and test the package because the upstream release line has been quiet for years
Skip it if

Setup reality

The base install is only pip install aws-requests-auth plus its requests dependency, but usable AWS authentication still takes care. AWSRequestsAuth requires an access key, secret key, exact hostname, region, and AWS service identifier. Temporary STS credentials also require aws_token; leaving the session token out produces a signature that AWS rejects. Do not paste long-lived keys into source. The BotoAWSRequestsAuth helper is safer because it asks botocore's credential provider chain for environment, shared-config, container, or instance-role credentials and refreshes them before signing, but botocore is not declared as a required dependency, so install it separately. The signer uses the hostname you pass rather than deriving it from the request URL, which makes custom ports, proxies, and mismatched endpoints easy to get wrong. Query parameters must already have the encoding AWS expects. Use HTTPS even though the old README examples show HTTP. There is no timeout, retry, connection pooling, or response handling here; those remain requests configuration. Pin the old 0.4.3 release and keep integration tests against the real AWS service because the repository has not shipped a release since 2020 and its last code push was in 2023.

Patterns

Sign a GET requestsign-get-request

import requests
from aws_requests_auth.aws_auth import AWSRequestsAuth

host = "search-example.us-east-1.es.amazonaws.com"
auth = AWSRequestsAuth(
    aws_access_key=access_key,
    aws_secret_access_key=secret_key,
    aws_host=host,
    aws_region="us-east-1",
    aws_service="es",
)
response = requests.get(f"https://{host}/_cluster/health", auth=auth, timeout=10)
response.raise_for_status()

aws_host must match the host that AWS validates, and requests still needs an explicit timeout.

Sign a JSON POSTsign-post-json

response = requests.post(
    f"https://{host}/my-index/_search",
    json={"query": {"match_all": {}}},
    auth=auth,
    timeout=30,
)
response.raise_for_status()

The signer hashes the prepared request body, so pass json or data when making the request rather than changing the body afterward.

Sign with temporary STS credentialsuse-session-token

auth = AWSRequestsAuth(
    aws_access_key=credentials["AccessKeyId"],
    aws_secret_access_key=credentials["SecretAccessKey"],
    aws_token=credentials["SessionToken"],
    aws_host=host,
    aws_region="us-east-1",
    aws_service="execute-api",
)

All three temporary credential values belong together; omitting aws_token makes the signed request invalid.

Use botocore credential discoverydiscover-credentials

from aws_requests_auth.boto_utils import BotoAWSRequestsAuth

auth = BotoAWSRequestsAuth(
    aws_host=host,
    aws_region="us-east-1",
    aws_service="execute-api",
)

Install botocore separately. This helper resolves and refreshes credentials when requests are signed.

Call an IAM-protected API Gateway routecall-api-gateway

host = "abc123.execute-api.us-east-1.amazonaws.com"
auth = BotoAWSRequestsAuth(host, "us-east-1", "execute-api")
response = requests.post(
    f"https://{host}/prod/jobs",
    json={"job": "reindex"},
    auth=auth,
    timeout=15,
)

The service identifier for API Gateway is execute-api, not apigateway.

Reuse connections with a requests sessionreuse-http-session

session = requests.Session()
session.auth = auth
session.headers.update({"Accept": "application/json"})

for index in ("orders", "customers"):
    r = session.get(f"https://{host}/{index}/_count", timeout=10)
    r.raise_for_status()

A Session reuses connections, but every prepared request is signed independently with its current body and URL.

Send already encoded query parameterssend-query-parameters

from urllib.parse import urlencode

query = urlencode({"Action": "GetCallerIdentity", "Version": "2011-06-15"}, quote_via=__import__("urllib.parse").parse.quote)
r = requests.get(f"https://{host}/?{query}", auth=auth, timeout=10)

The implementation assumes the URL query is already encoded and sorts its raw key-value fragments during canonicalization.

Prepare and inspect signing headersinspect-signed-request

request = requests.Request("GET", f"https://{host}/")
prepared = request.prepare()
auth(prepared)

print(prepared.headers["Authorization"])
print(prepared.headers["x-amz-date"])

Useful in tests, but do not log full Authorization headers in production because they contain credential identifiers and signatures.

Alternatives

PackageRegistryPick it when
requests-aws4authPyPIYou want a requests-compatible SigV4 adapter with newer service examples and active release history
botocorePyPIYou want AWS-maintained credential discovery, request signing, refresh behavior, and service models
httpx-authPyPIYour application uses HTTPX and needs composable authentication rather than a requests-only hook