noumanjavaid commited on
Commit
3e8fb84
Β·
verified Β·
1 Parent(s): 55e4136

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +201 -106
app.py CHANGED
@@ -1,42 +1,29 @@
1
  import gradio as gr
2
  import logging
3
  import traceback
 
 
 
 
 
 
4
 
5
- # Logging configuration
 
 
 
6
  logging.basicConfig(
7
  level=logging.INFO,
8
- format='%(asctime)s - %(levelname)s: %(message)s',
9
  handlers=[
10
- logging.FileHandler('centurion_platform.log'),
11
  logging.StreamHandler()
12
  ]
13
  )
14
  logger = logging.getLogger(__name__)
15
 
16
- # CSS with validation
17
- def validate_css(css):
18
- """
19
- Basic CSS validation
20
- """
21
- required_selectors = [
22
- '.header',
23
- '.logo',
24
- '.header-title',
25
- '.container',
26
- '.main-content',
27
- '.iframe-container',
28
- '.nav-grid',
29
- '.nav-card'
30
- ]
31
-
32
- for selector in required_selectors:
33
- if selector not in css:
34
- logger.warning(f"Missing CSS selector: {selector}")
35
-
36
- return css
37
-
38
- # CSS with enhanced validation
39
- css = validate_css("""
40
  * {
41
  margin: 0;
42
  padding: 0;
@@ -124,12 +111,109 @@ body {
124
  grid-template-columns: 1fr;
125
  }
126
  }
127
- """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
 
129
- # Configuration validation
130
- def validate_configuration(demo_config):
 
 
131
  """
132
- Validate Gradio configuration
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
  """
134
  required_attributes = [
135
  'title',
@@ -145,7 +229,7 @@ def validate_configuration(demo_config):
145
  validation_results = {}
146
  for attr in required_attributes:
147
  try:
148
- value = getattr(demo_config, attr, None)
149
  validation_results[attr] = value is not None
150
  except Exception as e:
151
  logger.error(f"Error validating {attr}: {e}")
@@ -153,88 +237,99 @@ def validate_configuration(demo_config):
153
 
154
  return validation_results
155
 
156
- # Navigation cards validation
157
- def validate_navigation_cards(cards):
158
  """
159
- Validate navigation card configuration
160
  """
161
- required_keys = ['icon', 'title', 'url']
162
- invalid_cards = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
 
164
- for card in cards:
165
- missing_keys = [key for key in required_keys if key not in card]
166
- if missing_keys:
167
- invalid_cards.append({
168
- 'card': card,
169
- 'missing_keys': missing_keys
170
- })
 
 
 
171
 
172
- return invalid_cards
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
 
174
- def create_demo():
175
- """
176
- Create Gradio demo with comprehensive validation
177
- """
178
  try:
179
- cards = [
180
- {"icon": "πŸ”", "title": "DeepFake Detection", "url": "https://noumanjavaid-new-space.hf.space"},
181
- {"icon": "πŸ“„", "title": "Document Analysis", "url": "https://noumanjavaid-centurionv2.hf.space"},
182
- {"icon": "πŸŽ₯", "title": "Video Watermarking", "url": "https://noumanjavaid-watermark-demo-video.hf.space"},
183
- {"icon": "πŸ”", "title": "Image Authentication", "url": "https://noumanjavaid-centii.hf.space"},
184
- ]
185
 
186
- # Validate navigation cards
187
- invalid_cards = validate_navigation_cards(cards)
188
- if invalid_cards:
189
- logger.warning(f"Invalid navigation cards: {invalid_cards}")
190
 
191
- # Generate HTML for navigation cards
192
- html_cards = "".join(
193
- f'''
194
- <div class="nav-card" role="navigation" aria-label="{card['title']}">
195
- <a href="{card['url']}" target="_blank">
196
- {card['icon']} {card['title']}
197
- </a>
198
- </div>
199
- ''' for card in cards
200
- )
201
-
202
- # Create Gradio block
203
- with gr.Blocks(css=css, title="Centurion Analysis Platform") as demo:
204
- # Header
205
- with gr.Row(elem_classes=["header"]):
206
- gr.Image(
207
- "https://raw.githubusercontent.com/noumanjavaid96/ai-as-an-api/refs/heads/master/image%20(39).png",
208
- elem_classes=["logo"],
209
- show_label=False,
210
- container=False
211
- )
212
- gr.Markdown("Centurion Analysis", elem_classes=["header-title"])
213
-
214
- # Main content
215
- with gr.Row(elem_classes=["container"]):
216
- with gr.Column(elem_classes=["main-content"]):
217
- gr.HTML('''
218
- <div class="iframe-container">
219
- <iframe
220
- src="https://noumanjavaid-centii.hf.space"
221
- loading="lazy"
222
- title="Centurion Main Platform"
223
- ></iframe>
224
- </div>
225
- ''')
226
-
227
- # Navigation grid
228
- with gr.Row(elem_classes=["nav-grid"]):
229
- gr.HTML(html_cards)
230
 
 
 
 
 
 
231
 
232
  if __name__ == "__main__":
233
- demo.launch(
234
- show_error=True,
235
- show_api=False,
236
- show_tips=False,
237
- height=800,
238
- analytics_enabled=False,
239
- enable_queue=False
240
- )
 
1
  import gradio as gr
2
  import logging
3
  import traceback
4
+ import time
5
+ import re
6
+ import os
7
+ from functools import wraps, lru_cache
8
+ from dotenv import load_dotenv
9
+ from urllib.parse import urlparse
10
 
11
+ # Load environment variables
12
+ load_dotenv()
13
+
14
+ # Enhanced logging configuration
15
  logging.basicConfig(
16
  level=logging.INFO,
17
+ format='%(asctime)s - %(levelname)s - %(message)s',
18
  handlers=[
19
+ logging.FileHandler('centurion_platform.log', encoding='utf-8', mode='a'),
20
  logging.StreamHandler()
21
  ]
22
  )
23
  logger = logging.getLogger(__name__)
24
 
25
+ # CSS Configuration
26
+ css = """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  * {
28
  margin: 0;
29
  padding: 0;
 
111
  grid-template-columns: 1fr;
112
  }
113
  }
114
+ """
115
+
116
+ # Performance and security decorators
117
+ def performance_monitor(func):
118
+ @wraps(func)
119
+ def wrapper(*args, **kwargs):
120
+ start = time.time()
121
+ try:
122
+ result = func(*args, **kwargs)
123
+ execution_time = time.time() - start
124
+ logger.info(f"{func.__name__} execution time: {execution_time:.2f} seconds")
125
+ return result
126
+ except Exception as e:
127
+ logger.error(f"Error in {func.__name__}: {e}")
128
+ logger.error(traceback.format_exc())
129
+ raise
130
+ return wrapper
131
+
132
+ # URL Validation and Sanitization
133
+ @lru_cache(maxsize=100)
134
+ def validate_and_sanitize_url(url):
135
+ """
136
+ Comprehensive URL validation and sanitization
137
+ """
138
+ try:
139
+ # Validate URL pattern
140
+ url_pattern = re.compile(
141
+ r'^https?://' # http:// or https://
142
+ r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?|' # domain...
143
+ r'localhost|' # localhost...
144
+ r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip
145
+ r'(?::\d+)?' # optional port
146
+ r'(?:/?|[/?]\S+)$', re.IGNORECASE)
147
+
148
+ if not url_pattern.match(url):
149
+ logger.warning(f"Invalid URL format: {url}")
150
+ return None
151
+
152
+ # Parse and validate URL
153
+ parsed_url = urlparse(url)
154
+
155
+ # Whitelist allowed domains
156
+ allowed_domains = [
157
+ 'noumanjavaid-new-space.hf.space',
158
+ 'noumanjavaid-centurionv2.hf.space',
159
+ 'noumanjavaid-watermark-demo-video.hf.space',
160
+ 'noumanjavaid-centii.hf.space',
161
+ 'localhost'
162
+ ]
163
+
164
+ if parsed_url.netloc not in allowed_domains:
165
+ logger.warning(f"Unauthorized domain: {parsed_url.netloc}")
166
+ return None
167
+
168
+ return url
169
+ except Exception as e:
170
+ logger.error(f"URL validation error: {e}")
171
+ return None
172
+
173
+ # Platform Configuration
174
+ PLATFORM_CONFIG = {
175
+ 'main_platform_url': os.getenv('MAIN_PLATFORM_URL', 'https://noumanjavaid-centii.hf.space'),
176
+ 'launch_config': {
177
+ 'show_error': True,
178
+ 'show_api': False,
179
+ 'show_tips': False,
180
+ 'height': 800,
181
+ 'analytics_enabled': False,
182
+ 'enable_queue': False,
183
+ 'prevent_thread_lock': True
184
+ }
185
+ }
186
 
187
+ # Error Notification (Optional)
188
+ def send_error_notification(error):
189
+ """
190
+ Send error notifications via external service
191
  """
192
+ try:
193
+ import requests
194
+
195
+ webhook_url = os.getenv('ERROR_WEBHOOK_URL')
196
+ if webhook_url:
197
+ payload = {
198
+ "text": f"🚨 Centurion Platform Error: {str(error)}",
199
+ "blocks": [
200
+ {
201
+ "type": "section",
202
+ "text": {
203
+ "type": "mrkdwn",
204
+ "text": f"```{traceback.format_exc()}```"
205
+ }
206
+ }
207
+ ]
208
+ }
209
+ requests.post(webhook_url, json=payload)
210
+ except Exception as log_error:
211
+ logger.error(f"Error sending notification: {log_error}")
212
+
213
+ # Configuration Validation
214
+ def validate_configuration(demo):
215
+ """
216
+ Validate Gradio demo configuration
217
  """
218
  required_attributes = [
219
  'title',
 
229
  validation_results = {}
230
  for attr in required_attributes:
231
  try:
232
+ value = getattr(demo, attr, None)
233
  validation_results[attr] = value is not None
234
  except Exception as e:
235
  logger.error(f"Error validating {attr}: {e}")
 
237
 
238
  return validation_results
239
 
240
+ @performance_monitor
241
+ def create_demo():
242
  """
243
+ Create Gradio demo with comprehensive validation
244
  """
245
+ # Navigation Cards with URL Validation
246
+ cards = [
247
+ {
248
+ "icon": "πŸ”",
249
+ "title": "DeepFake Detection",
250
+ "url": validate_and_sanitize_url(os.getenv('DEEPFAKE_URL', 'https://noumanjavaid-new-space.hf.space'))
251
+ },
252
+ {
253
+ "icon": "πŸ“„",
254
+ "title": "Document Analysis", "url": validate_and_sanitize_url(os.getenv('DOCUMENT_URL', 'https://noumanjavaid-centurionv2.hf.space'))
255
+ },
256
+ {
257
+ "icon": "πŸŽ₯",
258
+ "title": "Video Watermarking",
259
+ "url": validate_and_sanitize_url(os.getenv('WATERMARK_URL', 'https://noumanjavaid-watermark-demo-video.hf.space'))
260
+ },
261
+ {
262
+ "icon": "πŸ”",
263
+ "title": "Image Authentication",
264
+ "url": validate_and_sanitize_url(os.getenv('AUTH_URL', 'https://noumanjavaid-centii.hf.space'))
265
+ },
266
+ ]
267
+
268
+ # Validate navigation cards
269
+ invalid_cards = [card for card in cards if card['url'] is None]
270
+ if invalid_cards:
271
+ logger.warning(f"Invalid navigation card URLs: {invalid_cards}")
272
 
273
+ # Generate HTML for navigation cards
274
+ html_cards = "".join(
275
+ f'''
276
+ <div class="nav-card" role="navigation" aria-label="{card['title']}" tabindex="0">
277
+ <a href="{card['url']}" target="_blank" rel="noopener noreferrer">
278
+ {card['icon']} {card['title']}
279
+ </a>
280
+ </div>
281
+ ''' for card in cards if card['url'] is not None
282
+ )
283
 
284
+ # Create Gradio block
285
+ with gr.Blocks(css=css, title="Centurion Analysis Platform") as demo:
286
+ # Header
287
+ with gr.Row(elem_classes=["header"]):
288
+ gr.Image(
289
+ "https://raw.githubusercontent.com/noumanjavaid96/ai-as-an-api/refs/heads/master/image%20(39).png",
290
+ elem_classes=["logo"],
291
+ show_label=False,
292
+ container=False
293
+ )
294
+ gr.Markdown("Centurion Analysis", elem_classes=["header-title"])
295
+
296
+ # Main content
297
+ with gr.Row(elem_classes=["container"]):
298
+ with gr.Column(elem_classes=["main-content"]):
299
+ gr.HTML(f'''
300
+ <div class="iframe-container">
301
+ <iframe
302
+ src="{PLATFORM_CONFIG['main_platform_url']}"
303
+ loading="lazy"
304
+ title="Centurion Main Platform"
305
+ ></iframe>
306
+ </div>
307
+ ''')
308
+
309
+ # Navigation grid
310
+ with gr.Row(elem_classes=["nav-grid"]):
311
+ gr.HTML(html_cards)
312
 
313
+ return demo
314
+
315
+ def main():
 
316
  try:
317
+ demo = create_demo()
 
 
 
 
 
318
 
319
+ # Validate configuration before launching
320
+ config_validation = validate_configuration(demo)
321
+ logger.info(f"Configuration Validation: {config_validation}")
 
322
 
323
+ validation_errors = [k for k, v in config_validation.items() if not v]
324
+ if validation_errors:
325
+ logger.error(f"Configuration validation failed for: {validation_errors}")
326
+ raise ValueError(f"Invalid configuration: {validation_errors}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
327
 
328
+ demo.launch(**PLATFORM_CONFIG['launch_config'])
329
+ except Exception as e:
330
+ logger.critical(f"Application launch failed: {e}")
331
+ logger.critical(traceback.format_exc())
332
+ send_error_notification(e)
333
 
334
  if __name__ == "__main__":
335
+ main()