web42-auth (Python)
Token introspection client and framework middleware helpers for the Web42 auth platform.
Installation
# Core client only
pip install web42-auth
# With FastAPI middleware
pip install 'web42-auth[fastapi]'
# With Flask middleware
pip install 'web42-auth[flask]'
# With A2A server support (includes uvicorn)
pip install 'web42-auth[a2a]'
# Everything
pip install 'web42-auth[all]'
Quick start
from web42_auth import Web42Client
client = Web42Client(
client_id="your-client-id",
client_secret="your-client-secret",
)
token_info = client.introspect("Bearer eyJ...")
if token_info.active:
print(token_info.sub) # subject (user/agent ID)
Async
from web42_auth import AsyncWeb42Client
client = AsyncWeb42Client(
client_id="your-client-id",
client_secret="your-client-secret",
)
token_info = await client.introspect("eyJ...")
Reference
Web42Client / AsyncWeb42Client
| Parameter | Type | Description |
|---|---|---|
client_id |
str |
OAuth2 client ID |
client_secret |
str |
OAuth2 client secret |
Methods:
introspect(token: str) -> TokenInfo— validate a Bearer token
TokenInfo
| Field | Type | Description |
|---|---|---|
active |
bool |
Whether the token is valid |
sub |
str | None |
Subject (user or agent identifier) |
exp |
int | None |
Expiry timestamp (Unix) |
iat |
int | None |
Issued-at timestamp (Unix) |
scope |
str | None |
Space-separated scopes |
Web42AuthError
Raised when the auth server returns an unexpected error response.
FastAPI middleware
import os
from fastapi import FastAPI
from web42_auth import AsyncWeb42Client
from web42_auth.middleware.fastapi import make_require_token
w42 = AsyncWeb42Client(
client_id=os.environ["WEB42_CLIENT_ID"],
client_secret=os.environ["WEB42_CLIENT_SECRET"],
)
app = FastAPI()
require_token = make_require_token(w42)
@app.get("/protected", dependencies=[Depends(require_token)])
async def protected():
return {"status": "ok"}
Environment variables: WEB42_CLIENT_ID, WEB42_CLIENT_SECRET
Flask middleware
import os
from flask import Flask
from web42_auth import Web42Client
from web42_auth.middleware.flask import Web42FlaskMiddleware
w42 = Web42Client(
client_id=os.environ["WEB42_CLIENT_ID"],
client_secret=os.environ["WEB42_CLIENT_SECRET"],
)
app = Flask(__name__)
Web42FlaskMiddleware(app, client=w42)
A2A server
Build an A2A-protocol agent server with Web42 Bearer auth enforced on every request:
import os
from web42_auth import AsyncWeb42Client
from web42_auth.a2a import create_a2a_server, AgentCardOptions
w42 = AsyncWeb42Client(
client_id=os.environ["WEB42_CLIENT_ID"],
client_secret=os.environ["WEB42_CLIENT_SECRET"],
)
server = create_a2a_server(
web42=w42,
card=AgentCardOptions(
name="My Agent",
description="Does cool things",
base_url="http://localhost:8000",
skills=[{"id": "cool", "name": "Cool Skill", "description": "..."}],
),
executor=MyCoolExecutor(),
)
server.listen(port=8000)
server.app exposes the raw Starlette ASGI app if you need to mount it under an existing FastAPI application:
fastapi_app.mount("/", server.app)
Agent card helpers
from web42_auth.a2a import build_agent_card, build_agent_card_security, AgentCardOptions
card = build_agent_card(AgentCardOptions(
name="My Agent",
description="...",
base_url="https://my-agent.example.com",
))
# Returns a dict compatible with a2a.types.AgentCard
security = build_agent_card_security()
# Returns {"securitySchemes": {...}, "security": [...]}
| Symbol | Description |
|---|---|
create_a2a_server |
Factory — returns A2AServer |
A2AServer |
Wraps the ASGI app; has .listen() and .app |
AgentCardOptions |
Dataclass for agent card configuration |
build_agent_card |
Build a full agent card dict |
build_agent_card_security |
Build the Web42 Bearer security scheme block |
WEB42_SECURITY_SCHEME |
Constant "Web42Bearer" used in agent cards |
AP2 Payments
Build and parse AP2 payment mandates for agent commerce.
from web42_auth import (
build_cart_mandate,
build_cart_mandate_data_part,
build_cart_mandate_artifact,
is_cart_mandate_part,
is_payment_mandate_part,
parse_cart_mandate,
parse_payment_mandate,
verify_payment,
async_verify_payment,
)
Types
| Type | Description |
|---|---|
AP2Amount |
Dataclass: currency: str, value: float |
DisplayItem |
Dataclass: label: str, amount: AP2Amount |
CartMandate |
Full cart mandate with contents + merchant signature |
PaymentMandate |
Payment proof with contents + user authorization JWT |
PaymentVerification |
Dataclass: valid: bool, payment_mandate_id, payer_id, amount, etc. |
Building a CartMandate (merchant agents)
from web42_auth import build_cart_mandate, build_cart_mandate_data_part, AP2Amount, DisplayItem
cart = build_cart_mandate(
order_id="order_latte_456",
items=[
DisplayItem(label="Iced Latte", amount=AP2Amount(currency="USD", value=4.50)),
DisplayItem(label="Tax", amount=AP2Amount(currency="USD", value=0.45)),
],
total=DisplayItem(label="Total", amount=AP2Amount(currency="USD", value=4.95)),
merchant_signature="sig_starbucks_456",
)
data_part = build_cart_mandate_data_part(cart)
Parsing mandates (shopping agents)
from web42_auth import is_payment_mandate_part, parse_payment_mandate
for part in message["parts"]:
if is_payment_mandate_part(part):
mandate = parse_payment_mandate(part)
print(mandate.user_authorization) # JWT token
Verifying payment (merchant agents)
Sync:
from web42_auth import Web42Client, verify_payment
client = Web42Client(
client_id="...",
client_secret="...",
)
result = verify_payment(client, payment_token, "order_latte_456")
if result.valid:
print(f"Verified: ${result.amount.value} from {result.payer_id}")
Async:
from web42_auth import AsyncWeb42Client, async_verify_payment
client = AsyncWeb42Client(...)
result = await async_verify_payment(client, payment_token, "order_latte_456")
Metadata
Release files for web42-auth 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| web42_auth-0.1.0.tar.gz | 11.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| web42_auth-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 24.4 kB
Release files / web42_auth-0.1.0.tar.gz
| Download URL | web42_auth-0.1.0.tar.gz |
|---|---|
| Size | 11.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
96fafe49eaf2c706848059019ad61e6d46834cb4613c6c41baf27f913633085f
|
|
BLAKE2b-256 checksum How to use checksums |
309196e82db4d0a0b50a20cceabe0dc49a87998d92c3aad09d72705dc500f01e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Mar 31, 2026.
Transparency logRelease files / web42_auth-0.1.0-py3-none-any.whl
| Download URL | web42_auth-0.1.0-py3-none-any.whl |
|---|---|
| Size | 12.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1cfeb42c697f07b034440eb910b9f26281020bc7d6aec2947f0fd8fd651e7725
|
|
BLAKE2b-256 checksum How to use checksums |
022596d0a94c9f7d2efad7c27a2392943360cd97dd25738700529757ecdb5f45
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Mar 31, 2026.
Transparency log