Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ classifiers = [
dependencies = [
"fastapi>=0.136,<1",
"uvicorn>=0.32,<1",
# The /track-ws endpoint needs a WebSocket protocol backend at runtime.
# Bare `uvicorn` ships none (it lives in the `[standard]` extra), so under
# gunicorn's UvicornWorker every upgrade 404s with "No supported WebSocket
# library detected". Depend on `websockets` directly — lighter than the
# full `[standard]` extra (no uvloop/httptools/watchfiles) and all the
# worker actually needs to accept the upgrade.
"websockets>=14,<17",
"gunicorn>=23.0,<24",
"httpx>=0.28,<1",
"tenacity>=9.0,<10",
Expand Down
19 changes: 19 additions & 0 deletions tests/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,3 +196,22 @@ async def receive(): # type: ignore[no-untyped-def]
assert starts and starts[0]["status"] == 403
# App was never called because the middleware short-circuited.
assert ("app", GATED_PATH) not in received


def test_uvicorn_has_websocket_backend() -> None:
"""Guard the /track-ws upgrade against a missing WebSocket backend.

Under gunicorn's ``UvicornWorker`` the WebSocket upgrade only works if a
protocol library (``websockets`` or ``wsproto``) is installed. Bare
``uvicorn`` ships neither — they live in the ``uvicorn[standard]`` extra —
so without an explicit dependency the env builds fine, tests pass via
Starlette's in-process TestClient, and yet every live ``/track-ws`` 404s
with "No supported WebSocket library detected". This asserts the backend
is present so that regression can't ship silently again.
"""
import importlib.util

assert importlib.util.find_spec("websockets") or importlib.util.find_spec("wsproto"), (
"no WebSocket backend (websockets/wsproto) installed — /track-ws will 404 "
"under uvicorn; add `websockets` to project dependencies"
)
2 changes: 2 additions & 0 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.