All checks were successful
Build Container / build (push) Successful in 1m18s
- Flask backend with SSH discovery and Claude AI integration - React/Vite frontend with Tailwind CSS - Docker multi-stage build - Gitea Actions workflow for container builds 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
66 lines
2.0 KiB
Python
66 lines
2.0 KiB
Python
import os
|
|
import base64
|
|
from dataclasses import dataclass
|
|
from typing import Optional
|
|
|
|
|
|
@dataclass
|
|
class Config:
|
|
"""Application configuration loaded from environment variables."""
|
|
|
|
ssh_private_key: str
|
|
uptime_kuma_url: str
|
|
uptime_kuma_api_key: str
|
|
claude_api_key: str
|
|
dev_mode: bool = False
|
|
|
|
@classmethod
|
|
def from_env(cls) -> "Config":
|
|
"""Load configuration from environment variables."""
|
|
ssh_key_b64 = os.environ.get("SSH_PRIVATE_KEY", "")
|
|
|
|
# Decode base64 SSH key
|
|
try:
|
|
ssh_private_key = base64.b64decode(ssh_key_b64).decode("utf-8") if ssh_key_b64 else ""
|
|
except Exception:
|
|
ssh_private_key = ssh_key_b64 # Allow plain text for development
|
|
|
|
return cls(
|
|
ssh_private_key=ssh_private_key,
|
|
uptime_kuma_url=os.environ.get("UPTIME_KUMA_URL", "http://localhost:3001"),
|
|
uptime_kuma_api_key=os.environ.get("UPTIME_KUMA_API_KEY", ""),
|
|
claude_api_key=os.environ.get("CLAUDE_API_KEY", ""),
|
|
dev_mode=os.environ.get("DEV_MODE", "false").lower() == "true",
|
|
)
|
|
|
|
def validate(self) -> list[str]:
|
|
"""Validate configuration and return list of errors."""
|
|
errors = []
|
|
if not self.ssh_private_key:
|
|
errors.append("SSH_PRIVATE_KEY is required")
|
|
if not self.uptime_kuma_url:
|
|
errors.append("UPTIME_KUMA_URL is required")
|
|
if not self.uptime_kuma_api_key:
|
|
errors.append("UPTIME_KUMA_API_KEY is required")
|
|
if not self.claude_api_key:
|
|
errors.append("CLAUDE_API_KEY is required")
|
|
return errors
|
|
|
|
|
|
# Global config instance
|
|
_config: Optional[Config] = None
|
|
|
|
|
|
def get_config() -> Config:
|
|
"""Get the global configuration instance."""
|
|
global _config
|
|
if _config is None:
|
|
_config = Config.from_env()
|
|
return _config
|
|
|
|
|
|
def set_dev_mode(enabled: bool) -> None:
|
|
"""Update dev mode setting."""
|
|
config = get_config()
|
|
config.dev_mode = enabled
|