fix: bump uvicorn to 0.51.0 to move off the legacy websocket implementation (#27553)

Uvicorn's `--ws auto` selected its `websockets_impl` protocol on 0.41.0, which is built on `websockets.legacy`. That module raises `AssertionError` in `_drain_helper` during keepalive pings and kills the websocket connection. Each crash runs the Socket.IO `disconnect` handler and drops the session from `SESSION_POOL`, so every subsequent server-to-browser call fails. The most visible symptom is the Pyodide code execution tool, which reaches the browser through `sio.call('events', ...)` and returns `{"stderr": "Client session disconnected."}` on every run.

Uvicorn 0.50.0 changed `--ws auto` to select the sans-io implementation whenever websockets is installed, and deprecated the legacy one. Bumping the pin therefore fixes this on every launch path at once, without adding a `--ws` flag to the startup scripts. Doing nothing is not stable either: websockets is unpinned apart from uvicorn's own `>=13.0` floor, and `websockets.legacy` is removed outright in websockets 17, which turns the current AssertionError into an ImportError on a fresh install.

Bumping to 0.51.0 rather than the minimum 0.50.0 also picks up the sans-io keepalive pings added in 0.44.0, so raw websocket endpoints keep the idle-timeout behaviour they have today behind a reverse proxy. Uvicorn 0.51.0 drops colorama from its `standard` extra and raises the httptools floor to 0.8.0, which the lockfile already satisfies.

Verified on the bumped pin: the backend boots, `/health` returns 200, `--ws auto` resolves to `WebSocketsSansIOProtocol`, a Socket.IO client completes a websocket handshake against the running app, and a bidirectional `sio.call` round trip succeeds. The unit test suite reports an identical 2273 passed / 7 failed on 0.41.0 and 0.51.0, with the 7 failures unrelated to uvicorn.

Fixes #27550
This commit is contained in:
Classic298
2026-07-26 23:55:44 +02:00
committed by GitHub
parent 1e0ab84717
commit 3ce734c6c6
4 changed files with 7 additions and 8 deletions

View File

@@ -2,7 +2,7 @@
# WIP: use this as a reference to build a minimal docker image
fastapi==0.136.3
uvicorn[standard]==0.41.0
uvicorn[standard]==0.51.0
pydantic==2.13.4
python-multipart==0.0.32
itsdangerous==2.2.0

View File

@@ -1,5 +1,5 @@
fastapi==0.136.3
uvicorn[standard]==0.41.0
uvicorn[standard]==0.51.0
pydantic==2.13.4
python-multipart==0.0.32
itsdangerous==2.2.0

View File

@@ -7,7 +7,7 @@ authors = [
license = { file = "LICENSE" }
dependencies = [
"fastapi==0.136.3",
"uvicorn[standard]==0.41.0",
"uvicorn[standard]==0.51.0",
"pydantic==2.13.4",
"python-multipart==0.0.32",
"itsdangerous==2.2.0",

9
uv.lock generated
View File

@@ -3247,7 +3247,7 @@ requires-dist = [
{ name = "transformers", specifier = "==5.5.4" },
{ name = "unstructured", marker = "extra == 'all'", specifier = "==0.22.31" },
{ name = "unstructured", marker = "extra == 'unstructured'", specifier = "==0.22.31" },
{ name = "uvicorn", extras = ["standard"], specifier = "==0.41.0" },
{ name = "uvicorn", extras = ["standard"], specifier = "==0.51.0" },
{ name = "validators", specifier = "==0.35.0" },
{ name = "weaviate-client", marker = "extra == 'all'", specifier = "==4.20.3" },
{ name = "xlrd", specifier = "==2.0.2" },
@@ -5827,20 +5827,19 @@ wheels = [
[[package]]
name = "uvicorn"
version = "0.41.0"
version = "0.51.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "click" },
{ name = "h11" },
]
sdist = { url = "https://files.pythonhosted.org/packages/32/ce/eeb58ae4ac36fe09e3842eb02e0eb676bf2c53ae062b98f1b2531673efdd/uvicorn-0.41.0.tar.gz", hash = "sha256:09d11cf7008da33113824ee5a1c6422d89fbc2ff476540d69a34c87fab8b571a", size = 82633 }
sdist = { url = "https://files.pythonhosted.org/packages/a2/65/b7c6c443ccc58678c91e1e973bbe2a878591538655d6e1d47f24ba1c51f3/uvicorn-0.51.0.tar.gz", hash = "sha256:f6f4b69b657c312f516dd2d268ab9ae6f254b11e4bac504f37b2ab58b24dd0b0", size = 94412 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/83/e4/d04a086285c20886c0daad0e026f250869201013d18f81d9ff5eada73a88/uvicorn-0.41.0-py3-none-any.whl", hash = "sha256:29e35b1d2c36a04b9e180d4007ede3bcb32a85fbdfd6c6aeb3f26839de088187", size = 68783 },
{ url = "https://files.pythonhosted.org/packages/45/ec/dbb7e5a6b91f86bfb9eb7d2988a2730907b6a729875b949c7f022e8b88fa/uvicorn-0.51.0-py3-none-any.whl", hash = "sha256:5d38af6cd620f2ae3849fb44fd4879e0890aa1febe8d47eb355fb45d93fe6a5b", size = 73219 },
]
[package.optional-dependencies]
standard = [
{ name = "colorama", marker = "sys_platform == 'win32'" },
{ name = "httptools" },
{ name = "python-dotenv" },
{ name = "pyyaml" },