Woodglue¶
Self-documenting opinionated async server that hosts logic and data.
Woodglue is a JSON-RPC 2.0 server built on Tornado and lythonic that automatically generates LLM-friendly documentation from your Python functions and Pydantic models, signs people in, and hosts the UIs built on top of it.
Architecture¶
┌──────────────────────────────────────────────────────────┐
│ woodglue │
│ HTTP server · JSON-RPC · Docs │
│ Users · Roles · Grants · Sign-in (OIDC, GitHub, proxy) │
│ Console · project UIs (static, Streamlit) │
├──────────────────────────────────────────────────────────┤
│ lythonic │
│ Namespaces · DAGs · Caching · Triggers │
└──────────────────────────────────────────────────────────┘
▲ optional: Caddy in front for TLS and static files
Woodglue is the HTTP layer; lythonic provides the core runtime
(namespaces, DAG orchestration, caching, and scheduled triggers).
The design decisions behind authentication and UI hosting are recorded in
the ADRs under docs/adr/, and the vocabulary (User, Role, Grant, Session,
Personal Access Token, Delegated Token, UI) in GLOSSARY.md.
Features¶
- JSON-RPC 2.0 with multi-namespace routing — register Python functions, call them over HTTP with dot-prefixed namespace routing
- Auto-generated docs —
llms.txtindex, per-method markdown, OpenAPI 3.0.3 spec, each showing only what the caller may use - Users, Roles, and Grants — per-namespace authorization; Personal Access Tokens that can be narrowed and expire (how-to)
- Sign-in — Google, Entra ID, Okta, Auth0, or any OpenID Connect provider; GitHub; or a trusted proxy such as Cloudflare Access, Google IAP, or oauth2-proxy (how-to)
- The Console — browser-based API browsing, runs and triggers, DAG visualization, and your own tokens
- Project UIs — host your own single-page app (how-to) or Streamlit app (how-to) next to the Console, signed in as the same User
- Run attribution — runs and trigger changes record which User caused them
wgl login— get a token for a remote server through the browser- Optional Caddy edge —
wgl caddy configprints a Caddyfile (how-to) - Typed async client — auto-resolved return types via
x-global-ref - YAML-driven namespace configuration — declarative setup with per-method tags and explicit gref/file/entries fields
- DAG orchestration with scheduled triggers — workflow execution and scheduling via lythonic
- System namespace — the server's own management API is a regular namespace (dogfooding)
Quick Start¶
# hello_api.py
from lythonic.compose.namespace import Namespace
from pydantic import BaseModel
class HelloIn(BaseModel):
name: str
age: int
class HelloOut(BaseModel):
eman: str
ega: int
def pydantic_hello(input: HelloIn) -> HelloOut:
return HelloOut(eman=input.name[::-1], ega=-input.age)
ns = Namespace()
ns.register(pydantic_hello, nsref="pydantic_hello", tags=["api"])
Configure in data/woodglue.yaml:
Run the server and get the admin token:
Open http://127.0.0.1:5321/ and sign in with the token. See
Getting Started for calling the API, and the how-to
guides for Users, sign-in, and UIs.
Endpoints¶
POST /rpc— JSON-RPC 2.0 endpointGET /docs/llms.txt— method indexGET /docs/methods/{name}.md— per-method documentationGET /docs/openapi.json— OpenAPI specGET /console/— the Console, the built-in browser UIGET /ui/{name}/— project UIsGET /auth/login— browser sign-in;POST /auth/logoutsigns outGET /auth/start/{provider},/auth/callback/{provider}— Identity Provider sign-inGET /auth/cli— approval page forwgl loginGET /auth/verify— access check for a reverse proxy'sforward_auth