"""Centralized runtime URL and configuration values for the main app. This module loads the root .env file once and exposes resolved values so the rest of the app can import config instead of reading environment variables at each call site. """ import os from dotenv import load_dotenv load_dotenv() # runtime_urls.py lives at the repo root, so its directory IS the project root. # This is a far more stable anchor than walking ".." from a nested module. PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__)) def _env(name: str, default: str) -> str: return os.getenv(name, default) def _env_bool(name: str, default: bool = False) -> bool: value = os.getenv(name) return default if value is None else value.lower() in ("true", "1", "t", "yes", "y") def _env_int(name: str, default: int) -> int: value = os.getenv(name) return default if value is None else int(value) def _env_float(name: str, default: float) -> float: value = os.getenv(name) return default if value is None else float(value) DATABASE_URL = _env("DATABASE_URL", "mysql://theapi_user:theapi_password@172.17.0.1:3306/theapi") REDIS_URL = _env("REDIS_URL", "redis://172.17.0.1:6379/2") REDIS_BROKER_URL = _env("BROKER_URL", _env("CELERY_BROKER_URL", "redis://172.17.0.1:6379/0")) REDIS_RESULT_BACKEND_URL = _env("RESULT_BACKEND", _env("CELERY_RESULT_BACKEND", "redis://172.17.0.1:6379/1")) API_BASE_URL = _env("API_BASE_URL", "http://172.17.0.1:5000/api") WEBSOCKET_SERVER_URL = _env("WEBSOCKET_SERVER_URL", "http://172.17.0.1:6001") WEBSOCKET_SERVER_PATH = _env("WEBSOCKET_SERVER_PATH", "/ws") VNC_PROXY_HTTP_PORT = _env_int("VNC_PROXY_HTTP_PORT", 6002) VNC_PORT_LOCAL = _env_int("VNC_PORT_LOCAL", 5900) ENGINEIO_LOGGER_LEVEL = _env("ENGINEIO_LOGGER_LEVEL", "WARNING").upper() SIO_LOGGER_LEVEL = _env("SIO_LOGGER_LEVEL", "WARNING").upper() BASE_DOMAIN = _env("BASE_DOMAIN", "xcloudify.tech") TUNNEL_DOMAIN = _env("TUNNEL_DOMAIN", "hawkvelt.tech") VNC_BASE_URL = _env("VNC_BASE_URL", "https://vnc-console.xcloudify.tech/vnc.html") VNC_PROXY_HOST = _env("VNC_PROXY_HOST", "vnc-proxy.xcloudify.tech") VNC_PROXY_PORT = _env("VNC_PROXY_PORT", "443") VNC_PROXY_WS_PATH = _env("VNC_PROXY_WS_PATH", "vnc") VNC_SECRET_KEY = _env("VNC_SECRET_KEY", "your-very-secret-key") CHECK_PERMISSION_URL = _env("CHECK_PERMISSION_URL", "http://172.17.0.1:5000/api/check_permission") APP_ENV = _env("APP_ENV", "") FLASK_ENV = _env("FLASK_ENV", "development") JWT_SECRET_KEY = _env("JWT_SECRET_KEY", "your-very-secret-key") XCLOUDIFY_API_KEY = _env("XCLOUDIFY_API_KEY", "") SCHEDULER_MAX_ALLOCATION_ATTEMPTS = _env_int("SCHEDULER_MAX_ALLOCATION_ATTEMPTS", 8) SCHEDULER_RETRY_BASE_DELAY_SECONDS = _env_int("SCHEDULER_RETRY_BASE_DELAY_SECONDS", 60) SCHEDULER_RETRY_BACKOFF_FACTOR = _env_float("SCHEDULER_RETRY_BACKOFF_FACTOR", 2.0) SCHEDULER_RETRY_JITTER_SECONDS = _env_int("SCHEDULER_RETRY_JITTER_SECONDS", 30) SCHEDULER_RETRY_MAX_DELAY_SECONDS = _env_int("SCHEDULER_RETRY_MAX_DELAY_SECONDS", 1800) SCHEDULER_CONF_PATH = _env("SCHEDULER_CONF_PATH", os.path.join(PROJECT_ROOT, "conf", "scheduler.conf")) CLOUDFLARE_API_TOKEN = _env("CLOUDFLARE_API_TOKEN", "") CLOUDFLARE_ACCOUNT_ID = _env("CLOUDFLARE_ACCOUNT_ID", "") CLOUDFLARE_ZONE_ID = _env("CLOUDFLARE_ZONE_ID", "") PING_HEARTBEAT_TIMEOUT_SECONDS = _env_int("PING_HEARTBEAT_TIMEOUT_SECONDS", 30) ENABLE_TASK_ASSIGNMENT_DEBUG = _env_bool("ENABLE_TASK_ASSIGNMENT_DEBUG", False) ENABLE_WEBSOCKET_PING_DEBUG = _env_bool("ENABLE_WEBSOCKET_PING_DEBUG", False)