Quazim0t0 commited on
Commit
6525801
·
verified ·
1 Parent(s): 189379e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +113 -232
app.py CHANGED
@@ -14,10 +14,6 @@ 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()
@@ -102,8 +98,99 @@ button, input, textarea, select, option,
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:
@@ -118,8 +205,8 @@ def check_user(request: gr.Request):
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():
@@ -133,9 +220,21 @@ def start_queue_worker():
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("""
@@ -172,232 +271,14 @@ with gr.Blocks(css=css, title="Dynamic Highscores") as app:
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" />
192
- <meta name="viewport" content="width=device-width" />
193
- <title>Dynamic Highscores Login</title>
194
- <script src="https://unpkg.com/[email protected]/dist/es-module-shims.js"></script>
195
- <script type="importmap">
196
- {
197
- "imports": {
198
- "@huggingface/hub": "https://cdn.jsdelivr.net/npm/@huggingface/[email protected]/+esm"
199
- }
200
- }
201
- </script>
202
- <style>
203
- body {
204
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
205
- background-color: #f5f5f5;
206
- display: flex;
207
- flex-direction: column;
208
- align-items: center;
209
- justify-content: center;
210
- height: 100vh;
211
- margin: 0;
212
- padding: 20px;
213
- }
214
- .card {
215
- background: white;
216
- border-radius: 8px;
217
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
218
- padding: 30px;
219
- max-width: 500px;
220
- width: 100%;
221
- text-align: center;
222
- }
223
- h1 {
224
- color: #333;
225
- margin-top: 0;
226
- }
227
- .signin-btn {
228
- cursor: pointer;
229
- display: block;
230
- margin: 20px auto;
231
- transition: transform 0.3s ease;
232
- }
233
- .signin-btn:hover {
234
- transform: scale(1.05);
235
- }
236
- .hidden {
237
- display: none;
238
- }
239
- #status {
240
- margin-top: 20px;
241
- padding: 10px;
242
- border-radius: 4px;
243
- }
244
- .success {
245
- background-color: #d4edda;
246
- color: #155724;
247
- }
248
- .loading {
249
- background-color: #fff3cd;
250
- color: #856404;
251
- }
252
- a.button {
253
- display: inline-block;
254
- background-color: #3498db;
255
- color: white;
256
- padding: 10px 20px;
257
- border-radius: 4px;
258
- text-decoration: none;
259
- font-weight: bold;
260
- margin-top: 20px;
261
- }
262
- a.button:hover {
263
- background-color: #2980b9;
264
- }
265
- </style>
266
- </head>
267
- <body>
268
- <div class="card">
269
- <h1>Dynamic Highscores</h1>
270
- <p>Sign in with your HuggingFace account to submit models and benchmarks.</p>
271
-
272
- <img src="https://huggingface.co/datasets/huggingface/badges/resolve/main/sign-in-with-huggingface-xl-dark.svg"
273
- alt="Sign in with Hugging Face"
274
- class="signin-btn"
275
- id="signin">
276
-
277
- <div id="status" class="hidden"></div>
278
-
279
- <a href="/app" class="button hidden" id="continue-btn">Continue to Dynamic Highscores</a>
280
- </div>
281
-
282
- <script type="module">
283
- import { oauthLoginUrl, oauthHandleRedirectIfPresent } from "@huggingface/hub";
284
-
285
- const statusElement = document.getElementById("status");
286
- const signinButton = document.getElementById("signin");
287
- const continueButton = document.getElementById("continue-btn");
288
-
289
- // Function to show status message
290
- function showStatus(message, type) {
291
- statusElement.textContent = message;
292
- statusElement.className = type;
293
- statusElement.classList.remove("hidden");
294
- }
295
-
296
- // Check if we're returning from OAuth redirect
297
- async function checkLogin() {
298
- try {
299
- showStatus("Checking login status...", "loading");
300
-
301
- // Check if we already have OAuth data in localStorage
302
- let oauthResult = localStorage.getItem("oauth");
303
- if (oauthResult) {
304
- try {
305
- oauthResult = JSON.parse(oauthResult);
306
- } catch {
307
- oauthResult = null;
308
- }
309
- }
310
-
311
- // If not, check if we're returning from a redirect
312
- if (!oauthResult) {
313
- oauthResult = await oauthHandleRedirectIfPresent();
314
- }
315
-
316
- // If we have OAuth data, we're logged in
317
- if (oauthResult) {
318
- localStorage.setItem("oauth", JSON.stringify(oauthResult));
319
-
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");
326
- }
327
- } catch (error) {
328
- console.error("Error checking login:", error);
329
- showStatus("Error checking login status", "error");
330
- }
331
- }
332
-
333
- // Setup sign in button
334
- signinButton.addEventListener("click", async () => {
335
- try {
336
- showStatus("Redirecting to HuggingFace login...", "loading");
337
- window.location.href = await oauthLoginUrl({
338
- redirectUrl: window.location.href,
339
- scopes: ["openid", "profile"]
340
- });
341
- } catch (error) {
342
- console.error("Error generating login URL:", error);
343
- showStatus("Error starting login process", "error");
344
- }
345
- });
346
-
347
- // Check login status when page loads
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()
 
 
 
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
 
18
  # Initialize components in main thread
19
  db = DynamicHighscoresDB()
 
98
  background-color: rgba(250, 250, 250, 0.1);
99
  text-align: center;
100
  }
101
+
102
+ /* Login button styling */
103
+ .login-button {
104
+ background-color: #4CAF50 !important;
105
+ color: white !important;
106
+ font-weight: bold;
107
+ }
108
+
109
+ /* Force high contrast on specific input areas */
110
+ input[type="text"], input[type="password"], textarea {
111
+ background-color: var(--background-fill-primary) !important;
112
+ color: var(--body-text-color) !important;
113
+ }
114
+
115
+ /* Force text visibility in multiple contexts */
116
+ .gradio-markdown p, .gradio-markdown h1, .gradio-markdown h2,
117
+ .gradio-markdown h3, .gradio-markdown h4, .gradio-markdown li {
118
+ color: var(--body-text-color) !important;
119
+ }
120
+
121
+ /* Fix dark mode text visibility */
122
+ @media (prefers-color-scheme: dark) {
123
+ input, textarea, select {
124
+ color: #ffffff !important;
125
+ }
126
+
127
+ ::placeholder {
128
+ color: rgba(255, 255, 255, 0.5) !important;
129
+ }
130
+ }
131
  """
132
 
133
+ # JavaScript login implementation
134
+ def js_login_script():
135
+ space_host = os.environ.get("SPACE_HOST", "localhost:7860")
136
+ redirect_uri = f"https://{space_host}"
137
+
138
+ return f"""
139
+ <script src="https://unpkg.com/@huggingface/[email protected]/dist/index.umd.min.js"></script>
140
+ <script>
141
+ (async function() {{
142
+ const HfHub = window.HfHub;
143
+ try {{
144
+ // Check if we're returning from OAuth redirect
145
+ const oauthResult = await HfHub.oauthHandleRedirectIfPresent();
146
+
147
+ if (oauthResult) {{
148
+ console.log("User logged in:", oauthResult);
149
+
150
+ // Store the user info in localStorage
151
+ localStorage.setItem("hf_user", JSON.stringify(oauthResult.userInfo));
152
+ localStorage.setItem("hf_token", oauthResult.accessToken);
153
+
154
+ // Update the UI to show logged in state
155
+ document.getElementById("login-status").textContent = "Logged in as: " + oauthResult.userInfo.name;
156
+ document.getElementById("login-button").style.display = "none";
157
+
158
+ // Refresh the page to update server-side state
159
+ setTimeout(() => window.location.reload(), 1000);
160
+ }}
161
+ }} catch (error) {{
162
+ console.error("OAuth error:", error);
163
+ }}
164
+
165
+ // Check if user is already logged in from localStorage
166
+ const storedUser = localStorage.getItem("hf_user");
167
+ if (storedUser) {{
168
+ try {{
169
+ const userInfo = JSON.parse(storedUser);
170
+ document.getElementById("login-status").textContent = "Logged in as: " + userInfo.name;
171
+ document.getElementById("login-button").style.display = "none";
172
+ }} catch (e) {{
173
+ console.error("Error parsing stored user:", e);
174
+ }}
175
+ }}
176
+
177
+ // Setup login button
178
+ document.getElementById("login-button").addEventListener("click", async function() {{
179
+ try {{
180
+ const loginUrl = await HfHub.oauthLoginUrl({{
181
+ redirectUrl: "{redirect_uri}",
182
+ scopes: ["openid", "profile"]
183
+ }});
184
+ window.location.href = loginUrl;
185
+ }} catch (error) {{
186
+ console.error("Error generating login URL:", error);
187
+ alert("Error starting login process. Please try again.");
188
+ }}
189
+ }});
190
+ }})();
191
+ </script>
192
+ """
193
+
194
  # Simple manual authentication check
195
  def check_user(request: gr.Request):
196
  if request:
 
205
  is_admin = (username == "Quazim0t0")
206
  db.add_user(username, username, is_admin)
207
  user = db.get_user_by_username(username)
208
+ return username
209
+ return None
210
 
211
  # Start evaluation queue worker
212
  def start_queue_worker():
 
220
 
221
  # Create Gradio app
222
  with gr.Blocks(css=css, title="Dynamic Highscores") as app:
223
+ # State to track user
224
+ user_state = gr.State(None)
225
+
226
+ # Login section
227
  with gr.Row(elem_classes=["login-section"]):
228
+ with gr.Column():
229
+ gr.HTML("""
230
+ <div style="display: flex; justify-content: space-between; align-items: center;">
231
+ <div id="login-status">Not logged in</div>
232
+ <button id="login-button" style="padding: 8px 16px; background-color: #4CAF50; color: white; border: none; border-radius: 4px; cursor: pointer;">Login with HuggingFace</button>
233
+ </div>
234
+ """)
235
+
236
+ # Add the JS login script
237
+ gr.HTML(js_login_script())
238
 
239
  gr.Markdown("# 🏆 Dynamic Highscores", elem_classes=["header"])
240
  gr.Markdown("""
 
271
  app.load(
272
  fn=check_user,
273
  inputs=[],
274
+ outputs=[user_state]
275
  )
276
 
277
+ # Launch the app
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
278
  if __name__ == "__main__":
279
+ # Start queue worker in a separate thread
280
  queue_thread = threading.Thread(target=start_queue_worker)
281
  queue_thread.daemon = True
282
+ queue_thread.start()
283
+
284
+ app.launch()