Skip to content

feat(embed): add the Python router (FastAPI) - #16

Open
mattj-monad wants to merge 2 commits into
feature/pro-403from
feature/pro-404
Open

feat(embed): add the Python router (FastAPI)#16
mattj-monad wants to merge 2 commits into
feature/pro-403from
feature/pro-404

Conversation

@mattj-monad

Copy link
Copy Markdown
Contributor

Layer 5 of the Monad Embed SDK staged rollout (PRO-404) — the last router. Stacked on #15 (PRO-403) — targets feature/pro-403; review/merge the stack bottom-up.

What this adds

  • routers/python — the Python port: embed_router(EmbedConfig(…)) as a mountable FastAPI/Starlette APIRouter (package monad-embed, httpx-based). Idiomatic Python; same contract.
  • Adds the python leg to the conformance matrix: the harness venv also installs fastapi/uvicorn + the router (editable), boots servers/py_server.py, and runs ROUTER=python. Restores py_server.py (deferred from PRO-402).

With this, all three routers — ts, go, python — are proven against one contract.

Verification (local)

  • python router unit tests: 11 passed
  • conformance: ROUTER=python 14/14, ROUTER=go 14/14, ROUTER=ts 14/14

Stack

400 → 401 → 402 → 403 → 404 → 405 (docs/CI). Last router; 405 is the optional docs + CI-hardening finish.

🤖 Generated with Claude Code

https://claude.ai/code/session_011ASKA2VrufrNLGGrcFjY7n

@mattj-monad

Copy link
Copy Markdown
Contributor Author

Force-pushed review fixes (Python router):

  • Path injection: urllib.parse.quote(..., safe='') on every id + org (client.py and the router.py delete paths).
  • Upstream body leak: MonadError now carries the detail for a server-side log; the browser gets a generic 502. The 500 and 401-resolver paths no longer echo str(exc).
    pytest 11 + ROUTER=python conformance 17/17.

@mattj-monad

Copy link
Copy Markdown
Contributor Author

Force-pushed: 404/409 handling for the Python router — the MonadError handler now maps exc.status: 404 → not_found / 409 → conflict / else 502. ROUTER=python conformance 19/19.

@mattj-monad
mattj-monad force-pushed the feature/pro-403 branch 2 times, most recently from e287e68 to a0dd428 Compare July 31, 2026 20:30
@mattj-monad
mattj-monad force-pushed the feature/pro-404 branch 2 times, most recently from 78a0e3e to 8508962 Compare July 31, 2026 20:42
@mattj-monad

Copy link
Copy Markdown
Contributor Author

Force-pushed: fixed a null-handling bug found running the demo against live staging. When a tenant has no connectors of a kind, Monad returns { <kind>s: null } (not []); Python's .get(key, []) returns that null'NoneType' object is not iterable. TS (?? []) and Go (nil-slice) both coalesce null[]; Python now does too via .get(key) or []. ROUTER=python 19/19.

mattj-monad and others added 2 commits July 31, 2026 15:42
Adds the Python port of the /embed router — embed_router(EmbedConfig(...)) as a
mountable FastAPI/Starlette APIRouter (package monad-embed, httpx-based). Same
contract, idiomatic Python.

Adds the python leg to the conformance matrix: the harness venv also installs
fastapi/uvicorn and the router (editable), boots servers/py_server.py, and runs
ROUTER=python. Restores py_server.py (deferred from the TS-router layer). This
completes the router set — ts, go, and python all proven against one contract.

Local: python router unit tests pass; conformance green for ROUTER=python, ts,
and go.

Layer 5 (PRO-404), stacked on the Go router (PRO-403).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011ASKA2VrufrNLGGrcFjY7n
Parameterizes the Python conformance server from env, matching TS/Go.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011ASKA2VrufrNLGGrcFjY7n
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant