lightmate commited on
Commit
ea1c959
·
verified ·
1 Parent(s): 1ebb565

Delete app.py

Browse files
Files changed (1) hide show
  1. app.py +0 -913
app.py DELETED
@@ -1,913 +0,0 @@
1
- """
2
- DGaze - Simplified Auth0 + Gradio Implementation
3
- Based on proven patterns from successful implementations.
4
- """
5
-
6
- import os
7
- import gradio as gr
8
- import uvicorn
9
- import time
10
- import uuid
11
- from fastapi import FastAPI, Request, Depends
12
- from fastapi.responses import RedirectResponse, FileResponse
13
- from starlette.middleware.sessions import SessionMiddleware
14
- from urllib.parse import quote_plus, urlencode
15
- from starlette.config import Config
16
- from authlib.integrations.starlette_client import OAuth, OAuthError
17
-
18
- # Import our modular components
19
- from config.settings import settings
20
- from api.client import api_client
21
- from components.verification_result import format_verification_results
22
-
23
- # Create FastAPI app
24
- app = FastAPI(title="DGaze - News Verification")
25
-
26
- # Add CORS middleware for better API access
27
- from fastapi.middleware.cors import CORSMiddleware
28
- app.add_middleware(
29
- CORSMiddleware,
30
- allow_origins=["*"], # In production, this should be more restrictive
31
- allow_credentials=True,
32
- allow_methods=["*"],
33
- allow_headers=["*"],
34
- )
35
-
36
- # Static files handler to fix 404 errors with Gradio assets
37
- @app.get("/assets/{path:path}")
38
- async def get_assets(path: str):
39
- """Handle asset requests that might be missing when Gradio is mounted."""
40
- # Try to serve from demo assets first
41
- demo_asset_path = f"/demo/assets/{path}"
42
- return RedirectResponse(url=demo_asset_path)
43
-
44
- # Configure OAuth
45
- config_data = {
46
- 'AUTH0_CLIENT_ID': settings.AUTH0_CLIENT_ID,
47
- 'AUTH0_CLIENT_SECRET': settings.AUTH0_CLIENT_SECRET
48
- }
49
- starlette_config = Config(environ=config_data)
50
- oauth = OAuth(starlette_config)
51
-
52
- oauth.register(
53
- "auth0",
54
- client_id=settings.AUTH0_CLIENT_ID,
55
- client_secret=settings.AUTH0_CLIENT_SECRET,
56
- client_kwargs={
57
- "scope": "openid profile email",
58
- },
59
- server_metadata_url=f'https://{settings.AUTH0_DOMAIN}/.well-known/openid-configuration',
60
- )
61
-
62
- # Add session middleware
63
- app.add_middleware(SessionMiddleware, secret_key=settings.SECRET_KEY)
64
-
65
- # Simple user dependency
66
- def get_user(request: Request):
67
- """Get current user from session."""
68
- user = request.session.get('user')
69
- if user:
70
- return user.get('name') or user.get('email', 'Unknown User')
71
- return None
72
-
73
- # Free trial management functions
74
- # In-memory trial tracking (since session data doesn't persist properly with mounted Gradio apps)
75
- trial_tracker = {}
76
- session_timestamps = {}
77
-
78
- def get_or_create_session_id(request: Request) -> str:
79
- """Get existing session ID or create a new one."""
80
- session_id = request.session.get('session_id')
81
- if not session_id:
82
- session_id = f"trial_{uuid.uuid4().hex[:12]}"
83
- request.session['session_id'] = session_id
84
- print(f"DEBUG: Created new session ID: {session_id}")
85
- return session_id
86
-
87
- def cleanup_old_sessions():
88
- """Clean up sessions older than 24 hours."""
89
- current_time = time.time()
90
- old_sessions = []
91
- for session_id, timestamp in session_timestamps.items():
92
- if current_time - timestamp > 86400: # 24 hours
93
- old_sessions.append(session_id)
94
-
95
- for session_id in old_sessions:
96
- trial_tracker.pop(session_id, None)
97
- session_timestamps.pop(session_id, None)
98
-
99
- if old_sessions:
100
- print(f"DEBUG: Cleaned up {len(old_sessions)} old sessions")
101
-
102
- def get_trial_count(request: Request) -> int:
103
- """Get current trial verification count from in-memory tracker."""
104
- session_id = get_or_create_session_id(request)
105
- cleanup_old_sessions() # Periodic cleanup
106
- count = trial_tracker.get(session_id, 0)
107
- print(f"DEBUG: get_trial_count() for session {session_id}: {count}")
108
- return count
109
-
110
- def increment_trial_count(request: Request) -> int:
111
- """Increment and return trial verification count."""
112
- session_id = get_or_create_session_id(request)
113
- current_count = trial_tracker.get(session_id, 0)
114
- new_count = current_count + 1
115
- trial_tracker[session_id] = new_count
116
- session_timestamps[session_id] = time.time() # Update timestamp
117
- print(f"DEBUG: increment_trial_count() for session {session_id}: {current_count} -> {new_count}")
118
- print(f"DEBUG: Trial tracker state: {dict(list(trial_tracker.items())[-3:])}") # Show last 3 for brevity
119
- return new_count
120
-
121
- def has_remaining_trials(request: Request) -> bool:
122
- """Check if user has remaining free trials."""
123
- remaining = get_trial_count(request) < 2
124
- print(f"DEBUG: has_remaining_trials() returning: {remaining}")
125
- return remaining
126
-
127
- # Authentication routes
128
- @app.get('/')
129
- def public(user: str = Depends(get_user), request: Request = None):
130
- # Check if this is an Auth0 callback (has code parameter)
131
- if request:
132
- query_params = dict(request.query_params)
133
- if 'code' in query_params and 'state' in query_params:
134
- # This is an Auth0 callback, redirect to auth handler
135
- return RedirectResponse(url=f'/auth?{request.url.query}')
136
-
137
- if user:
138
- # Authenticated user - go to full demo
139
- return RedirectResponse(url='/demo')
140
- else:
141
- # Unauthenticated user - go to free trial
142
- return RedirectResponse(url='/trial')
143
-
144
- @app.route('/login')
145
- async def login(request: Request):
146
- # Use root URL as redirect_uri to match React app pattern
147
- redirect_uri = f"http://localhost:{settings.GRADIO_SERVER_PORT}/"
148
- return await oauth.auth0.authorize_redirect(request, redirect_uri)
149
-
150
- @app.route('/logout')
151
- async def logout(request: Request):
152
- # Clean up trial data
153
- session_id = request.session.get('session_id')
154
- if session_id:
155
- trial_tracker.pop(session_id, None)
156
- session_timestamps.pop(session_id, None)
157
- print(f"DEBUG: Cleaned up trial data for session {session_id}")
158
-
159
- request.session.pop('user', None)
160
- request.session.pop('session_id', None)
161
- return RedirectResponse(url=
162
- "https://"
163
- + settings.AUTH0_DOMAIN
164
- + "/v2/logout?"
165
- + urlencode(
166
- {
167
- "returnTo": f"http://localhost:{settings.GRADIO_SERVER_PORT}/",
168
- "client_id": settings.AUTH0_CLIENT_ID,
169
- },
170
- quote_via=quote_plus,
171
- )
172
- )
173
-
174
- @app.route('/auth') # callback
175
- async def auth(request: Request):
176
- try:
177
- access_token = await oauth.auth0.authorize_access_token(request)
178
- userinfo = dict(access_token)["userinfo"]
179
- print(f"DEBUG: Auth successful, userinfo: {userinfo}") # Debug log
180
- request.session['user'] = userinfo
181
- print(f"DEBUG: Session after setting user: {dict(request.session)}") # Debug log
182
- return RedirectResponse(url='/')
183
- except OAuthError as e:
184
- print(f"DEBUG: Auth error: {e}") # Debug log
185
- return RedirectResponse(url='/')
186
-
187
- @app.get('/api/user')
188
- async def get_user_info(request: Request):
189
- """API endpoint to get current user info for JavaScript."""
190
- print(f"DEBUG: /api/user endpoint called!")
191
- print(f"DEBUG: Request headers: {dict(request.headers)}")
192
- print(f"DEBUG: Request cookies: {request.cookies}")
193
- user = request.session.get('user')
194
- print(f"DEBUG: Session user data: {user}") # Debug log
195
- print(f"DEBUG: All session data: {dict(request.session)}") # Debug log
196
- if user:
197
- user_response = {
198
- "authenticated": True,
199
- "user": {
200
- "name": user.get('name'),
201
- "email": user.get('email'),
202
- "picture": user.get('picture')
203
- }
204
- }
205
- print(f"DEBUG: Returning user response: {user_response}")
206
- return user_response
207
- else:
208
- print("DEBUG: No user found in session")
209
- return {"authenticated": False}
210
-
211
- # Enhanced verification function with trial tracking
212
- def verify_news_with_trial_check(input_text: str, request: gr.Request) -> str:
213
- """Verification function with free trial tracking."""
214
- if not input_text.strip():
215
- return "Please enter some text or URL to verify"
216
-
217
- try:
218
- # Debug logging for session tracking
219
- print(f"DEBUG: Request type: {type(request)}")
220
- print(f"DEBUG: Request attributes: {dir(request)}")
221
-
222
- # Get the FastAPI request object from Gradio request
223
- fastapi_request = None
224
- if hasattr(request, 'request'):
225
- fastapi_request = request.request
226
- elif hasattr(request, 'fastapi_request'):
227
- fastapi_request = request.fastapi_request
228
- else:
229
- print(f"DEBUG: Cannot find FastAPI request in Gradio request object")
230
- # Fallback - proceed without trial tracking for now
231
- data = api_client.verify_news(input_text)
232
- result = format_verification_results(data)
233
- return f"""
234
- <div style="background: #fff3cd; border: 1px solid #ffeaa7; padding: 1rem; margin: 1rem 0; border-radius: 4px;">
235
- <p style="margin: 0; color: #856404; font-size: 0.9rem;">
236
- ⚠️ Session tracking unavailable. Please sign in for full functionality.
237
- <a href="/login" style="color: #856404; text-decoration: underline;">Sign in here</a>
238
- </p>
239
- </div>
240
- """ + result
241
-
242
- print(f"DEBUG: FastAPI request found: {fastapi_request is not None}")
243
-
244
- if fastapi_request:
245
- # Check current trial count
246
- current_count = get_trial_count(fastapi_request)
247
- print(f"DEBUG: Current trial count: {current_count}")
248
- print(f"DEBUG: Session data: {dict(fastapi_request.session)}")
249
-
250
- # Check if user is authenticated
251
- user = get_user(fastapi_request)
252
- print(f"DEBUG: User authenticated: {user is not None}")
253
-
254
- if not user:
255
- # For non-authenticated users, check trial limits
256
- if current_count >= 2: # Changed from has_remaining_trials to direct check
257
- print(f"DEBUG: Trial limit reached, showing sign-in prompt")
258
- # Redirect to sign up page
259
- return """
260
- <div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
261
- padding: 2rem; border-radius: 12px; color: white; text-align: center;
262
- box-shadow: 0 10px 25px rgba(0,0,0,0.1);">
263
- <h2 style="margin: 0 0 1rem 0; font-size: 1.5rem; color: white !important;">🔐 Please Sign In for More Searches</h2>
264
- <p style="margin: 0 0 1.5rem 0; opacity: 0.9; color: white !important;">
265
- You've used your 2 free verifications! Sign in to continue using DGaze with unlimited access.
266
- </p>
267
- <a href="/login" style="
268
- display: inline-block;
269
- background-color: #4f46e5;
270
- color: white !important;
271
- padding: 12px 30px;
272
- text-decoration: none;
273
- border-radius: 8px;
274
- font-weight: 600;
275
- transition: all 0.3s ease;
276
- box-shadow: 0 4px 12px rgba(0,0,0,0.2);
277
- " onmouseover="this.style.backgroundColor='#4338ca'; this.style.transform='translateY(-2px)'"
278
- onmouseout="this.style.backgroundColor='#4f46e5'; this.style.transform='translateY(0)'">
279
- 🚀 Sign In Now
280
- </a>
281
- <p style="margin: 1.5rem 0 0 0; font-size: 0.9rem; opacity: 0.8; color: white !important;">
282
- Free • Secure • No spam
283
- </p>
284
- </div>
285
- """
286
-
287
- # Increment trial count for non-authenticated users
288
- new_count = increment_trial_count(fastapi_request)
289
- remaining = 2 - new_count
290
- print(f"DEBUG: Incremented trial count to: {new_count}, remaining: {remaining}")
291
-
292
- # Proceed with verification
293
- data = api_client.verify_news(input_text)
294
- result = format_verification_results(data)
295
-
296
- # Add trial info for non-authenticated users
297
- trial_info = f"""
298
- <div style="background: #e3f2fd; border-left: 4px solid #2196f3; padding: 1rem; margin: 1rem 0; border-radius: 4px;">
299
- <p style="margin: 0; color: #1565c0; font-size: 0.9rem;">
300
- ⚡ Free Trial: <strong>{remaining} verification{'s' if remaining != 1 else ''} remaining</strong>
301
- {' • <a href="/login" style="color: #1565c0; text-decoration: underline;">Sign in for unlimited access</a>' if remaining > 0 else ''}
302
- </p>
303
- </div>
304
- """
305
- result = trial_info + result
306
- return result
307
- else:
308
- # Authenticated user - proceed normally
309
- data = api_client.verify_news(input_text)
310
- return format_verification_results(data)
311
- else:
312
- # Fallback if we can't access session
313
- data = api_client.verify_news(input_text)
314
- return format_verification_results(data)
315
-
316
- except Exception as e:
317
- print(f"DEBUG: Error in verify_news_with_trial_check: {e}")
318
- return f"Error: {str(e)}"
319
-
320
- # Regular verification function for authenticated users
321
- def verify_news(input_text: str) -> str:
322
- """Main verification function for authenticated users."""
323
- if not input_text.strip():
324
- return "Please enter some text or URL to verify"
325
-
326
- try:
327
- data = api_client.verify_news(input_text)
328
- return format_verification_results(data)
329
- except Exception as e:
330
- return f"Error: {str(e)}"
331
-
332
- # Gradio interfaces
333
- def create_trial_interface():
334
- """Create free trial interface for non-authenticated users."""
335
- with gr.Blocks(
336
- title="DGaze - Free Trial",
337
- css="""
338
- /* White theme - full width design */
339
- html, body {
340
- background-color: white !important;
341
- margin: 0 !important;
342
- padding: 0 !important;
343
- }
344
-
345
- .gradio-container {
346
- background-color: white !important;
347
- max-width: none !important;
348
- margin: 0 !important;
349
- padding: 20px !important;
350
- min-height: 100vh !important;
351
- }
352
-
353
- .main {
354
- background-color: white !important;
355
- max-width: 1200px !important;
356
- margin: 0 auto !important;
357
- padding: 0 20px !important;
358
- }
359
-
360
- /* Block elements */
361
- .block {
362
- background-color: white !important;
363
- }
364
-
365
- .block.padded {
366
- background-color: white !important;
367
- }
368
-
369
- /* Trial banner styling */
370
- .trial-banner {
371
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
372
- color: white !important;
373
- padding: 1.5rem !important;
374
- border-radius: 12px !important;
375
- margin-bottom: 2rem !important;
376
- box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1) !important;
377
- text-align: center !important;
378
- }
379
-
380
- /* Ensure all text in trial banner is white */
381
- .trial-banner h1,
382
- .trial-banner h2,
383
- .trial-banner h3,
384
- .trial-banner h4,
385
- .trial-banner h5,
386
- .trial-banner h6,
387
- .trial-banner p,
388
- .trial-banner span,
389
- .trial-banner div {
390
- color: white !important;
391
- }
392
-
393
- /* Input styling - white background, dark text */
394
- .gr-textbox, .gr-text-input, textarea {
395
- background-color: white !important;
396
- border: 1px solid #e0e0e0 !important;
397
- color: #212529 !important;
398
- border-radius: 8px !important;
399
- }
400
-
401
- .gr-textbox input, .gr-textbox textarea {
402
- background-color: white !important;
403
- color: #212529 !important;
404
- border: 1px solid #e0e0e0 !important;
405
- }
406
-
407
- /* Focus states */
408
- .gr-textbox:focus-within, textarea:focus, input:focus {
409
- border-color: #4263eb !important;
410
- outline: none !important;
411
- box-shadow: 0 0 0 2px rgba(66, 99, 235, 0.1) !important;
412
- }
413
-
414
- /* Button styling */
415
- .gr-button {
416
- background-color: #4263eb !important;
417
- color: white !important;
418
- border: none !important;
419
- border-radius: 8px !important;
420
- }
421
-
422
- .gr-button:hover {
423
- background-color: #364fc7 !important;
424
- }
425
-
426
- /* Form containers */
427
- .gr-form {
428
- background-color: #f8f9fa !important;
429
- border: 1px solid #e9ecef !important;
430
- border-radius: 8px !important;
431
- padding: 16px !important;
432
- }
433
-
434
- /* Examples styling */
435
- .gr-examples {
436
- background-color: #f8f9fa !important;
437
- border: 1px solid #e9ecef !important;
438
- border-radius: 8px !important;
439
- padding: 16px !important;
440
- }
441
-
442
- /* Labels and text */
443
- label, .gr-form label {
444
- color: #212529 !important;
445
- font-weight: 500 !important;
446
- }
447
-
448
- /* Ensure proper text contrast everywhere */
449
- p, span, div, h1, h2, h3, h4, h5, h6 {
450
- color: #212529 !important;
451
- }
452
-
453
- /* Output HTML container */
454
- .gr-html {
455
- background-color: white !important;
456
- }
457
-
458
- /* Main title styling */
459
- .main-title {
460
- color: #212529 !important;
461
- text-align: center !important;
462
- font-size: 3rem !important;
463
- font-weight: 800 !important;
464
- margin: 2rem 0 0.5rem 0 !important;
465
- }
466
-
467
- /* Subtitle styling */
468
- .subtitle {
469
- text-align: center !important;
470
- color: #495057 !important;
471
- font-size: 1.2rem !important;
472
- margin-top: 0 !important;
473
- margin-bottom: 2rem !important;
474
- }
475
- """
476
- ) as demo:
477
- # Trial banner
478
- gr.HTML("""
479
- <div class="trial-banner">
480
- <h2 style="margin: 0 0 0.5rem 0; font-size: 1.8rem; font-weight: bold; color: white !important;">🚀 Free Trial - DGaze</h2>
481
- <p style="margin: 0; opacity: 0.9; font-size: 1.1rem; color: white !important;">Try our news verification system with 2 free searches!</p>
482
- <p style="margin: 0.5rem 0 0 0; font-size: 0.9rem; opacity: 0.8; color: white !important;">No signup required • Sign in for unlimited access</p>
483
- </div>
484
- """)
485
-
486
- # Main title
487
- gr.HTML('<h1 class="main-title">DGaze</h1>')
488
- gr.HTML('<p class="subtitle">Advanced News Verification System</p>')
489
-
490
- # Auth options
491
- with gr.Row():
492
- with gr.Column():
493
- gr.HTML("""
494
- <div style="text-align: center; margin: 1rem 0;">
495
- <a href="/login" style="
496
- display: inline-block;
497
- background-color: #4263eb;
498
- color: white;
499
- padding: 12px 24px;
500
- text-decoration: none;
501
- border-radius: 8px;
502
- font-weight: 600;
503
- margin-right: 1rem;
504
- transition: all 0.3s ease;
505
- " onmouseover="this.style.backgroundColor='#364fc7'"
506
- onmouseout="this.style.backgroundColor='#4263eb'">
507
- 🔐 Sign In for Unlimited Access
508
- </a>
509
- <span style="color: #6c757d; font-size: 0.9rem;">or continue with free trial below</span>
510
- </div>
511
- """)
512
-
513
- # Main interface
514
- with gr.Column():
515
- input_text = gr.Textbox(
516
- label="Enter news text or URL to verify",
517
- placeholder="Paste news text to verify...",
518
- lines=5,
519
- max_lines=10
520
- )
521
-
522
- submit_btn = gr.Button("Check Truthfulness (Free Trial)", variant="primary")
523
-
524
- with gr.Column():
525
- output_html = gr.HTML(label="Verification Results", visible=True)
526
-
527
- # Handle submission with trial tracking
528
- submit_btn.click(fn=verify_news_with_trial_check, inputs=input_text, outputs=output_html)
529
- input_text.submit(fn=verify_news_with_trial_check, inputs=input_text, outputs=output_html)
530
-
531
- # Examples
532
- gr.Examples(
533
- examples=[
534
- ["""BREAKING: Revolutionary AI breakthrough! 🚀 Scientists at MIT have developed a new quantum AI system that can predict earthquakes with 99.7% accuracy up to 6 months in advance. The system, called "QuakeNet AI", uses quantum computing combined with machine learning to analyze seismic patterns invisible to current technology. Dr. Sarah Chen, lead researcher, claims this could save millions of lives and prevent billions in damages. The technology will be commercially available by 2026 according to insider sources. This comes just weeks after similar breakthroughs in cancer detection AI. What do you think about this amazing discovery? #AI #Earthquake #MIT #Science"""],
535
- ["""SpaceX conducted another major test for their Starship program yesterday, with Elon Musk claiming on social media that Flight 10 is "ready to revolutionize space travel forever." The company fired up all 33 Raptor engines on their Super Heavy booster at the Starbase facility in Texas. According to various reports and this detailed article (https://www.space.com/space-exploration/launches-spacecraft/spacex-fires-up-super-heavy-booster-ahead-of-starships-10th-test-flight-video), the test was part of preparations for the upcoming 10th test flight. However, some critics argue that SpaceX is moving too fast without proper safety protocols, especially after Flight 9 experienced issues. The FAA is still investigating the previous mission where both the booster and ship were lost. Industry experts remain divided on whether this aggressive testing schedule is beneficial or dangerous for the future of commercial spaceflight. 🚀 #SpaceX #Starship #Space"""]
536
- ],
537
- inputs=[input_text]
538
- )
539
-
540
- return demo
541
-
542
- def create_login_interface():
543
- """Create login page interface."""
544
- with gr.Blocks(
545
- title="DGaze - Login",
546
- css="""
547
- /* White theme - full width design */
548
- html, body {
549
- background-color: white !important;
550
- margin: 0 !important;
551
- padding: 0 !important;
552
- }
553
-
554
- .gradio-container {
555
- max-width: none !important;
556
- width: 100% !important;
557
- margin: 0 !important;
558
- padding: 0 !important;
559
- background-color: white !important;
560
- min-height: 100vh !important;
561
- display: flex !important;
562
- align-items: center !important;
563
- justify-content: center !important;
564
- }
565
-
566
- .login-card {
567
- background: #f8f9fa !important;
568
- border-radius: 12px !important;
569
- box-shadow: 0 4px 20px rgba(0,0,0,0.1) !important;
570
- padding: 3rem !important;
571
- text-align: center !important;
572
- border: 1px solid #e9ecef !important;
573
- width: 100% !important;
574
- max-width: 500px !important;
575
- margin: 2rem !important;
576
- }
577
-
578
- /* Ensure all text is visible */
579
- h1, h2, h3, h4, h5, h6, p, span, div, label {
580
- color: #212529 !important;
581
- }
582
- """
583
- ) as demo:
584
- gr.HTML("""
585
- <div class="login-card">
586
- <div style="margin-bottom: 2rem;">
587
- <h1 style="color: #212529; margin-bottom: 1rem; font-size: 2.5rem; font-weight: bold;">🔐 DGaze</h1>
588
- <p style="color: #495057; font-size: 1.2rem; margin-bottom: 0.5rem;">News Verification System</p>
589
- <p style="color: #6c757d;">Sign in for unlimited verifications</p>
590
- </div>
591
-
592
- <div style="margin: 2rem 0;">
593
- <a href="/login" style="
594
- display: inline-block;
595
- background-color: #4263eb;
596
- color: white;
597
- padding: 15px 40px;
598
- text-decoration: none;
599
- border-radius: 8px;
600
- font-weight: 600;
601
- font-size: 1.1rem;
602
- transition: all 0.3s ease;
603
- box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
604
- " onmouseover="this.style.backgroundColor='#364fc7'; this.style.transform='translateY(-1px)'"
605
- onmouseout="this.style.backgroundColor='#4263eb'; this.style.transform='translateY(0)'">
606
- 🚀 Login with Auth0
607
- </a>
608
- </div>
609
-
610
- <div style="margin: 1.5rem 0;">
611
- <p style="color: #6c757d; font-size: 0.9rem;">Or try our free version:</p>
612
- <a href="/trial" style="
613
- color: #4263eb;
614
- text-decoration: underline;
615
- font-weight: 500;
616
- ">
617
- Continue with 2 Free Verifications
618
- </a>
619
- </div>
620
-
621
- <p style="color: #6c757d; font-size: 0.9rem; margin-top: 1rem;">
622
- Powered by Auth0 • Secure & Private
623
- </p>
624
- </div>
625
- """)
626
- return demo
627
-
628
- def create_main_interface():
629
- """Create main authenticated interface."""
630
- with gr.Blocks(
631
- title="DGaze - News Verification",
632
- css="""
633
- /* White theme - keeping original format */
634
- html, body {
635
- background-color: white !important;
636
- margin: 0 !important;
637
- padding: 0 !important;
638
- }
639
-
640
- .gradio-container {
641
- background-color: white !important;
642
- max-width: none !important;
643
- margin: 0 !important;
644
- padding: 20px !important;
645
- min-height: 100vh !important;
646
- }
647
-
648
- .main {
649
- background-color: white !important;
650
- max-width: 1200px !important;
651
- margin: 0 auto !important;
652
- padding: 0 20px !important;
653
- }
654
-
655
- /* Block elements */
656
- .block {
657
- background-color: white !important;
658
- }
659
-
660
- .block.padded {
661
- background-color: white !important;
662
- }
663
-
664
- /* User info section - keeping original format but white */
665
- .user-info {
666
- background: #f8f9fa !important;
667
- color: #212529 !important;
668
- padding: 1.5rem !important;
669
- border-radius: 12px !important;
670
- margin-bottom: 2rem !important;
671
- box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1) !important;
672
- border: 1px solid #e9ecef !important;
673
- }
674
-
675
- /* Input styling - white background, dark text */
676
- .gr-textbox, .gr-text-input, textarea {
677
- background-color: white !important;
678
- border: 1px solid #e0e0e0 !important;
679
- color: #212529 !important;
680
- border-radius: 8px !important;
681
- }
682
-
683
- .gr-textbox input, .gr-textbox textarea {
684
- background-color: white !important;
685
- color: #212529 !important;
686
- border: 1px solid #e0e0e0 !important;
687
- }
688
-
689
- /* Ensure textarea content is visible */
690
- textarea, input[type="text"] {
691
- background-color: white !important;
692
- color: #212529 !important;
693
- border: 1px solid #e0e0e0 !important;
694
- }
695
-
696
- /* Focus states */
697
- .gr-textbox:focus-within, textarea:focus, input:focus {
698
- border-color: #4263eb !important;
699
- outline: none !important;
700
- box-shadow: 0 0 0 2px rgba(66, 99, 235, 0.1) !important;
701
- }
702
-
703
- /* Button styling */
704
- .gr-button {
705
- background-color: #4263eb !important;
706
- color: white !important;
707
- border: none !important;
708
- border-radius: 8px !important;
709
- }
710
-
711
- .gr-button:hover {
712
- background-color: #364fc7 !important;
713
- }
714
-
715
- .gr-button[variant="secondary"] {
716
- background-color: #6b7280 !important;
717
- color: white !important;
718
- }
719
-
720
- .gr-button[variant="secondary"]:hover {
721
- background-color: #4b5563 !important;
722
- }
723
-
724
- /* Form containers */
725
- .gr-form {
726
- background-color: #f8f9fa !important;
727
- border: 1px solid #e9ecef !important;
728
- border-radius: 8px !important;
729
- padding: 16px !important;
730
- }
731
-
732
- /* Examples styling */
733
- .gr-examples {
734
- background-color: #f8f9fa !important;
735
- border: 1px solid #e9ecef !important;
736
- border-radius: 8px !important;
737
- padding: 16px !important;
738
- }
739
-
740
- /* Labels and text */
741
- label, .gr-form label {
742
- color: #212529 !important;
743
- font-weight: 500 !important;
744
- }
745
-
746
- /* Ensure proper text contrast everywhere */
747
- p, span, div, h1, h2, h3, h4, h5, h6 {
748
- color: #212529 !important;
749
- }
750
-
751
- /* Output HTML container */
752
- .gr-html {
753
- background-color: white !important;
754
- }
755
-
756
- /* Main title styling - keeping original format */
757
- .main-title {
758
- color: #212529 !important;
759
- text-align: center !important;
760
- font-size: 3rem !important;
761
- font-weight: 800 !important;
762
- margin: 2rem 0 0.5rem 0 !important;
763
- }
764
-
765
- /* Subtitle styling */
766
- .subtitle {
767
- text-align: center !important;
768
- color: #495057 !important;
769
- font-size: 1.2rem !important;
770
- margin-top: 0 !important;
771
- margin-bottom: 2rem !important;
772
- }
773
- """
774
- ) as demo:
775
- # User info section - load user data server-side using our existing get_user function
776
- def format_user_info(request: gr.Request):
777
- """Format user info HTML based on current user session"""
778
- try:
779
- # Use our existing user detection logic
780
- user_name = get_user(request.request) if hasattr(request, 'request') else None
781
- print(f"DEBUG: Gradio user detection result: {user_name}")
782
-
783
- if user_name:
784
- return f"""
785
- <div class="user-info" id="user-section">
786
- <div style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap;">
787
- <div style="flex: 1;">
788
- <h3 style="margin: 0; font-size: 1.3rem; color: #212529;">👋 Welcome!</h3>
789
- <p style="margin: 5px 0 0 0; color: #495057; font-size: 1rem;">Hello, {user_name}! Unlimited verifications available 🎉</p>
790
- </div>
791
- <div style="margin-top: 10px;">
792
- <a href="/logout" style="
793
- background-color: #dc3545;
794
- color: white;
795
- padding: 10px 20px;
796
- text-decoration: none;
797
- border-radius: 8px;
798
- font-size: 0.95rem;
799
- font-weight: 500;
800
- transition: background-color 0.3s ease;
801
- " onmouseover="this.style.backgroundColor='#c82333'"
802
- onmouseout="this.style.backgroundColor='#dc3545'">
803
- Logout
804
- </a>
805
- </div>
806
- </div>
807
- </div>
808
- """
809
- else:
810
- return """
811
- <div class="user-info" id="user-section">
812
- <div style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap;">
813
- <div style="flex: 1;">
814
- <h3 style="margin: 0; font-size: 1.3rem; color: #212529;">👋 Welcome!</h3>
815
- <p style="margin: 5px 0 0 0; color: #495057; font-size: 1rem;">Please log in to continue</p>
816
- </div>
817
- <div style="margin-top: 10px;">
818
- <a href="/logout" style="
819
- background-color: #dc3545;
820
- color: white;
821
- padding: 10px 20px;
822
- text-decoration: none;
823
- border-radius: 8px;
824
- font-size: 0.95rem;
825
- font-weight: 500;
826
- transition: background-color 0.3s ease;
827
- ">
828
- Logout
829
- </a>
830
- </div>
831
- </div>
832
- </div>
833
- """
834
- except Exception as e:
835
- print(f"DEBUG: Error formatting user info: {e}")
836
- return """
837
- <div class="user-info" id="user-section">
838
- <div style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap;">
839
- <div style="flex: 1;">
840
- <h3 style="margin: 0; font-size: 1.3rem; color: #212529;">👋 Welcome!</h3>
841
- <p style="margin: 5px 0 0 0; color: #495057; font-size: 1rem;">Loading user info...</p>
842
- </div>
843
- <div style="margin-top: 10px;">
844
- <a href="/logout" style="
845
- background-color: #dc3545;
846
- color: white;
847
- padding: 10px 20px;
848
- text-decoration: none;
849
- border-radius: 8px;
850
- font-size: 0.95rem;
851
- font-weight: 500;
852
- ">
853
- Logout
854
- </a>
855
- </div>
856
- </div>
857
- </div>
858
- """
859
-
860
- user_info_html = gr.HTML()
861
- demo.load(format_user_info, None, user_info_html)
862
-
863
- # Main title - keeping original format
864
- gr.HTML('<h1 class="main-title">DGaze</h1>')
865
- gr.HTML('<p class="subtitle">Advanced News Verification System - Unlimited Access</p>')
866
-
867
- # Main interface - keeping original format
868
- with gr.Column():
869
- input_text = gr.Textbox(
870
- label="Enter news text or URL to verify",
871
- placeholder="Paste news text to verify...",
872
- lines=5,
873
- max_lines=10
874
- )
875
-
876
- submit_btn = gr.Button("Check Truthfulness", variant="primary")
877
-
878
- with gr.Column():
879
- output_html = gr.HTML(label="Verification Results", visible=True)
880
-
881
- # Handle submission
882
- submit_btn.click(fn=verify_news, inputs=input_text, outputs=output_html)
883
- input_text.submit(fn=verify_news, inputs=input_text, outputs=output_html)
884
-
885
- # Examples - keeping original format
886
- gr.Examples(
887
- examples=[
888
- ["""BREAKING: Revolutionary AI breakthrough! 🚀 Scientists at MIT have developed a new quantum AI system that can predict earthquakes with 99.7% accuracy up to 6 months in advance. The system, called "QuakeNet AI", uses quantum computing combined with machine learning to analyze seismic patterns invisible to current technology. Dr. Sarah Chen, lead researcher, claims this could save millions of lives and prevent billions in damages. The technology will be commercially available by 2026 according to insider sources. This comes just weeks after similar breakthroughs in cancer detection AI. What do you think about this amazing discovery? #AI #Earthquake #MIT #Science"""],
889
- ["""SpaceX conducted another major test for their Starship program yesterday, with Elon Musk claiming on social media that Flight 10 is "ready to revolutionize space travel forever." The company fired up all 33 Raptor engines on their Super Heavy booster at the Starbase facility in Texas. According to various reports and this detailed article (https://www.space.com/space-exploration/launches-spacecraft/spacex-fires-up-super-heavy-booster-ahead-of-starships-10th-test-flight-video), the test was part of preparations for the upcoming 10th test flight. However, some critics argue that SpaceX is moving too fast without proper safety protocols, especially after Flight 9 experienced issues. The FAA is still investigating the previous mission where both the booster and ship were lost. Industry experts remain divided on whether this aggressive testing schedule is beneficial or dangerous for the future of commercial spaceflight. 🚀 #SpaceX #Starship #Space"""]
890
- ],
891
- inputs=[input_text]
892
- )
893
-
894
- return demo
895
-
896
- if __name__ == "__main__":
897
- # Create interfaces
898
- trial_demo = create_trial_interface()
899
- login_demo = create_login_interface()
900
- main_demo = create_main_interface()
901
-
902
- # Mount Gradio apps
903
- gr.mount_gradio_app(app, trial_demo, path="/trial")
904
- gr.mount_gradio_app(app, login_demo, path="/login-page")
905
- gr.mount_gradio_app(app, main_demo, path="/demo")
906
-
907
- # Run the application
908
- uvicorn.run(
909
- app,
910
- host=settings.GRADIO_SERVER_NAME,
911
- port=settings.GRADIO_SERVER_PORT,
912
- reload=False
913
- )