brief-extractor/backend/server/config_runtime.py
2026-03-06 18:42:46 +00:00

94 lines
No EOL
3.5 KiB
Python
Executable file

"""
Runtime configuration for the Brief Extractor GUI server
Extends the existing core configuration with web-specific settings
"""
import os
from typing import List, Optional
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
class ServerConfig:
"""Server-specific configuration extending core config"""
# Server Configuration
HOST: str = os.getenv('SERVER_HOST', '0.0.0.0')
PORT: int = int(os.getenv('SERVER_PORT', '8000'))
WORKERS: int = int(os.getenv('SERVER_WORKERS', '2'))
DEBUG: bool = os.getenv('DEBUG', 'false').lower() == 'true'
# Development Mode
DEV_MODE: bool = os.getenv('DEV_MODE', 'true').lower() == 'true'
# CORS Configuration
ALLOWED_ORIGINS: List[str] = [
origin.strip()
for origin in os.getenv('ALLOWED_ORIGINS', 'http://localhost:3000,http://localhost:5173').split(',')
]
# MSAL Authentication
MSAL_CLIENT_ID: str = os.getenv('MSAL_CLIENT_ID', '')
MSAL_CLIENT_SECRET: str = os.getenv('MSAL_CLIENT_SECRET', '')
MSAL_TENANT_ID: str = os.getenv('MSAL_TENANT_ID', '')
MSAL_REDIRECT_URI: str = os.getenv('MSAL_REDIRECT_URI', 'http://localhost:3000/auth/callback')
MSAL_AUTHORITY: str = os.getenv('MSAL_AUTHORITY', f'https://login.microsoftonline.com/{MSAL_TENANT_ID}')
# Security Configuration
SESSION_SECRET: str = os.getenv('SESSION_SECRET', 'your-session-secret-here')
SECURE_COOKIES: bool = os.getenv('SECURE_COOKIES', 'false').lower() == 'true'
HTTPS_ONLY: bool = os.getenv('HTTPS_ONLY', 'false').lower() == 'true'
# File Upload Configuration
MAX_UPLOAD_SIZE_MB: int = int(os.getenv('MAX_UPLOAD_SIZE_MB', '200'))
MAX_CONTENT_LENGTH: int = MAX_UPLOAD_SIZE_MB * 1024 * 1024 # Convert to bytes
ALLOWED_EXTENSIONS: set = {'.pdf', '.pptx', '.docx', '.xlsx', '.ppt', '.doc', '.xls'}
# Job Management Configuration
MAX_CONCURRENT_JOBS: int = int(os.getenv('MAX_CONCURRENT_JOBS', '2'))
FILE_RETENTION_HOURS: int = int(os.getenv('FILE_RETENTION_HOURS', '24'))
# WebSocket Configuration
WS_PING_INTERVAL_SECONDS: int = int(os.getenv('WS_PING_INTERVAL_SECONDS', '30'))
# Data Storage Paths
DATA_DIR: str = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data')
UPLOAD_DIR: str = os.path.join(DATA_DIR, 'uploads')
OUTPUT_DIR: str = os.path.join(DATA_DIR, 'outputs')
@classmethod
def ensure_directories(cls):
"""Ensure all required directories exist"""
os.makedirs(cls.DATA_DIR, exist_ok=True)
os.makedirs(cls.UPLOAD_DIR, exist_ok=True)
os.makedirs(cls.OUTPUT_DIR, exist_ok=True)
@classmethod
def validate_auth_config(cls) -> bool:
"""Validate MSAL configuration is complete for production"""
if cls.DEV_MODE:
return True # Skip validation in dev mode
# For PKCE flow (public client), client secret is not required
# Only validate client ID and tenant ID
required_fields = [
cls.MSAL_CLIENT_ID,
cls.MSAL_TENANT_ID
]
return all(field and field.strip() != ''
for field in required_fields)
@classmethod
def get_cors_config(cls) -> dict:
"""Get CORS configuration for Quart"""
return {
'allow_origin': cls.ALLOWED_ORIGINS,
'allow_methods': ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
'allow_headers': ['Content-Type', 'Authorization', 'Accept'],
'allow_credentials': True
}
# Global instance
server_config = ServerConfig()