Skip to main content

Add your description here

Project description

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.

Project details


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.6.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.6-py3-none-any.whl (10.0 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for httpx_oauth2-1.0.6.tar.gz
Algorithm Hash digest
SHA256 d3f3afb3db38cf2cba519ca205337f143872772c8e578e67e2f93dfb63093f33
MD5 fe864d431241695e6648fd25ee7b04ce
BLAKE2b-256 00731b42fb93f9489f144dbc4cc79223e0fb47c9855caa91b5363c93a4b54e80

See more details on using hashes here.

File details

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

File metadata

  • Download URL: httpx_oauth2-1.0.6-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.7

File hashes

Hashes for httpx_oauth2-1.0.6-py3-none-any.whl
Algorithm Hash digest
SHA256 240652a70bbff7267693b39478e0a4a11eed88056a3c59a7968dd319ccca201f
MD5 a753b1a747fa83fce17ee811254d15d8
BLAKE2b-256 1c3fda911e594fad049c5a675f1c75fd0642af7ac118c76310fcdc338d577393

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page