feat(admin): add safe processing monitor and operation correlation
This commit is contained in:
@@ -20,6 +20,7 @@ import torch
|
||||
import threading
|
||||
import time
|
||||
import zipfile
|
||||
from uuid import UUID
|
||||
from urllib import request as urllib_request
|
||||
from urllib.error import URLError, HTTPError
|
||||
from contextvars import ContextVar
|
||||
@@ -66,6 +67,16 @@ async def require_service_token(request: Request, call_next):
|
||||
{"detail": "Invalid or missing service token."},
|
||||
status_code=401,
|
||||
)
|
||||
operation_id = None
|
||||
supplied_id = request.headers.get("X-Operation-Id", "")
|
||||
if len(supplied_id) == 36:
|
||||
try:
|
||||
parsed_id = UUID(supplied_id)
|
||||
if parsed_id.int:
|
||||
operation_id = str(parsed_id)
|
||||
except ValueError:
|
||||
pass
|
||||
request.state.operation_id = operation_id
|
||||
allowed = (
|
||||
EXTERNAL_AI_ENABLED
|
||||
and request.headers.get(EXTERNAL_AI_ALLOWED_HEADER, "").strip().lower() == "true"
|
||||
@@ -78,6 +89,8 @@ async def require_service_token(request: Request, call_next):
|
||||
state_token = _route_state.set(state)
|
||||
try:
|
||||
response = await call_next(request)
|
||||
if operation_id:
|
||||
response.headers["X-Operation-Id"] = operation_id
|
||||
if request.url.path.startswith("/cv/"):
|
||||
if state["provider"]:
|
||||
response.headers["X-Ai-Provider"] = state["provider"]
|
||||
|
||||
@@ -60,6 +60,24 @@ def load_app_module(
|
||||
return importlib.reload(module)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value,expected", [
|
||||
("11111111-1111-4111-8111-111111111111", "11111111-1111-4111-8111-111111111111"),
|
||||
("AAAAAAAA-AAAA-4AAA-8AAA-AAAAAAAAAAAA", "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa"),
|
||||
("SECRET_document_content", None),
|
||||
("00000000-0000-0000-0000-000000000000", None),
|
||||
("x" * 128, None),
|
||||
])
|
||||
def test_operation_correlation_echoes_only_a_nonempty_bounded_uuid(monkeypatch, value, expected):
|
||||
module = load_app_module(monkeypatch, service_token="synthetic-token")
|
||||
client = TestClient(module.app)
|
||||
response = client.post("/cv/rewrite", json={}, headers={"X-Ai-Service-Token": "synthetic-token", "X-Operation-Id": value})
|
||||
assert response.status_code == 422 # Schema rejection exercises middleware without inference.
|
||||
assert response.headers.get("X-Operation-Id") == expected
|
||||
denied = client.post("/cv/rewrite", json={}, headers={"X-Operation-Id": value})
|
||||
assert denied.status_code == 401
|
||||
assert "X-Operation-Id" not in denied.headers
|
||||
|
||||
|
||||
def test_health_reports_runtime_without_ollama_and_without_forcing_model_load(monkeypatch):
|
||||
module = load_app_module(monkeypatch)
|
||||
client = TestClient(module.app)
|
||||
|
||||
Reference in New Issue
Block a user