Skip to content

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

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

mattj-monad wants to merge 14 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
…-457]

Ports the fixes from the Go and TypeScript routers so all three stay
contract-identical on the wire.

- resolve a connector's pipeline via `component_of` instead of scanning every
  pipeline; the scan sent no `limit` and Monad defaults it to 10
- `set_enabled` PATCHes `{enabled}` alone now that PATCH is a true partial
  update, instead of rebuilding and replacing the node/edge graph
- drain the connector list rather than one `limit=1000` request
- send `type` on output create; `output_type` is deprecated
- drop the speculative `data` / `config` response-shape fallbacks
- map `kind` to its path segment explicitly rather than appending "s"
# Conflicts:
#	routers/typescript/src/monad.ts
Credgate and others added 8 commits August 4, 2026 12:52
fix(embed): Python router vs the real Monad API [PRO-457]
Completes the main-sync cascade across the router stack. Verified on the tip:
lint (0 errors)/format/typecheck/build pass; conformance mock 35/35 and LIVE
(real Monad staging) 21 passed/0 failed for ts+go+python.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011ASKA2VrufrNLGGrcFjY7n
Carries up the TS + Go pagination/body fixes and the Node-24 conformance CI fix.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011ASKA2VrufrNLGGrcFjY7n
listConnectors: drain until a short page; drop the pagination.total early-break
(truncates when Monad under-reports total); add _MAX_PAGES cap so an upstream
that never returns a short page bounds the loop instead of spinning / OOMing.
(Body-size limits are handled at the ASGI/proxy layer for FastAPI.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011ASKA2VrufrNLGGrcFjY7n
Carries up the TS + Go orphan-safety/redaction fixes, the doc, and the
conformance changes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011ASKA2VrufrNLGGrcFjY7n
- wire_pipeline: a transient status-poll failure no longer fails the request —
  the pipeline exists, so return it as built (last-known status) rather than
  orphaning it and inviting a retry duplicate. (D)
- build_dev_null: best-effort delete the created sink if wiring fails. (E)
- pipeline_for: document the one-pipeline-per-connector invariant behind
  component_of[0]. (F)
(Router error redaction (H) was already clean in the Python router.)

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.

2 participants