Spaces:
Sleeping
Sleeping
GitHub Actions Deployer
Automated Worker deployment from GitHub commit e01e0e57b4098452f16a9b5baf85b3b230865b5f
185ef9e | # app_environment.py - Production-grade environment configuration | |
| """ | |
| Production environment configuration for OmniBiMol Streamlit app. | |
| Provides clean environment handling to separate development/debug output | |
| from production-ready user-facing UI. | |
| Usage: | |
| from app_environment import AppEnvironment | |
| env = AppEnvironment() | |
| if env.is_development(): | |
| # Show debug UI elements | |
| if env.should_show_backend_status(): | |
| render_backend_status_badge() | |
| """ | |
| import os | |
| import logging | |
| from typing import Optional | |
| logger = logging.getLogger(__name__) | |
| class AppEnvironment: | |
| """ | |
| Manages application environment configuration. | |
| Separates development/debug UI from production user-facing UI. | |
| """ | |
| # Environment modes | |
| DEVELOPMENT = "development" | |
| PRODUCTION = "production" | |
| def __init__(self): | |
| """Initialize environment configuration from APP_ENV variable.""" | |
| # Default to production for safety | |
| self.env = os.getenv("APP_ENV", self.PRODUCTION).strip().lower() | |
| # Validate environment | |
| if self.env not in {self.DEVELOPMENT, self.PRODUCTION}: | |
| logger.warning( | |
| f"Invalid APP_ENV='{self.env}'. Valid values: " | |
| f"'{self.DEVELOPMENT}', '{self.PRODUCTION}'. Defaulting to '{self.PRODUCTION}'." | |
| ) | |
| self.env = self.PRODUCTION | |
| logger.info(f"OmniBiMol running in {self.env} mode") | |
| def is_development(self) -> bool: | |
| """Check if running in development mode.""" | |
| return self.env == self.DEVELOPMENT | |
| def is_production(self) -> bool: | |
| """Check if running in production mode.""" | |
| return self.env == self.PRODUCTION | |
| def should_show_backend_status(self) -> bool: | |
| """ | |
| Determine if backend status badge should be shown. | |
| Returns: | |
| True in development mode, False in production. | |
| """ | |
| return self.is_development() | |
| def should_show_debug_ui(self) -> bool: | |
| """ | |
| Determine if debug/development UI elements should be visible. | |
| Includes: | |
| - Backend routing details | |
| - Environment labels | |
| - Debug status indicators | |
| - Internal error details | |
| Returns: | |
| True in development mode, False in production. | |
| """ | |
| return self.is_development() | |
| def should_expose_errors(self) -> bool: | |
| """ | |
| Determine if raw errors should be exposed in UI. | |
| Returns: | |
| True in development mode, False in production (user-friendly messages only). | |
| """ | |
| return self.is_development() | |
| def get_user_message(self, internal_error: Optional[str] = None) -> str: | |
| """ | |
| Get user-friendly message, hiding internal details in production. | |
| Args: | |
| internal_error: The actual error for logging purposes | |
| Returns: | |
| Production: Generic user message | |
| Development: Full error details | |
| """ | |
| if self.is_production(): | |
| return "Processing request... Some data could not be loaded. Results may be partial." | |
| else: | |
| return internal_error or "An error occurred." | |
| def log_debug(self, message: str, **kwargs) -> None: | |
| """Log debug message (visible in logs, not UI).""" | |
| logger.debug(message, extra=kwargs) | |
| def log_info(self, message: str, **kwargs) -> None: | |
| """Log info message.""" | |
| logger.info(message, extra=kwargs) | |
| def log_error(self, message: str, **kwargs) -> None: | |
| """Log error message.""" | |
| logger.error(message, extra=kwargs) | |
| # Global singleton instance | |
| _app_environment: Optional[AppEnvironment] = None | |
| def get_environment() -> AppEnvironment: | |
| """ | |
| Get or create the global app environment instance. | |
| Returns: | |
| AppEnvironment singleton | |
| """ | |
| global _app_environment | |
| if _app_environment is None: | |
| _app_environment = AppEnvironment() | |
| return _app_environment | |