diff --git a/app/main.py b/app/main.py index c1be198..4531f8e 100644 --- a/app/main.py +++ b/app/main.py @@ -15,6 +15,7 @@ from app.config import Settings, load_settings from app.pipeline import ModelsMissing, Pipeline, to_wav16k from app.security import check_token, ip_allowed, parse_allowlist from app.store import JobStatus, JobStore +from app.version import __version__ log = logging.getLogger("talkscore-asr") @@ -113,13 +114,23 @@ def guard(request: Request) -> None: @app.get("/health") -def health() -> JSONResponse: - """Проверка живости - без токена, чтобы годилась для мониторинга.""" +def health(request: Request) -> JSONResponse: + """Проверка живости - без токена, чтобы годилась для мониторинга. + + Показывает адрес обратившегося и вердикт по списку доступа: без этого + отладка отказов превращается в гадание, а сам адрес клиенту и так известен. + Список разрешённых адресов при этом не раскрывается. + """ + client_ip = request.client.host if request.client else None return JSONResponse({ "status": "ok" if _state["ready"] else "no_models", + "version": __version__, "error": _state["error"], "queue": store.stats(), "threads": settings.effective_threads(), + "your_ip": client_ip, + "your_ip_allowed": ip_allowed(client_ip, allowlist), + "ip_filter_active": bool(allowlist), }) diff --git a/app/version.py b/app/version.py index bbab024..1276d02 100644 --- a/app/version.py +++ b/app/version.py @@ -1 +1 @@ -__version__ = "0.1.4" +__version__ = "0.1.5" diff --git a/tests/test_api.py b/tests/test_api.py index 9db85bb..a6ae0f4 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -123,3 +123,28 @@ class TestSchemaExposure: def test_redoc_hidden_by_default(self, client): assert client.get("/redoc").status_code == 404 + + +class TestHealthDiagnostics: + """Без этих полей отказ по адресу отлаживается вслепую.""" + + def test_reports_client_ip(self, client): + body = client.get("/health").json() + assert "your_ip" in body + + def test_reports_verdict_on_client_ip(self, client): + body = client.get("/health").json() + assert body["your_ip_allowed"] is True # в тестовом конфиге список пуст + + def test_reports_whether_filter_is_active(self, client): + assert client.get("/health").json()["ip_filter_active"] is False + + def test_reports_version(self, client): + from app.version import __version__ + + assert client.get("/health").json()["version"] == __version__ + + def test_does_not_leak_allowlist(self, client): + """Список разрешённых адресов - не для посторонних глаз.""" + body = client.get("/health").json() + assert "allow_ips" not in body and "allowlist" not in body