* perf: cut per-instance CPU cost of shared socket.io Redis pub/sub channel Profiling a multi-instance deployment (py-spy --gil) showed ~44% of worker CPU in the socket.io pub/sub listener. Two causes, two fixes: - Add hiredis so redis-py parses the RESP protocol in C instead of pure Python (redis/_parsers/resp3.py alone accounted for ~28% of GIL samples; redis-py auto-selects the hiredis parser when importable). - Subclass AsyncRedisManager to drop emits whose target room has no local participants before upstream _handle_emit re-encodes the full packet. Every instance receives every emit published on the shared channel, so with N instances all but the hosting one were paying full packet re-serialization per message just to deliver it to nobody. Broadcasts (room=None) are unaffected. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q9CQ9qnp3sZGYQQwztsCJT * fix: restrict pub/sub emit early-out to string rooms Adversarial review against python-socketio 5.16.2 found one divergence from upstream: for a degenerate empty-sequence room (emit to room=[]) on an instance whose namespace has no local clients, the filter's get_participants probe raises IndexError from room[0] where upstream returns silently at the namespace guard and still publishes to Redis. Open WebUI only ever emits to scalar string rooms or room=None, so the case is unreachable today; guard on isinstance(room, str) anyway so any non-string room shape passes through to upstream behavior unchanged. Every open-webui emit uses a string room, so the fast path still covers all real traffic. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q9CQ9qnp3sZGYQQwztsCJT * Update requirements.txt * Update pyproject.toml * Update requirements-min.txt --------- Co-authored-by: Claude <noreply@anthropic.com>
59 lines
964 B
Plaintext
59 lines
964 B
Plaintext
# Minimal requirements for backend to run
|
|
# WIP: use this as a reference to build a minimal docker image
|
|
|
|
fastapi==0.136.3
|
|
uvicorn[standard]==0.41.0
|
|
pydantic==2.13.4
|
|
python-multipart==0.0.27
|
|
itsdangerous==2.2.0
|
|
|
|
python-socketio==5.16.2
|
|
python-jose==3.5.0
|
|
cryptography
|
|
bcrypt==5.0.0
|
|
argon2-cffi==25.1.0
|
|
PyJWT[crypto]==2.13.0
|
|
authlib==1.7.2
|
|
|
|
requests==2.34.2
|
|
aiohttp==3.13.5 # do not update to 3.13.3 - broken
|
|
async-timeout
|
|
aiocache
|
|
aiofiles
|
|
starlette-compress==1.7.1
|
|
Brotli==1.2.0
|
|
brotlicffi==1.2.0.1
|
|
httpx[socks,http2,zstd,cli,brotli]==0.28.1
|
|
starsessions[redis]==2.2.1
|
|
|
|
sqlalchemy==2.0.50
|
|
aiosqlite==0.22.1
|
|
psycopg[binary]==3.3.4
|
|
alembic==1.18.4
|
|
|
|
pycrdt==0.13.1
|
|
redis
|
|
hiredis
|
|
|
|
APScheduler==3.11.2
|
|
RestrictedPython==8.2
|
|
|
|
loguru==0.7.3
|
|
asgiref==3.11.1
|
|
|
|
mcp==1.27.2
|
|
openai
|
|
|
|
langchain==1.2.10
|
|
langchain-community==0.4.2
|
|
langchain-classic==1.0.7
|
|
langchain-text-splitters==1.1.2
|
|
|
|
fake-useragent==2.2.0
|
|
|
|
chromadb==1.5.9
|
|
black==26.5.1
|
|
pydub
|
|
chardet==7.4.3
|
|
beautifulsoup4
|