Skip to content

Commit 12c3db4

Browse files
authored
Add bootstrap logging, path preparation helpers, and broader tooling/documentation improvements (#5)
* feat: add bootstrap logging workflow and refresh package docs Introduce runtime bootstrap logging with start_file_logger() and stop_file_logger() so early startup records can be buffered, stdout/stderr can be captured, and buffered messages can be flushed once configure_logger() installs the final handlers. Expose the new bootstrap logging helpers through the public API, update console handler creation to support explicit streams, flush buffered records during logger configuration, and harden config loading by importing YAML support lazily so environments without PyYAML fail through the shared error policy instead of at module import time. Refine typing and packaging details by adding overloads for handle_error(), marking the PyYAML import for type checking, expanding pyproject metadata and optional dev dependencies, splitting runtime and development requirements, adding pytest discovery settings, and broadening .gitignore coverage for Python, tooling, editor, and OS artifacts. Rework the test suite around pytest fixtures and temporary cache directories, remove the old bootstrap/path helpers, simplify test modules into direct function-based tests, and extend logger coverage to verify buffered bootstrap records plus stdout/stderr capture behavior alongside the existing file, config, masking, and serialization checks. Rewrite the README and large parts of the documentation to better onboard new users, clarify the library's purpose, document the error-handling and logging concepts in more depth, expand the tool pages with practical examples and usage guidance, and add dedicated reference pages for start_file_logger() and stop_file_logger(). This commit is still a broad work-in-progress snapshot. The new logging flow and the larger documentation/testing refresh are in place, but the state should continue to be validated and may still receive follow-up adjustments, cleanup, and refinement. * feat: add path preparation helpers for files and directories Introduce ensure_file() and ensure_dir() as new public helpers for preparing filesystem targets before later reads, writes, logging, cache generation, or export steps. The new path utility module normalizes single-path and multi-path inputs, creates missing parent directories as needed, and routes validation or filesystem failures through the shared clevertools error policy. Expose the new helpers through the package root API so they can be imported directly from clevertools, and document them in the main README plus the tools index to make the expanded filesystem helper surface easier to discover. Add dedicated documentation pages for ensure_file() and ensure_dir() with signatures, behavior notes, and practical examples covering single paths, multiple paths, nested directory preparation, replacement content, and binary file initialization. Extend the test suite with focused coverage for the new path utilities, including creation of missing files and directories, list input support, content replacement behavior, binary payload handling, preservation of existing files by default, and validation failures for wrong target types or invalid path inputs. This snapshot appears to be a smaller incremental feature update rather than a large refactor, but it is still a work in progress and may receive follow-up cleanup, polish, or additional validation in later commits. * fix: harden bootstrap logging and path helper error handling Prevent duplicated bootstrap console output when stdout or stderr capture is enabled and the final logger configuration also writes to the console. Update the runtime bootstrap flow to keep explicit stream redirect objects, flush buffered partial output before restoring the original streams, and ensure early startup messages are emitted exactly once through the configured logger handlers. Align ensure_file() and ensure_dir() with the package-wide error policy by restoring None-based on_error defaults so configured global error handling is respected automatically. Clean up path helper validation messages so conflicting file and directory targets report the concrete path value instead of a literal placeholder. Expand logger regression coverage with a dedicated test that verifies captured bootstrap stdout and stderr do not appear twice on the console while still being persisted to the log file. * fix: tighten logger formatter behavior and coverage Make the datetime logging preset honor custom date_format values instead of always rendering the built-in default date layout. Route console color detection through the actual handler stream so ANSI coloring follows the real output target rather than relying on sys.stdout. Pass the console handler stream into CleverToolsFormatter and keep the formatter logic aligned with the configured logger output path. Expand logger regression coverage with focused tests for custom datetime formatting and stream-aware color handling, alongside the earlier bootstrap logging protections. This keeps the logger API behavior consistent with its configuration surface while preserving clean test and mypy results in the project venv.
1 parent e20e5ef commit 12c3db4

61 files changed

Lines changed: 2315 additions & 636 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 88 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,50 @@
22
__pycache__/
33
*.py[cod]
44
*$py.class
5+
*.pyd
6+
*.pyo
7+
*.py,cover
8+
9+
# Python environments and local version files
10+
.env
11+
.env.*
12+
.venv/
13+
.python-version
14+
env/
15+
venv/
16+
ENV/
17+
env.bak/
18+
venv.bak/
19+
20+
# Python packaging, builds, and installers
21+
build/
22+
dist/
23+
site/
24+
.eggs/
25+
*.egg-info/
26+
*.egg
27+
pip-wheel-metadata/
28+
share/python-wheels/
29+
wheelhouse/
30+
sdist/
31+
develop-eggs/
32+
downloads/
33+
parts/
34+
var/
35+
wheels/
36+
MANIFEST
37+
38+
# Python tooling and dependency managers
39+
__pypackages__/
40+
poetry.toml
41+
.pdm.toml
42+
.pdm-build/
43+
.pdm-python
44+
dmypy.json
45+
.pyre/
46+
.pytype/
47+
.pybuilder/
48+
cython_debug/
549

650
# Test, lint, and type-checker caches
751
.pytest_cache/
@@ -14,37 +58,60 @@ __pycache__/
1458
.coverage.*
1559
htmlcov/
1660
coverage.xml
17-
18-
# Build and packaging artifacts
19-
build/
20-
dist/
21-
.eggs/
22-
*.egg-info/
23-
*.egg
24-
pip-wheel-metadata/
25-
26-
# Virtual environments
27-
.env
28-
.venv/
29-
env/
30-
venv/
31-
ENV/
32-
33-
# Local tool configuration
34-
poetry.toml
35-
.pdm.toml
61+
nosetests.xml
62+
*.cover
63+
*.py.cover
64+
.cache/
3665

3766
# Documentation builds
3867
docs/_build/
68+
_build/
3969

40-
# Editors
70+
# Jupyter and notebooks
71+
.ipynb_checkpoints/
72+
73+
# Editors and IDEs
4174
.vscode/
4275
.vscode/*
4376
!.vscode/settings.json
4477
!.vscode/tasks.json
4578
!.vscode/launch.json
4679
!.vscode/extensions.json
4780
!.vscode/*.code-snippets
81+
.vscode-test/
4882
.idea/
83+
.fleet/
4984
.history/
50-
.ionide/
85+
.ionide/
86+
*.code-workspace
87+
*.iml
88+
*.suo
89+
*.user
90+
*.userossc
91+
*.rsuser
92+
*.sln.docstates
93+
*.swp
94+
*.swo
95+
*~
96+
97+
# OS and file manager artifacts
98+
.DS_Store
99+
.DS_Store?
100+
Thumbs.db
101+
Desktop.ini
102+
$RECYCLE.BIN/
103+
.Spotlight-V100/
104+
.Trashes/
105+
._*
106+
107+
# Logs and runtime files
108+
*.log
109+
*.out
110+
*.err
111+
*.pid
112+
*.pid.lock
113+
114+
# Local archives and temporary files
115+
*.tmp
116+
*.temp
117+
*.bak

README.md

Lines changed: 142 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,95 +1,190 @@
11
# clevertools
22

3-
`clevertools` is a compact Python utility library for everyday workflows like file I/O, masking sensitive values, runtime configuration, and logger setup.
3+
`clevertools` is a practical Python helper library for everyday application code. It focuses on the boring but important parts that show up in many projects: reading and writing files, handling JSON/TOML/YAML, masking sensitive values, loading split configuration, and setting up logging without repetitive boilerplate.
44

5-
## What You Get
5+
The package is intentionally small, but it still gives you enough structure that a new teammate can open the project and understand how configuration, file access, and logging are supposed to work.
66

7-
- simple text and binary file helpers
8-
- JSON, TOML, and YAML read/write helpers
9-
- masking for tokens, secrets, IDs, and similar values
10-
- global configuration for shared error behavior
11-
- ready-to-use console and file logging
12-
- lower-level logging utilities when you need more control
7+
## What clevertools is for
138

14-
## Quick Example
9+
Use `clevertools` when you want:
10+
11+
- a consistent way to read and write text, bytes, JSON, TOML, and YAML
12+
- one shared error-handling model across helpers
13+
- simple masking for API keys, tokens, emails, IDs, and similar values
14+
- merged configuration from multiple files with dot access
15+
- fast logger setup for console and file logging
16+
- lower-level logging primitives when you need custom control
17+
18+
## What is included
19+
20+
### Core helpers
21+
22+
- `configure()` stores package-wide defaults such as error handling and logger overrides
23+
- `log` is the shared default logger
24+
- `mask()` partially hides sensitive strings before you log or display them
25+
26+
### File helpers
27+
28+
- `read()` and `write()` handle plain text and raw bytes
29+
- `ensure_file()` and `ensure_dir()` make sure file and directory paths exist
30+
- `read_json()` and `write_json()` handle JSON files
31+
- `read_toml()` and `write_toml()` handle TOML files
32+
- `read_yaml()` and `write_yaml()` handle YAML files
33+
- `load_config()` merges multiple config files into one object
34+
35+
### Logging helpers
36+
37+
- `configure_logger()` creates or refreshes a logger with console and file handlers
38+
- `start_file_logger()` captures early startup output before final logger setup is ready
39+
- `stop_file_logger()` restores captured `stdout` and `stderr`
40+
- `get_logger()` returns a named logger without modifying it
41+
- `CleverToolsFormatter` adds structured time fields and optional colors
42+
- `build_console_handler()` and `build_file_handler()` expose the low-level handler builders
43+
- `reset_handlers()` safely clears existing handlers
44+
- `resolve_logger_options()` shows the final logger settings after overrides are applied
45+
46+
## Quick example
1547

1648
```python
17-
from clevertools import configure, configure_logger, mask, read_json, write_json
49+
from clevertools import (
50+
configure,
51+
configure_logger,
52+
load_config,
53+
mask,
54+
read_json,
55+
write_json,
56+
)
1857

1958
configure(
2059
error_mode="raise",
2160
logger_overrides={
2261
"level": "INFO",
62+
"format_preset": "datetime",
2363
"console_enabled": True,
2464
},
2565
)
2666

27-
logger = configure_logger(name="demo", use_colors=False)
67+
logger = configure_logger(name="billing", use_colors=False)
2868

2969
payload = {
3070
"service": "billing",
3171
"token": mask("sk-demo-123456789", 4, 3),
72+
"retries": 3,
3273
}
3374

34-
write_json("tmp/config.json", payload)
75+
write_json("tmp/config.json", payload, indent=2, ensure_ascii=False)
3576
loaded = read_json("tmp/config.json")
3677

3778
logger.info("Loaded config: %s", loaded)
79+
80+
config = load_config("config/base.toml", "config/local.yaml")
81+
logger.info("Feature enabled: %s", config.get("features.billing.enabled"))
3882
```
3983

40-
For split configuration setups, `load_config()` merges multiple TOML, JSON, or YAML files into one config object with dot access.
84+
## Typical workflows
4185

42-
## Public API Overview
86+
### 1. Read and write structured files
4387

44-
### Core
88+
```python
89+
from clevertools import read_toml, write_yaml
4590

46-
- `configure`
47-
- `log`
48-
- `mask`
91+
settings = read_toml("settings.toml", on_error="raise")
92+
write_yaml("build/settings.yaml", settings, sort_keys=False)
93+
```
4994

50-
### File helpers
95+
### 2. Hide secrets before logging
5196

52-
- `read`
53-
- `write`
54-
- `read_json`
55-
- `write_json`
56-
- `read_toml`
57-
- `write_toml`
58-
- `read_yaml`
59-
- `write_yaml`
60-
- `load_config`
97+
```python
98+
from clevertools import mask, log
6199

62-
### Logging helpers
100+
token = "sk-prod-abcdef1234567890"
101+
log.info("Using token %s", mask(token, 5, 4))
102+
```
103+
104+
### 3. Merge config from multiple sources
105+
106+
```python
107+
from clevertools import load_config
108+
109+
config = load_config(
110+
"config/defaults.toml",
111+
"config/team.json",
112+
"config/local.yaml",
113+
)
114+
115+
print(config.database.host)
116+
print(config.get("features.search.enabled", False))
117+
```
118+
119+
### 4. Set up application logging
120+
121+
```python
122+
from clevertools import configure_logger
123+
124+
logger = configure_logger(
125+
name="worker",
126+
level="INFO",
127+
format_preset="datetime",
128+
console_enabled=True,
129+
file_logging_enabled=True,
130+
file_log_path="logs/worker.log",
131+
file_write_mode="buffered",
132+
use_colors=False,
133+
)
134+
135+
logger.info("worker started")
136+
```
137+
138+
## Error handling model
139+
140+
Most helpers support `on_error`. If you do not pass it, the package-wide default from `configure()` is used.
141+
142+
- `"raise"` raises the original exception
143+
- `"log"` logs the error and returns the helper's fallback value
144+
- `"silent"` suppresses the error and returns the helper's fallback value
145+
146+
Example:
147+
148+
```python
149+
from clevertools import configure, read_json
150+
151+
configure(error_mode="silent")
152+
153+
payload = read_json("missing.json")
154+
print(payload) # None
155+
```
156+
157+
## Documentation map
158+
159+
If this is your first time in the repository, read the docs in this order:
63160

64-
- `configure_logger`
65-
- `get_logger`
66-
- `CleverToolsFormatter`
67-
- `build_console_handler`
68-
- `build_file_handler`
69-
- `reset_handlers`
70-
- `resolve_logger_options`
161+
1. [docs/README.md](./docs/README.md)
162+
2. [docs/installation.md](./docs/installation.md)
163+
3. [docs/quickstart.md](./docs/quickstart.md)
164+
4. [docs/tools/README.md](./docs/tools/README.md)
165+
5. [docs/concepts/README.md](./docs/concepts/README.md)
71166

72-
## Why It Exists
167+
Important reference pages:
73168

74-
`clevertools` stays intentionally small. It focuses on practical helpers that are easy to drop into scripts and small projects without turning simple tasks into a framework.
169+
- [docs/getting-started.md](./docs/getting-started.md) for a guided first run
170+
- [docs/tools/README.md](./docs/tools/README.md) for the full API map
171+
- [docs/concepts/error-handling.md](./docs/concepts/error-handling.md) for shared fallback behavior
172+
- [docs/concepts/logging.md](./docs/concepts/logging.md) for logger architecture and write modes
75173

76-
## Repository Guide
174+
## Repository layout
77175

78-
- [docs/README.md](./docs/README.md) is the documentation entry point
79-
- [docs/installation.md](./docs/installation.md) shows local setup
80-
- [docs/quickstart.md](./docs/quickstart.md) shows an end-to-end example
81-
- [docs/tools/README.md](./docs/tools/README.md) lists every tool page
82-
- [docs/concepts/README.md](./docs/concepts/README.md) explains shared behavior
83-
- [src/clevertools](./src/clevertools) contains the implementation
84-
- [tests](./tests) contains the test suite
176+
- `src/clevertools/` contains the library code
177+
- `tests/` contains the automated test suite
178+
- `docs/` contains the user-facing documentation
179+
- `README.md` is the first overview for new users
85180

86181
## Installation
87182

88183
```bash
89184
pip install -e .
90185
```
91186

92-
For a full local setup, see [docs/installation.md](./docs/installation.md).
187+
For a full local setup including virtual environments and dependencies, see [docs/installation.md](./docs/installation.md).
93188

94189
## Requirements
95190

0 commit comments

Comments
 (0)