Files
pyrogram-bridge/tests/mock_config.py
T
claude code agent 870e0a40d8 fix(stability): stage 3 — serve via FileResponse, pure-ASGI logging, bigger executor
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>
2026-07-05 08:26:35 +03:00

41 lines
1.3 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
def setup_logging(level_name: str = "INFO") -> None:
"""No-op logging setup for tests (mirrors config.setup_logging signature)."""
return None
def get_settings():
"""
Mock config for testing without requiring TG_API_ID and TG_API_HASH
"""
return {
"tg_api_id": 12345,
"tg_api_hash": "test_hash",
"session_path": "tests/test_data",
"api_host": "127.0.0.1",
"api_port": 8080,
"pyrogram_bridge_url": "http://test.example.com",
"log_level": "DEBUG",
"debug": False,
"token": "test_token",
"time_based_merge": False,
"show_bridge_link": False,
"show_post_flags": True,
"proxy": None,
"trusted_proxies": [],
"tg_rpc_timeout": 60,
"tg_watchdog_enabled": True,
"tg_watchdog_interval": 60,
"tg_watchdog_timeout": 10,
"tg_watchdog_failures": 3,
"tg_watchdog_restart_timeout": 90,
"tg_watchdog_heartbeat_every": 30,
"tg_disconnect_flap_limit": 3,
"tg_disconnect_flap_window": 120,
"media_download_timeout_min": 120,
"media_download_timeout_max": 1800,
"media_download_min_speed": 256 * 1024,
"io_thread_pool_size": 32,
}