import gradio as gr import logging import traceback import time import re import os from functools import wraps, lru_cache from dotenv import load_dotenv from urllib.parse import urlparse # Load environment variables load_dotenv() # Enhanced logging configuration logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler('centurion_platform.log', encoding='utf-8', mode='a'), logging.StreamHandler() ] ) logger = logging.getLogger(__name__) # CSS Configuration css = """ * { margin: 0; padding: 0; box-sizing: border-box; } body { background-color: #ffffff; color: #000000; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; } .header { background: #ffffff; border-bottom: 1px solid #e5e5e5; padding: 1rem 2rem; display: flex; align-items: center; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); } .logo { width: 45px; height: 45px; margin-right: 15px; transition: transform 0.3s ease; } .header-title { color: #000000; font-size: 24px; font-weight: 600; } .container { max-width: 1400px; margin: 0 auto; padding: 2rem; background: #ffffff; } .main-content { background: #ffffff; border-radius: 12px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); margin: 2rem 0; overflow: hidden; border: 1px solid #e5e5e5; } .iframe-container { position: relative; width: 100%; height: 0; padding-bottom: 65%; background: #ffffff; } .iframe-container iframe { position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none; } .nav-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1.5rem; margin-top: 2rem; } .nav-card { background: #ffffff; border: 1px solid #e5e5e5; border-radius: 10px; padding: 1.5rem; transition: all 0.3s ease; } @media (max-width: 768px) { .nav-grid { grid-template-columns: 1fr; } } """ # Performance and security decorators def performance_monitor(func): @wraps(func) def wrapper(*args, **kwargs): start = time.time() try: result = func(*args, **kwargs) execution_time = time.time() - start logger.info(f"{func.__name__} execution time: {execution_time:.2f} seconds") return result except Exception as e: logger.error(f"Error in {func.__name__}: {e}") logger.error(traceback.format_exc()) raise return wrapper # URL Validation and Sanitization @lru_cache(maxsize=100) def validate_and_sanitize_url(url): """ Comprehensive URL validation and sanitization """ try: # Validate URL pattern url_pattern = re.compile( r'^https?://' # http:// or https:// r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?|' # domain... r'localhost|' # localhost... r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip r'(?::\d+)?' # optional port r'(?:/?|[/?]\S+)$', re.IGNORECASE) if not url_pattern.match(url): logger.warning(f"Invalid URL format: {url}") return None # Parse and validate URL parsed_url = urlparse(url) # Whitelist allowed domains allowed_domains = [ 'noumanjavaid-new-space.hf.space', 'noumanjavaid-centurionv2.hf.space', 'noumanjavaid-watermark-demo-video.hf.space', 'noumanjavaid-centii.hf.space', 'localhost' ] if parsed_url.netloc not in allowed_domains: logger.warning(f"Unauthorized domain: {parsed_url.netloc}") return None return url except Exception as e: logger.error(f"URL validation error: {e}") return None # Platform Configuration PLATFORM_CONFIG = { 'main_platform_url': os.getenv('MAIN_PLATFORM_URL', 'https://noumanjavaid-centii.hf.space'), 'launch_config': { 'show_error': True, 'show_api': False, 'show_tips': False, 'height': 800, 'analytics_enabled': False, 'enable_queue': False, 'prevent_thread_lock': True } } # Error Notification (Optional) def send_error_notification(error): """ Send error notifications via external service """ try: import requests webhook_url = os.getenv('ERROR_WEBHOOK_URL') if webhook_url: payload = { "text": f"🚨 Centurion Platform Error: {str(error)}", "blocks": [ { "type": "section", "text": { "type": "mrkdwn", "text": f"```{traceback.format_exc()}```" } } ] } requests.post(webhook_url, json=payload) except Exception as log_error: logger.error(f"Error sending notification: {log_error}") # Configuration Validation def validate_configuration(demo): """ Validate Gradio demo configuration """ required_attributes = [ 'title', 'css', 'show_error', 'show_api', 'show_tips', 'height', 'analytics_enabled', 'enable_queue' ] validation_results = {} for attr in required_attributes: try: value = getattr(demo, attr, None) validation_results[attr] = value is not None except Exception as e: logger.error(f"Error validating {attr}: {e}") validation_results[attr] = False return validation_results @performance_monitor def create_demo(): """ Create Gradio demo with comprehensive validation """ # Navigation Cards with URL Validation cards = [ { "icon": "🔍", "title": "DeepFake Detection", "url": validate_and_sanitize_url(os.getenv('DEEPFAKE_URL', 'https://noumanjavaid-new-space.hf.space')) }, { "icon": "📄", "title": "Document Analysis", "url": validate_and_sanitize_url(os.getenv('DOCUMENT_URL', 'https://noumanjavaid-centurionv2.hf.space')) }, { "icon": "🎥", "title": "Video Watermarking", "url": validate_and_sanitize_url(os.getenv('WATERMARK_URL', 'https://noumanjavaid-watermark-demo-video.hf.space')) }, { "icon": "🔐", "title": "Image Authentication", "url": validate_and_sanitize_url(os.getenv('AUTH_URL', 'https://noumanjavaid-centii.hf.space')) }, ] # Validate navigation cards invalid_cards = [card for card in cards if card['url'] is None] if invalid_cards: logger.warning(f"Invalid navigation card URLs: {invalid_cards}") # Generate HTML for navigation cards html_cards = "".join( f''' ''' for card in cards if card['url'] is not None ) # Create Gradio block with gr.Blocks(css=css, title="Centurion Analysis Platform") as demo: # Header with gr.Row(elem_classes=["header"]): gr.Image( "https://raw.githubusercontent.com/noumanjavaid96/ai-as-an-api/refs/heads/master/image%20(39).png", elem_classes=["logo"], show_label=False, container=False ) gr.Markdown("Centurion Analysis", elem_classes=["header-title"]) # Main content with gr.Row(elem_classes=["container"]): with gr.Column(elem_classes=["main-content"]): gr.HTML(f'''
''') # Navigation grid with gr.Row(elem_classes=["nav-grid"]): gr.HTML(html_cards) return demo def main(): try: demo = create_demo() # Validate configuration before launching config_validation = validate_configuration(demo) logger.info(f"Configuration Validation: {config_validation}") validation_errors = [k for k, v in config_validation.items() if not v] if validation_errors: logger.error(f"Configuration validation failed for: {validation_errors}") raise ValueError(f"Invalid configuration: {validation_errors}") demo.launch(**PLATFORM_CONFIG['launch_config']) except Exception as e: logger.critical(f"Application launch failed: {e}") logger.critical(traceback.format_exc()) send_error_notification(e) if __name__ == "__main__": main()