Quazim0t0 commited on
Commit
e73561d
·
verified ·
1 Parent(s): bad101b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +241 -18
app.py CHANGED
@@ -1,4 +1,191 @@
1
- <!DOCTYPE html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  <html>
3
  <head>
4
  <meta charset="utf-8" />
@@ -133,22 +320,6 @@
133
  signinButton.classList.add("hidden");
134
  showStatus(`Logged in as ${oauthResult.userInfo.name}`, "success");
135
  continueButton.classList.remove("hidden");
136
-
137
- // Send user info to backend
138
- try {
139
- await fetch("/api/register_user", {
140
- method: "POST",
141
- headers: {
142
- "Content-Type": "application/json",
143
- },
144
- body: JSON.stringify({
145
- username: oauthResult.userInfo.name,
146
- token: oauthResult.accessToken
147
- }),
148
- });
149
- } catch (error) {
150
- console.error("Error registering user:", error);
151
- }
152
  } else {
153
  statusElement.classList.add("hidden");
154
  signinButton.classList.remove("hidden");
@@ -177,4 +348,56 @@
177
  checkLogin();
178
  </script>
179
  </body>
180
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Main application for Dynamic Highscores system.
3
+
4
+ This file integrates all components into a unified application.
5
+ """
6
+
7
+ import os
8
+ import gradio as gr
9
+ import threading
10
+ import time
11
+ from database_schema import DynamicHighscoresDB
12
+ from auth import HuggingFaceAuth
13
+ from benchmark_selection import BenchmarkSelector, create_benchmark_selection_ui
14
+ from evaluation_queue import EvaluationQueue, create_model_submission_ui
15
+ from leaderboard import Leaderboard, create_leaderboard_ui
16
+ from sample_benchmarks import add_sample_benchmarks
17
+ from fastapi import FastAPI, Request, HTTPException
18
+ from fastapi.responses import FileResponse, HTMLResponse
19
+ from fastapi.staticfiles import StaticFiles
20
+ from pydantic import BaseModel
21
+
22
+ # Initialize components in main thread
23
+ db = DynamicHighscoresDB()
24
+ auth_manager = HuggingFaceAuth(db)
25
+ benchmark_selector = BenchmarkSelector(db, auth_manager)
26
+ evaluation_queue = EvaluationQueue(db, auth_manager)
27
+ leaderboard = Leaderboard(db)
28
+
29
+ # Initialize sample benchmarks if none exist
30
+ print("Checking for existing benchmarks...")
31
+ benchmarks = db.get_benchmarks()
32
+ if not benchmarks or len(benchmarks) == 0:
33
+ print("No benchmarks found. Adding sample benchmarks...")
34
+ try:
35
+ # Make sure the database path is clear
36
+ print(f"Database path: {db.db_path}")
37
+
38
+ # Import and call the function directly
39
+ num_added = add_sample_benchmarks()
40
+ print(f"Added {num_added} sample benchmarks.")
41
+ except Exception as e:
42
+ print(f"Error adding sample benchmarks: {str(e)}")
43
+ # Try direct DB insertion as fallback
44
+ try:
45
+ print("Attempting direct benchmark insertion...")
46
+ db.add_benchmark(
47
+ name="MMLU (Massive Multitask Language Understanding)",
48
+ dataset_id="cais/mmlu",
49
+ description="Tests knowledge across 57 subjects"
50
+ )
51
+ print("Added fallback benchmark.")
52
+ except Exception as inner_e:
53
+ print(f"Fallback insertion failed: {str(inner_e)}")
54
+ else:
55
+ print(f"Found {len(benchmarks)} existing benchmarks.")
56
+
57
+ # Custom CSS with theme awareness
58
+ css = """
59
+ /* Theme-adaptive colored info box */
60
+ .info-text {
61
+ background-color: rgba(53, 130, 220, 0.1);
62
+ padding: 12px;
63
+ border-radius: 8px;
64
+ border-left: 4px solid #3498db;
65
+ margin: 12px 0;
66
+ }
67
+
68
+ /* High-contrast text for elements - works in light and dark themes */
69
+ .info-text, .header, .footer, .tab-content,
70
+ button, input, textarea, select, option,
71
+ .gradio-container *, .markdown-text {
72
+ color: var(--text-color, inherit) !important;
73
+ }
74
+
75
+ /* Container styling */
76
+ .container {
77
+ max-width: 1200px;
78
+ margin: 0 auto;
79
+ }
80
+
81
+ /* Header styling */
82
+ .header {
83
+ text-align: center;
84
+ margin-bottom: 20px;
85
+ font-weight: bold;
86
+ font-size: 24px;
87
+ }
88
+
89
+ /* Footer styling */
90
+ .footer {
91
+ text-align: center;
92
+ margin-top: 40px;
93
+ padding: 20px;
94
+ border-top: 1px solid var(--border-color-primary, #eee);
95
+ }
96
+
97
+ /* Login section styling */
98
+ .login-section {
99
+ padding: 10px;
100
+ margin-bottom: 15px;
101
+ border-radius: 8px;
102
+ background-color: rgba(250, 250, 250, 0.1);
103
+ text-align: center;
104
+ }
105
+ """
106
+
107
+ # Simple manual authentication check
108
+ def check_user(request: gr.Request):
109
+ if request:
110
+ username = request.headers.get("HF-User")
111
+ if username:
112
+ # User is logged in via HF Spaces
113
+ print(f"User logged in: {username}")
114
+ user = db.get_user_by_username(username)
115
+ if not user:
116
+ # Create user if they don't exist
117
+ print(f"Creating new user: {username}")
118
+ is_admin = (username == "Quazim0t0")
119
+ db.add_user(username, username, is_admin)
120
+ user = db.get_user_by_username(username)
121
+ return f"Logged in as: {username}"
122
+ return "Not logged in. Please <a href='/'>login</a> first."
123
+
124
+ # Start evaluation queue worker
125
+ def start_queue_worker():
126
+ # Wait a moment to ensure app is initialized
127
+ time.sleep(2)
128
+ try:
129
+ print("Starting evaluation queue worker...")
130
+ evaluation_queue.start_worker()
131
+ except Exception as e:
132
+ print(f"Error starting queue worker: {e}")
133
+
134
+ # Create Gradio app
135
+ with gr.Blocks(css=css, title="Dynamic Highscores") as app:
136
+ # Display login status
137
+ with gr.Row(elem_classes=["login-section"]):
138
+ login_status = gr.Markdown("Checking login status...")
139
+
140
+ gr.Markdown("# 🏆 Dynamic Highscores", elem_classes=["header"])
141
+ gr.Markdown("""
142
+ Welcome to Dynamic Highscores - a community benchmark platform for evaluating and comparing language models.
143
+
144
+ - **Add your own benchmarks** from HuggingFace datasets
145
+ - **Submit your models** for CPU-only evaluation
146
+ - **Compare performance** across different models and benchmarks
147
+ - **Filter results** by model type (Merge, Agent, Reasoning, Coding, etc.)
148
+ """, elem_classes=["info-text"])
149
+
150
+ # Main tabs
151
+ with gr.Tabs() as tabs:
152
+ with gr.TabItem("📊 Leaderboard", id=0):
153
+ leaderboard_ui = create_leaderboard_ui(leaderboard, db)
154
+
155
+ with gr.TabItem("🚀 Submit Model", id=1):
156
+ submission_ui = create_model_submission_ui(evaluation_queue, auth_manager, db)
157
+
158
+ with gr.TabItem("🔍 Benchmarks", id=2):
159
+ benchmark_ui = create_benchmark_selection_ui(benchmark_selector, auth_manager)
160
+
161
+ gr.Markdown("""
162
+ ### About Dynamic Highscores
163
+
164
+ This platform allows users to select benchmarks from HuggingFace datasets and evaluate models against them.
165
+ Each user can submit one benchmark per day (admin users are exempt from this limit).
166
+ All evaluations run on CPU only to ensure fair comparisons.
167
+
168
+ Created by Quazim0t0
169
+ """, elem_classes=["footer"])
170
+
171
+ # Check login on page load
172
+ app.load(
173
+ fn=check_user,
174
+ inputs=[],
175
+ outputs=[login_status]
176
+ )
177
+
178
+ # Create a FastAPI app to handle the static login page
179
+ fastapi_app = FastAPI()
180
+
181
+ # Make sure to create a static directory and put the login.html file there
182
+ os.makedirs("static", exist_ok=True)
183
+
184
+ # Save the login HTML to a file
185
+ login_html_path = os.path.join("static", "login.html")
186
+ if not os.path.exists(login_html_path):
187
+ with open(login_html_path, "w") as f:
188
+ f.write("""<!DOCTYPE html>
189
  <html>
190
  <head>
191
  <meta charset="utf-8" />
 
320
  signinButton.classList.add("hidden");
321
  showStatus(`Logged in as ${oauthResult.userInfo.name}`, "success");
322
  continueButton.classList.remove("hidden");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
323
  } else {
324
  statusElement.classList.add("hidden");
325
  signinButton.classList.remove("hidden");
 
348
  checkLogin();
349
  </script>
350
  </body>
351
+ </html>""")
352
+
353
+ # Create API endpoint for user registration
354
+ class UserInfo(BaseModel):
355
+ username: str
356
+ token: str
357
+
358
+ @fastapi_app.post("/api/register_user")
359
+ async def register_user(userinfo: UserInfo):
360
+ try:
361
+ # Create user in database if they don't exist
362
+ user = db.get_user_by_username(userinfo.username)
363
+ if not user:
364
+ is_admin = (userinfo.username == "Quazim0t0")
365
+ db.add_user(userinfo.username, userinfo.username, is_admin)
366
+ return {"status": "success"}
367
+ except Exception as e:
368
+ raise HTTPException(status_code=500, detail=str(e))
369
+
370
+ # Serve static files
371
+ fastapi_app.mount("/static", StaticFiles(directory="static"), name="static")
372
+
373
+ # Root path serves the login page
374
+ @fastapi_app.get("/")
375
+ async def serve_login_page():
376
+ return FileResponse("static/login.html")
377
+
378
+ # App path serves the Gradio interface
379
+ @fastapi_app.get("/app")
380
+ async def serve_app():
381
+ # This will redirect to the Gradio interface
382
+ html_content = """
383
+ <!DOCTYPE html>
384
+ <html>
385
+ <head>
386
+ <meta http-equiv="refresh" content="0;url=/gradio">
387
+ <title>Redirecting...</title>
388
+ </head>
389
+ <body>
390
+ Redirecting to Dynamic Highscores...
391
+ </body>
392
+ </html>
393
+ """
394
+ return HTMLResponse(content=html_content)
395
+
396
+ # Mount Gradio app to FastAPI app
397
+ app = gr.mount_gradio_app(fastapi_app, app, path="/gradio")
398
+
399
+ # Start the queue worker
400
+ if __name__ == "__main__":
401
+ queue_thread = threading.Thread(target=start_queue_worker)
402
+ queue_thread.daemon = True
403
+ queue_thread.start()