Files
breakpilot-compliance/consent-tester/routes_matrix.py
T
Benjamin Admin 881e9c28de feat(consent-tester): /scan-matrix echt — Profil je Engine + Per-Engine-Summary (Phase 1.2)
- _scanner_run reicht browser_profile an run_consent_test durch (statt Single-Chromium-Shim)
- neue scan_matrix_summary.matrix_scan_dict: ConsentTestResult -> schlanke
  Matrix-dict-Form (phases fuer _extract_dimensions + kompakter `summary`:
  cookies_before_consent/after_reject, reject_respected-Heuristik [keine
  Verstoesse UND kein neuer Tracker], surface, screenshot)
- multi_browser_scanner._run_one hebt summary + engine + is_mobile an die
  Zeile, verwirft die vollen Cookie-Listen (JSONB-Persistenz schlank)
- consent_scanner: _ctx_base mit Mobile-Device-Emulation (iPhone-Profil ->
  echtes Mobile-Viewport/Touch), alle 5 new_context auf **_ctx_base
- Tests: test_scan_matrix_summary (6) inkl. _extract_dimensions-Vertrag

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-12 22:46:42 +02:00

67 lines
2.4 KiB
Python

"""POST /scan-matrix — browser-matrix stage-1 endpoint.
Runs the existing consent_scanner once per browser profile and
returns the aggregated robustness-score per browser plus a
worst-of/best-of summary. Kept in its own module so main.py stays
under the 500-LOC cap.
Stage 1.b (erledigt): `run_consent_test` nimmt jetzt einen `browser_profile`
kwarg → echte Engine-Diversität (Firefox/Gecko, WebKit/Safari, Blink inkl.
Chrome-/Edge-Channel + Brave). `_scanner_run` reicht das Profil durch.
"""
from __future__ import annotations
import logging
from datetime import datetime, timezone
from fastapi import APIRouter
from pydantic import BaseModel
from services.consent_scanner import run_consent_test
from services.multi_browser_scanner import run_matrix
from services.scan_matrix_summary import matrix_scan_dict
logger = logging.getLogger(__name__)
router = APIRouter()
class MatrixScanRequest(BaseModel):
url: str
timeout_per_phase: int = 10
categories: list[str] = []
# Resolved against browser_profiles.resolve_profiles. None or
# empty list → default 4 profiles (chromium/firefox/webkit/iphone).
browser_profiles: list[str] | None = None
async def _scanner_run(url: str, browser_profile: dict | None = None,
timeout_per_phase: int = 10,
categories: list[str] | None = None):
"""Adapter: reicht das aufgelöste `browser_profile` (Engine/Channel/Device)
an `run_consent_test` durch, damit jede Matrix-Zeile auf der echten Engine
läuft (Firefox/WebKit/Blink + Chrome-/Edge-Channel + Brave). Projiziert
das ConsentTestResult auf die schlanke Matrix-dict-Form (phases +
kompakter `summary`)."""
result = await run_consent_test(url, timeout_per_phase,
categories or [],
browser_profile=browser_profile)
return matrix_scan_dict(result)
@router.post("/scan-matrix")
async def scan_matrix(req: MatrixScanRequest):
"""Run consent-scan across the resolved browser-profile matrix."""
logger.info("Matrix scan for %s profiles=%s", req.url,
req.browser_profiles or "default")
matrix = await run_matrix(
_scanner_run,
req.url,
requested_profiles=req.browser_profiles,
timeout_per_phase=req.timeout_per_phase,
categories=req.categories,
)
matrix["url"] = req.url
matrix["scanned_at"] = datetime.now(timezone.utc).isoformat()
return matrix