Перейти к содержанию

chutils: Рутина — в прошлом!

License: MIT Python PyPI version Documentation

chutils — это набор простых утилит для Python, который избавляет от повторяющейся настройки конфигурации, логирования и секретов в ваших проектах.

Начните новый проект и сразу сфокусируйтесь на главном, а не на рутине.

Полная документация доступна на нашем сайте.

Проблема

Каждый раз, начиная новый проект, приходится решать одни и те же задачи:

  • Как удобно читать настройки из файла конфигурации?
  • Как настроить логирование, чтобы сообщения писались и в консоль, и в файл с ежедневной ротацией?
  • Как безопасно хранить API-ключи, не прописывая их в коде?
  • Как сделать, чтобы всё это работало "из коробки", без прописывания путей?

chutils предлагает готовые решения для всех этих проблем.

Ключевые возможности

  • ✨ Ноль конфигурации: Библиотека автоматически находит корень вашего проекта и файлы config.yml или config.ini. Используется ленивая инициализация — никаких тяжелых действий до реального обращения к функциям.
  • ⚙️ Гибкая конфигурация: Поддержка YAML и INI форматов. Простые функции для получения типизированных данных.
  • ✍️ Продвинутый логгер: Функция setup_logger() "из коробки" настраивает логирование в консоль и в ротируемые файлы. Возвращает кастомный логгер с дополнительными уровнями отладки (devdebug, mediumdebug) и автоматическим маскированием секретов, а также умным определением ширины консоли для IDE.
  • 🔒 Безопасное хранилище секретов: Модуль secret_manager предоставляет простой интерфейс для сохранения и получения секретов через системный keyring с автоматическим откатом к .env файлам.
  • 🚀 CLI Booster: Превращайте любую функцию в CLI-инструмент за секунды с помощью декоратора @cli_command с автоматическим маппингом типов и парсингом докстрингов.
  • ⏰ Painless Datetime: Всегда "осведомленные" UTC утилиты времени, умный парсинг и человекочитаемые интервалы.
  • 📡 Распределенное трассирование: Бесшовная интеграция с OpenTelemetry, декоратор @trace и автоматическая связь логов с трассами.
  • 🔍 Config Diagnostics: Интерактивная трассировка источников и приоритетов настроек через команду config debug.
  • 🌐 Дистанционная конфигурация: Загрузка настроек через HTTP/HTTPS с поддержкой фонового обновления и fallback-режима.
  • 🔄 Hot-Reload конфигурации: Поддержка автоматического обновления настроек при изменении файлов config.yml или config.local.yml без перезапуска приложения (требуется pip install chutils[watch]).
  • ⚡ Поддержка Async: Большинство функций имеют асинхронные версии (с префиксом a) для работы в неблокирующем режиме.
  • 🚀 Готовность к работе: Просто установите и используйте.

Интерфейс командной строки (CLI)

Библиотека предоставляет консольную команду chutils для удобного управления секретами без написания кода.

Управление секретами

# Сохранить секрет в системное хранилище (keyring)
chutils secrets set MY_API_KEY "super-secret-value"

# Удалить секрет
chutils secrets delete MY_API_KEY

# Указать имя сервиса (service_name) явно
chutils secrets set DB_PASSWORD "12345" --service my_custom_app

Установка

poetry add chutils

Или с помощью pip:

pip install chutils

Примеры использования

В папке examples вы найдете готовые к запуску скрипты, демонстрирующие ключевые возможности библиотеки. Каждый пример сфокусирован на одной конкретной задаче.

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

1. Работа с конфигурацией

  1. (Опционально) Создайте файл config.yml в корне вашего проекта:

yaml # config.yml Database: host: localhost port: 5432

  1. Получайте значения в коде:

```python from chutils import get_config_value, get_config_int

db_host = get_config_value("Database", "host", fallback="127.0.0.1") db_port = get_config_int("Database", "port", fallback=5432) ```

Валидация через Pydantic (Опционально)

Если вам нужна строгая типизация и валидация, вы можете использовать Pydantic модели (требуется pip install chutils[pydantic]):

from pydantic import BaseModel
from chutils import get_config


class AppConfig(BaseModel):
    app_name: str
    version: str


# Функция вернет экземпляр модели AppConfig
cfg = get_config(model=AppConfig)
print(cfg.app_name)

Вы также можете валидировать отдельные секции:

from chutils import get_config_section

db_cfg = get_config_section("Database", model=MyDbModel)

Переопределение через переменные окружения

Вы можете переопределить любое значение из конфигурационного файла с помощью переменных окружения. Это особенно полезно при работе с Docker или Kubernetes.

  • Шаблон: CH_[SECTION]_[KEY] (в верхнем регистре).
  • Пример: Переменная CH_DATABASE_PORT=6000 перекроет значение port в секции Database.

Если вам нужно полностью отключить этот механизм (например, в целях безопасности), установите переменную окружения CH_DISABLE_ENV_OVERRIDE=true.

Переопределение локальным файлом (config.local.yml)

Вы можете создать config.local.yml рядом с основным файлом. Значения из него будут переопределять основные (но уступать переменным окружения CH_*). Это удобно для локальной разработки или хранения секретов (не забудьте добавить *.local.* в .gitignore).

2. Hot-Reload конфигурации

Вы можете настроить приложение так, чтобы оно реагировало на изменения в файлах конфигурации в реальном времени.

from chutils import start_config_watcher, on_config_change, get_config_value


def reload_logic():
    print("Конфигурация обновилась!")
    # Здесь можно обновить состояние приложения
    db_url = get_config_value("Database", "url")


# Регистрируем коллбэк
on_config_change(reload_logic)

# Запускаем мониторинг (требуется пакет watchdog)
start_config_watcher()

Для работы этой функции необходимо установить пакет watchdog: pip install chutils[watch]

3. Настройка логирования

from chutils import setup_logger, ChutilsLogger

# Автоматически читает настройки из секции [Logging] в config.yml
logger: ChutilsLogger = setup_logger()

logger.info("Приложение запущено.")
logger.devdebug("Очень подробное сообщение (уровень 9).")

Структурированное логирование (JSON)

Если вам нужно выводить логи в формате JSON для ELK или Splunk (требуется pip install chutils[json]):

# Через код
logger = setup_logger(json_format=True)

# Или через конфиг в секции [Logging]
# json_format: true

Контекстное логирование (ContextVar)

Вы можете привязывать метаданные к текущему контексту выполнения (потоку или корутине), и они будут автоматически добавляться во все сообщения логов.

from chutils import setup_logger, bind_context

logger = setup_logger()

# Привязываем ID запроса и имя пользователя к текущему контексту
bind_context(request_id="REQ-123", user="admin")

logger.info("Действие выполнено")
# Текст: ... [request_id=REQ-123 user=admin] Действие выполнено
# JSON: {..., "message": "Действие выполнено", "context": {"request_id": "REQ-123", "user": "admin"}}

Управление через переменные окружения

  • CH_LOG_JSON=true: Принудительно включает JSON-формат.
  • CH_LOG_NO_TIME=true: Удаляет дату/время из формата (удобно для чистых логов в Docker).
  • CH_LOG_NO_FILE=true: Полностью отключает создание файлов логов.

Переменные имеют высший приоритет над кодом и конфигурационным файлом.

3. Управление секретами

SecretManager ищет секреты в порядке: Keyring > .env файл > Переменные окружения.

from chutils import SecretManager

secrets = SecretManager("my_awesome_app")

# Сохранить (один раз)
secrets.save_secret("API_KEY", "secret-value-123")

# Использовать везде
key = secrets.get_secret("API_KEY")

Отключение Keyring (Опционально)

В Docker или CI/CD, где keyring недоступен, можно подавить варнинги:

  • Установите переменную CH_DISABLE_KEYRING_WARNING=true.
  • Или добавьте disable_keyring: true в секцию secrets в config.yml.

Обзор API

Конфигурация (chutils.config)

  • get_config_value(section, key, fallback) / aget_config()
  • get_config_int, get_config_boolean, get_config_list, get_config_path
  • save_config_value(section, key, value, notify=True) / asave_config_value()
  • Параметр notify=False позволяет обновить файл без срабатывания Hot-Reload коллбэков.

Логирование (chutils.logger)

  • setup_logger(name, log_level, log_file_name, rotation_type, compress, ...)
  • Уровни: logger.devdebug (9), logger.mediumdebug (15) и стандартные.

Секреты (chutils.secret_manager)

  • SecretManager(service_name, prefix)
  • save_secret / asave_secret
  • get_secret / aget_secret
  • delete_secret / adelete_secret

Декораторы (chutils.decorators)

  • @log_function_details: Логирует аргументы, время и результат функции (уровень DEVDEBUG).
  • @timeout(seconds, fallback): Ограничивает время выполнения функции. Поддерживает sync/async и опциональный fallback.
  • @retry: Автоматически повторяет выполнение функции при ошибках. Поддерживает синхронные и асинхронные функции, экспоненциальную задержку (backoff), случайный шум (jitter) и фильтрацию исключений.

Пример использования @retry:

from chutils.decorators import retry


@retry(retries=3, delay=1.0, backoff=2.0)
def fetch_data():
    # Будет повторено до 3 раз при возникновении любого Exception
    ...

Интерфейс командной строки (CLI)

Библиотека включает в себя набор утилит chutils для ускорения разработки и отладки.

1. Инициализация проекта

Быстрое создание базовой конфигурации и правил .gitignore:

# Интерактивный режим
chutils init

# Быстрый режим (используются значения по умолчанию)
chutils init -y

2. Валидация конфигурации

Проверьте, соответствуют ли ваши файлы конфигурации Pydantic-моделям:

# Автоматический поиск класса 'Settings' в context.py или config.py
chutils validate

# Указание конкретного пути к модели
chutils validate --model src.settings:AppConfig

3. Отладка путей поиска

Узнайте, где именно библиотека ищет файлы настроек и какой у них приоритет:

# Обычный текстовый вывод
chutils show-paths

# Машиночитаемый JSON
chutils show-paths --json

4. Управление секретами

Управляйте секретами в системном хранилище (keyring) напрямую из терминала:

# Сохранить секрет
chutils secrets set API_KEY "your-secret-value" --service my_app

# Удалить секрет
chutils secrets delete API_KEY --service my_app

5. Отладка конфигурации

Узнайте точно, из какого источника пришло каждое значение:

chutils config debug

Лицензия

Проект распространяется под лицензией MIT.