from __future__ import annotations from typing import Literal from pydantic import AliasChoices, Field, SecretStr from pydantic_settings import BaseSettings, SettingsConfigDict _prefix = "OPENBAO__SETTINGS" class Settings(BaseSettings): """Настройки сервиса «Портфели ДРРК». Конвенция (`OPENBAO__SETTINGS__*`, pydantic-settings + AliasChoices) скопирована с SFM-parser (../sfm/app/core/config.py): в Раисе секреты инжектятся из OpenBao с префиксом, локально — без префикса из .env. """ LOCATION: Literal["local", "test", "prod"] = Field( default="prod", description="Контур: local — mock-авторизация и SQLite, test/prod — Раиса", validation_alias=AliasChoices(f"{_prefix}__LOCATION", "LOCATION"), ) DATABASE_URL: str = Field( default="sqlite+aiosqlite:///./drrk_local.db", description="URL подключения к БД (asyncpg в Раисе, aiosqlite локально)", validation_alias=AliasChoices(f"{_prefix}__DATABASE_URL", "DATABASE_URL"), ) DATABASE_SCHEMA: str = Field( default="", description="Схема БД (для Postgres search_path); для SQLite оставлять пустой", validation_alias=AliasChoices(f"{_prefix}__DATABASE_SCHEMA", "DATABASE_SCHEMA"), ) GATEWAY_URL: str = Field( default="https://gateway.rshbdev.ru", description="Шлюз Gravitee: тест https://gateway.rshbdev.ru, прод https://gateway.rshb.pro", validation_alias=AliasChoices(f"{_prefix}__GATEWAY_URL", "GATEWAY_URL"), ) MOEX_PATH: str = Field( default="/external/moex-iss", description="Context-path шлюза к https://iss.moex.com (в запросах далее /iss/...)", validation_alias=AliasChoices(f"{_prefix}__MOEX_PATH", "MOEX_PATH"), ) CBR_PATH: str = Field( default="/external/cbr", description="Context-path шлюза к https://cbr.ru", validation_alias=AliasChoices(f"{_prefix}__CBR_PATH", "CBR_PATH"), ) MOEX_API_KEY: SecretStr = Field( default=SecretStr(""), description="Ключ шлюза для MOEX (X-Rshb-Api-Key). Отличается от ключа ЦБ.", validation_alias=AliasChoices(f"{_prefix}__MOEX_API_KEY", "MOEX_API_KEY"), ) CBR_API_KEY: SecretStr = Field( default=SecretStr(""), description="Ключ шлюза для ЦБ (X-Rshb-Api-Key). Отличается от ключа MOEX.", validation_alias=AliasChoices(f"{_prefix}__CBR_API_KEY", "CBR_API_KEY"), ) HTTP_TIMEOUT_SECONDS: float = Field( default=15, description="Таймаут одного HTTP-запроса к шлюзу, секунды", validation_alias=AliasChoices( f"{_prefix}__HTTP_TIMEOUT_SECONDS", "HTTP_TIMEOUT_SECONDS" ), ) HTTP_RETRIES: int = Field( default=3, description="Число повторов после первой попытки (всего до HTTP_RETRIES + 1 запросов)", validation_alias=AliasChoices(f"{_prefix}__HTTP_RETRIES", "HTTP_RETRIES"), ) MOEX_PREFERRED_BOARDS: list[str] = Field( default=["TQCB", "TQOB"], description="Режимы торгов в порядке приоритета при выборе строки истории", validation_alias=AliasChoices( f"{_prefix}__MOEX_PREFERRED_BOARDS", "MOEX_PREFERRED_BOARDS" ), ) model_config = SettingsConfigDict(env_file=".env", extra="ignore") settings = Settings()