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

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

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

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

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

Установка

pip install dagstack-config

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

Создайте базовый файл app-config.yaml в корне приложения. Env-подстановки ищут переменные окружения при загрузке; без :-default отсутствующая переменная — ошибка.

app-config.yaml
app:
name: "order-service"
tagline: "Обработчик заказов"

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 реестр загрузит три файла в порядке base → local → production, выполнит deep-merge и вернёт итоговый 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)

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

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

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

sub = config.onSectionChange("database", DatabaseConfig, callback=lambda new: apply_pool(new))
# ... работа ...
sub.unsubscribe()

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

Для каких приложений подходит

dagstack/config не зависит от домена приложения. Подходит одинаково для:

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

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

Что дальше

Понятия — как устроен конфиг-стек:

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

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

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

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

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