add reporting foundation: multipage nav, auth gate, date-range fetch
First increment of the clinical reporting feature (see docs/requirements-reporting.md and docs/design-reporting.md): moves the existing live view to pages/1_Live.py, adds a password gate since the dashboard URL will be shared with the diabetes team, adds fetch_entries_range/fetch_treatments_range for multi-day report queries, and adds reporting.py with the core clinical calculations (GMI, %CV, 5-band time-in-range, hypo/hyper event detection per the Battelino et al. 2019 persistence rule). No report pages wired up yet — that's next. Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
"""
|
||||
Eenvoudige wachtwoord-gate voor de dashboardpagina's.
|
||||
|
||||
Streamlit heeft geen ingebouwde authenticatie. Omdat dashboard-URL's straks
|
||||
gedeeld worden met het diabetesteam, staat hier een lichte sessie-gebaseerde
|
||||
wachtwoordcontrole voor — geen volwaardig account-systeem, wel een drempel
|
||||
tegen toevallig meekijken. Het wachtwoord zelf staat nooit in plaintext in de
|
||||
configuratie: net als bij het Nightscout API secret in nightscout_client.py
|
||||
wordt hier een hash vergeleken, niet de ruwe waarde.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import os
|
||||
|
||||
import streamlit as st
|
||||
|
||||
|
||||
def require_auth() -> None:
|
||||
"""Blokkeer de pagina totdat het juiste wachtwoord is ingevoerd.
|
||||
|
||||
Slaat de status op in st.session_state zodat dit maar één keer per
|
||||
browsersessie hoeft. Moet als eerste statement van elke pagina aangeroepen
|
||||
worden (app.py en elk bestand in pages/), omdat Streamlit iedere pagina
|
||||
als los script uitvoert.
|
||||
"""
|
||||
if st.session_state.get("authenticated"):
|
||||
return
|
||||
|
||||
st.title("Glucose dashboard")
|
||||
password = st.text_input("Wachtwoord", type="password")
|
||||
|
||||
if not password:
|
||||
st.stop()
|
||||
|
||||
if verify_password(password, os.environ.get("DASHBOARD_PASSWORD_HASH", "")):
|
||||
st.session_state["authenticated"] = True
|
||||
st.rerun()
|
||||
|
||||
st.error("Onjuist wachtwoord")
|
||||
st.stop()
|
||||
|
||||
|
||||
def verify_password(password: str, expected_hash: str) -> bool:
|
||||
"""Vergelijk een ingevoerd wachtwoord met de geconfigureerde sha256-hash."""
|
||||
if not expected_hash:
|
||||
return False
|
||||
return hashlib.sha256(password.encode("utf-8")).hexdigest() == expected_hash
|
||||
Reference in New Issue
Block a user