chutils 2.6.0a0__tar.gz → 2.7.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.
Files changed (64) hide show
  1. chutils-2.7.0/PKG-INFO +393 -0
  2. chutils-2.6.0a0/PKG-INFO → chutils-2.7.0/README.md +175 -26
  3. chutils-2.7.0/pyproject.toml +91 -0
  4. chutils-2.7.0/src/chutils/__init__.py +184 -0
  5. chutils-2.7.0/src/chutils/__init__.pyi +226 -0
  6. chutils-2.7.0/src/chutils/cache/__init__.py +5 -0
  7. chutils-2.7.0/src/chutils/cache/base.py +85 -0
  8. chutils-2.7.0/src/chutils/cache/decorator.py +93 -0
  9. chutils-2.7.0/src/chutils/cache/in_memory.py +70 -0
  10. chutils-2.7.0/src/chutils/cache/utils.py +51 -0
  11. chutils-2.7.0/src/chutils/cli.py +57 -0
  12. chutils-2.7.0/src/chutils/cli_booster.py +151 -0
  13. chutils-2.7.0/src/chutils/cli_utils.py +95 -0
  14. chutils-2.7.0/src/chutils/commands/__init__.py +29 -0
  15. chutils-2.7.0/src/chutils/commands/base.py +39 -0
  16. chutils-2.7.0/src/chutils/commands/config.py +123 -0
  17. chutils-2.7.0/src/chutils/commands/dev.py +162 -0
  18. chutils-2.7.0/src/chutils/commands/init.py +135 -0
  19. chutils-2.7.0/src/chutils/commands/paths.py +78 -0
  20. chutils-2.7.0/src/chutils/commands/secrets.py +81 -0
  21. chutils-2.7.0/src/chutils/commands/template.py +92 -0
  22. chutils-2.7.0/src/chutils/commands/utils.py +24 -0
  23. chutils-2.7.0/src/chutils/commands/validate.py +76 -0
  24. chutils-2.7.0/src/chutils/config/GEMINI.md +23 -0
  25. chutils-2.7.0/src/chutils/config/__init__.py +222 -0
  26. chutils-2.7.0/src/chutils/config/core.py +273 -0
  27. chutils-2.7.0/src/chutils/config/diagnostics.py +128 -0
  28. chutils-2.7.0/src/chutils/config/generator.py +134 -0
  29. chutils-2.7.0/src/chutils/config/getters.py +280 -0
  30. chutils-2.7.0/src/chutils/config/manager.py +435 -0
  31. chutils-2.7.0/src/chutils/config/providers.py +459 -0
  32. chutils-2.7.0/src/chutils/config/schema.py +114 -0
  33. chutils-2.7.0/src/chutils/config/utils.py +139 -0
  34. chutils-2.7.0/src/chutils/config/watcher.py +141 -0
  35. chutils-2.7.0/src/chutils/context.py +73 -0
  36. {chutils-2.6.0a0 → chutils-2.7.0}/src/chutils/decorators.py +71 -5
  37. chutils-2.7.0/src/chutils/dev/__init__.py +3 -0
  38. chutils-2.7.0/src/chutils/dev/ast_indexer.py +279 -0
  39. chutils-2.7.0/src/chutils/dev/models.py +64 -0
  40. chutils-2.7.0/src/chutils/exceptions.py +86 -0
  41. chutils-2.7.0/src/chutils/features.py +187 -0
  42. chutils-2.7.0/src/chutils/fs.py +130 -0
  43. chutils-2.7.0/src/chutils/lifecycle.py +199 -0
  44. chutils-2.7.0/src/chutils/logger/GEMINI.md +21 -0
  45. chutils-2.7.0/src/chutils/logger/__init__.py +38 -0
  46. chutils-2.7.0/src/chutils/logger/core.py +539 -0
  47. chutils-2.7.0/src/chutils/logger/formatters.py +45 -0
  48. chutils-2.7.0/src/chutils/logger/handlers.py +124 -0
  49. chutils-2.7.0/src/chutils/logger/masking.py +102 -0
  50. chutils-2.7.0/src/chutils/secret_manager/GEMINI.md +20 -0
  51. chutils-2.7.0/src/chutils/secret_manager/__init__.py +10 -0
  52. chutils-2.7.0/src/chutils/secret_manager/core.py +189 -0
  53. chutils-2.7.0/src/chutils/secret_manager/providers.py +249 -0
  54. chutils-2.7.0/src/chutils/testing/__init__.py +11 -0
  55. chutils-2.7.0/src/chutils/testing/fixtures.py +205 -0
  56. chutils-2.7.0/src/chutils/time.py +202 -0
  57. chutils-2.7.0/src/chutils/tracing.py +187 -0
  58. chutils-2.6.0a0/README.md +0 -168
  59. chutils-2.6.0a0/pyproject.toml +0 -62
  60. chutils-2.6.0a0/src/chutils/__init__.py +0 -114
  61. chutils-2.6.0a0/src/chutils/config.py +0 -751
  62. chutils-2.6.0a0/src/chutils/logger.py +0 -620
  63. chutils-2.6.0a0/src/chutils/secret_manager.py +0 -328
  64. {chutils-2.6.0a0 → chutils-2.7.0}/LICENSE +0 -0
chutils-2.7.0/PKG-INFO ADDED
@@ -0,0 +1,393 @@
1
+ Metadata-Version: 2.4
2
+ Name: chutils
3
+ Version: 2.7.0
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
+
53
+ [Русская версия](docs/README_RU.md)
54
+
55
+ # chutils: Stop the Routine!
56
+
57
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
58
+ [![Python](https://img.shields.io/badge/python-3.9%2B-blue.svg)](https://www.python.org/downloads/)
59
+ [![PyPI version](https://badge.fury.io/py/chutils.svg)](https://badge.fury.io/py/chutils)
60
+ [![Documentation](https://img.shields.io/badge/documentation-read-brightgreen)](https://Chu4hel.github.io/chutils/)
61
+
62
+ **chutils** is a set of simple utilities for Python designed to eliminate the repetitive setup of configuration,
63
+ logging, and secrets in your projects.
64
+
65
+ Start a new project and focus on what matters, not the routine.
66
+
67
+ Full documentation is available on [our website](https://Chu4hel.github.io/chutils/) (currently in Russian).
68
+
69
+ ## The Problem
70
+
71
+ Every time you start a new project, you have to solve the same tasks:
72
+
73
+ - How to conveniently read settings from a configuration file?
74
+ - How to configure logging to write messages to both the console and a file with daily rotation?
75
+ - How to securely store API keys without hardcoding them in the code?
76
+ - How to make it all work "out of the box" without manually defining paths?
77
+
78
+ **chutils** offers ready-made solutions for all these problems.
79
+
80
+ ## Key Features
81
+
82
+ - **✨ Zero Configuration:** The library **automatically** finds your project root and the `config.yml` or `config.ini`
83
+ file. It uses **lazy initialization** — no heavy operations until you actually need them.
84
+ - **⚙️ Flexible Configuration:** Support for `YAML` and `INI` formats. Simple functions for retrieving typed data.
85
+ - **✍️ Advanced Logger:** The `setup_logger()` function configures logging to the console and rotating files out of the
86
+ box. It returns a custom logger with additional debug levels (`devdebug`, `mediumdebug`).
87
+ - **🔒 Secure Secret Storage:** The `secret_manager` module provides a simple interface for saving and retrieving secrets
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.
95
+ - **🔄 Hot-Reload:** Support for automatic configuration reloading on file changes without restart (requires
96
+ `pip install chutils[watch]`).
97
+ - **⚡ Async Ready:** Most core functions have asynchronous versions (prefixed with `a`) for non-blocking execution.
98
+ - **🚀 Ready to Use:** Just install and use.
99
+
100
+ ## Command Line Interface (CLI)
101
+
102
+ The library provides a `chutils` console command for convenient secret management without writing code.
103
+
104
+ ### Secret Management
105
+
106
+ ```bash
107
+ # Save a secret to the system storage (keyring)
108
+ chutils secrets set MY_API_KEY "super-secret-value"
109
+
110
+ # Delete a secret
111
+ chutils secrets delete MY_API_KEY
112
+
113
+ # Explicitly specify service name
114
+ chutils secrets set DB_PASSWORD "12345" --service my_custom_app
115
+ ```
116
+
117
+ ## Installation
118
+
119
+ ```bash
120
+ poetry add chutils
121
+ ```
122
+
123
+ Or using pip:
124
+
125
+ ```bash
126
+ pip install chutils
127
+ ```
128
+
129
+ ## Examples
130
+
131
+ In the [`/examples`](./examples/) folder, you will find ready-to-run scripts demonstrating the library's key features.
132
+ Each example focuses on a specific task.
133
+
134
+ ## Quick Start
135
+
136
+ ### 1. Working with Configuration
137
+
138
+ 1. (Optional) Create a `config.yml` file in your project root:
139
+
140
+ ```yaml
141
+ # config.yml
142
+ Database:
143
+ host: localhost
144
+ port: 5432
145
+ ```
146
+
147
+ 2. Get values in your code:
148
+
149
+ ```python
150
+ from chutils import get_config_value, get_config_int
151
+
152
+ db_host = get_config_value("Database", "host", fallback="127.0.0.1")
153
+ db_port = get_config_int("Database", "port", fallback=5432)
154
+ ```
155
+
156
+ #### Validation via Pydantic (Optional)
157
+
158
+ For strict typing and validation, you can use Pydantic models (requires `pip install chutils[pydantic]`):
159
+
160
+ ```python
161
+ from pydantic import BaseModel
162
+ from chutils import get_config
163
+
164
+ class AppConfig(BaseModel):
165
+ app_name: str
166
+ version: str
167
+
168
+ # Returns an instance of AppConfig
169
+ cfg = get_config(model=AppConfig)
170
+ print(cfg.app_name)
171
+ ```
172
+
173
+ You can also validate specific sections:
174
+ ```python
175
+ from chutils import get_config_section
176
+ db_cfg = get_config_section("Database", model=MyDbModel)
177
+ ```
178
+
179
+ #### Overriding Configuration with Local Files (`config.local.yml`)
180
+
181
+ You can create a `config.local.yml` next to your main file. Values from the local file will **override**
182
+ corresponding values from the main file. This is perfect for local development or storing sensitive data (ensure
183
+ `*.local.*` is in your `.gitignore`).
184
+
185
+ ### 2. Hot-Reload
186
+
187
+ You can make your application react to configuration file changes in real-time.
188
+
189
+ ```python
190
+ from chutils import start_config_watcher, on_config_change, get_config_value
191
+
192
+
193
+ def reload_logic():
194
+ print("Configuration updated!")
195
+ # Update app state here
196
+ db_url = get_config_value("Database", "url")
197
+
198
+
199
+ # Register callback
200
+ on_config_change(reload_logic)
201
+
202
+ # Start watcher (requires watchdog package)
203
+ start_config_watcher()
204
+ ```
205
+
206
+ To use this feature, install `watchdog`:
207
+ `pip install chutils[watch]`
208
+
209
+ ### 3. Logging Setup
210
+
211
+ 1. Configure and use the logger:
212
+
213
+ ```python
214
+ from chutils import setup_logger, ChutilsLogger
215
+
216
+ # Automatically reads settings from [Logging] section in config.yml
217
+ logger: ChutilsLogger = setup_logger()
218
+
219
+ logger.info("Application started.")
220
+ logger.devdebug("Deep debug message (level 9).")
221
+ ```
222
+
223
+ #### Structured Logging (JSON)
224
+
225
+ If you need to output logs in JSON format for ELK, Splunk, or cloud logging (requires `pip install chutils[json]`):
226
+
227
+ ```python
228
+ # Via code
229
+ logger = setup_logger(json_format=True)
230
+
231
+ # Or via config in the [Logging] section
232
+ # json_format: true
233
+ ```
234
+
235
+ #### Contextual Logging (ContextVar)
236
+
237
+ You can bind metadata to the current execution context (thread or coroutine), and it will be automatically
238
+ included in all log messages.
239
+
240
+ ```python
241
+ from chutils import setup_logger, bind_context
242
+
243
+ logger = setup_logger()
244
+
245
+ # Bind request ID and user to the current context
246
+ bind_context(request_id="REQ-123", user="admin")
247
+
248
+ logger.info("Action performed")
249
+ # Text: ... [request_id=REQ-123 user=admin] Action performed
250
+ # JSON: {..., "message": "Action performed", "context": {"request_id": "REQ-123", "user": "admin"}}
251
+ ```
252
+
253
+ #### Controlling Logging via Environment Variables
254
+
255
+ - `CH_LOG_JSON=true`: Forces JSON format.
256
+ - `CH_LOG_NO_TIME=true`: Removes the date/time from the log format (for clean Docker logs).
257
+ - `CH_LOG_NO_FILE=true`: Disables creating log files.
258
+
259
+ These variables have **highest priority** and override any code or config settings.
260
+
261
+ ### 3. Secret Management
262
+
263
+ `SecretManager` looks for secrets in the following order: **Keyring > .env File > Environment Variables**.
264
+
265
+ ```python
266
+ from chutils import SecretManager
267
+
268
+ secrets = SecretManager("my_awesome_app")
269
+
270
+ # Save once
271
+ secrets.save_secret("API_KEY", "secret-value-123")
272
+
273
+ # Use everywhere
274
+ key = secrets.get_secret("API_KEY")
275
+ ```
276
+
277
+ #### Disabling Keyring (Optional)
278
+
279
+ In environments like Docker or CI/CD where `keyring` is unavailable, you can suppress warnings and skip the check:
280
+
281
+ - Set `CH_DISABLE_KEYRING_WARNING=true` in environment.
282
+ - Or add `disable_keyring: true` under `secrets` section in `config.yml`.
283
+
284
+ ## API Overview
285
+
286
+ ### Configuration (`chutils.config`)
287
+
288
+ - `get_config_value(section, key, fallback)` / `aget_config()`
289
+ - `get_config_int`, `get_config_boolean`, `get_config_list`, `get_config_path`
290
+ - `save_config_value(section, key, value, notify=True)` / `asave_config_value()`
291
+ - Use `notify=False` to update the file without triggering Hot-Reload callbacks.
292
+
293
+ ### Logging (`chutils.logger`)
294
+
295
+ - `setup_logger(name, log_level, log_file_name, rotation_type, compress, ...)`
296
+ - Levels: `logger.devdebug` (9), `logger.mediumdebug` (15), and all standard ones.
297
+
298
+ ### Secret Management (`chutils.secret_manager`)
299
+
300
+ - `SecretManager(service_name, prefix)`
301
+ - `save_secret` / `asave_secret`
302
+ - `get_secret` / `aget_secret`
303
+ - `delete_secret` / `adelete_secret`
304
+
305
+ ### Decorators (`chutils.decorators`)
306
+
307
+ - `@log_function_details`: Logs arguments, execution time, and result (uses `DEVDEBUG` level).
308
+ - `@timeout(seconds, fallback)`: Limits function execution time. Supports sync/async and optional fallback.
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".
317
+
318
+ ### Example of @retry usage:
319
+
320
+ ```python
321
+ from chutils.decorators import retry
322
+
323
+
324
+ @retry(retries=3, delay=1.0, backoff=2.0)
325
+ def fetch_data():
326
+ # Will be retried up to 3 times on any Exception
327
+ ...
328
+ ```
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
+
390
+ ## License
391
+
392
+ The project is distributed under the MIT License.
393
+
@@ -1,25 +1,3 @@
1
- Metadata-Version: 2.4
2
- Name: chutils
3
- Version: 2.6.0a0
4
- Summary: Набор простых и удобных утилит для Python, который избавляет от рутины при работе с конфигурацией и логированием в новых проектах.
5
- License: MIT
6
- License-File: LICENSE
7
- Author: Chu4hel
8
- Author-email: sergeiivanov636@gmail.com
9
- Requires-Python: >=3.9, !=2.7.*, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*, !=3.7.*, !=3.8.*
10
- Classifier: License :: OSI Approved :: MIT License
11
- Classifier: Programming Language :: Python :: 3
12
- Classifier: Programming Language :: Python :: 3.10
13
- Classifier: Programming Language :: Python :: 3.11
14
- Classifier: Programming Language :: Python :: 3.12
15
- Classifier: Programming Language :: Python :: 3.13
16
- Classifier: Programming Language :: Python :: 3.14
17
- Requires-Dist: keyring (>=25.7.0,<26.0.0)
18
- Requires-Dist: python-dotenv (==1.2.1) ; python_version < "3.10"
19
- Requires-Dist: python-dotenv (>=1.2.2,<2.0.0) ; python_version >= "3.10"
20
- Requires-Dist: pyyaml (>=6.0.3,<7.0.0)
21
- Description-Content-Type: text/markdown
22
-
23
1
  [Русская версия](docs/README_RU.md)
24
2
 
25
3
  # chutils: Stop the Routine!
@@ -56,9 +34,34 @@ Every time you start a new project, you have to solve the same tasks:
56
34
  box. It returns a custom logger with additional debug levels (`devdebug`, `mediumdebug`).
57
35
  - **🔒 Secure Secret Storage:** The `secret_manager` module provides a simple interface for saving and retrieving secrets
58
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.
43
+ - **🔄 Hot-Reload:** Support for automatic configuration reloading on file changes without restart (requires
44
+ `pip install chutils[watch]`).
59
45
  - **⚡ Async Ready:** Most core functions have asynchronous versions (prefixed with `a`) for non-blocking execution.
60
46
  - **🚀 Ready to Use:** Just install and use.
61
47
 
48
+ ## Command Line Interface (CLI)
49
+
50
+ The library provides a `chutils` console command for convenient secret management without writing code.
51
+
52
+ ### Secret Management
53
+
54
+ ```bash
55
+ # Save a secret to the system storage (keyring)
56
+ chutils secrets set MY_API_KEY "super-secret-value"
57
+
58
+ # Delete a secret
59
+ chutils secrets delete MY_API_KEY
60
+
61
+ # Explicitly specify service name
62
+ chutils secrets set DB_PASSWORD "12345" --service my_custom_app
63
+ ```
64
+
62
65
  ## Installation
63
66
 
64
67
  ```bash
@@ -98,13 +101,60 @@ Each example focuses on a specific task.
98
101
  db_port = get_config_int("Database", "port", fallback=5432)
99
102
  ```
100
103
 
104
+ #### Validation via Pydantic (Optional)
105
+
106
+ For strict typing and validation, you can use Pydantic models (requires `pip install chutils[pydantic]`):
107
+
108
+ ```python
109
+ from pydantic import BaseModel
110
+ from chutils import get_config
111
+
112
+ class AppConfig(BaseModel):
113
+ app_name: str
114
+ version: str
115
+
116
+ # Returns an instance of AppConfig
117
+ cfg = get_config(model=AppConfig)
118
+ print(cfg.app_name)
119
+ ```
120
+
121
+ You can also validate specific sections:
122
+ ```python
123
+ from chutils import get_config_section
124
+ db_cfg = get_config_section("Database", model=MyDbModel)
125
+ ```
126
+
101
127
  #### Overriding Configuration with Local Files (`config.local.yml`)
102
128
 
103
129
  You can create a `config.local.yml` next to your main file. Values from the local file will **override**
104
130
  corresponding values from the main file. This is perfect for local development or storing sensitive data (ensure
105
131
  `*.local.*` is in your `.gitignore`).
106
132
 
107
- ### 2. Logging Setup
133
+ ### 2. Hot-Reload
134
+
135
+ You can make your application react to configuration file changes in real-time.
136
+
137
+ ```python
138
+ from chutils import start_config_watcher, on_config_change, get_config_value
139
+
140
+
141
+ def reload_logic():
142
+ print("Configuration updated!")
143
+ # Update app state here
144
+ db_url = get_config_value("Database", "url")
145
+
146
+
147
+ # Register callback
148
+ on_config_change(reload_logic)
149
+
150
+ # Start watcher (requires watchdog package)
151
+ start_config_watcher()
152
+ ```
153
+
154
+ To use this feature, install `watchdog`:
155
+ `pip install chutils[watch]`
156
+
157
+ ### 3. Logging Setup
108
158
 
109
159
  1. Configure and use the logger:
110
160
 
@@ -118,8 +168,39 @@ Each example focuses on a specific task.
118
168
  logger.devdebug("Deep debug message (level 9).")
119
169
  ```
120
170
 
171
+ #### Structured Logging (JSON)
172
+
173
+ If you need to output logs in JSON format for ELK, Splunk, or cloud logging (requires `pip install chutils[json]`):
174
+
175
+ ```python
176
+ # Via code
177
+ logger = setup_logger(json_format=True)
178
+
179
+ # Or via config in the [Logging] section
180
+ # json_format: true
181
+ ```
182
+
183
+ #### Contextual Logging (ContextVar)
184
+
185
+ You can bind metadata to the current execution context (thread or coroutine), and it will be automatically
186
+ included in all log messages.
187
+
188
+ ```python
189
+ from chutils import setup_logger, bind_context
190
+
191
+ logger = setup_logger()
192
+
193
+ # Bind request ID and user to the current context
194
+ bind_context(request_id="REQ-123", user="admin")
195
+
196
+ logger.info("Action performed")
197
+ # Text: ... [request_id=REQ-123 user=admin] Action performed
198
+ # JSON: {..., "message": "Action performed", "context": {"request_id": "REQ-123", "user": "admin"}}
199
+ ```
200
+
121
201
  #### Controlling Logging via Environment Variables
122
202
 
203
+ - `CH_LOG_JSON=true`: Forces JSON format.
123
204
  - `CH_LOG_NO_TIME=true`: Removes the date/time from the log format (for clean Docker logs).
124
205
  - `CH_LOG_NO_FILE=true`: Disables creating log files.
125
206
 
@@ -154,7 +235,8 @@ In environments like Docker or CI/CD where `keyring` is unavailable, you can sup
154
235
 
155
236
  - `get_config_value(section, key, fallback)` / `aget_config()`
156
237
  - `get_config_int`, `get_config_boolean`, `get_config_list`, `get_config_path`
157
- - `save_config_value(section, key, value)` / `asave_config_value()`
238
+ - `save_config_value(section, key, value, notify=True)` / `asave_config_value()`
239
+ - Use `notify=False` to update the file without triggering Hot-Reload callbacks.
158
240
 
159
241
  ### Logging (`chutils.logger`)
160
242
 
@@ -171,9 +253,17 @@ In environments like Docker or CI/CD where `keyring` is unavailable, you can sup
171
253
  ### Decorators (`chutils.decorators`)
172
254
 
173
255
  - `@log_function_details`: Logs arguments, execution time, and result (uses `DEVDEBUG` level).
256
+ - `@timeout(seconds, fallback)`: Limits function execution time. Supports sync/async and optional fallback.
174
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.
175
259
 
176
- #### Example of @retry usage:
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".
265
+
266
+ ### Example of @retry usage:
177
267
 
178
268
  ```python
179
269
  from chutils.decorators import retry
@@ -185,7 +275,66 @@ def fetch_data():
185
275
  ...
186
276
  ```
187
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
+
188
338
  ## License
189
339
 
190
340
  The project is distributed under the MIT License.
191
-