Skip to main content

Authorization for the HTTP client

PyPI Python License

English | Русский

The library adds an IAM access token to outgoing HTTP requests. It obtains the token using a key identifier and secret key, then caches and refreshes it automatically. Calling code does not need to manage token lifetime or retries.

Use it when a service requires Authorization: Bearer <token> and IAM issues the token. Works both directly with httpx and with the HTTP client.

Installation

Requires Python 3.13 or later.

pip install cloudru-qa-http-client-auth

Import the library as the http_client_auth module.

Skills for AI agents

The package includes the http-client-auth-usage skill with examples and usage rules for AI agents. Install the library in your project environment, then run this from its root (requires uv):

uvx library-skills install --skill http-client-auth-usage --yes

For Claude Code, add --claude. The instructions are shipped with the library version.

Quick start

Synchronous client

import httpx
from http_client import HttpClient, options
from http_client_auth import IAM_Auth, IAM_HttpClient

iam_client = IAM_HttpClient("https://iam.example.com")
auth = IAM_Auth("your_key_id", "your_key_secret", iam_client)

# Directly with httpx
response = httpx.get("https://api.example.com/data", auth=auth)

# With http-client
client = HttpClient("https://api.example.com", options.with_auth(auth))
response = client.get("/data")

Asynchronous client

import httpx
from http_client import AsyncHttpClient, options
from http_client_auth import IAM_AsyncAuth, IAM_AsyncHttpClient

iam_client = IAM_AsyncHttpClient("https://iam.example.com")
auth = IAM_AsyncAuth("your_key_id", "your_key_secret", iam_client)

# Directly with httpx
async with httpx.AsyncClient(auth=auth) as client:
    response = await client.get("https://api.example.com/data")

# With http-client
client = AsyncHttpClient("https://api.example.com", options.with_auth(auth))
response = await client.get("/data")

OpenID authorization

Use a different IAM client; everything else stays the same:

from http_client_auth import IAM_Auth, IAM_OpenID_HttpClient

iam_client = IAM_OpenID_HttpClient("https://iam.example.com")
auth = IAM_Auth("your_key_id", "your_key_secret", iam_client)

Closing clients

The IAM client owns its connection pool and must be closed by the caller; IAM_Auth does not own it:

with IAM_HttpClient("https://iam.example.com") as iam_client:
    auth = IAM_Auth("your_key_id", "your_key_secret", iam_client)
    with HttpClient("https://api.example.com", options.with_auth(auth)) as client:
        response = client.get("/data")

For a long-lived client, call close(); for an asynchronous client, use await aclose().

Custom token store

By default, tokens are stored in process memory. To reuse them across processes, implement AuthStore:

import json
from datetime import datetime

from http_client_auth import AuthStore, IAM_Auth, IAM_HttpClient, Token


class RedisAuthStore(AuthStore):
    def __init__(self, redis_client):
        self._redis = redis_client

    def get(self, key: str) -> Token | None:
        raw = self._redis.get(f"token_for:{key}")
        if raw is None:
            return None
        data = json.loads(raw)
        return Token(data["access_token"], datetime.fromisoformat(data["expires_at"]))

    def set(self, key: str, token: Token) -> None:
        self._redis.set(
            f"token_for:{key}",
            json.dumps(
                {
                    "access_token": token.access_token,
                    "expires_at": token.expires_at.isoformat(),
                }
            ),
        )


iam_client = IAM_HttpClient("https://iam.example.com")
auth = IAM_Auth("your_key_id", "your_key_secret", iam_client, store=RedisAuthStore(redis_client))

IAM_AsyncAuth accepts AsyncAuthStore, the same interface with asynchronous get and set:

from http_client_auth import AsyncAuthStore, Token


class RedisAsyncAuthStore(AsyncAuthStore):
    def __init__(self, redis_client):
        self._redis = redis_client

    async def get(self, key: str) -> Token | None: ...

    async def set(self, key: str, token: Token) -> None: ...

Logging

If you add logging to the IAM client, pass IAM_SANITIZE_KEYS. Otherwise the OpenID request's secret key and the response JWT appear in full in logs: http-client's default masking list does not cover them.

import logging

from http_client import options
from http_client_auth import IAM_SANITIZE_KEYS, IAM_OpenID_HttpClient

iam_client = IAM_OpenID_HttpClient(
    "https://iam.example.com",
    options.with_logger(logging.getLogger("iam"), sanitize_keys=IAM_SANITIZE_KEYS),
)

Components

Authorization:

Class Purpose
IAM_Auth authorization for synchronous requests; implements httpx.Auth
IAM_AsyncAuth the same for asynchronous requests

IAM clients are passed to the authorization object as the first argument after the keys:

Class Purpose
IAM_HttpClient public IAM API
IAM_AsyncHttpClient public IAM API, asynchronous
IAM_OpenID_HttpClient API OpenID
IAM_OpenID_AsyncHttpClient OpenID API, asynchronous

Token stores:

Class Purpose
AuthStore synchronous store interface
AsyncAuthStore asynchronous store interface
InMemoryAuthStore in-memory store, default for IAM_Auth
InMemoryAsyncAuthStore in-memory store, default for IAM_AsyncAuth
Token access token and its expiry time

Other:

Name Purpose
AuthData IAM response: access token, lifetime, id_token
IAM_SANITIZE_KEYS IAM secret keys for options.with_logger(sanitize_keys=...)

Exceptions:

Class Raised when
IAM_Error base class for all authorization errors
IAM_AuthError IAM service returned an unsuccessful status code
IAM_InvalidJsonResponseError IAM response could not be parsed

Development

The library is developed in the qa-libraries monorepo alongside the other cloudru-qa-* libraries. You need uv, GNU Make, and checkmake. Run commands from the repository root:

make sync                         # install dependencies for all libraries from uv.lock
make test-http-client-auth        # tests for this library
make typecheck-http-client-auth   # mypy for this library
make check                        # formatting, ruff, mypy, and tests for the entire workspace

Tests run on Python 3.13 and 3.14. Create a separate environment for another version: make sync test-http-client-auth PYTHON_VERSION=3.14.

Publish a release with the git tag http-client-auth/v<version>. The tag version must match the version in packages/http-client-auth/pyproject.toml.

Metadata

Release files for cloudru-qa-http-client-auth 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cloudru-qa-http-client-auth 1.0.0
File Size Uploaded Provenance Actions
cloudru_qa_http_client_auth-1.0.0.tar.gz 22.9 kB With provenance Details for cloudru_qa_http_client_auth-1.0.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for cloudru-qa-http-client-auth 1.0.0
File Interpreter ABI Platform Actions
cloudru_qa_http_client_auth-1.0.0-py3-none-any.whl Python 3 none any Details for cloudru_qa_http_client_auth-1.0.0-py3-none-any.whl

Total release size: 43.6 kB

Release files / cloudru_qa_http_client_auth-1.0.0.tar.gz

Download URL cloudru_qa_http_client_auth-1.0.0.tar.gz
Size 22.9 kB
Tags Source
SHA-256 checksum
How to use checksums
29ccc713d7b2a8833e3e3bc91e0eaefcba992e1458033ab636c56621f0aa0b87
BLAKE2b-256 checksum
How to use checksums
df201362d513dcd190325f442e793b3579a2eacf88c01c91afdc712b77d102fe
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 14, 2026.

Transparency log

Release files / cloudru_qa_http_client_auth-1.0.0-py3-none-any.whl

Download URL cloudru_qa_http_client_auth-1.0.0-py3-none-any.whl
Size 20.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9f1f688ea08b12292efb4d97f8779ccf75b414008e642323ccdb70508e3b6853
BLAKE2b-256 checksum
How to use checksums
629f0f6c674319e7e619a8cbaf8d7a52482a9d13b4a2a279a4a1bdf8c29e0688
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 14, 2026.

Transparency log

Security for cloudru-qa-http-client-auth 1.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for cloudru_qa_http_client_auth-1.0.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 14, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page