Перейти к основному содержимому

Быстрый старт

dagstack/config — это универсальный иерархический стек конфигурации для приложений любой предметной области (веб-сервисы, дата-пайплайны, оркестраторы воркфлоу, AI-платформы). Он даёт:

  • YAML как единый формат передачи — один и тот же файл одинаково читается из Python, TypeScript и Go.
  • Слои конфигурацииapp-config.yaml (база) → app-config.local.yaml (переопределения разработчика) → app-config.${DAGSTACK_ENV}.yaml (переопределения окружения).
  • Подстановку переменных окружения${VAR} / ${VAR:-default} интерполируется при загрузке.
  • Типизированный доступget_section / getSection / GetSection (в зависимости от языка) с pydantic / zod / struct-тегами под капотом.
  • Маскирование секретов — поля с именами вроде api_key, *_token, *_password автоматически исключаются из диагностических логов.
  • Горячую перезагрузку — подписка через on_section_change / onSectionChange / OnSectionChange (в зависимости от языка) без перезапуска процесса.

:::info Статус релиза Python- и TypeScript-пакеты готовятся к публикации на PyPI и npmjs.org. Сейчас они доступны из внутреннего репозитория. Go-биндинг — в плане; примеры ниже показывают будущую сигнатуру. :::

Установка

pip install dagstack-config

Первая конфигурация

Создай базовый файл app-config.yaml в корне приложения. Подстановки ${...} берут значения из переменных окружения на момент загрузки; без :-default отсутствие переменной приводит к ошибке.

app-config.yaml
app:
name: "order-service"
tagline: "Order processor"

database:
host: "${DB_HOST:-localhost}"
port: "${DB_PORT:-5432}"
name: "${DB_NAME:-orders}"
user: "${DB_USER}"
password: "${DB_PASSWORD}"
pool_size: 20

cache:
url: "${REDIS_URL:-redis://localhost:6379/0}"
ttl_min: 15

api:
host: "0.0.0.0"
port: 8080
request_timeout_s: 30

Локальные переопределения кладутся в app-config.local.yaml (этот файл указан в .gitignore):

app-config.local.yaml
database:
pool_size: 5 # меньше соединений локально

api:
request_timeout_s: 120 # медленный отладчик

Переопределения для конкретного окружения кладутся в app-config.production.yaml (коммитится):

app-config.production.yaml
database:
host: "prod-db.internal.example.com"
pool_size: 100

cache:
url: "redis://prod-cache.internal.example.com:6379/0"

При DAGSTACK_ENV=production загрузчик читает все три файла в порядке база → local → production, делает глубокое слияние и возвращает итоговый Config.

Загрузка и чтение

from dagstack.config import Config

config = Config.load("app-config.yaml")

# Базовые геттеры:
print(config.get_string("app.name")) # "order-service"
print(config.get_int("database.pool_size")) # 20
print(config.get_int("api.port")) # 8080

# Со значением по умолчанию — если путь отсутствует, возвращается переданное значение:
print(config.get_int("api.max_body_mb", default=10)) # 10

Типизированный доступ

Вместо череды вызовов get_string / get_int (Python), getString / getInt (TS), GetString / GetInt (Go) объяви секцию как модель и прочитай её целиком — с валидацией.

from pydantic import BaseModel, Field
from dagstack.config import Config


class DatabaseConfig(BaseModel):
host: str
port: int = Field(5432, ge=1, le=65535)
name: str
user: str
password: str = Field(..., min_length=1)
pool_size: int = Field(20, ge=1, le=1000)


config = Config.load("app-config.yaml")
db = config.get_section("database", DatabaseConfig)
# Доступ через атрибуты, с валидацией:
pool = create_pool(host=db.host, port=db.port, pool_size=db.pool_size)

Валидация схемы запускается прямо внутри getSection; при сбое получаешь ConfigError(validation_failed) с указанием проблемного поля.

Перезагрузка конфигурации в рантайме

Если источник конфигурации поддерживает наблюдение за изменениями (обычно YamlFileSource через fsnotify), компоненты могут подписаться на изменения своей секции:

sub = config.on_section_change("database", DatabaseConfig, callback=lambda new: apply_pool(new))
# ... выполняется работа ...
sub.unsubscribe()

Если источник не умеет следить за изменениями, подписка всё равно принимается, но active = false и inactive_reason = "subscription_without_watch". Код компонента не ломается — callback просто никогда не сработает.

Каким приложениям подходит

dagstack/config предметно-нейтрален. Он одинаково годится для:

  • Веб- и API-сервисов — секции database, cache, api, auth, rate_limit, workers.
  • Дата-пайплайнов — секции source, processor, sink, scheduler, retry_policy.
  • Оркестраторов воркфлоу — секции queue, executor, storage, retry.
  • AI- / RAG-платформ — секции llm, embedder, vector_store, retrieval.
  • Систем уведомлений — секции email, sms, push, webhook.
  • Биллинговых / платёжных сервисов — секции payment_provider, tax, subscriptions.

Механика везде одинаковая: объяви секцию в YAML, опиши её схему в нативном для языка формате, прочитай через getSection(). Знание предметной области остаётся в приложении, а не в стеке конфигурации.

Что читать дальше

Концепции — как устроен стек конфигурации:

Руководства — как решать типичные задачи:

Справочник — точные таблицы:

Спецификация — нормативные решения:

API (генерация отложена до стабилизации реализаций):

  • Python — готовится через pydoc-markdown.