chutils 2.6.1__tar.gz → 2.7.1__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.
Files changed (64) hide show
  1. chutils-2.6.1/README.md → chutils-2.7.1/PKG-INFO +127 -1
  2. chutils-2.6.1/PKG-INFO → chutils-2.7.1/README.md +74 -33
  3. {chutils-2.6.1 → chutils-2.7.1}/pyproject.toml +23 -2
  4. chutils-2.7.1/src/chutils/__init__.py +184 -0
  5. chutils-2.7.1/src/chutils/__init__.pyi +226 -0
  6. chutils-2.7.1/src/chutils/cache/__init__.py +5 -0
  7. chutils-2.7.1/src/chutils/cache/base.py +85 -0
  8. chutils-2.7.1/src/chutils/cache/decorator.py +93 -0
  9. chutils-2.7.1/src/chutils/cache/in_memory.py +70 -0
  10. chutils-2.7.1/src/chutils/cache/utils.py +51 -0
  11. chutils-2.7.1/src/chutils/cli.py +57 -0
  12. chutils-2.7.1/src/chutils/cli_booster.py +151 -0
  13. chutils-2.7.1/src/chutils/cli_utils.py +95 -0
  14. chutils-2.7.1/src/chutils/commands/__init__.py +29 -0
  15. chutils-2.7.1/src/chutils/commands/base.py +39 -0
  16. chutils-2.7.1/src/chutils/commands/config.py +123 -0
  17. chutils-2.7.1/src/chutils/commands/dev.py +162 -0
  18. chutils-2.7.1/src/chutils/commands/init.py +135 -0
  19. chutils-2.7.1/src/chutils/commands/paths.py +78 -0
  20. chutils-2.7.1/src/chutils/commands/secrets.py +81 -0
  21. chutils-2.7.1/src/chutils/commands/template.py +92 -0
  22. chutils-2.7.1/src/chutils/commands/utils.py +24 -0
  23. chutils-2.7.1/src/chutils/commands/validate.py +76 -0
  24. chutils-2.7.1/src/chutils/config/GEMINI.md +23 -0
  25. chutils-2.7.1/src/chutils/config/__init__.py +222 -0
  26. chutils-2.7.1/src/chutils/config/core.py +273 -0
  27. chutils-2.7.1/src/chutils/config/diagnostics.py +128 -0
  28. chutils-2.7.1/src/chutils/config/generator.py +134 -0
  29. chutils-2.7.1/src/chutils/config/getters.py +280 -0
  30. chutils-2.7.1/src/chutils/config/manager.py +435 -0
  31. chutils-2.7.1/src/chutils/config/providers.py +459 -0
  32. chutils-2.7.1/src/chutils/config/schema.py +114 -0
  33. {chutils-2.6.1 → chutils-2.7.1}/src/chutils/config/utils.py +27 -11
  34. {chutils-2.6.1 → chutils-2.7.1}/src/chutils/config/watcher.py +16 -12
  35. {chutils-2.6.1 → chutils-2.7.1}/src/chutils/context.py +13 -0
  36. {chutils-2.6.1 → chutils-2.7.1}/src/chutils/decorators.py +14 -4
  37. chutils-2.7.1/src/chutils/dev/__init__.py +3 -0
  38. chutils-2.7.1/src/chutils/dev/ast_indexer.py +279 -0
  39. chutils-2.7.1/src/chutils/dev/models.py +64 -0
  40. chutils-2.7.1/src/chutils/exceptions.py +86 -0
  41. chutils-2.7.1/src/chutils/features.py +187 -0
  42. chutils-2.7.1/src/chutils/fs.py +130 -0
  43. chutils-2.7.1/src/chutils/lifecycle.py +199 -0
  44. chutils-2.7.1/src/chutils/logger/GEMINI.md +21 -0
  45. chutils-2.7.1/src/chutils/logger/__init__.py +38 -0
  46. chutils-2.6.1/src/chutils/logger.py → chutils-2.7.1/src/chutils/logger/core.py +157 -297
  47. chutils-2.7.1/src/chutils/logger/formatters.py +48 -0
  48. chutils-2.7.1/src/chutils/logger/handlers.py +124 -0
  49. chutils-2.7.1/src/chutils/logger/masking.py +102 -0
  50. chutils-2.7.1/src/chutils/secret_manager/GEMINI.md +20 -0
  51. chutils-2.7.1/src/chutils/secret_manager/__init__.py +10 -0
  52. chutils-2.7.1/src/chutils/secret_manager/core.py +189 -0
  53. chutils-2.7.1/src/chutils/secret_manager/providers.py +249 -0
  54. chutils-2.7.1/src/chutils/testing/__init__.py +11 -0
  55. chutils-2.7.1/src/chutils/testing/fixtures.py +205 -0
  56. chutils-2.7.1/src/chutils/time.py +202 -0
  57. chutils-2.7.1/src/chutils/tracing.py +187 -0
  58. chutils-2.6.1/src/chutils/__init__.py +0 -127
  59. chutils-2.6.1/src/chutils/cli.py +0 -71
  60. chutils-2.6.1/src/chutils/config/__init__.py +0 -647
  61. chutils-2.6.1/src/chutils/config/manager.py +0 -98
  62. chutils-2.6.1/src/chutils/config/providers.py +0 -234
  63. chutils-2.6.1/src/chutils/secret_manager.py +0 -338
  64. {chutils-2.6.1 → chutils-2.7.1}/LICENSE +0 -0
@@ -1,3 +1,55 @@
1
+ Metadata-Version: 2.4
2
+ Name: chutils
3
+ Version: 2.7.1
4
+ Summary: Набор простых и удобных утилит для Python, который избавляет от рутины при работе с конфигурацией и логированием в новых проектах.
5
+ License-Expression: MIT
6
+ License-File: LICENSE
7
+ Author: Chu4hel
8
+ Author-email: sergeiivanov636@gmail.com
9
+ Requires-Python: >=3.9, !=3.9.0, !=3.9.1
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Programming Language :: Python :: 3.14
16
+ Provides-Extra: date
17
+ Provides-Extra: full
18
+ Provides-Extra: json
19
+ Provides-Extra: otel
20
+ Provides-Extra: pydantic
21
+ Provides-Extra: rich
22
+ Provides-Extra: secrets
23
+ Provides-Extra: testing
24
+ Provides-Extra: watch
25
+ Requires-Dist: keyring (>=25.7.0)
26
+ Requires-Dist: keyring (>=25.7.0) ; extra == "full"
27
+ Requires-Dist: keyring (>=25.7.0) ; extra == "secrets"
28
+ Requires-Dist: opentelemetry-api (>=1.41.1) ; extra == "full"
29
+ Requires-Dist: opentelemetry-api (>=1.41.1) ; extra == "otel"
30
+ Requires-Dist: opentelemetry-exporter-otlp (>=1.41.1) ; extra == "full"
31
+ Requires-Dist: opentelemetry-exporter-otlp (>=1.41.1) ; extra == "otel"
32
+ Requires-Dist: opentelemetry-sdk (>=1.41.1) ; extra == "full"
33
+ Requires-Dist: opentelemetry-sdk (>=1.41.1) ; extra == "otel"
34
+ Requires-Dist: pydantic (>=2.13.4) ; extra == "full"
35
+ Requires-Dist: pydantic (>=2.13.4,<3.0.0) ; extra == "pydantic"
36
+ Requires-Dist: pytest (>=8.0.0) ; (python_full_version < "3.10.0") and (extra == "full")
37
+ Requires-Dist: pytest (>=8.0.0) ; (python_full_version < "3.10.0") and (extra == "testing")
38
+ Requires-Dist: pytest (>=9.0.3) ; (python_full_version >= "3.10.0") and (extra == "full")
39
+ Requires-Dist: pytest (>=9.0.3) ; (python_full_version >= "3.10.0") and (extra == "testing")
40
+ Requires-Dist: python-dateutil (>=2.9.0) ; extra == "date"
41
+ Requires-Dist: python-dateutil (>=2.9.0) ; extra == "full"
42
+ Requires-Dist: python-dotenv (>=1.2.1) ; python_full_version < "3.10.0"
43
+ Requires-Dist: python-dotenv (>=1.2.2) ; python_full_version >= "3.10.0"
44
+ Requires-Dist: python-json-logger (>=3.2.1) ; extra == "full"
45
+ Requires-Dist: python-json-logger (>=3.2.1) ; extra == "json"
46
+ Requires-Dist: pyyaml (>=6.0.3)
47
+ Requires-Dist: rich (>=15.0.0) ; extra == "full"
48
+ Requires-Dist: rich (>=15.0.0) ; extra == "rich"
49
+ Requires-Dist: watchdog (>=6.0.0) ; extra == "full"
50
+ Requires-Dist: watchdog (>=6.0.0) ; extra == "watch"
51
+ Description-Content-Type: text/markdown
52
+
1
53
  [Русская версия](docs/README_RU.md)
2
54
 
3
55
  # chutils: Stop the Routine!
@@ -34,6 +86,12 @@ Every time you start a new project, you have to solve the same tasks:
34
86
  box. It returns a custom logger with additional debug levels (`devdebug`, `mediumdebug`).
35
87
  - **🔒 Secure Secret Storage:** The `secret_manager` module provides a simple interface for saving and retrieving secrets
36
88
  via the system `keyring`, with a fallback to `.env` files.
89
+ - **🚀 CLI Booster:** Turn any function into a CLI tool in seconds using the `@cli_command` decorator with automatic type
90
+ mapping and docstring parsing.
91
+ - **⏰ Painless Datetime:** Always-aware UTC time utilities, smart parsing, and human-readable time intervals.
92
+ - **📡 Distributed Tracing:** Seamless OpenTelemetry integration with `@trace` decorator and automatic log correlation.
93
+ - **🔍 Config Diagnostics:** Interactive trace of configuration sources and priorities via `config debug` command.
94
+ - **🌐 Remote Configuration:** Load settings from HTTP/HTTPS endpoints with background polling and fallback support.
37
95
  - **🔄 Hot-Reload:** Support for automatic configuration reloading on file changes without restart (requires
38
96
  `pip install chutils[watch]`).
39
97
  - **⚡ Async Ready:** Most core functions have asynchronous versions (prefixed with `a`) for non-blocking execution.
@@ -249,8 +307,15 @@ In environments like Docker or CI/CD where `keyring` is unavailable, you can sup
249
307
  - `@log_function_details`: Logs arguments, execution time, and result (uses `DEVDEBUG` level).
250
308
  - `@timeout(seconds, fallback)`: Limits function execution time. Supports sync/async and optional fallback.
251
309
  - `@retry`: Automatically retries a function if it fails. Supports sync/async, backoff, jitter, and exception filtering.
310
+ - `@cli_command`: Turns any function into a standalone CLI script with automatic argument parsing.
311
+
312
+ ### Time & Dates (`chutils.time`)
313
+
314
+ - `utc_now()`: Returns a timezone-aware UTC datetime.
315
+ - `parse_datetime(value)`: Smart parsing of strings and timestamps into UTC.
316
+ - `humanize_timedelta(dt)`: Returns human-readable strings like "5 minutes ago" or "tomorrow".
252
317
 
253
- #### Example of @retry usage:
318
+ ### Example of @retry usage:
254
319
 
255
320
  ```python
256
321
  from chutils.decorators import retry
@@ -262,6 +327,67 @@ def fetch_data():
262
327
  ...
263
328
  ```
264
329
 
330
+ ## Command Line Interface (CLI)
331
+
332
+ `chutils` includes a set of tools to speed up development and debugging.
333
+
334
+ ### 1. Initialize Project
335
+
336
+ Quickly set up a new project with a default configuration and `.gitignore` rules:
337
+
338
+ ```bash
339
+ # Interactive mode
340
+ chutils init
341
+
342
+ # Non-interactive mode (default values)
343
+ chutils init -y
344
+ ```
345
+
346
+ ### 2. Validate Configuration
347
+
348
+ Check if your configuration files match your Pydantic models:
349
+
350
+ ```bash
351
+ # Automatically finds 'Settings' class in context.py or config.py
352
+ chutils validate
353
+
354
+ # Explicitly specify the model path
355
+ chutils validate --model src.settings:AppConfig
356
+ ```
357
+
358
+ ### 3. Debug Search Paths
359
+
360
+ See exactly where `chutils` is looking for configuration files:
361
+
362
+ ```bash
363
+ # Human-readable output
364
+ chutils show-paths
365
+
366
+ # JSON output for automation
367
+ chutils show-paths --json
368
+ ```
369
+
370
+ ### 4. Manage Secrets
371
+
372
+ Manage your system keyring secrets directly from the terminal:
373
+
374
+ ```bash
375
+ # Set a secret
376
+ chutils secrets set API_KEY "your-secret-value" --service my_app
377
+
378
+ # Delete a secret
379
+ chutils secrets delete API_KEY --service my_app
380
+ ```
381
+
382
+ ### 5. Debug Configuration
383
+
384
+ Trace exactly where each configuration value comes from:
385
+
386
+ ```bash
387
+ chutils config debug
388
+ ```
389
+
265
390
  ## License
266
391
 
267
392
  The project is distributed under the MIT License.
393
+
@@ -1,34 +1,3 @@
1
- Metadata-Version: 2.4
2
- Name: chutils
3
- Version: 2.6.1
4
- Summary: Набор простых и удобных утилит для Python, который избавляет от рутины при работе с конфигурацией и логированием в новых проектах.
5
- License-Expression: MIT
6
- License-File: LICENSE
7
- Author: Chu4hel
8
- Author-email: sergeiivanov636@gmail.com
9
- Requires-Python: >=3.9, !=3.9.0, !=3.9.1
10
- Classifier: Programming Language :: Python :: 3
11
- Classifier: Programming Language :: Python :: 3.10
12
- Classifier: Programming Language :: Python :: 3.11
13
- Classifier: Programming Language :: Python :: 3.12
14
- Classifier: Programming Language :: Python :: 3.13
15
- Classifier: Programming Language :: Python :: 3.14
16
- Provides-Extra: full
17
- Provides-Extra: json
18
- Provides-Extra: pydantic
19
- Provides-Extra: watch
20
- Requires-Dist: keyring (>=25.7.0)
21
- Requires-Dist: pydantic (>=2.13.4) ; extra == "full"
22
- Requires-Dist: pydantic (>=2.13.4,<3.0.0) ; extra == "pydantic"
23
- Requires-Dist: python-dotenv (>=1.2.1) ; python_full_version < "3.10.0"
24
- Requires-Dist: python-dotenv (>=1.2.2) ; python_full_version >= "3.10.0"
25
- Requires-Dist: python-json-logger (>=3.2.1) ; extra == "full"
26
- Requires-Dist: python-json-logger (>=3.2.1) ; extra == "json"
27
- Requires-Dist: pyyaml (>=6.0.3)
28
- Requires-Dist: watchdog (>=6.0.0) ; extra == "full"
29
- Requires-Dist: watchdog (>=6.0.0) ; extra == "watch"
30
- Description-Content-Type: text/markdown
31
-
32
1
  [Русская версия](docs/README_RU.md)
33
2
 
34
3
  # chutils: Stop the Routine!
@@ -65,6 +34,12 @@ Every time you start a new project, you have to solve the same tasks:
65
34
  box. It returns a custom logger with additional debug levels (`devdebug`, `mediumdebug`).
66
35
  - **🔒 Secure Secret Storage:** The `secret_manager` module provides a simple interface for saving and retrieving secrets
67
36
  via the system `keyring`, with a fallback to `.env` files.
37
+ - **🚀 CLI Booster:** Turn any function into a CLI tool in seconds using the `@cli_command` decorator with automatic type
38
+ mapping and docstring parsing.
39
+ - **⏰ Painless Datetime:** Always-aware UTC time utilities, smart parsing, and human-readable time intervals.
40
+ - **📡 Distributed Tracing:** Seamless OpenTelemetry integration with `@trace` decorator and automatic log correlation.
41
+ - **🔍 Config Diagnostics:** Interactive trace of configuration sources and priorities via `config debug` command.
42
+ - **🌐 Remote Configuration:** Load settings from HTTP/HTTPS endpoints with background polling and fallback support.
68
43
  - **🔄 Hot-Reload:** Support for automatic configuration reloading on file changes without restart (requires
69
44
  `pip install chutils[watch]`).
70
45
  - **⚡ Async Ready:** Most core functions have asynchronous versions (prefixed with `a`) for non-blocking execution.
@@ -280,8 +255,15 @@ In environments like Docker or CI/CD where `keyring` is unavailable, you can sup
280
255
  - `@log_function_details`: Logs arguments, execution time, and result (uses `DEVDEBUG` level).
281
256
  - `@timeout(seconds, fallback)`: Limits function execution time. Supports sync/async and optional fallback.
282
257
  - `@retry`: Automatically retries a function if it fails. Supports sync/async, backoff, jitter, and exception filtering.
258
+ - `@cli_command`: Turns any function into a standalone CLI script with automatic argument parsing.
259
+
260
+ ### Time & Dates (`chutils.time`)
261
+
262
+ - `utc_now()`: Returns a timezone-aware UTC datetime.
263
+ - `parse_datetime(value)`: Smart parsing of strings and timestamps into UTC.
264
+ - `humanize_timedelta(dt)`: Returns human-readable strings like "5 minutes ago" or "tomorrow".
283
265
 
284
- #### Example of @retry usage:
266
+ ### Example of @retry usage:
285
267
 
286
268
  ```python
287
269
  from chutils.decorators import retry
@@ -293,7 +275,66 @@ def fetch_data():
293
275
  ...
294
276
  ```
295
277
 
278
+ ## Command Line Interface (CLI)
279
+
280
+ `chutils` includes a set of tools to speed up development and debugging.
281
+
282
+ ### 1. Initialize Project
283
+
284
+ Quickly set up a new project with a default configuration and `.gitignore` rules:
285
+
286
+ ```bash
287
+ # Interactive mode
288
+ chutils init
289
+
290
+ # Non-interactive mode (default values)
291
+ chutils init -y
292
+ ```
293
+
294
+ ### 2. Validate Configuration
295
+
296
+ Check if your configuration files match your Pydantic models:
297
+
298
+ ```bash
299
+ # Automatically finds 'Settings' class in context.py or config.py
300
+ chutils validate
301
+
302
+ # Explicitly specify the model path
303
+ chutils validate --model src.settings:AppConfig
304
+ ```
305
+
306
+ ### 3. Debug Search Paths
307
+
308
+ See exactly where `chutils` is looking for configuration files:
309
+
310
+ ```bash
311
+ # Human-readable output
312
+ chutils show-paths
313
+
314
+ # JSON output for automation
315
+ chutils show-paths --json
316
+ ```
317
+
318
+ ### 4. Manage Secrets
319
+
320
+ Manage your system keyring secrets directly from the terminal:
321
+
322
+ ```bash
323
+ # Set a secret
324
+ chutils secrets set API_KEY "your-secret-value" --service my_app
325
+
326
+ # Delete a secret
327
+ chutils secrets delete API_KEY --service my_app
328
+ ```
329
+
330
+ ### 5. Debug Configuration
331
+
332
+ Trace exactly where each configuration value comes from:
333
+
334
+ ```bash
335
+ chutils config debug
336
+ ```
337
+
296
338
  ## License
297
339
 
298
340
  The project is distributed under the MIT License.
299
-
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "chutils"
3
- version = "2.6.1"
3
+ version = "2.7.1"
4
4
  description = "Набор простых и удобных утилит для Python, который избавляет от рутины при работе с конфигурацией и логированием в новых проектах."
5
5
  authors = [{name = "Chu4hel", email = "sergeiivanov636@gmail.com"}]
6
6
  license = "MIT"
@@ -14,13 +14,33 @@ dependencies = [
14
14
  ]
15
15
 
16
16
  [project.optional-dependencies]
17
+ secrets = ["keyring (>=25.7.0)"]
17
18
  pydantic = ["pydantic (>=2.13.4,<3.0.0)"]
18
19
  json = ["python-json-logger (>=3.2.1)"]
19
20
  watch = ["watchdog (>=6.0.0)"]
21
+ rich = ["rich (>=15.0.0)"]
22
+ date = ["python-dateutil (>=2.9.0)"]
23
+ testing = [
24
+ "pytest (>=8.0.0) ; python_full_version < '3.10'",
25
+ "pytest (>=9.0.3) ; python_full_version >= '3.10'"
26
+ ]
27
+ otel = [
28
+ "opentelemetry-api (>=1.41.1)",
29
+ "opentelemetry-sdk (>=1.41.1)",
30
+ "opentelemetry-exporter-otlp (>=1.41.1)"
31
+ ]
20
32
  full = [
21
33
  "pydantic (>=2.13.4)",
22
34
  "python-json-logger (>=3.2.1)",
23
- "watchdog (>=6.0.0)"
35
+ "watchdog (>=6.0.0)",
36
+ "rich (>=15.0.0)",
37
+ "python-dateutil (>=2.9.0)",
38
+ "opentelemetry-api (>=1.41.1)",
39
+ "opentelemetry-sdk (>=1.41.1)",
40
+ "opentelemetry-exporter-otlp (>=1.41.1)",
41
+ "keyring (>=25.7.0)",
42
+ "pytest (>=8.0.0) ; python_full_version < '3.10'",
43
+ "pytest (>=9.0.3) ; python_full_version >= '3.10'"
24
44
  ]
25
45
 
26
46
  [project.scripts]
@@ -59,6 +79,7 @@ mkdocstrings-python = { version = "^2.0.3", python = ">=3.10" }
59
79
  pytest-cov = "^7.1.0"
60
80
  pytest-asyncio = { version = "^1.3.0", python = ">=3.10" }
61
81
  ruff = "^0.15.12"
82
+ rich = "^15.0.0"
62
83
 
63
84
  [build-system]
64
85
  requires = ["poetry-core>=2.0.0,<3.0.0"]
@@ -0,0 +1,184 @@
1
+ """
2
+ Пакет chutils - набор переиспользуемых утилит для Python.
3
+
4
+ Основная цель - упростить рутинные задачи, такие как работа с конфигурацией,
5
+ логированием и управлением секретами, с минимальными усилиями со стороны разработчика.
6
+
7
+ Ключевые особенности:
8
+ - Автоматическое обнаружение корня проекта и файла конфигурации.
9
+ - Поддержка форматов `config.yml`, `config.yaml` и `config.ini` (YAML в приоритете).
10
+ - Удобные функции для доступа к настройкам, включая разрешение путей.
11
+ - Асинхронные версии основных функций для неблокирующей работы.
12
+ - Готовый к работе логгер с выводом в консоль и ротируемые файлы.
13
+ - Безопасное хранение секретов через системное хранилище (keyring).
14
+
15
+ Основное использование:
16
+ ----------------------
17
+ Вам не нужно ничего инициализировать. Просто импортируйте и используйте:
18
+
19
+ from chutils import get_config_value, setup_logger, SecretManager
20
+
21
+ logger = setup_logger()
22
+ secrets = SecretManager("my_app")
23
+ db_host = get_config_value("Database", "host", "localhost")
24
+ logger.info(f"Подключение к базе данных на {db_host}")
25
+
26
+ Ручная инициализация (для нестандартных случаев):
27
+ -------------------------------------------------
28
+ Если автоматика не сработала, вы можете указать путь к корню проекта вручную:
29
+
30
+ import chutils
31
+ chutils.init(base_dir="/path/to/your/project")
32
+
33
+ """
34
+
35
+ import importlib
36
+ import os
37
+ from typing import Any
38
+
39
+ # Словарь соответствия имен атрибутов их модулям и именам внутри этих модулей.
40
+ # Формат: 'имя_атрибута': ('относительный_путь_к_модулю', 'имя_в_модуле' или None для самого модуля)
41
+ _LAZY_MAPPING = {
42
+ # modules
43
+ 'config': ('.config', None),
44
+ 'logger': ('.logger', None),
45
+ 'secret_manager': ('.secret_manager', None),
46
+ 'decorators': ('.decorators', None),
47
+ 'cache': ('.cache', None),
48
+ 'exceptions': ('.exceptions', None),
49
+ 'context': ('.context', None),
50
+ 'lifecycle': ('.lifecycle', None),
51
+ 'time': ('.time', None),
52
+ 'tracing': ('.tracing', None),
53
+ 'testing': ('.testing', None),
54
+
55
+ # config
56
+ 'get_config': ('.config', 'get_config'),
57
+ 'get_config_value': ('.config', 'get_config_value'),
58
+ 'get_config_int': ('.config', 'get_config_int'),
59
+ 'get_config_float': ('.config', 'get_config_float'),
60
+ 'get_config_boolean': ('.config', 'get_config_boolean'),
61
+ 'get_config_list': ('.config', 'get_config_list'),
62
+ 'get_config_section': ('.config', 'get_config_section'),
63
+ 'get_config_path': ('.config', 'get_config_path'),
64
+ 'aget_config': ('.config', 'aget_config'),
65
+ 'save_config_value': ('.config', 'save_config_value'),
66
+ 'asave_config_value': ('.config', 'asave_config_value'),
67
+ 'start_config_watcher': ('.config', 'start_config_watcher'),
68
+ 'stop_config_watcher': ('.config', 'stop_config_watcher'),
69
+ 'on_config_change': ('.config', 'on_config_change'),
70
+ 'generate_yaml_template': ('.config', 'generate_yaml_template'),
71
+ 'generate_env_template': ('.config', 'generate_env_template'),
72
+ 'generate_json_schema': ('.config', 'generate_json_schema'),
73
+
74
+ # features
75
+ 'is_feature_enabled': ('.features', 'is_feature_enabled'),
76
+ 'require_feature': ('.features', 'require_feature'),
77
+
78
+ # logger
79
+ 'setup_logger': ('.logger', 'setup_logger'),
80
+ 'ChutilsLogger': ('.logger', 'ChutilsLogger'),
81
+ 'SafeTimedRotatingFileHandler': ('.logger', 'SafeTimedRotatingFileHandler'),
82
+
83
+ # context
84
+ 'bind_context': ('.context', 'bind_context'),
85
+ 'unbind_context': ('.context', 'unbind_context'),
86
+ 'clear_context': ('.context', 'clear_context'),
87
+
88
+ # lifecycle
89
+ 'register_cleanup': ('.lifecycle', 'register_cleanup'),
90
+ 'setup_graceful_shutdown': ('.lifecycle', 'setup_graceful_shutdown'),
91
+
92
+ # cli_booster
93
+ 'cli_command': ('.cli_booster', 'cli_command'),
94
+
95
+ # time
96
+ 'utc_now': ('.time', 'utc_now'),
97
+ 'parse_datetime': ('.time', 'parse_datetime'),
98
+ 'humanize_timedelta': ('.time', 'humanize_timedelta'),
99
+
100
+ # secret_manager
101
+ 'SecretManager': ('.secret_manager', 'SecretManager'),
102
+
103
+ # decorators
104
+ 'log_function_details': ('.decorators', 'log_function_details'),
105
+ 'retry': ('.decorators', 'retry'),
106
+ 'timeout': ('.decorators', 'timeout'),
107
+
108
+ # tracing
109
+ 'trace': ('.tracing', 'trace'),
110
+ 'setup_tracing': ('.tracing', 'setup_tracing'),
111
+ 'IS_OTEL_AVAILABLE': ('.tracing', 'IS_OTEL_AVAILABLE'),
112
+
113
+ # exceptions
114
+ 'ChutilsException': ('.exceptions', 'ChutilsException'),
115
+ 'ConfigError': ('.exceptions', 'ConfigError'),
116
+ 'ConfigLoadError': ('.exceptions', 'ConfigLoadError'),
117
+ 'ConfigParseError': ('.exceptions', 'ConfigParseError'),
118
+ 'SecretError': ('.exceptions', 'SecretError'),
119
+ 'SecretNotFoundError': ('.exceptions', 'SecretNotFoundError'),
120
+ 'SecretProviderError': ('.exceptions', 'SecretProviderError'),
121
+ 'LoggerConfigurationError': ('.exceptions', 'LoggerConfigurationError'),
122
+ 'WatcherInitializationError': ('.exceptions', 'WatcherInitializationError'),
123
+ 'OptionalDependencyError': ('.exceptions', 'OptionalDependencyError'),
124
+ 'ChutilsTimeoutError': ('.exceptions', 'ChutilsTimeoutError'),
125
+ }
126
+
127
+
128
+ def __getattr__(name: str) -> Any:
129
+ """
130
+ Реализация ленивой загрузки согласно PEP 562.
131
+ Вызывается при обращении к атрибутам модуля, которые не определены явно.
132
+ """
133
+ if name in _LAZY_MAPPING:
134
+ mod_path, attr_name = _LAZY_MAPPING[name]
135
+ module = importlib.import_module(mod_path, __name__)
136
+ if attr_name is None:
137
+ return module
138
+ return getattr(module, attr_name)
139
+
140
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
141
+
142
+
143
+ def __dir__():
144
+ """
145
+ Возвращает список всех доступных атрибутов для поддержки автодополнения и интроспекции.
146
+ """
147
+ return sorted(list(_LAZY_MAPPING.keys()) + [
148
+ 'init', '__all__', '__doc__', '__file__', '__path__',
149
+ '__name__', '__package__', '__spec__'
150
+ ])
151
+
152
+
153
+ def init(base_dir: str):
154
+ """
155
+ Ручная инициализация пакета с указанием базовой директории проекта.
156
+
157
+ Эту функцию нужно вызывать только в том случае, если автоматическое
158
+ определение корня проекта не сработало. Вызывать следует один раз
159
+ в самом начале работы основного скрипта вашего приложения.
160
+
161
+ Args:
162
+ base_dir (str): Абсолютный путь к корневой директории проекта.
163
+
164
+ Raises:
165
+ ChutilsException: Если указанная директория не существует.
166
+ """
167
+ if not os.path.isdir(base_dir):
168
+ # Импортируем исключение лениво
169
+ from .exceptions import ChutilsException
170
+ raise ChutilsException(
171
+ f"Указанная директория base_dir не существует или не является директорией: {base_dir}",
172
+ base_dir=base_dir
173
+ )
174
+
175
+ # Вручную устанавливаем базовую директорию через менеджер состояний.
176
+ from .config.manager import _cm
177
+ _cm.base_dir = base_dir
178
+ _cm.paths_initialized = True
179
+
180
+ print(f"Пакет chutils вручную инициализирован с базовой директорией: {base_dir}")
181
+
182
+
183
+ # --- Определение публичного API (`__all__`) ---
184
+ __all__ = list(_LAZY_MAPPING.keys()) + ['init']