chutils 2.0.0__tar.gz → 2.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
chutils-2.2.0/PKG-INFO ADDED
@@ -0,0 +1,388 @@
1
+ Metadata-Version: 2.4
2
+ Name: chutils
3
+ Version: 2.2.0
4
+ Summary: Набор простых и удобных утилит для Python, который избавляет от рутины при работе с конфигурацией и логированием в новых проектах.
5
+ License: MIT
6
+ License-File: LICENSE
7
+ Author: Chu4hel
8
+ Author-email: sergeiivanov636@gmail.com
9
+ Requires-Python: >=3.9
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.9
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Programming Language :: Python :: 3.14
18
+ Requires-Dist: dotenv (>=0.9.9,<0.10.0)
19
+ Requires-Dist: keyring (>=25.6.0,<26.0.0)
20
+ Requires-Dist: python-dotenv (>=1.2.1,<2.0.0)
21
+ Requires-Dist: pyyaml (>=6.0.3,<7.0.0)
22
+ Description-Content-Type: text/markdown
23
+
24
+ # chutils: Рутина — в прошлом!
25
+
26
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
27
+ [![Python](https://img.shields.io/badge/python-3.9%2B-blue.svg)](https://www.python.org/downloads/)
28
+ [![PyPI version](https://badge.fury.io/py/chutils.svg)](https://badge.fury.io/py/chutils)
29
+ [![Documentation](https://img.shields.io/badge/документация-читать-brightgreen)](https://Chu4hel.github.io/chutils/)
30
+
31
+ **chutils** — это набор простых утилит для Python, который избавляет от повторяющейся настройки конфигурации,
32
+ логирования и секретов в ваших проектах.
33
+
34
+ Начните новый проект и сразу сфокусируйтесь на главном, а не на рутине.
35
+
36
+ Полная документация доступна на [нашем сайте](https://Chu4hel.github.io/chutils/).
37
+
38
+ ## Проблема
39
+
40
+ Каждый раз, начиная новый проект, приходится решать одни и те же задачи:
41
+
42
+ - Как удобно читать настройки из файла конфигурации?
43
+ - Как настроить логирование, чтобы сообщения писались и в консоль, и в файл с ежедневной ротацией?
44
+ - Как безопасно хранить API-ключи, не прописывая их в коде?
45
+ - Как сделать, чтобы всё это работало "из коробки", без прописывания путей?
46
+
47
+ **chutils** предлагает готовые решения для всех этих проблем.
48
+
49
+ ## Ключевые возможности
50
+
51
+ - **✨ Ноль конфигурации:** Библиотека **автоматически** находит корень вашего проекта и файл `config.yml` или
52
+ `config.ini`. Если файл не найден, используются безопасные настройки по умолчанию (например, логирование только в консоль).
53
+ - **⚙️ Гибкая конфигурация:** Поддержка `YAML` и `INI` форматов. Простые функции для получения типизированных данных.
54
+ - **✍️ Продвинутый логгер:** Функция `setup_logger()` "из коробки" настраивает логирование в консоль и в ротируемые
55
+ файлы. Возвращает кастомный логгер с дополнительными уровнями отладки (`devdebug`, `mediumdebug`).
56
+ - **🔒 Безопасное хранилище секретов:** Модуль `secret_manager` предоставляет простой интерфейс для сохранения и
57
+ получения секретов. Поддерживает системное хранилище `keyring` и может использовать `.env` файлы как запасной вариант.
58
+ - **🚀 Готовность к работе:** Просто установите и используйте.
59
+
60
+ ## Установка
61
+
62
+ ```bash
63
+ poetry add chutils
64
+ ```
65
+
66
+ Или с помощью pip:
67
+
68
+ ```bash
69
+ pip install chutils
70
+ ```
71
+
72
+ Для разработки клонируйте репозиторий и установите его в режиме редактирования:
73
+
74
+ ```bash
75
+ git clone https://github.com/Chu4hel/chutils.git
76
+ cd chutils
77
+ pip install -e .
78
+ ```
79
+
80
+ ## Примеры использования
81
+
82
+ В папке [`/examples`](./examples/) вы найдете готовые к запуску скрипты, демонстрирующие ключевые возможности
83
+ библиотеки. Каждый пример сфокусирован на одной конкретной задаче.
84
+
85
+ ## Быстрый старт
86
+
87
+ ### 1. Работа с конфигурацией
88
+
89
+ 1. (Опционально) Создайте файл `config.yml` в корне вашего проекта. Если этого не сделать, библиотека будет использовать настройки по умолчанию:
90
+
91
+ ```yaml
92
+ # config.yml
93
+ Database:
94
+ host: localhost
95
+ port: 5432
96
+ user: my_user
97
+ ```
98
+
99
+ 2. Получайте значения в вашем коде:
100
+
101
+ ```python
102
+ # main.py
103
+ from chutils import get_config_value, get_config_int
104
+
105
+ db_host = get_config_value("Database", "host", fallback="127.0.0.1")
106
+ db_port = get_config_int("Database", "port", fallback=5433)
107
+
108
+ print(f"Подключаемся к БД по адресу: {db_host}:{db_port}")
109
+ # Вывод: Подключаемся к БД по адресу: localhost:5432
110
+ ```
111
+ `chutils` автоматически найдет `config.yml` и прочитает из него данные.
112
+
113
+ #### Переопределение конфигурации локальным файлом (`config.local.yml`)
114
+
115
+ Вы можете создать локальный файл конфигурации (например, `config.local.yml` или `config.local.ini`) рядом с основным
116
+ файлом (`config.yml` или `config.ini`). Значения из локального файла будут **переопределять** соответствующие
117
+ значения из основного файла. Это удобно для:
118
+ - Хранения чувствительных данных, которые не должны попадать в систему контроля версий (добавьте `config.local.yml` в `.gitignore`).
119
+ - Переопределения настроек для локальной разработки без изменения основного файла.
120
+
121
+ Пример:
122
+ Если `config.yml` содержит:
123
+ ```yaml
124
+ # config.yml
125
+ Database:
126
+ host: production_db.com
127
+ port: 5432
128
+ App:
129
+ debug: false
130
+ ```
131
+ А `config.local.yml` содержит:
132
+ ```yaml
133
+ # config.local.yml
134
+ Database:
135
+ host: localhost
136
+ App:
137
+ debug: true
138
+ developer_mode: true
139
+ ```
140
+ Тогда `get_config()` вернет:
141
+ ```yaml
142
+ Database:
143
+ host: localhost # Переопределено локальным файлом
144
+ port: 5432 # Взято из основного файла
145
+ App:
146
+ debug: true # Переопределено локальным файлом
147
+ developer_mode: true # Добавлено из локального файла
148
+ ```
149
+ **Важно:** Убедитесь, что вы добавили `config.local.yml` (или `config.local.ini`) в ваш `.gitignore`, чтобы случайно
150
+ не закоммитить локальные или чувствительные настройки.
151
+
152
+ ### 2. Настройка логирования
153
+
154
+ 1. Добавьте секцию `Logging` в ваш `config.yml` (опционально):
155
+
156
+ ```yaml
157
+ # config.yml
158
+ Logging:
159
+ log_level: DEBUG
160
+ log_file_name: my_app.log
161
+ ```
162
+
163
+ 2. Используйте логгер:
164
+
165
+ ```python
166
+ # main.py
167
+ from chutils import setup_logger, ChutilsLogger
168
+
169
+ # Настраиваем логгер. Он сам прочитает настройки из конфига.
170
+ logger: ChutilsLogger = setup_logger()
171
+
172
+ logger.info("Приложение запущено.")
173
+ logger.debug("Это отладочное сообщение.")
174
+ # Вывод в консоли и запись в файл logs/my_app.log
175
+ ```
176
+ Папка `logs` будет создана автоматически.
177
+
178
+ Вы также можете указать имя файла лога напрямую при вызове `setup_logger`, переопределив значение из конфигурации:
179
+ ```python
180
+ # main.py
181
+ from chutils import setup_logger, ChutilsLogger
182
+
183
+ # Логгер будет писать в custom.log, игнорируя log_file_name из config.yml
184
+ logger: ChutilsLogger = setup_logger(log_file_name="custom.log")
185
+
186
+ logger.info("Сообщение в кастомном файле.")
187
+ ```
188
+
189
+ #### Создание нескольких логгеров
190
+
191
+ Вы можете создавать разные логгеры для разных частей вашего приложения, передавая уникальное имя в `setup_logger`. Это
192
+ помогает фильтровать и разделять логи.
193
+
194
+ ```python
195
+ # main.py
196
+ from chutils import setup_logger
197
+
198
+ # Основной логгер приложения будет писать в main_app.log
199
+ main_logger = setup_logger("main_app", log_file_name="main_app.log")
200
+ # Логгер для модуля, отвечающего за работу с базой данных, будет писать в database.log
201
+ db_logger = setup_logger("database", log_file_name="database.log")
202
+
203
+ main_logger.info("Приложение запущено.")
204
+ db_logger.debug("Инициализация подключения к БД...")
205
+ ```
206
+ В лог-файлах вы увидите сообщения от соответствующих логгеров.
207
+ Более подробный пример можно найти в [`/examples/05_different_log_levels.py`](./examples/05_different_log_levels.py).
208
+
209
+ ### 3. Управление секретами
210
+
211
+ `SecretManager` ищет секреты в следующем порядке:
212
+ 1. **Системное хранилище (`keyring`)**: Наиболее безопасный способ.
213
+ 2. **Файл `.env`**: Если секрет не найден в `keyring`, менеджер будет искать его в файле `.env` в корне вашего проекта.
214
+ 3. **Переменные окружения**: Если секрета нет и там, будет произведен поиск в переменных окружения ОС.
215
+
216
+ #### Способ 1: Keyring (рекомендуемый)
217
+
218
+ 1. Инициализируйте `SecretManager` и сохраните ваш секрет. **Это нужно сделать один раз.**
219
+
220
+ ```python
221
+ # setup_secrets.py
222
+ from chutils import SecretManager
223
+
224
+ secrets = SecretManager("my_awesome_app")
225
+ secrets.save_secret("DB_PASSWORD", "MySuperSecretDbPassword123!")
226
+ print("Пароль от БД сохранен в системном хранилище!")
227
+ ```
228
+
229
+ 2. Получайте секрет в основном коде, не "светя" им:
230
+
231
+ ```python
232
+ # main.py
233
+ from chutils import SecretManager, get_config_value
234
+
235
+ secrets = SecretManager("my_awesome_app")
236
+ db_user = get_config_value("Database", "user")
237
+
238
+ # Получаем пароль из безопасного хранилища
239
+ db_password = secrets.get_secret("DB_PASSWORD")
240
+
241
+ if db_password:
242
+ print(f"Получен пароль для пользователя {db_user}.")
243
+ else:
244
+ print("Пароль не найден!")
245
+ ```
246
+
247
+ #### Способ 2: Файл .env (удобно для Docker и CI/CD)
248
+
249
+ 1. Создайте файл `.env` в корне вашего проекта:
250
+ ```dotenv
251
+ # .env
252
+ DB_PASSWORD="AnotherSecretPassword"
253
+ API_KEY="abcdef123456"
254
+ ```
255
+
256
+ 2. `SecretManager` автоматически найдет этот файл и прочитает из него переменные, если не найдет их в `keyring`.
257
+
258
+ ```python
259
+ # main.py
260
+ from chutils import SecretManager
261
+
262
+ secrets = SecretManager("my_awesome_app")
263
+
264
+ # Этот секрет будет взят из .env, если его нет в keyring
265
+ api_key = secrets.get_secret("API_KEY")
266
+ print(f"Найден API ключ: {api_key}")
267
+ ```
268
+
269
+ ## Комплексный пример
270
+
271
+ Этот пример показывает, как все компоненты `chutils` работают вместе.
272
+
273
+ 1. **Файл `config.yml`:**
274
+ ```yaml
275
+ API:
276
+ base_url: https://api.example.com
277
+
278
+ Database:
279
+ host: localhost
280
+ port: 5432
281
+ user: my_user
282
+
283
+ Logging:
284
+ log_level: INFO
285
+ ```
286
+
287
+ 2. **Код `main.py`:**
288
+ ```python
289
+ # main.py
290
+ from chutils import get_config_value, setup_logger, SecretManager, ChutilsLogger
291
+
292
+ # 1. Настраиваем логгер. Он автоматически прочитает настройки из конфига.
293
+ logger: ChutilsLogger = setup_logger()
294
+
295
+ # 2. Инициализируем менеджер секретов для нашего приложения.
296
+ secrets = SecretManager("my_awesome_app")
297
+
298
+ def setup_credentials():
299
+ """Функция для первоначального сохранения пароля, если его нет."""
300
+ db_user = get_config_value("Database", "user")
301
+ password_key = f"{db_user}_password"
302
+
303
+ if not secrets.get_secret(password_key):
304
+ logger.info("Пароль для БД не найден. Сохраняем новый...")
305
+ secrets.save_secret(password_key, "MySuperSecretDbPassword123!")
306
+ logger.info("Пароль для БД сохранен в системном хранилище.")
307
+
308
+ def connect_to_db():
309
+ """Пример подключения к БД с использованием конфига и секретов."""
310
+ db_host = get_config_value("Database", "host")
311
+ db_user = get_config_value("Database", "user")
312
+ db_password = secrets.get_secret(f"{db_user}_password")
313
+
314
+ if not db_password:
315
+ logger.error("Не удалось получить пароль для БД!")
316
+ return
317
+
318
+ logger.info(f"Подключаемся к {db_host} от имени {db_user}...")
319
+ # ... логика подключения ...
320
+ logger.info("Успешно подключились!")
321
+
322
+ def main():
323
+ logger.info("Приложение запущено.")
324
+ setup_credentials()
325
+ connect_to_db()
326
+ logger.info("Приложение завершило работу.")
327
+
328
+ if __name__ == "__main__":
329
+ main()
330
+ ```
331
+
332
+ ## API
333
+
334
+ ### Работа с конфигурацией (`chutils.config`)
335
+
336
+ - `get_config_value(section, key, fallback="")`: Получить значение.
337
+ - `get_config_int(section, key, fallback=0)`: Получить целое число.
338
+ - `get_config_boolean(section, key, fallback=False)`: Получить булево значение.
339
+ - `get_config_list(section, key, fallback=[])`: Получить список.
340
+ - `get_config_section(section)`: Получить всю секцию как словарь.
341
+ - `save_config_value(section, key, value)`: Сохранить значение. Работает для `.yml` и `.ini`.
342
+ **Важно**: при сохранении в `.yml` комментарии и форматирование будут утеряны. При сохранении в `.ini` - сохраняются.
343
+
344
+ ### Настройка логирования (`chutils.logger`)
345
+
346
+ - `setup_logger(name='app_logger', log_level_str='')`: Настраивает и возвращает экземпляр `ChutilsLogger`.
347
+ - `logger.mediumdebug("message")`: Логирование с уровнем 15. Промежуточный уровень между `DEBUG` и `INFO`.
348
+ - `logger.devdebug("message")`: Логирование с уровнем 9. Самый подробный уровень для глубокой отладки (например, для вывода дампов переменных).
349
+
350
+ ### Управление секретами (`chutils.secret_manager`)
351
+
352
+ - `SecretManager(service_name, prefix="Chutils_")`: Создает менеджер, изолированный по имени сервиса.
353
+ - `secrets.save_secret(key, value)`: Сохраняет секрет.
354
+ - `secrets.get_secret(key)`: Получает секрет.
355
+ - `secrets.delete_secret(key)`: Удаляет секрет.
356
+
357
+ ### Декораторы (`chutils.decorators`)
358
+
359
+ - `log_function_details`: Декоратор для логирования деталей вызова функции (аргументы, время выполнения, результат).
360
+
361
+ ### Ручная инициализация (`chutils.init`)
362
+
363
+ В 99% случаев вам это **не понадобится**. Но если автоматика не справилась, вы можете один раз указать путь к проекту
364
+ вручную в самом начале работы приложения:
365
+
366
+ ```python
367
+ import chutils
368
+
369
+ chutils.init(base_dir="/path/to/my/project/root")
370
+ ```
371
+
372
+ ### Особенности `secret_manager` (Keyring)
373
+
374
+ Модуль `SecretManager` использует библиотеку `keyring` для безопасного хранения секретов в системном хранилище.
375
+
376
+ - На **Windows** и **macOS** это работает "из коробки".
377
+ - **Требования для Linux**: На Linux для безопасной работы `keyring` требуется установленный и настроенный "бэкенд"
378
+ (хранилище секретов), например, `GNOME Keyring` (Seahorse) или `KWallet`. На серверах или минималистичных сборках его
379
+ может понадобиться установить вручную.
380
+ Подробнее — в [официальной документации `keyring`](https://keyring.readthedocs.io/en/latest/).
381
+ - **Использование на мобильных ОС**: Этот модуль **не предназначен** для использования на мобильных операционных
382
+ системах (Android, iOS). `keyring` с высокой вероятностью не найдет системного хранилища и будет использовать
383
+ **незащищенный** способ хранения ваших секретов.
384
+
385
+ ## Лицензия
386
+
387
+ Проект распространяется под лицензией MIT.
388
+