fenghebonjour commited on
Commit
4d92e2c
Β·
verified Β·
1 Parent(s): 6b59c02

Upload folder using huggingface_hub

Browse files
Files changed (4) hide show
  1. .gitignore +1 -0
  2. apps/omyfish_web/main.py +59 -0
  3. requirements.txt +1 -0
  4. shared/config.py +2 -0
.gitignore CHANGED
@@ -23,3 +23,4 @@ notebooks/*.ipynb
23
  .DS_Store
24
  *.swp
25
  .env
 
 
23
  .DS_Store
24
  *.swp
25
  .env
26
+ .local_session
apps/omyfish_web/main.py CHANGED
@@ -23,6 +23,55 @@ st.html('<style>html{overflow-y:scroll!important}</style>')
23
 
24
  _checkpoint_exists = Path(settings.checkpoint_path).exists()
25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  # ── Auth helpers ──────────────────────────────────────────────────────────────
27
 
28
  def _auth_repo():
@@ -43,6 +92,8 @@ def _auth_sidebar():
43
  st.caption(f"Role: {user['role']}")
44
  if st.button("Log out", use_container_width=True):
45
  del st.session_state["auth_user"]
 
 
46
  st.rerun()
47
  return
48
 
@@ -56,6 +107,10 @@ def _auth_sidebar():
56
  u = repo.get_by_email(email)
57
  if u and verify_password(password, u["hashed_password"]) and u["is_active"]:
58
  st.session_state["auth_user"] = {"id": u["id"], "email": u["email"], "role": u["role"]}
 
 
 
 
59
  st.rerun()
60
  else:
61
  st.error("Invalid credentials.")
@@ -72,6 +127,10 @@ def _auth_sidebar():
72
  else:
73
  u = repo.create(new_email, hash_password(new_pw))
74
  st.session_state["auth_user"] = {"id": u["id"], "email": u["email"], "role": u["role"]}
 
 
 
 
75
  st.rerun()
76
 
77
 
 
23
 
24
  _checkpoint_exists = Path(settings.checkpoint_path).exists()
25
 
26
+ # ── Token persistence ─────────────────────────────────────────────────────────
27
+ # Tokens are stored in two places:
28
+ # 1. st.query_params β€” survives page refresh (URL-based)
29
+ # 2. .local_session file β€” survives server restarts on local dev
30
+ # (on HF Spaces the file is ephemeral, so users re-login after a Space restart)
31
+
32
+ _SESSION_FILE = ROOT / ".local_session"
33
+
34
+
35
+ def _save_session(token: str):
36
+ try:
37
+ _SESSION_FILE.write_text(token)
38
+ except Exception:
39
+ pass
40
+
41
+
42
+ def _clear_session():
43
+ try:
44
+ _SESSION_FILE.unlink(missing_ok=True)
45
+ except Exception:
46
+ pass
47
+
48
+
49
+ def _restore_from_token(token: str) -> bool:
50
+ from jose import JWTError, jwt
51
+ try:
52
+ payload = jwt.decode(token, settings.jwt_secret, algorithms=["HS256"])
53
+ from apps.omyfish_api.db.engine import ensure_db
54
+ from apps.omyfish_api.repositories.user_repository import UserRepository
55
+ ensure_db()
56
+ u = UserRepository().get_by_id(payload["sub"])
57
+ if u and u["is_active"]:
58
+ st.session_state["auth_user"] = {"id": u["id"], "email": u["email"], "role": u["role"]}
59
+ st.query_params["token"] = token
60
+ return True
61
+ except (JWTError, Exception):
62
+ pass
63
+ return False
64
+
65
+
66
+ if "auth_user" not in st.session_state:
67
+ _token = st.query_params.get("token")
68
+ if not _token and _SESSION_FILE.exists():
69
+ _token = _SESSION_FILE.read_text().strip()
70
+ if _token:
71
+ if not _restore_from_token(_token):
72
+ st.query_params.pop("token", None)
73
+ _clear_session()
74
+
75
  # ── Auth helpers ──────────────────────────────────────────────────────────────
76
 
77
  def _auth_repo():
 
92
  st.caption(f"Role: {user['role']}")
93
  if st.button("Log out", use_container_width=True):
94
  del st.session_state["auth_user"]
95
+ st.query_params.pop("token", None)
96
+ _clear_session()
97
  st.rerun()
98
  return
99
 
 
107
  u = repo.get_by_email(email)
108
  if u and verify_password(password, u["hashed_password"]) and u["is_active"]:
109
  st.session_state["auth_user"] = {"id": u["id"], "email": u["email"], "role": u["role"]}
110
+ from apps.omyfish_api.auth import create_access_token
111
+ _tok = create_access_token(u["id"], u["role"])
112
+ st.query_params["token"] = _tok
113
+ _save_session(_tok)
114
  st.rerun()
115
  else:
116
  st.error("Invalid credentials.")
 
127
  else:
128
  u = repo.create(new_email, hash_password(new_pw))
129
  st.session_state["auth_user"] = {"id": u["id"], "email": u["email"], "role": u["role"]}
130
+ from apps.omyfish_api.auth import create_access_token
131
+ _tok = create_access_token(u["id"], u["role"])
132
+ st.query_params["token"] = _tok
133
+ _save_session(_tok)
134
  st.rerun()
135
 
136
 
requirements.txt CHANGED
@@ -48,3 +48,4 @@ alembic>=1.13.0 # Database migration framework (PostGIS pat
48
  piexif>=1.1.3 # EXIF GPS extraction from uploaded images
49
  folium>=0.15.0 # Leaflet-based map rendering
50
  streamlit-folium>=0.17.0 # Embed Folium maps in Streamlit
 
 
48
  piexif>=1.1.3 # EXIF GPS extraction from uploaded images
49
  folium>=0.15.0 # Leaflet-based map rendering
50
  streamlit-folium>=0.17.0 # Embed Folium maps in Streamlit
51
+ python-dotenv>=1.0.0 # Load .env file for local development
shared/config.py CHANGED
@@ -1,8 +1,10 @@
1
  import os
2
  import secrets
3
  from pathlib import Path
 
4
 
5
  _REPO_ROOT = Path(__file__).resolve().parent.parent
 
6
 
7
 
8
  class Settings:
 
1
  import os
2
  import secrets
3
  from pathlib import Path
4
+ from dotenv import load_dotenv
5
 
6
  _REPO_ROOT = Path(__file__).resolve().parent.parent
7
+ load_dotenv(_REPO_ROOT / ".env")
8
 
9
 
10
  class Settings: