Skip to content

feat: FastAPI surface, Streamlit dashboard, README screenshot#5

Merged
adel-saoud merged 1 commit into
mainfrom
feat/api-dashboard
Jun 17, 2026
Merged

feat: FastAPI surface, Streamlit dashboard, README screenshot#5
adel-saoud merged 1 commit into
mainfrom
feat/api-dashboard

Conversation

@adel-saoud

@adel-saoud adel-saoud commented Jun 17, 2026

Copy link
Copy Markdown
Owner

Summary

  • FastAPI surface, five routes: POST /v1/ingest, POST /v1/query, GET /v1/audit/{document_id}, GET /v1/stats, GET /health
  • Query-side PII redaction before embedding, post-generation audit on every answer, X-Guardian-Pii-Audit / X-Guardian-Chunks-Used / X-Guardian-Request-Id headers
  • Lifespan-managed AppState with lazy ML backends (GLiNER, DeBERTa, sentence-transformers) and thread-safe StatsCollector
  • Streamlit dashboard with three tabs (PII Protection Stats, Redaction Explorer, Eval Results), scripts/composite_dashboard.py builds the 2x2 README banner
  • Dashboard banner shipped at docs/dashboard.png

Test plan

  • uv run ruff check . clean
  • uv run pyright 0 errors / 0 warnings
  • uv run pytest tests/test_api.py all green
  • Full project: 125 tests, 92.68% coverage
  • CI green on the PR

Surface:
- `POST /v1/ingest` runs detect, redact, persist redaction map, chunk,
  embed, and store. BM25 index is refreshed after every ingestion.
- `POST /v1/query` redacts the user query before embedding, runs the
  hybrid retriever, generates a grounded answer, and re-runs the audit
  over the answer. Response headers carry the audit verdict, the chunk
  count, the faithfulness slot, and a request id.
- `GET /v1/audit/{document_id}` returns the persisted redaction map so
  reviewers can see exactly what was caught at ingestion time.
- `GET /v1/stats` exposes aggregate detector counters.
- `GET /health` for the orchestrator.

Wiring:
- `dependencies.py` carries `AppState` (settings, detector, redactor,
  pipeline, store, retriever, generator, auditor, stats) plus
  `Annotated`-typed `*Dep` aliases so routes can be overridden by tests
  with `app.dependency_overrides[...]`.
- `app.py` exposes `build_app(state)` for tests and `create_app()` for
  production. The lifespan handler is where the heavy ML imports
  finally happen: GLiNER, DeBERTa zero-shot validator, and the
  sentence-transformers embedder are all loaded lazily.
- `StatsCollector` is thread-safe (lock-protected) in-memory.

Dashboard:
- Three Streamlit tabs: PII Protection Stats (donut, KPIs), Redaction
  Explorer (paste text, see entities highlighted, diff before / after,
  entity table), Eval Results (gauges against the golden corpus,
  per-category table).
- `scripts/composite_dashboard.py` builds the 2x2 README banner from
  per-tab screenshots; `docs/dashboard.png` is included.
- `scripts/demo.py` runs the end-to-end stack against a real Ollama
  instance for local demos.

README image reference is restored now that the file exists.
@adel-saoud adel-saoud self-assigned this Jun 17, 2026
@adel-saoud
adel-saoud merged commit c37ce62 into main Jun 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant