Skip to content

feat(DB-773): take a SQL session key and report the API's session fallback - #79

Merged
kcheng486 merged 2 commits into
mainfrom
kevin/session-fallback
Oct 16, 2026
Merged

kcheng486 merged 2 commits into
mainfrom
kevin/session-fallback

Conversation

@kcheng486

Copy link
Copy Markdown
Contributor

Summary

The driver can now ask for a SQL session of its own and tell the caller when the API gave it a shared one instead.

  • connect(session_key=...) sends sessionKey on the session request, and only when set. The API reuses a session only for requests with the same key, and never one opened without a key. Waldo uses this to keep one SQL session per chat, so a heavy query in one chat no longer holds the session another chat's queries run on.
  • Connection.session_fallback reports when the key didn't get its own session. If a session of the key's own would exceed the org's quota, the API shares another of the user's sessions instead and names the reason (quota) in an X-Wherobots-Sql-Session-Fallback header on its 303. requests follows that redirect, so the driver reads the header from resp.history[0] and passes it through connect_direct(session_fallback=...). The driver also logs a warning when it happens.
  • Connection.session_id is now public. It was already parsed from the redirect URL, but only kept privately for error messages.

New keyword arguments go at the end of each signature. Callers that don't pass a key see no change: the request body is the same as before, and against an API without the header session_fallback is None.

Related Issues

  • DB-773: give each Waldo chat its own SQL session.
  • API side: wherobots/studio-backend#2884 adds sessionKey, the quota fallback and the header.
  • After this is released, a studio-backend follow-up bumps the driver in the MCP server, so query jobs report a fallback to Waldo and the model.

Requester Checklist

Complete these before marking Ready for Review

  • I have self-reviewed my own code
  • I have added/updated tests that prove my fix/feature works
  • I have included visual proof (screenshot, video, or test output) if applicable
  • All CI checks are passing
  • PR size is S/M, OR I have justified the size and added a walkthrough
  • I have updated documentation if needed

Visual Proof

Unit tests: TestConnectSessionKey in tests/test_driver.py covers the key in the body, the key omitted, the 303's fallback header reaching connect_direct with and without the header, and the fallback and session id reaching Connection through the real connect_direct (only the WebSocket stubbed). test_connection_reports_its_session_and_fallback in tests/test_disconnect.py covers the new properties.

$ uv run pytest tests -q
240 passed in 16.61s

End to end against the API change in wherobots/studio-backend#2884. This driver's connect() (loaded from this branch via PYTHONPATH) ran against the real API app, served by uvicorn on a test Postgres. The org's CPU quota fit one tiny session, and chat 1's session already used it. The real connect_direct ran with only the WebSocket stubbed, since there is no cluster to open one to, and the arguments Connection was built with are printed:

quota: 15 CPU; chat 1's session ps22ypkgnavejs uses it all
connect(session_key='waldo:chat-1') -> Connection(session_id=ps22ypkgnavejs, session_fallback=None)
connect(session_key='waldo:chat-2') -> Connection(session_id=ps22ypkgnavejs, session_fallback='quota')
connect(session_key=None) -> Connection(session_id=ps22ypkgnavejs, session_fallback='quota')
WARNI [src.routers.sql] SQL session for user ntu8zzue4bmgno, key waldo:chat-2, is over quota; sharing session ps22ypkgnavejs
WARNI [root] The API shared a SQL session under another key (quota).
WARNI [src.routers.sql] SQL session for user ntu8zzue4bmgno, key None, is over quota; sharing session ps22ypkgnavejs
WARNI [root] The API shared a SQL session under another key (quota).

Not tested: against a live deployment, since the API change isn't deployed yet.

Size Justification (if L/XL)

N/A: small.


Reviewer Checklist

If these are not met, close the tab — this PR is not ready for review

  • Requester checklist above is complete
  • All CI checks are passing
  • Tests adequately cover the changes

Model: Claude Opus 5.5 (claude-opus-5-5), harness: Claude Code (VS Code extension).

🤖 Generated with Claude Code

connect() takes session_key, sent as the session request's sessionKey:
the API reuses a session only for requests with the same key, so a
caller can keep sessions of its own (Waldo keeps one per chat).

When a session of the key's own would exceed a quota, the API shares
another of the user's sessions and names why in the
X-Wherobots-Sql-Session-Fallback header of its redirect. requests
follows that redirect, so the driver reads the header from the
response history and exposes it as Connection.session_fallback, next
to a now-public Connection.session_id.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kcheng486
kcheng486 marked this pull request as ready for review October 15, 2026 23:51
@kcheng486
kcheng486 requested a review from a team as a code owner October 15, 2026 23:51
Comment thread wherobots/db/driver.py Outdated

@salty-hambot salty-hambot Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed by Salty Hambot 🤖🧂 at bf42a1f

No issues found.
💰 $0.0927 · 81.9k in / 1.6k out tokens · ⏱️ 16.8s · us.openai.gpt-6-sol high, prompt coverage-v1
💬 To request a re-review, comment @salty-hambot review

Salty Hambot: when the session POST is first redirected by a 307 or 308
(to a canonical endpoint, say) before the API's 303, requests keeps both
in resp.history, and reading history[0] missed the header, so the
connection reported no fallback. Read every hop, latest first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kcheng486
kcheng486 merged commit 5d2fa88 into main Oct 16, 2026
7 checks passed
@kcheng486
kcheng486 deleted the kevin/session-fallback branch October 16, 2026 23:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants