ifURI examples
← all examples

Transports & layers

One registry, many transports. The URI + registry + JSON Schema + policy gate are the contract; a transport only moves {uri, payload} to where v2.run executes it. So adopting a new layer is "add a transport adapter", never a redesign - and every transport returns the same envelope.

URI + registry + JSON Schema + policy gate            (the contract, never changes)
        │  validate -> gate -> render -> execute
        ▼
  ┌───────────── transports (pluggable) ─────────────┐
  inprocess · CLI/shell · HTTP · gRPC · queue · serverless · MCP/A2A · ...

What runs here

demo.py drives the same URI over five transports and shows identical output; test_transports.py asserts they agree (and that schema validation is uniform).

cd 07-transports
PYTHONPATH=../../../adapters/python python3 demo.py
inprocess   ok=True  stdout='hello transports'
queue       ok=True  stdout='hello transports'
serverless  ok=True  stdout='hello transports'
http        ok=True  stdout='hello transports'
grpc        ok=True  stdout='hello transports'

Simple scan & run

One command: point at a source (it is scanned/compiled in memory), name a URI, pick a transport.

# scan a directory (or load a bindings/registry file) and run a URI in-process
python3 scan_and_run.py ./my-project 'text://local/upper/run' --payload '{"text":"hi"}'

# same registry, over HTTP or gRPC (target host or URI_SERVICE_MAP / URI_GRPC_MAP)
python3 scan_and_run.py registry.bindings.json 'text://local/echo/run' \
  --payload '{"args":["hi"]}' --transport grpc --target 127.0.0.1 --execute

Dry-run (default) prints the exact command/request; --execute runs it through the policy gate.

Implementation matrix (anticipate every layer)

Layer / transportModuleShapeStatusWhen to use
In-processv2.runrun(uri, registry, payload)✅ workingsame-process, tests, embedding
CLI / shellargv-template / shell-templateurirun-v2 run✅ workinglocal tools, scripts, ffmpeg/git
HTTP /run /routesv2_servicecall(uri, payload, registry)✅ workingservices, browser, public API
gRPC (generic Run)v2_grpccall(...) / RunStream✅ workingeast-west mesh, streaming, deadlines
Async queue / event bus(stdlib demo)consumer: topic → v2.run✅ demo (in-mem)fan-out, retry, decoupling (MQTT/NATS/Kafka)
Serverless functionpure handler(event)v2.run(event.uri, ...)✅ workingLambda / Cloud Run, per-request registry
MCP (LLM tools)v2_mcptools/list + tools/call✅ workingLLM tool calling
A2A (agent card)v2_mcpagent card + skill call✅ workingagent-to-agent discovery
Docker (exec / run)v1 docker-exec/docker-runrun in/with a container✅ workingcontainer as execution surface
WebSocket / SSE(transport adapter)stream events to browser⬜ sketchlive progress to the browser
MQTT real brokermqtt-publish + consumerpublish/subscribe⬜ sketchIoT / device fleets
Service mesh / API gatewayedge filterroute URI, gate at edge⬜ sketchplatform ingress, mTLS
WASM / edgeembed v2.runin-sandbox dispatch⬜ sketchedge compute, plugins

The ✅ rows are runnable (here, or in docker_uri_flow, html_uri_app); the ⬜ rows follow the identical pattern: a thin adapter that turns the transport's message into {uri, payload} and calls v2.run (server side) or dispatches to a remote worker (client side), with schema validation + policy at the edge.

The recipe for any new transport

  1. Server: receive the transport's message → v2.run(uri, registry, payload, policy) → return the envelope. (HTTP /run, gRPC Run, queue consumer, Lambda handler all do exactly this.)
  2. Client: validate against the registry schema (v2.validate_input), resolve the target, send {uri, payload}. (v2_service.call, v2_grpc.call.)
  3. Discovery: project the registry (/routes, ListRoutes, MCP tools/list, A2A card).

Because steps 1–3 are identical across transports, the contract and the safety gate live in one place no matter how many layers you deploy on.

Files

MakefileREADME.mddemo.pyregistry.bindings.jsonscan_and_run.pytest_transports.pytransport_lib.py.benchmarks/

View on GitHub →