Skip to content

feat: pass through fastapi.Response returns unchanged#5

Merged
thorwhalen merged 1 commit into
masterfrom
feat-response-passthrough
May 15, 2026
Merged

feat: pass through fastapi.Response returns unchanged#5
thorwhalen merged 1 commit into
masterfrom
feat-response-passthrough

Conversation

@thorwhalen
Copy link
Copy Markdown
Member

Summary

When a wrapped function returns a fastapi.Response (or any subclass — StreamingResponse, FileResponse, PlainTextResponse, etc.), the endpoint now returns it verbatim instead of trying to JSON-encode it.

Why

Lets qh-built apps emit non-JSON payloads (PDFs, file downloads, streams) without bypassing qh and hand-rolling FastAPI routes. The reelee project is the first customer (chunk 9: PDF export from a wrapped Python function).

What changed

  • qh/endpoint.py — single isinstance check before the default JSON encoding step.
  • qh/tests/test_mk_app.py — 2 new tests:
    • PDF-style Response with custom content-disposition + bytes body.
    • StreamingResponse driven by a generator.

Verify

  • python3 -m pytest qh/ -q136 / 136 green.

When a wrapped function returns a `fastapi.Response` (or any subclass
— StreamingResponse, FileResponse, PlainTextResponse, etc.), the
endpoint now returns it verbatim instead of trying to JSON-encode it.

This lets qh-built apps emit non-JSON payloads (PDFs, file downloads,
streams) without bypassing qh — reelee's chunk-9 PDF export is the
first customer.

Tests: 2 new in test_mk_app.py (Response with custom headers + bytes,
StreamingResponse from a generator). 136 / 136 total.
@thorwhalen thorwhalen merged commit ceec6d7 into master May 15, 2026
4 of 6 checks passed
@thorwhalen thorwhalen deleted the feat-response-passthrough branch May 15, 2026 10:06
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