hermes-kanban-miniapp/backend/app/config.py
kisskin ade88808fb
Some checks failed
CI / backend (push) Failing after 37s
CI / frontend (push) Failing after 21s
feat: M4 docker deployment - bridge + frontend containers
- packages/bridge/Dockerfile: multi-stage build (node:22-alpine)
- frontend/Dockerfile: multi-stage build + nginx:alpine
- frontend/nginx.conf: proxy /bridge to bridge service
- docker-compose.yml: bridge (3456) + frontend (8080)
- .dockerignore: exclude backend/node_modules/dist
- Fix vite proxy target to port 3456
- .env with bridge vars (AUTH_MODE=dev)
2026-07-10 14:58:20 +03:00

61 lines
2.5 KiB
Python

import json
from functools import lru_cache
from typing import Annotated, Literal
from pydantic import Field, field_validator
from pydantic_settings import BaseSettings, NoDecode, SettingsConfigDict
class Settings(BaseSettings):
model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8", extra="ignore", populate_by_name=True)
hermes_bin: str = Field(default="hermes", alias="HERMES_BIN")
hermes_home: str | None = Field(default=None, alias="HERMES_HOME")
default_board: str = Field(default="default", alias="HERMES_KANBAN_BOARD")
auth_mode: Literal["telegram", "none", "dev"] = Field(default="dev", alias="KANBAN_UI_AUTH_MODE")
telegram_bot_token: str | None = Field(default=None, alias="TELEGRAM_BOT_TOKEN")
telegram_allowed_user_ids: Annotated[list[int], NoDecode] = Field(default_factory=list, alias="TELEGRAM_ALLOWED_USER_IDS")
allowed_origins: Annotated[list[str], NoDecode] = Field(default_factory=lambda: ["http://localhost:5173"], alias="KANBAN_UI_ALLOWED_ORIGINS")
command_timeout_seconds: int = Field(default=30, alias="KANBAN_UI_COMMAND_TIMEOUT_SECONDS")
frontend_dist_dir: str | None = Field(default=None, alias="KANBAN_UI_FRONTEND_DIST_DIR")
@field_validator("telegram_allowed_user_ids", mode="before")
@classmethod
def parse_user_ids(cls, value):
if value is None or value == "":
return []
if isinstance(value, str):
value = value.strip()
if value.startswith("["):
try:
value = json.loads(value)
except json.JSONDecodeError:
pass
if isinstance(value, str):
return [int(part.strip()) for part in value.split(",") if part.strip()]
if isinstance(value, (list, tuple)):
return [int(v) for v in value]
return value
@field_validator("allowed_origins", mode="before")
@classmethod
def parse_origins(cls, value):
if value is None or value == "":
return []
if isinstance(value, str):
value = value.strip()
if value.startswith("["):
try:
value = json.loads(value)
except json.JSONDecodeError:
pass
if isinstance(value, str):
return [part.strip() for part in value.split(",") if part.strip()]
if isinstance(value, (list, tuple)):
return [str(v) for v in value]
return value
@lru_cache
def get_settings() -> Settings:
return Settings()