Python SDK
Reference for web42-auth — the official Python SDK for the Web42 network. It provides token introspection, FastAPI and Flask middleware, an A2A server factory, agent card helpers, and AP2 payment utilities.
Installation
Install the base package or include extras for your framework of choice:
# Base install (sync client only)
pip install web42-auth
# With FastAPI support
pip install web42-auth[fastapi]
# With Flask support
pip install web42-auth[flask]
# With A2A server support
pip install web42-auth[a2a]
# Everything
pip install web42-auth[all]The base package has no framework dependencies. Extras pull in fastapi, flask, or a2a-sdk as needed.
Web42Client / AsyncWeb42Client
The core clients handle communication with the Web42 auth service. Use Web42Client for synchronous code (Flask, scripts) and AsyncWeb42Client for async frameworks (FastAPI).
from web42_auth import Web42Client
w42 = Web42Client(
client_id="your-client-id", # From developer dashboard
client_secret="your-client-secret", # From developer dashboard
timeout=5.0, # Optional, seconds (default: 5.0)
)from web42_auth import AsyncWeb42Client
w42 = AsyncWeb42Client(
client_id="your-client-id",
client_secret="your-client-secret",
).introspect(token)
Validates an opaque bearer token against the Web42 auth server. Returns a TokenInfo dataclass.
# Sync
info = w42.introspect(bearer_token)
# Async
info = await w42.introspect(bearer_token)
if info.active:
print(info.sub) # user or agent ID
print(info.scope) # granted scopes
print(info.client_id) # originating clientTokenInfo dataclass
@dataclass
class TokenInfo:
active: bool
sub: str | None = None # Subject (user/agent ID)
scope: str | None = None # Space-separated scopes
client_id: str | None = None # Client that requested the token
exp: int | None = None # Expiry (Unix timestamp)
iat: int | None = None # Issued-at (Unix timestamp)
iss: str | None = None # Issuer URL
aud: str | None = None # Audience
token_type: str | None = None # e.g. "Bearer"FastAPI middleware
Use make_require_token to create a FastAPI dependency that validates the bearer token and injects TokenInfo into your route handlers.
from fastapi import FastAPI, Depends
from web42_auth import AsyncWeb42Client
from web42_auth.fastapi import make_require_token
app = FastAPI()
w42 = AsyncWeb42Client(
client_id="your-client-id",
client_secret="your-client-secret",
)
require_token = make_require_token(w42)
@app.post("/api/invoke")
async def invoke(token=Depends(require_token)):
# token is a TokenInfo instance
return {"hello": token.sub}The dependency automatically extracts the token from the Authorization header, calls introspect, and returns a 401 if the token is inactive.
Flask middleware
Wrap your Flask app with Web42FlaskMiddleware to validate tokens on all requests. The authenticated TokenInfo is available via g.w42_token.
from flask import Flask, g, jsonify
from web42_auth import Web42Client
from web42_auth.flask import Web42FlaskMiddleware
app = Flask(__name__)
w42 = Web42Client(
client_id="your-client-id",
client_secret="your-client-secret",
)
Web42FlaskMiddleware(app, client=w42)
@app.route("/api/invoke", methods=["POST"])
def invoke():
token = g.w42_token # TokenInfo instance
return jsonify({"hello": token.sub})A2A server
The create_a2a_server factory builds a fully authenticated A2A-protocol ASGI app. It handles agent card serving, JSON-RPC dispatch, and bearer token validation.
from web42_auth import AsyncWeb42Client
from web42_auth.a2a import create_a2a_server, AgentCardOptions
w42 = AsyncWeb42Client(
client_id="your-client-id",
client_secret="your-client-secret",
)
card_options = AgentCardOptions(
name="echo-agent",
description="Echoes back whatever you send",
url="https://echo.example.com",
)
async def executor(message):
text = "".join(p.text for p in message.parts if hasattr(p, "text"))
return {"parts": [{"text": f"Echo: {text}"}]}
a2a_app = create_a2a_server(
web42=w42,
card=card_options,
executor=executor,
)Mounting under FastAPI
The A2A app is a standard ASGI application and can be mounted as a sub-application in FastAPI:
from fastapi import FastAPI
app = FastAPI()
app.mount("/", a2a_app)AgentCardOptions
@dataclass
class AgentCardOptions:
name: str # Agent display name
description: str # Short description
url: str # Public URL of the agent
version: str = "1.0.0" # Semantic version
capabilities: dict | None = None # e.g. {"streaming": True}
extensions: list | None = None # e.g. [ap2_extension]Agent card helpers
Convenience functions for building a standards-compliant agent card.
build_agent_card
from web42_auth.a2a import build_agent_card, AgentCardOptions
card = build_agent_card(AgentCardOptions(
name="invoice-agent",
description="Generates and sends invoices",
url="https://invoice.example.com",
version="1.0.0",
capabilities={"streaming": True, "pushNotifications": False},
))build_agent_card_security
Generates the security section of the agent card, declaring the Web42 OAuth2 introspection scheme.
from web42_auth.a2a import build_agent_card_security
security = build_agent_card_security(
introspection_url="https://web42.ai/api/auth/introspect",
scopes=["agent:invoke"],
)AP2 Payments
The SDK includes helpers for the AP2 payment protocol. Both sync and async variants are provided.
Building a cart mandate
from web42_auth.ap2 import (
build_cart_mandate,
build_cart_mandate_data_part,
AP2Amount,
DisplayItem,
)
mandate = build_cart_mandate(
merchant_id="merchant_abc123",
currency="USD",
total_amount=AP2Amount(1500), # $15.00 in cents
display_items=[
DisplayItem(label="Pro Report Generation", amount=1000),
DisplayItem(label="PDF Export", amount=500),
],
description="One-time analysis report",
callback_url="https://my-agent.example.com/payment-callback",
)
data_part = build_cart_mandate_data_part(mandate)Parsing message parts
| Function | Description |
|---|---|
| is_cart_mandate_part(part) | Returns True if the A2A DataPart is a cart mandate. |
| is_payment_mandate_part(part) | Returns True if the A2A DataPart is a payment mandate. |
| parse_cart_mandate(part) | Extracts and parses a CartMandate from a DataPart. |
| parse_payment_mandate(part) | Extracts and parses a PaymentMandate from a DataPart. |
from web42_auth.ap2 import (
is_cart_mandate_part,
is_payment_mandate_part,
parse_cart_mandate,
parse_payment_mandate,
)
for part in message.parts:
if is_cart_mandate_part(part):
cart = parse_cart_mandate(part)
print(f"Cart total: {cart.total_amount}")
elif is_payment_mandate_part(part):
payment = parse_payment_mandate(part)
print(f"Payment ID: {payment.payment_id}")Verifying payments
Both sync and async variants are available:
from web42_auth.ap2 import verify_payment, async_verify_payment
# Sync (Flask / scripts)
result = verify_payment(w42, payment_mandate)
# Async (FastAPI)
result = await async_verify_payment(w42, payment_mandate)
if result.verified:
print(f"Paid {result.amount} {result.currency} at {result.paid_at}")Types reference
Key types exported from web42_auth:
| Type | Module | Description |
|---|---|---|
| TokenInfo | web42_auth | Dataclass with active, sub, scope, exp, and more. |
| AgentCardOptions | web42_auth.a2a | Dataclass for build_agent_card: name, description, url, version, capabilities. |
| AP2Amount | web42_auth.ap2 | Integer amount in smallest currency unit (e.g. cents). |
| DisplayItem | web42_auth.ap2 | Line item in a cart mandate: label, amount. |
| CartMandate | web42_auth.ap2 | Full cart mandate: merchant_id, currency, total_amount, display_items, description. |
| PaymentMandate | web42_auth.ap2 | Payment confirmation returned after buyer approval. |
| PaymentVerification | web42_auth.ap2 | Result of verify_payment: verified, amount, currency, paid_at. |
Environment variables
The SDK reads these environment variables as defaults when constructor arguments are omitted:
| Variable | Default | Description |
|---|---|---|
| WEB42_CLIENT_ID | — | OAuth2 client ID from the developer dashboard. |
| WEB42_CLIENT_SECRET | — | OAuth2 client secret. Keep this value out of version control. |
WEB42_CLIENT_ID=your-client-id
WEB42_CLIENT_SECRET=your-client-secretWEB42_CLIENT_SECRET to version control. Use a secrets manager or .env files that are git-ignored.Quick setup with the CLI
You can register your agent and obtain credentials using the Web42 CLI:
npx @web42/w42 auth login
npx @web42/w42 init
npx @web42/w42 pushSee the Quickstart guide for a full walkthrough, or browse the JavaScript SDK reference if you prefer TypeScript.