Skip to main content

HALO — HTTP API Language for Operations. FastAPI plugin for self-describing APIs for LLM agents.

Project description

halo-fastapi

The Python reference implementation of the HALO protocol — a server-side FastAPI plugin and an agent-side HTTP client.

What It Does

Server-side (HaloRegister) — A single line added to any FastAPI application makes every route HALO-compliant. The plugin introspects existing routes, Pydantic models, and dependency injection at startup to automatically generate application/llm+json schemas served via OPTIONS handlers.

Client-side (HaloClient) — A client that discovers and consumes any HALO-compliant API. Handles root manifest discovery, per-route schema fetching with caching, credential injection (bearer, API key, basic), and retry with exponential backoff.

Installation

uv add halo-fastapi

Optional Extras

The framework adapters have optional dependencies that conflict with each other (azure-ai-projects version mismatch), so they cannot be installed in the same environment:

# Agent Framework adapter
uv add "halo-fastapi[agent-framework]"

# Semantic Kernel adapter
uv add "halo-fastapi[semantic-kernel]"

Development (Monorepo)

halo-fastapi is a workspace member. To sync the core workspace:

uv sync --all-packages

The sample agent apps are excluded from the workspace due to conflicting transitive dependencies. Install them on demand:

# Agent Framework sample
uv pip install -e samples/agents/agent-framework

# Semantic Kernel sample
uv pip install -e samples/agents/semantic-kernel

Server Usage

from halo_fastapi import HaloRegister
from fastapi import FastAPI

app = FastAPI(title="My API", version="1.0.0")
HaloRegister(app)

Everything is derived automatically from your existing route definitions, Pydantic models, docstrings, and dependency injection. LLM-native fields (why, tags, effects) can be added via json_schema_extra on your Pydantic models.

Multi-Method Paths

When multiple HTTP methods share the same path (e.g. GET and POST on /api/books), each method gets its own HALO schema. OPTIONS /api/books returns an array — one schema per method.

GET Endpoints with Query Parameters

For GET endpoints using query parameters, use a Pydantic model via Depends() to carry LLM metadata:

from fastapi import Depends

class BookSearchRequest(BaseModel):
    query: str | None = Field(None, description="Search term")
    model_config = ConfigDict(json_schema_extra={"llm": {"why": "Search books", "tags": ["books", "read"]}})

@app.get("/api/books")
async def search_books(params: BookSearchRequest = Depends()):
    ...

The Pydantic model's json_schema_extra provides why, tags, and examples — the same pattern used for POST body models.

Auth Detection

HaloRegister walks the FastAPI dependency tree and maps security classes to HALO auth shapes:

FastAPI Security Class HALO Auth Type
HTTPBearer bearer
HTTPBasic basic
APIKeyHeader apikey (with custom header name)
OAuth2PasswordBearer oauth (with tokenUrl and scopes)

Client Usage

from halo_fastapi import HaloClient

plugin = await HaloClient(
    base_url="https://api.example.com",
    bearer_token=os.getenv("API_KEY"),
).discover(tags=["payments"])

# Fetch a single tool schema (cached after first call)
schema = await plugin.get_tool("/api/payments/charge")

# Invoke a tool — credentials injected automatically
result = await plugin.invoke("/api/payments/charge", body={"amount": 1000})

Retry Behaviour

HaloClient retries failed requests with exponential backoff on connection errors, HTTP 429, and 5xx responses. Defaults: 5 retries, 0.5s base delay, 30s max delay — configurable via constructor parameters.

Agent Framework Integration (Optional)

HaloAgentFrameworkAdapter converts discovered HALO tools into Microsoft Agent Framework FunctionTool instances. Install with the optional extra:

uv add "halo-fastapi[agent-framework]"
from halo_fastapi import HaloClient, HaloAgentFrameworkAdapter

client = await HaloClient(base_url="https://api.example.com").discover()
adapter = HaloAgentFrameworkAdapter(client)
tools = await adapter.create_tools()  # list[FunctionTool]

create_tools() fetches the full schema for each discovered tool via HaloClient.get_tool() and builds a FunctionTool from the result. Schemas are cached by HaloClient so subsequent invocations do not repeat the OPTIONS requests.

Semantic Kernel Integration (Optional)

HaloSemanticKernelAdapter converts discovered HALO tools into a Semantic Kernel KernelPlugin. Install with the optional extra (cannot coexist with halo-fastapi[agent-framework] due to transitive dependency conflicts):

uv add "halo-fastapi[semantic-kernel]"
from halo_fastapi import HaloClient, HaloSemanticKernelAdapter

client = await HaloClient(base_url="https://api.example.com").discover()
adapter = HaloSemanticKernelAdapter(client)
plugin = await adapter.create_plugin()  # KernelPlugin

kernel.add_plugin(plugin)

create_plugin() wraps each discovered tool as a @kernel_function-decorated async function inside a KernelPlugin. Semantic Kernel handles automatic function calling when FunctionChoiceBehavior.Auto() is configured.

Licence

Apache 2.0

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

halo_fastapi-0.3.0.tar.gz (24.7 kB view details)

Uploaded Source

Built Distribution

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

halo_fastapi-0.3.0-py3-none-any.whl (18.0 kB view details)

Uploaded Python 3

File details

Details for the file halo_fastapi-0.3.0.tar.gz.

File metadata

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

File hashes

Hashes for halo_fastapi-0.3.0.tar.gz
Algorithm Hash digest
SHA256 1fc0bd701bf43bf51874b08543e33a74add2ea6d600f0bcbb411ed902807c50c
MD5 01669dc8b061e1d7298b99026b6205df
BLAKE2b-256 495d92597ca5d138388e1db0dbecb1def76050a913ed6a5ac6ff142e88852d06

See more details on using hashes here.

Provenance

The following attestation bundles were made for halo_fastapi-0.3.0.tar.gz:

Publisher: publish.yml on irarainey/halo

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file halo_fastapi-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: halo_fastapi-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 18.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for halo_fastapi-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a4132be4f86e48f1347d97cec3035eaf0aa1b69281a51d0bac50dd992eab7a17
MD5 1bc5c9cd8f6ff94ca4483addeaf8afc2
BLAKE2b-256 c3f3f596373927377c742342128b9e9f10a129a186b76f56f35f50a8b5d6e9d1

See more details on using hashes here.

Provenance

The following attestation bundles were made for halo_fastapi-0.3.0-py3-none-any.whl:

Publisher: publish.yml on irarainey/halo

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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