Skip to main content

Python reference library for consuming ia.json files — the universal standard for AI interaction with websites

Project description

iajson

Python reference library for consuming ia.json files -- the universal standard for AI interaction with websites.

Installation

# Install from GitHub
pip install "iajson @ git+https://github.com/Dandte/ai.json.git#subdirectory=libraries/python"

Requires Python 3.10+. The only runtime dependency is httpx.

Quick start

Synchronous

from iajson import IaJsonClient

# Discover and connect to a site
client = IaJsonClient.discover("techstore.example.com")

# Inspect the site
print(client.site.name)        # "TechStore"
print(client.site.type)        # "ecommerce"
print(client.version)          # "1.0.0"
print(client.capabilities)     # {"read": True, "write": True, ...}

# List available endpoints
for ep in client.get_endpoints():
    print(f"{ep.name} [{ep.method} {ep.path}] ({ep.level})")

# Filter by access level
public_endpoints = client.get_endpoints(level="public")

# Call a public endpoint
products = client.call("search_products", q="wireless headphones")
print(products)

Asynchronous

import asyncio
from iajson import IaJsonClient

async def main():
    client = await IaJsonClient.adiscover("techstore.example.com")

    products = await client.acall("search_products", q="wireless headphones")
    print(products)

    product = await client.acall("get_product", id="prod_abc123")
    print(product)

asyncio.run(main())

Authentication

Signed-key authentication (protected endpoints)

If you already have credentials:

client = IaJsonClient.discover(
    "techstore.example.com",
    api_key="ia_live_abc123def456",
    secret="sec_xyz789uvw012",
)

# Call a protected endpoint -- signing is automatic
inventory = client.call("get_inventory")

Or set credentials after discovery:

client = IaJsonClient.discover("techstore.example.com")
client.set_credentials(api_key="ia_live_abc123def456", secret="sec_xyz789uvw012")
inventory = client.call("get_inventory")

Agent registration

The full registration flow (Section 5.1 of the ia.json spec):

from iajson import IaJsonClient, AgentInfo

client = IaJsonClient.discover("techstore.example.com")

# Step 1: Send registration request
agent = AgentInfo(
    name="My AI Assistant",
    domain="myai.example.com",
    webhook_url="https://myai.example.com/verify",
    contact="admin@myai.example.com",
    description="AI shopping assistant",
)
client.register(agent)

# Step 2: The site sends a verification code to your webhook_url.
#          Handle that in your webhook handler.

# Step 3 & 4: Submit the verification code and receive credentials
verification_code = "vc_abc123def456"  # received at your webhook
creds = client.complete_registration(verification_code)

print(creds.api_key)       # "ia_live_..."
print(creds.secret)         # "sec_..."
print(creds.expires_at)     # "2026-05-12T00:00:00Z"
print(creds.permissions)    # ["public", "protected"]

# Credentials are now stored on the client automatically
inventory = client.call("get_inventory")

OAuth2 (user_required endpoints)

from iajson import IaJsonClient
from iajson.auth.oauth import OAuth2Config, generate_pkce_challenge, build_authorization_url, exchange_code

client = IaJsonClient.discover("techstore.example.com")

# Parse OAuth2 config from the ia.json document
oauth_config = OAuth2Config.from_dict(client.document["auth"]["oauth2"])

# Generate PKCE challenge
pkce = generate_pkce_challenge()

# Build the authorization URL for the user to visit
auth_url = build_authorization_url(
    oauth_config,
    client_id="your_client_id",
    redirect_uri="https://myai.example.com/callback",
    scopes=["cart:read", "cart:write", "orders:write"],
    state="random_csrf_token",
    pkce=pkce,
)
print(f"Send user to: {auth_url}")

# After the user authorizes, exchange the code for a token
token = exchange_code(
    oauth_config,
    client_id="your_client_id",
    client_secret="your_client_secret",
    code="authorization_code_from_callback",
    redirect_uri="https://myai.example.com/callback",
    code_verifier=pkce.verifier,
)

# Set the token on the client
client.set_access_token(token.access_token)

# Now call user_required endpoints
cart = client.call("get_cart")
client.call("add_to_cart", product_id="prod_abc123", quantity=2)

Request signing

If you need to compute signatures manually:

from iajson import sign, create_signed_headers

# Low-level: compute a signature
signature = sign(
    secret="sec_xyz789uvw012",
    timestamp=1707753600,
    body='{"product_id":"prod_123","quantity":2}',
)

# High-level: get a full set of auth headers
headers = create_signed_headers(
    api_key="ia_live_abc123def456",
    secret="sec_xyz789uvw012",
    body='{"product_id":"prod_123","quantity":2}',
    prefix="X-IA-",
    algorithm="sha256",
)
# headers = {
#     "X-IA-Key": "ia_live_abc123def456",
#     "X-IA-Signature": "a1b2c3d4...",
#     "X-IA-Timestamp": "1707753600",
# }

Discovery

Low-level discovery (without creating a client):

from iajson import discover, adiscover

# Synchronous
doc = discover("techstore.example.com")
print(doc["site"]["name"])

# Asynchronous
doc = await adiscover("techstore.example.com")
print(doc["api"]["base_url"])

Endpoint introspection

client = IaJsonClient.discover("techstore.example.com")

# Get a specific endpoint
ep = client.get_endpoint("search_products")
print(ep.name)          # "search_products"
print(ep.method)        # "GET"
print(ep.path)          # "/products/search"
print(ep.level)         # "public"
print(ep.description)   # "Search products by keyword"

# Inspect parameters
for param in ep.parameters:
    print(f"  {param.name}: {param.type} (required={param.required})")
    # q: string (required=True)
    # min_price: number (required=False)
    # max_price: number (required=False)

# Inspect body fields (for POST endpoints)
ep_order = client.get_endpoint("create_order")
for field in ep_order.body_fields:
    print(f"  {field.name}: {field.type} (required={field.required})")

Error handling

from iajson import (
    IaJsonClient,
    IaJsonError,
    AuthenticationError,
    DiscoveryError,
    RateLimitError,
)

try:
    client = IaJsonClient.discover("unknown-site.example.com")
except DiscoveryError as e:
    print(f"Discovery failed: {e.message}")
    print(f"Domain: {e.domain}")
    print(f"HTTP status: {e.status_code}")

try:
    result = client.call("get_inventory")
except AuthenticationError as e:
    print(f"Auth failed: {e.message}")
    print(f"Error code: {e.error_code}")  # e.g. "invalid_signature"
except RateLimitError as e:
    print(f"Rate limited! Retry after {e.retry_after} seconds")
except IaJsonError as e:
    print(f"General error: {e.message}")

API reference

IaJsonClient

Method Description
IaJsonClient.discover(domain) Fetch ia.json and create a client (sync)
IaJsonClient.adiscover(domain) Fetch ia.json and create a client (async)
client.call(endpoint, **params) Invoke an endpoint (sync)
client.acall(endpoint, **params) Invoke an endpoint (async)
client.get_endpoints(level=None) List endpoints, optionally filtered
client.get_endpoint(name) Get a single endpoint by name
client.register(agent_info) Start agent registration
client.complete_registration(code) Finish registration with verification code
client.sign(body) Compute a request signature
client.set_credentials(key, secret) Set signed_key credentials
client.set_access_token(token) Set an OAuth2 access token

Properties

Property Type Description
client.site SiteInfo Parsed site metadata
client.base_url str API base URL
client.version str ia.json spec version
client.capabilities dict Feature flags
client.document dict Raw ia.json document

License

MIT

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

iajson-1.0.0.tar.gz (14.7 kB view details)

Uploaded Source

Built Distribution

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

iajson-1.0.0-py3-none-any.whl (18.9 kB view details)

Uploaded Python 3

File details

Details for the file iajson-1.0.0.tar.gz.

File metadata

  • Download URL: iajson-1.0.0.tar.gz
  • Upload date:
  • Size: 14.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for iajson-1.0.0.tar.gz
Algorithm Hash digest
SHA256 51df2a7da7abd739e8b0e1adf9bfd7640a670598ab70b67df742a9b63f5d11c1
MD5 fce3bd5b89a517426573c44ba856e803
BLAKE2b-256 dc5cf57d7ef4e4377478895b317120cf0987a9ceb766167160cadbce89a81979

See more details on using hashes here.

File details

Details for the file iajson-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: iajson-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 18.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for iajson-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 55fd65edca4726fd8adaa03233177829640f99692c1110163f25b7662d9d68e4
MD5 60817e789349eaee92788748f9c441aa
BLAKE2b-256 2a0846ece9a8fdbbe00c2fe1a37f3334217347f34f0c7855d38365c4a91d46b3

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