870e0a40d8
Replaces the hand-rolled media streaming with Starlette FileResponse, drops the
BaseHTTPMiddleware, and enlarges the default threadpool.
3.1 prepare_file_response now returns FileResponse (handles Range/If-Range/206/
416/multipart, sets Accept-Ranges/ETag/Last-Modified, reads efficiently — no
per-64KB to_thread hop that starved the pool). Kept: the early 404 pre-check,
the MIME logic (python-magic + SQLite cache), and every stage-2 behavior — the
temp_* mtime touch (now DEBOUNCED, see below), delete_after -> BackgroundTask
(passed as FileResponse background=), the media_key MIME cache. Removed the
manual Range parsing, file_chunk_generator, and hand-built headers;
Content-Disposition is formed by FileResponse from filename= (no double-set).
206 slices are byte-identical to the old code; accepted RFC-7233 deltas
documented in the tests.
3.2 RequestLoggingMiddleware rewritten as a pure-ASGI class (wraps only send to
observe the status line, never buffers the body, passes non-http scopes
through) — the streaming body flows untouched.
3.3 lifespan sets a larger default executor (ThreadPoolExecutor, IO_THREAD_POOL_SIZE
default 32) and shuts it down on exit.
Review round-1 fixes folded in: the temp_* mtime touch is DEBOUNCED
(TEMP_MTIME_REFRESH_INTERVAL=300s) so FileResponse's mtime-derived ETag stays
stable across a resume/seek session (an every-serve touch broke If-Range resume);
starlette pinned to 0.45.3; the io executor is shut down on lifespan exit; the
ASGI logger includes the query string.
Tests (tests/test_stage3_fileresponse.py, 18): the Range matrix vs FileResponse
with every delta documented; temp_* mtime refreshed when stale AND stable when
fresh (ETag identical); delete_after background runs and removes the file;
media_key MIME cache hit/miss; the ASGI middleware passes the body and logs.
213 passed (195 baseline + 18).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
19 lines
492 B
Plaintext
19 lines
492 B
Plaintext
fastapi==0.115.8
|
|
# Pinned explicitly (fastapi only requires a range): the stage-3 FileResponse Range
|
|
# behaviour and the multipart-byteranges test are tied to this Starlette version.
|
|
starlette==0.45.3
|
|
uvicorn==0.34.0
|
|
python-multipart==0.0.20
|
|
Kurigram==2.2.22
|
|
#git+https://github.com/KurimuzonAkuma/pyrogram.git@dev#egg=Kurigram
|
|
TgCrypto
|
|
uvloop
|
|
pillow==11.1.0
|
|
feedgen==1.0.0
|
|
python-dateutil==2.9.0.post0
|
|
python-magic==0.4.27
|
|
bleach[css]==6.1.0
|
|
types-bleach
|
|
pytest-asyncio==1.4.0
|
|
httpx==0.28.1
|