TurboGears / TurboGears/backlash

Add ASGI support for the interactive debugger

Open
#23 0 comments 0 reactions 1 assignee View on GitHub

@amol- is already working on this.

Since Jul 29, 2026.

Dominant language
Python
Stars
13
Forks
13
PR merge metrics
No merged PRs in 30d

Description

Goal

Provide an ASGI counterpart to DebuggedApplication so ASGI applications (Starlette, FastAPI, and bare ASGI apps) can get the same in-browser interactive traceback debugger currently available only to WSGI applications.

Done criteria:

  • A new AsgiDebuggedApplication middleware (e.g. backlash/asgi.py) that:
    • Passes through non-http scopes (websocket, lifespan) untouched.
    • Catches unhandled exceptions and renders the existing debugger page when the response has not started; falls back to log-only when http.response.start was already sent (mirroring the WSGI streamed-response fallback).
    • Serves the existing debugger endpoints (resource, source, cmd eval, /__console__) over ASGI, honoring scope["root_path"] for mounted apps.
  • Reuse tbtools.py, console.py, and statics/ as-is; they are already transport-agnostic.
  • Consider dropping the WebOb dependency in the same pass: debug.py is the only module importing it (query parsing plus small responses), and stdlib urllib.parse covers the need. This would make the package dependency-free and easier to vendor.

Why

The interactive debugger is the most valuable part of backlash, but it is WSGI-only. Modern Python web frameworks (FastAPI, Starlette, Shiny, Gradio) are ASGI, so they cannot use it today. Roughly 90% of the code (traceback capture/rendering, console eval, static assets) is transport-independent, so ASGI support is a thin adapter rather than a rewrite.

One known integration caveat worth documenting: Starlette's ServerErrorMiddleware is outermost in a Starlette app; it sends its own 500 response before re-raising, so an outer wrap sees the exception only after the response has started. Injecting via app.add_middleware(AsgiDebuggedApplication) places the debugger inside ServerErrorMiddleware but outside the routes, catching exceptions before any response starts.

References

  • backlash/debug.py (DebuggedApplication) — WSGI dispatch logic to mirror; sole WebOb consumer.
  • backlash/tbtools.py, backlash/console.py, backlash/statics/ — transport-agnostic pieces to reuse.
  • Starlette ServerErrorMiddleware behavior: catches, responds 500, then re-raises — relevant to middleware placement.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.