"""Server package — FastAPI/Gradio routes and utilities. Enhanced with: - Session management - Export functionality - Template system - Better error handling """ from __future__ import annotations import json import logging import os import time from pathlib import Path from typing import Any, Optional import gradio as gr logger = logging.getLogger(__name__) def create_app() -> gr.Server: """Create and configure the Gradio Server with all routes.""" from code.server.routes import get_app app = get_app() return app def get_workspace_root() -> Path: """Get the workspace root directory.""" from code.config import WORKSPACE_ROOT return WORKSPACE_ROOT def get_download_dir() -> Path: """Get the download directory for exports.""" download_dir = Path("./downloads") download_dir.mkdir(parents=True, exist_ok=True) return download_dir # Template-related functions def get_code_templates() -> dict[str, Any]: """Get available code templates.""" from code.config.constants import CODE_TEMPLATES return { key: { "name": tpl["name"], "description": tpl["description"], "language": tpl["language"], "framework": tpl["framework"], } for key, tpl in CODE_TEMPLATES.items() } def get_template_content(template_id: str) -> Optional[str]: """Get the content of a specific template.""" from code.config.constants import CODE_TEMPLATES if template_id in CODE_TEMPLATES: return CODE_TEMPLATES[template_id]["template"] return None # Utility functions for the server def format_file_size(size_bytes: int) -> str: """Format file size in human-readable format.""" for unit in ['B', 'KB', 'MB', 'GB']: if size_bytes < 1024.0: return f"{size_bytes:.1f} {unit}" size_bytes /= 1024.0 return f"{size_bytes:.1f} TB" def sanitize_filename(filename: str) -> str: """Sanitize a filename by removing dangerous characters.""" # Remove path separators and dangerous characters sanitized = os.path.basename(filename) # Replace non-alphanumeric (except dash, underscore, dot) with underscore sanitized = "".join(c if c.isalnum() or c in '-_.' else '_' for c in sanitized) # Remove consecutive underscores while '__' in sanitized: sanitized = sanitized.replace('__', '_') # Limit length if len(sanitized) > 255: name, ext = os.path.splitext(sanitized) sanitized = name[:255-len(ext)] + ext return sanitized or "unnamed" def get_system_info() -> dict[str, Any]: """Get system information for diagnostics.""" import platform import torch info = { "platform": platform.platform(), "python_version": platform.python_version(), "hostname": platform.node(), } # GPU info if available if torch.cuda.is_available(): info["gpu"] = { "name": torch.cuda.get_device_name(0), "memory_gb": round(torch.cuda.get_device_properties(0).total_mem / 1e9, 2), "cuda_version": torch.version.cuda, } # Model status try: from code.model.loader import get_model_status info["model"] = get_model_status() except Exception: info["model"] = {"status": "unknown"} return info