Omnibimol-Worker / app_environment.py
GitHub Actions Deployer
Automated Worker deployment from GitHub commit e01e0e57b4098452f16a9b5baf85b3b230865b5f
185ef9e
Raw
History Blame Contribute Delete
4.11 kB
# 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