HFswapnil commited on
Commit
d3fc796
Β·
verified Β·
1 Parent(s): b447322

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +129 -53
src/streamlit_app.py CHANGED
@@ -2,24 +2,29 @@ import streamlit as st
2
  import pandas as pd
3
  import os
4
  import hashlib
 
5
  from datetime import datetime
6
  from pathlib import Path
7
  from huggingface_hub import CommitScheduler
8
- from eval_answer_therapy import evaluate_submission
9
  from PIL import Image
10
 
11
- # --- PERSISTENCE CONFIGURATION ---
12
- DATA_FILENAME = "submissions.csv"
13
- USER_FILENAME = "users.csv"
 
 
 
 
 
 
14
  DATA_DIR = Path("data")
15
  DATA_DIR.mkdir(exist_ok=True)
 
 
16
 
17
- DATA_PATH = DATA_DIR / DATA_FILENAME
18
- USER_PATH = DATA_DIR / USER_FILENAME
19
-
20
- # Initialize CommitScheduler
21
- # This will automatically sync everything in the /data folder to your HF Dataset
22
- repo_id = "your-username/your-private-dataset-name" # TODO: Change this
23
 
24
  scheduler = CommitScheduler(
25
  repo_id=repo_id,
@@ -30,81 +35,78 @@ scheduler = CommitScheduler(
30
  token=os.getenv("HF_TOKEN")
31
  )
32
 
33
- # --- DB HELPERS (Replaced SQLite with Pandas/CSV) ---
34
 
35
  def init_db():
36
- # Create files if they don't exist
37
- if not USER_PATH.exists():
38
- pd.DataFrame(columns=["username", "password"]).to_csv(USER_PATH, index=False)
39
- if not DATA_PATH.exists():
40
- pd.DataFrame(columns=["username", "bbox_mAP", "bbox_AP50", "segm_mAP", "segm_AP50", "timestamp"]).to_csv(DATA_PATH, index=False)
 
41
 
42
  def make_hashes(password):
43
  return hashlib.sha256(str.encode(password)).hexdigest()
44
 
45
  def add_user(username, password):
46
  with scheduler.lock:
47
- df = pd.read_csv(USER_PATH)
48
  if username in df['username'].values:
49
  return False
50
  new_user = pd.DataFrame([{"username": username, "password": make_hashes(password)}])
51
  df = pd.concat([df, new_user], ignore_index=True)
52
- df.to_csv(USER_PATH, index=False)
53
  return True
54
 
55
  def login_user(username, password):
56
- df = pd.read_csv(USER_PATH)
57
- user_row = df[(df['username'] == username) & (df['password'] == make_hashes(password))]
58
- return not user_row.empty
 
 
59
 
60
  def save_submission(username, bbox_mAP, bbox_AP50, segm_mAP, segm_AP50):
61
  with scheduler.lock:
62
- df = pd.read_csv(DATA_PATH)
63
- new_sub = pd.DataFrame([{
64
  "username": username,
65
  "bbox_mAP": bbox_mAP,
66
  "bbox_AP50": bbox_AP50,
67
  "segm_mAP": segm_mAP,
68
  "segm_AP50": segm_AP50,
69
  "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
70
- }])
71
- df = pd.concat([df, new_sub], ignore_index=True)
72
- df.to_csv(DATA_PATH, index=False)
73
 
74
  def get_leaderboard_data():
75
- if not DATA_PATH.exists():
76
  return pd.DataFrame()
77
 
78
- df = pd.read_csv(DATA_PATH)
79
  if df.empty:
80
  return df
81
 
82
- # Logic to get the BEST score per user
83
- # Sorting by segm_mAP (desc) and timestamp (asc) to get best/earliest
84
  df = df.sort_values(by=['segm_mAP', 'timestamp'], ascending=[False, True])
85
  df_best = df.drop_duplicates(subset='username', keep='first')
86
 
87
- df_best = df_best.rename(columns={'segm_mAP': 'Best_segm_mAP'})
88
  return df_best
89
 
90
- # --- CONFIGURATION & SETUP ---
91
- st.set_page_config(page_title="AI Benchmark Arena", page_icon="πŸ†", layout="wide")
92
-
93
- # (The rest of your ui_login_signup and main_app functions remain largely the same)
94
- # Just ensure you call the new CSV-based functions.
95
 
96
- # ... [KEEP YOUR ui_login_signup() and UI code here] ...
97
  def ui_login_signup():
98
-
99
  st.title("Welcome to Benchmark Arena πŸ†")
100
-
101
  tab1, tab2 = st.tabs(["Login", "Sign Up"])
102
 
103
  with tab1:
104
  st.subheader("Sign In")
105
  username = st.text_input("Username", key="login_user")
106
  password = st.text_input("Password", type='password', key="login_pass")
107
-
108
  if st.button("Login"):
109
  if login_user(username, password):
110
  st.session_state['logged_in'] = True
@@ -117,27 +119,101 @@ def ui_login_signup():
117
  st.subheader("Create New Account")
118
  new_user = st.text_input("Username", key="new_user")
119
  new_pass = st.text_input("Password", type='password', key="new_pass")
120
-
121
  if st.button("Sign Up"):
122
  if add_user(new_user, new_pass):
123
  st.success("Account created! Please navigate to Login.")
124
  else:
125
  st.warning("Username already exists.")
126
 
127
-
128
-
129
  def main_app():
130
- # (Sidebar and Expanders code here - same as your original)
 
 
 
131
 
132
- # In your "Evaluate" button logic:
133
- # Ensure variables are mapped correctly to the new save_submission()
134
- if st.button("Evaluate"):
135
- with st.spinner('Calculating...'):
136
- bbox_mAP, bbox_AP50, segm_mAP, segm_AP50 = evaluate_submission("src/biv_query.json", save_path)
137
- if bbox_mAP is not None:
138
- save_submission(st.session_state['username'], bbox_mAP, bbox_AP50, segm_mAP, segm_AP50)
139
- st.balloons()
140
- st.success("Submission Successful!")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
 
142
  if __name__ == '__main__':
143
  init_db()
 
2
  import pandas as pd
3
  import os
4
  import hashlib
5
+ import sqlite3 # Kept for potential local debugging, though we use CSV for persistence
6
  from datetime import datetime
7
  from pathlib import Path
8
  from huggingface_hub import CommitScheduler
9
+ from localization_eval import evaluate_submission
10
  from PIL import Image
11
 
12
+ # --- CONFIGURATION & SETUP ---
13
+ st.set_page_config(
14
+ page_title="AI Benchmark Arena",
15
+ page_icon="πŸ†",
16
+ layout="wide",
17
+ initial_sidebar_state="expanded"
18
+ )
19
+
20
+ # --- HUGGING FACE PERSISTENCE SETUP ---
21
  DATA_DIR = Path("data")
22
  DATA_DIR.mkdir(exist_ok=True)
23
+ SUBMISSIONS_CSV = DATA_DIR / "submissions.csv"
24
+ USERS_CSV = DATA_DIR / "users.csv"
25
 
26
+ # Change 'your-username/your-dataset-name' to your actual repo ID
27
+ repo_id = "your-username/your-private-dataset"
 
 
 
 
28
 
29
  scheduler = CommitScheduler(
30
  repo_id=repo_id,
 
35
  token=os.getenv("HF_TOKEN")
36
  )
37
 
38
+
39
 
40
  def init_db():
41
+ """Initializes the CSV files if they do not exist in the data directory."""
42
+ if not USERS_CSV.exists():
43
+ pd.DataFrame(columns=["username", "password"]).to_csv(USERS_CSV, index=False)
44
+
45
+ if not SUBMISSIONS_CSV.exists():
46
+ pd.DataFrame(columns=["username", "bbox_mAP", "bbox_AP50", "segm_mAP", "segm_AP50", "timestamp"]).to_csv(SUBMISSIONS_CSV, index=False)
47
 
48
  def make_hashes(password):
49
  return hashlib.sha256(str.encode(password)).hexdigest()
50
 
51
  def add_user(username, password):
52
  with scheduler.lock:
53
+ df = pd.read_csv(USERS_CSV)
54
  if username in df['username'].values:
55
  return False
56
  new_user = pd.DataFrame([{"username": username, "password": make_hashes(password)}])
57
  df = pd.concat([df, new_user], ignore_index=True)
58
+ df.to_csv(USERS_CSV, index=False)
59
  return True
60
 
61
  def login_user(username, password):
62
+ if not USERS_CSV.exists():
63
+ return []
64
+ df = pd.read_csv(USERS_CSV)
65
+ user_match = df[(df['username'] == username) & (df['password'] == make_hashes(password))]
66
+ return user_match.values.tolist()
67
 
68
  def save_submission(username, bbox_mAP, bbox_AP50, segm_mAP, segm_AP50):
69
  with scheduler.lock:
70
+ df = pd.read_csv(SUBMISSIONS_CSV)
71
+ new_row = {
72
  "username": username,
73
  "bbox_mAP": bbox_mAP,
74
  "bbox_AP50": bbox_AP50,
75
  "segm_mAP": segm_mAP,
76
  "segm_AP50": segm_AP50,
77
  "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
78
+ }
79
+ df = pd.concat([df, pd.DataFrame([new_row])], ignore_index=True)
80
+ df.to_csv(SUBMISSIONS_CSV, index=False)
81
 
82
  def get_leaderboard_data():
83
+ if not SUBMISSIONS_CSV.exists():
84
  return pd.DataFrame()
85
 
86
+ df = pd.read_csv(SUBMISSIONS_CSV)
87
  if df.empty:
88
  return df
89
 
90
+ # Logic: Get the highest segm_mAP per user, then the earliest timestamp if tied
91
+ df['timestamp'] = pd.to_datetime(df['timestamp'])
92
  df = df.sort_values(by=['segm_mAP', 'timestamp'], ascending=[False, True])
93
  df_best = df.drop_duplicates(subset='username', keep='first')
94
 
95
+ df_best = df_best.rename(columns={'segm_mAP': 'Best_segm_mAP', 'timestamp': 'last_submission'})
96
  return df_best
97
 
98
+ # --- User Interface ---
 
 
 
 
99
 
 
100
  def ui_login_signup():
 
101
  st.title("Welcome to Benchmark Arena πŸ†")
102
+
103
  tab1, tab2 = st.tabs(["Login", "Sign Up"])
104
 
105
  with tab1:
106
  st.subheader("Sign In")
107
  username = st.text_input("Username", key="login_user")
108
  password = st.text_input("Password", type='password', key="login_pass")
109
+
110
  if st.button("Login"):
111
  if login_user(username, password):
112
  st.session_state['logged_in'] = True
 
119
  st.subheader("Create New Account")
120
  new_user = st.text_input("Username", key="new_user")
121
  new_pass = st.text_input("Password", type='password', key="new_pass")
122
+
123
  if st.button("Sign Up"):
124
  if add_user(new_user, new_pass):
125
  st.success("Account created! Please navigate to Login.")
126
  else:
127
  st.warning("Username already exists.")
128
 
 
 
129
  def main_app():
130
+ # Sidebar Navigation
131
+ st.sidebar.title(f"Hi, {st.session_state['username']}!")
132
+ menu = ["Submit Model", "Leaderboard"]
133
+ choice = st.sidebar.radio("Navigation", menu)
134
 
135
+ st.sidebar.markdown("---")
136
+ if st.sidebar.button("Logout"):
137
+ st.session_state['logged_in'] = False
138
+ st.session_state['username'] = None
139
+ st.rerun()
140
+
141
+ with st.expander("ℹ️ Overview of the AI Benchmark Arena"):
142
+ st.markdown(
143
+ """
144
+ A natural application of computer vision is to assist blind people, whether that may be to overcome their daily visual challenges or break down their social accessibility barriers. BIV-Priv is proposed to preserve a blind person's visual privacy to ensure they can access visual-related tools safely.
145
+ VizWiz Challenge 2025 is the 1th edition of the Few-Shot Private Object Localization Challenge on the BIV-Priv dataset. To participate in the challenge, you can find instructions on the Challenge website.
146
+ Note: All the timings on the EvalAI platform are local to your timezone.
147
+ """
148
+ )
149
+ try:
150
+ overview_image = Image.open("src/overview_image.png").resize((600, 600))
151
+ st.image(overview_image, caption="Example of an object localization task")
152
+ except FileNotFoundError:
153
+ st.warning("Overview image not found in src/ folder.")
154
+
155
+ with st.expander("πŸ“ How is the Score Calculated?"):
156
+ st.markdown(
157
+ """
158
+ **Terms and Conditions**
159
+ The images and annotations in this dataset belong to the VizWiz team and are licensed under a Commons Attribution 4.0 International License.
160
+ """
161
+ )
162
+
163
+ st.markdown("---")
164
+
165
+ if choice == "Submit Model":
166
+ st.header("πŸš€ Submit your Predictions")
167
+
168
+ col1, col2 = st.columns([2, 1])
169
+
170
+ with col1:
171
+ uploaded_file = st.file_uploader("Choose a JSON file", type="json")
172
+
173
+ if uploaded_file is not None:
174
+ save_path = f"./{uploaded_file.name}"
175
+
176
+ with open(save_path, "wb") as f:
177
+ f.write(uploaded_file.getbuffer())
178
+
179
+ if st.button("Evaluate"):
180
+ with st.spinner('Calculating score against Ground Truth...'):
181
+ # Using your custom evaluation function
182
+ bbox_mAP, bbox_AP50, segm_mAP, segm_AP50 = evaluate_submission("src/biv_query.json", save_path)
183
+
184
+ if all(v is not None for v in [bbox_mAP, bbox_AP50, segm_mAP, segm_AP50]):
185
+ st.success(f"Results: bbox_mAP: {bbox_mAP:.2f}, bbox_AP50: {bbox_AP50:.2f}, segm_mAP: {segm_mAP:.2f}, segm_AP50: {segm_AP50:.2f}")
186
+ save_submission(st.session_state['username'], bbox_mAP, bbox_AP50, segm_mAP, segm_AP50)
187
+ st.balloons()
188
+ st.success("Submission Successful!")
189
+ else:
190
+ st.error("Evaluation failed. Please check your JSON format.")
191
+
192
+ elif choice == "Leaderboard":
193
+ st.header("πŸ† Leaderboard")
194
+ st.write("Rankings based on the highest segmentation mAP score achieved.")
195
+
196
+ df_leaderboard = get_leaderboard_data()
197
+
198
+ if not df_leaderboard.empty:
199
+ df_leaderboard.insert(0, 'Rank', range(1, len(df_leaderboard) + 1))
200
+
201
+ st.dataframe(
202
+ df_leaderboard,
203
+ column_config={
204
+ "Rank": st.column_config.Column("Rank", width="small"),
205
+ "username": "Participant",
206
+ "Best_segm_mAP": st.column_config.NumberColumn("segm_mAP (Primary)", format="%.4f"),
207
+ "bbox_mAP": st.column_config.NumberColumn("bbox_mAP", format="%.4f"),
208
+ "bbox_AP50": st.column_config.NumberColumn("bbox_AP50", format="%.4f"),
209
+ "segm_AP50": st.column_config.NumberColumn("segm_AP50", format="%.4f"),
210
+ "last_submission": st.column_config.DatetimeColumn("Last Active Submission", format="D MMM YYYY, h:mm a"),
211
+ },
212
+ use_container_width=True,
213
+ hide_index=True,
214
+ )
215
+ else:
216
+ st.info("No submissions yet. Be the first to submit your model!")
217
 
218
  if __name__ == '__main__':
219
  init_db()