Skip to main content

HTTPX-OAuth2

My implementation of an httpx.BaseTransport that negotiates an access token and puts it in the request headers before sending it.

Installation

pip install httpx-oauth2

Usage

The library only needs to be setup. Once it is done, the authentication will happen behind the usage of httpx.Client, meaning you shouldn't need to change existing httpx code.

Imports

import httpx
from httpx_oauth2 import (
	OAuthAuthorityClient,
	ClientCredentials,
	ResourceOwnerCredentials,
	AuthenticatingTransportFactory
)

Client Credentials

api_client = httpx.Client(base_url='http://example')

# ============== ADD THIS ==============

oauth_authority = OAuthAuthorityClient(
	httpx.Client(base_url='http://localhost:8080/realms/master'),
)

transports = AuthenticatingTransportFactory(oauth_authority)

credentials = ClientCredentials('client-1', 'my-secret', ('scope-1',))

api_client._transport = transports.authenticating_transport(api_client._transport, credentials)

# ===== JUST THIS. NOW USE A USUAL =====

api_client.get('/users')

Resource Owner (Client Credentials with a technical account)

api_client = httpx.Client(base_url='http://example')

# ============== ADD THIS ==============

oauth_authority = OAuthAuthorityClient(
	httpx.Client(base_url='http://localhost:8080/realms/master'),
)

transports = AuthenticatingTransportFactory(oauth_authority)

credentials = ResourceOwnerCredentials('client-3', 'my-secret').with_username_password('user', 'pwd')

api_client._transport = transports.authenticating_transport(api_client._transport, credentials)

# ===== JUST THIS. NOW USE A USUAL =====

api_client.get('/users')

Token Exchange

api_client = httpx.Client(base_url='http://example')

# ============== ADD THIS ==============

oauth_authority = OAuthAuthorityClient(
	httpx.Client(base_url='http://localhost:8080/realms/master'),
)

transports = AuthenticatingTransportFactory(oauth_authority)

credentials = ClientCredentials('client-1', 'my-secret', ('scope-1',))

api_client._transport = transports.token_exchange_transport(
	api_client._transport,
	credentials,
	lambda: flask.request.headers['Authorization'].removeprefix('Bearer ') # A callable that returns the token to be exchanged
)

# ===== JUST THIS. NOW USE A USUAL =====

api_client.get('/users')

Getting an access token

oauth_authority = OAuthAuthorityClient(
	httpx.Client(base_url='http://localhost:8080/realms/master'),
)

credentials = ClientCredentials('client-1', 'my-secret', ('scope-1',))

token = oauth_authority.get_token(credentials)

Cache and Automatic retry

Access token are cached. Exchanged tokens too.

If the AuthenticatingTransport see that the response is 401 (meaning the token wasn't valid anymore), it will:

  • Try to refresh the token with the refresh_token if supported.
  • Request a new token.
  • Re-send the request.

Multithreading

The Token negotiation is behind a thread synchronization mechanism, meaning if multiple threads need a token at the same time, only one token will be negotiated with the authority and shared across all threads.

But '_' means its protected?

Yes. But I haven't found an easier way to let httpx build the base transport but still be able to wrap it with custom behavior.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

httpx_oauth2-1.0.7.tar.gz (18.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

httpx_oauth2-1.0.7-py3-none-any.whl (10.0 kB view details)

Uploaded Python 3

File details

Details for the file httpx_oauth2-1.0.7.tar.gz.

File metadata

  • Download URL: httpx_oauth2-1.0.7.tar.gz
  • Upload date:
  • Size: 18.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for httpx_oauth2-1.0.7.tar.gz
Algorithm Hash digest
SHA256 0681b1d8328de1e99e1e76160955fd1d66cfb41c4fd930e23fc3a88a6259ab38
MD5 afecbce2b541094a082e5ab029594f54
BLAKE2b-256 652881723d07051b191d6e7f8fc9fb95bdb45eece57f764cda9bb75fb0823a6c

See more details on using hashes here.

File details

Details for the file httpx_oauth2-1.0.7-py3-none-any.whl.

File metadata

  • Download URL: httpx_oauth2-1.0.7-py3-none-any.whl
  • Upload date:
  • Size: 10.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for httpx_oauth2-1.0.7-py3-none-any.whl
Algorithm Hash digest
SHA256 fa5556183836d13a7815401ec4dc79de2f0d0b9357b1b2d06a6331397ba16fe6
MD5 9fb849cbd318d7e167442d9008fdf51b
BLAKE2b-256 c251ea187d004a5947eb413407680f8bff36b24df45a65f0943c9a55ec7a2afc

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.0.7 This release

2 files

1.0.6

2 files

1.0.5

2 files

1.0.4

2 files

1.0.2

2 files

0.1.0

2 files

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