Gann_Time_Cycle / auth.py
Swakakade's picture
Update auth.py
b3ad474 verified
Raw History Blame Contribute Delete
5.1 kB
# =========================================================
# AUTHENTICATION MODULE FOR STREAMLIT (HF SPACES SAFE)
# =========================================================
import streamlit as st
import hashlib
from typing import Optional, Dict, Any
# =========================================================
# LOAD PASSWORD HASH FROM SECRETS
# =========================================================
def _get_password_hash() -> Optional[str]:
try:
raw = st.secrets.get("APP_PASSWORD", None)
except Exception:
raw = None
if not raw:
return None
return hashlib.sha256(raw.encode("utf-8")).hexdigest()
PASSWORD_HASH = _get_password_hash()
# =========================================================
# SESSION UTILITIES
# =========================================================
def is_logged_in() -> bool:
return bool(st.session_state.get("_logged_in", False))
def set_logged_in(value: bool = True):
st.session_state["_logged_in"] = bool(value)
def logout():
st.session_state["_logged_in"] = False
# =========================================================
# QUERY PARAM COMPATIBILITY LAYER
# =========================================================
def _get_query_params() -> Dict[str, Any]:
"""Return query params safely across Streamlit versions"""
# New Streamlit API
try:
if hasattr(st, "query_params"):
qp = dict(st.query_params or {})
return qp
except Exception:
pass
# Old experimental API
try:
if hasattr(st, "experimental_get_query_params"):
qp = st.experimental_get_query_params() or {}
return dict(qp)
except Exception:
pass
return {}
def _set_query_params(**kwargs):
"""Set query params safely across Streamlit versions"""
# New Streamlit API
try:
if hasattr(st, "set_query_params"):
st.set_query_params(**kwargs)
return
except Exception:
pass
# Old experimental API
try:
if hasattr(st, "experimental_set_query_params"):
st.experimental_set_query_params(**kwargs)
return
except Exception:
pass
# No query-param API available → do nothing
return
# =========================================================
# SAFE RERUN (works on all HF Streamlit builds)
# =========================================================
def _safe_rerun():
"""Try every known rerun mechanism."""
try:
if hasattr(st, "experimental_rerun"):
st.experimental_rerun()
return
except Exception:
pass
try:
if hasattr(st, "rerun"):
st.rerun()
return
except Exception:
pass
# Fallback for environments where rerun is blocked
try:
st.markdown('<meta http-equiv="refresh" content="0">', unsafe_allow_html=True)
except Exception:
pass
# =========================================================
# LOGIN UI (Used ONLY on /pages/auth.py)
# =========================================================
def login_ui() -> bool:
"""Returns True ONLY when login succeeds."""
st.title("🔒 Authentication")
if PASSWORD_HASH is None:
st.error("APP_PASSWORD not defined in Secrets.")
return False
pwd = st.text_input("Password", type="password")
if st.button("Login"):
entered_hash = hashlib.sha256(pwd.encode("utf-8")).hexdigest()
if entered_hash == PASSWORD_HASH:
set_logged_in(True)
st.success("Login successful! Redirecting…")
st.markdown("Login Successful - Click on any option from Left sidebar")
return True
else:
st.error("Incorrect password")
return False
# =========================================================
# AUTH ENFORCER FOR ALL OTHER PAGES
# =========================================================
def require_login(auth_page_name: str = "auth", redirect_page: str = "HOW TO USE"):
"""
Call this at TOP of every protected page.
If not logged in → redirect to auth page.
"""
if "_logged_in" not in st.session_state:
st.session_state["_logged_in"] = False
if is_logged_in():
return # Already authenticated
# Find current page
params = _get_query_params()
cur_page = None
if "page" in params:
p = params["page"]
if isinstance(p, list):
cur_page = p[0] if p else None
else:
cur_page = p
# Allow rendering of auth page itself
if cur_page == auth_page_name:
return
# Redirect user to AUTH page
_set_query_params(page=auth_page_name)
st.stop()
# =========================================================
# AUTH PAGE HANDLER (CALLED ONLY INSIDE pages/auth.py)
# =========================================================
def auth_page_handler(redirect_page="HOW TO USE"):
succeeded = login_ui()
if succeeded:
_set_query_params(page=redirect_page)
_safe_rerun()
st.stop()