dotenvmodel 0.1.1__tar.gz → 0.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.
Files changed (57) hide show
  1. dotenvmodel-0.2.0/.release-please-manifest.json +3 -0
  2. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/CHANGELOG.md +7 -0
  3. dotenvmodel-0.2.0/CONTRIBUTING.md +381 -0
  4. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/PKG-INFO +294 -1
  5. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/README.md +293 -0
  6. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/dotenvmodel/__init__.py +4 -1
  7. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/dotenvmodel/config.py +127 -1
  8. dotenvmodel-0.2.0/dotenvmodel/describe.py +985 -0
  9. dotenvmodel-0.2.0/examples/describe_documentation.py +176 -0
  10. dotenvmodel-0.2.0/examples/generate_env_example.py +75 -0
  11. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/pyproject.toml +1 -1
  12. dotenvmodel-0.2.0/tests/test_describe.py +1696 -0
  13. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/uv.lock +1 -1
  14. dotenvmodel-0.1.1/.release-please-manifest.json +0 -3
  15. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/.github/workflows/ci.yml +0 -0
  16. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/.github/workflows/publish.yml +0 -0
  17. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/.github/workflows/release-please.yml +0 -0
  18. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/.gitignore +0 -0
  19. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/.python-version +0 -0
  20. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/.vscode/settings.json +0 -0
  21. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/LICENSE +0 -0
  22. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/Makefile +0 -0
  23. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/dotenvmodel/coercion.py +0 -0
  24. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/dotenvmodel/exceptions.py +0 -0
  25. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/dotenvmodel/fields.py +0 -0
  26. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/dotenvmodel/loading.py +0 -0
  27. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/dotenvmodel/logging_config.py +0 -0
  28. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/dotenvmodel/py.typed +0 -0
  29. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/dotenvmodel/types.py +0 -0
  30. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/dotenvmodel/validation.py +0 -0
  31. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/examples/advanced_types.py +0 -0
  32. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/examples/basic_usage.py +0 -0
  33. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/examples/logging_example.py +0 -0
  34. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/release-please-config.json +0 -0
  35. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/tests/__init__.py +0 -0
  36. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/tests/conftest.py +0 -0
  37. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/tests/test_basic.py +0 -0
  38. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/tests/test_coercion.py +0 -0
  39. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/tests/test_collection_validators.py +0 -0
  40. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/tests/test_empty_collection_items.py +0 -0
  41. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/tests/test_empty_strings.py +0 -0
  42. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/tests/test_errors.py +0 -0
  43. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/tests/test_field_constraints.py +0 -0
  44. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/tests/test_inheritance.py +0 -0
  45. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/tests/test_json.py +0 -0
  46. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/tests/test_json_and_optional.py +0 -0
  47. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/tests/test_loading.py +0 -0
  48. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/tests/test_logging_config.py +0 -0
  49. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/tests/test_prefix.py +0 -0
  50. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/tests/test_reload.py +0 -0
  51. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/tests/test_secretstr_security.py +0 -0
  52. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/tests/test_types.py +0 -0
  53. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/tests/test_union_types.py +0 -0
  54. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/tests/test_url_dsn.py +0 -0
  55. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/tests/test_url_password_decoding.py +0 -0
  56. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/tests/test_url_unquote.py +0 -0
  57. {dotenvmodel-0.1.1 → dotenvmodel-0.2.0}/tests/test_urls.py +0 -0
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.2.0"
3
+ }
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.2.0](https://github.com/AZX-PBC/dotenvmodel/compare/v0.1.1...v0.2.0) (2025-12-05)
9
+
10
+
11
+ ### Features
12
+
13
+ * add describe functionality for configuration classes and related tests ([#6](https://github.com/AZX-PBC/dotenvmodel/issues/6)) ([49767ea](https://github.com/AZX-PBC/dotenvmodel/commit/49767ea34e8216706a0071072cb92452890451f3))
14
+
8
15
  ## [0.1.1](https://github.com/AZX-PBC/dotenvmodel/compare/v0.1.0...v0.1.1) (2025-12-05)
9
16
 
10
17
 
@@ -0,0 +1,381 @@
1
+ # Contributing to dotenvmodel
2
+
3
+ Thank you for your interest in contributing to dotenvmodel! We appreciate your time and effort in making this library better for everyone.
4
+
5
+ ## Development Setup
6
+
7
+ ### Prerequisites
8
+
9
+ - Python 3.12 or higher
10
+ - [uv](https://docs.astral.sh/uv/) - Fast Python package installer and resolver
11
+
12
+ ### Getting Started
13
+
14
+ 1. **Clone the repository:**
15
+ ```bash
16
+ git clone https://github.com/azxio/dotenvmodel.git
17
+ cd dotenvmodel
18
+ ```
19
+
20
+ 2. **Install dependencies:**
21
+
22
+ This project uses `uv` for dependency management. Install development dependencies with:
23
+ ```bash
24
+ uv sync --dev
25
+ ```
26
+
27
+ This will create a virtual environment and install all necessary dependencies including pytest, mypy, ruff, and other development tools.
28
+
29
+ ## Running Tests
30
+
31
+ **IMPORTANT: Always use `uv run` to execute pytest and other development commands.**
32
+
33
+ Using `uv run` ensures that:
34
+ - Commands run in the correct virtual environment
35
+ - All dependencies are properly resolved
36
+ - You're using the exact versions specified in the project
37
+ - No conflicts with globally installed packages
38
+
39
+ ### Test Commands
40
+
41
+ ```bash
42
+ # Run all tests
43
+ uv run pytest
44
+
45
+ # Run specific test file
46
+ uv run pytest tests/test_describe.py
47
+
48
+ # Run specific test class
49
+ uv run pytest tests/test_describe.py::TestLineEndings
50
+
51
+ # Run specific test function
52
+ uv run pytest tests/test_core.py::TestDotEnvConfig::test_load_from_dict
53
+
54
+ # Run with verbose output
55
+ uv run pytest -v
56
+
57
+ # Run with coverage report
58
+ uv run pytest --cov=dotenvmodel --cov-report=html
59
+
60
+ # Run tests matching a pattern
61
+ uv run pytest -k "test_validation"
62
+
63
+ # Run tests with output from print statements
64
+ uv run pytest -s
65
+ ```
66
+
67
+ ### Understanding Test Output
68
+
69
+ The project is configured with the following pytest settings (in `pyproject.toml`):
70
+ - Coverage is automatically collected for the `dotenvmodel` package
71
+ - HTML coverage reports are generated in `htmlcov/`
72
+ - Tests must maintain at least 95% code coverage
73
+ - Coverage reports exclude test files and implementation details
74
+
75
+ ## Code Quality
76
+
77
+ ### Type Checking
78
+
79
+ The project uses `ty` (a wrapper around pyright) for type checking:
80
+
81
+ ```bash
82
+ # Run type checking
83
+ uv run ty check
84
+
85
+ # Type check specific file
86
+ uv run ty check dotenvmodel/core.py
87
+ ```
88
+
89
+ ### Linting and Formatting
90
+
91
+ The project uses `ruff` for both linting and formatting:
92
+
93
+ ```bash
94
+ # Check for linting issues
95
+ uv run ruff check dotenvmodel
96
+
97
+ # Auto-fix linting issues
98
+ uv run ruff check --fix dotenvmodel
99
+
100
+ # Format code
101
+ uv run ruff format dotenvmodel
102
+
103
+ # Check formatting without making changes
104
+ uv run ruff format --check dotenvmodel
105
+ ```
106
+
107
+ ### Running All Quality Checks
108
+
109
+ Before submitting a PR, run all quality checks:
110
+
111
+ ```bash
112
+ # Run tests with coverage
113
+ uv run pytest
114
+
115
+ # Run type checking
116
+ uv run ty check
117
+
118
+ # Run linting
119
+ uv run ruff check dotenvmodel
120
+
121
+ # Check formatting
122
+ uv run ruff format --check dotenvmodel
123
+ ```
124
+
125
+ ## Making Changes
126
+
127
+ ### Workflow
128
+
129
+ 1. **Create a feature branch:**
130
+ ```bash
131
+ git checkout -b feat/your-feature-name
132
+ ```
133
+
134
+ Or for bug fixes:
135
+ ```bash
136
+ git checkout -b fix/bug-description
137
+ ```
138
+
139
+ 2. **Make your changes:**
140
+ - Write clear, readable code
141
+ - Follow existing code patterns and conventions
142
+ - Add type hints to all functions and methods
143
+ - Keep functions focused and modular
144
+
145
+ 3. **Write tests:**
146
+ - Add tests for all new functionality
147
+ - Update existing tests if modifying behavior
148
+ - Ensure tests are clear and well-documented
149
+ - Test edge cases and error conditions
150
+ - Run tests with `uv run pytest`
151
+
152
+ 4. **Update documentation:**
153
+ - Update README.md if adding new features
154
+ - Add docstrings to new functions and classes
155
+ - Update type hints and examples
156
+
157
+ 5. **Verify your changes:**
158
+ ```bash
159
+ # Run all tests
160
+ uv run pytest
161
+
162
+ # Check types
163
+ uv run ty check
164
+
165
+ # Check linting
166
+ uv run ruff check dotenvmodel
167
+
168
+ # Check formatting
169
+ uv run ruff format --check dotenvmodel
170
+ ```
171
+
172
+ ## Pull Request Process
173
+
174
+ ### Before Submitting
175
+
176
+ 1. **Ensure all tests pass:**
177
+ ```bash
178
+ uv run pytest
179
+ ```
180
+
181
+ 2. **Ensure type checking passes:**
182
+ ```bash
183
+ uv run ty check
184
+ ```
185
+
186
+ 3. **Ensure code is properly formatted:**
187
+ ```bash
188
+ uv run ruff format dotenvmodel
189
+ uv run ruff check --fix dotenvmodel
190
+ ```
191
+
192
+ 4. **Verify coverage hasn't decreased:**
193
+ ```bash
194
+ uv run pytest --cov=dotenvmodel --cov-report=term-missing
195
+ ```
196
+
197
+ Coverage should remain at or above 95%.
198
+
199
+ ### Submitting Your PR
200
+
201
+ 1. **Push your branch:**
202
+ ```bash
203
+ git push origin feat/your-feature-name
204
+ ```
205
+
206
+ 2. **Create a pull request on GitHub**
207
+
208
+ 3. **In your PR description:**
209
+ - Clearly describe what changes you made
210
+ - Explain why the changes are needed
211
+ - Reference any related issues
212
+ - Include examples of new functionality (if applicable)
213
+ - List any breaking changes
214
+
215
+ ### PR Description Template
216
+
217
+ ```markdown
218
+ ## Summary
219
+ Brief description of what this PR does
220
+
221
+ ## Changes
222
+ - Change 1
223
+ - Change 2
224
+ - Change 3
225
+
226
+ ## Testing
227
+ Describe how you tested these changes
228
+
229
+ ## Related Issues
230
+ Fixes #123
231
+ ```
232
+
233
+ ## Code Review
234
+
235
+ ### What to Expect
236
+
237
+ - All changes must pass automated tests and type checking
238
+ - Code reviewers will check for:
239
+ - Implementation correctness
240
+ - Code clarity and maintainability
241
+ - Adequate test coverage
242
+ - Documentation completeness
243
+ - Adherence to project conventions
244
+
245
+ - You may be asked to make revisions
246
+ - Reviews are constructive - they help improve code quality
247
+
248
+ ### Addressing Feedback
249
+
250
+ When reviewers request changes:
251
+
252
+ 1. Make the requested changes in your branch
253
+ 2. Run tests again: `uv run pytest`
254
+ 3. Push the updates: `git push origin feat/your-feature-name`
255
+ 4. Respond to reviewer comments
256
+
257
+ ## Development Tips
258
+
259
+ ### Virtual Environment
260
+
261
+ The `uv run` command automatically manages the virtual environment. You don't need to manually activate it.
262
+
263
+ If you prefer to activate the environment manually:
264
+ ```bash
265
+ # uv creates a .venv directory
266
+ source .venv/bin/activate # Linux/macOS
267
+ # or
268
+ .venv\Scripts\activate # Windows
269
+ ```
270
+
271
+ However, we recommend using `uv run` for consistency.
272
+
273
+ ### Interactive Testing
274
+
275
+ You can use `uv run python` to start a Python interpreter with the correct environment:
276
+
277
+ ```bash
278
+ uv run python
279
+ ```
280
+
281
+ Then test your changes interactively:
282
+ ```python
283
+ from dotenvmodel import DotEnvConfig, Field
284
+
285
+ class TestConfig(DotEnvConfig):
286
+ value: str = Field()
287
+
288
+ config = TestConfig.load_from_dict({"value": "test"})
289
+ print(config.value)
290
+ ```
291
+
292
+ ### Debugging Tests
293
+
294
+ To debug a specific test with pdb:
295
+
296
+ ```bash
297
+ # Add breakpoint() in your test or code
298
+ # Then run with -s to see output
299
+ uv run pytest -s tests/test_describe.py::test_specific_function
300
+ ```
301
+
302
+ ### Coverage Reports
303
+
304
+ After running tests with coverage, view the HTML report:
305
+
306
+ ```bash
307
+ uv run pytest --cov=dotenvmodel --cov-report=html
308
+ # Open htmlcov/index.html in your browser
309
+ ```
310
+
311
+ ## Code Style Guidelines
312
+
313
+ ### General Principles
314
+
315
+ - Write clear, self-documenting code
316
+ - Use meaningful variable and function names
317
+ - Keep functions short and focused (ideally under 50 lines)
318
+ - Avoid deep nesting (max 3-4 levels)
319
+ - Comments should explain "why", not "what"
320
+
321
+ ### Type Hints
322
+
323
+ Always use type hints:
324
+
325
+ ```python
326
+ # Good
327
+ def process_value(value: str, default: int = 0) -> int:
328
+ return int(value) if value else default
329
+
330
+ # Bad
331
+ def process_value(value, default=0):
332
+ return int(value) if value else default
333
+ ```
334
+
335
+ ### Docstrings
336
+
337
+ Use clear docstrings for public APIs:
338
+
339
+ ```python
340
+ def describe(cls, format: str = "table") -> str:
341
+ """Generate documentation for the configuration class.
342
+
343
+ Args:
344
+ format: Output format - "table", "markdown", "json", "html", or "dotenv"
345
+
346
+ Returns:
347
+ Formatted documentation string
348
+
349
+ Raises:
350
+ ValueError: If format is not supported
351
+ """
352
+ ```
353
+
354
+ ### Error Messages
355
+
356
+ Write helpful error messages:
357
+
358
+ ```python
359
+ # Good
360
+ raise ValueError(
361
+ f"Invalid format '{format}'. "
362
+ f"Supported formats: table, markdown, json, html, dotenv"
363
+ )
364
+
365
+ # Bad
366
+ raise ValueError("Invalid format")
367
+ ```
368
+
369
+ ## Getting Help
370
+
371
+ - **Questions?** Open a [GitHub Discussion](https://github.com/azxio/dotenvmodel/discussions)
372
+ - **Bug Reports?** Open an [Issue](https://github.com/azxio/dotenvmodel/issues)
373
+ - **Feature Requests?** Open an [Issue](https://github.com/azxio/dotenvmodel/issues) with the `enhancement` label
374
+
375
+ ## License
376
+
377
+ By contributing, you agree that your contributions will be licensed under the MIT License.
378
+
379
+ ## Thank You!
380
+
381
+ Your contributions help make dotenvmodel better for everyone. We appreciate your time and effort!
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dotenvmodel
3
- Version: 0.1.1
3
+ Version: 0.2.0
4
4
  Summary: Type-safe environment configuration with automatic .env file loading
5
5
  Project-URL: Homepage, https://github.com/AZX-PBC/dotenvmodel
6
6
  Project-URL: Repository, https://github.com/AZX-PBC/dotenvmodel
@@ -42,6 +42,9 @@ Description-Content-Type: text/markdown
42
42
  - **Developer Experience**: Intuitive Pydantic-style API
43
43
  - **Smart .env Loading**: Automatic cascading of `.env`, `.env.{env}`, `.env.{env}.local` files
44
44
  - **Configuration Reload**: Reload configuration at runtime without creating new instances
45
+ - **Configuration Documentation**: Generate docs in multiple formats (table, markdown, JSON, HTML, dotenv) with `describe()`
46
+ - **.env.example Generation**: Automatically generate `.env.example` files with type hints, constraints, and examples
47
+ - **File Export**: Save documentation directly to files for integration with build tools and wikis
45
48
  - **Environment Prefixes**: Class-level `env_prefix` to namespace environment variables
46
49
  - **Validation**: Numeric constraints (ge, le, gt, lt), string constraints (min_length, max_length, regex), choice validation, and collection size constraints (min_items, max_items)
47
50
  - **Clear Error Messages**: Helpful validation errors that guide you to fixes
@@ -85,6 +88,9 @@ config = AppConfig.load(env="dev")
85
88
  print(f"Connecting to {config.database_url}") # config.database_url: str
86
89
  print(f"Running on port {config.port}") # config.port: int
87
90
  print(f"Debug mode: {config.debug}") # config.debug: bool
91
+
92
+ # Generate documentation for your configuration
93
+ print(AppConfig.describe())
88
94
  ```
89
95
 
90
96
  ## Type Safety and IntelliSense
@@ -650,6 +656,293 @@ The `reload()` method:
650
656
  - Validates all fields and raises errors if validation fails
651
657
  - Returns the same instance (useful for method chaining)
652
658
 
659
+ ## Configuration Documentation
660
+
661
+ Generate human-readable documentation for your configuration classes using the `describe()` method. This is useful for:
662
+
663
+ - **Creating documentation** for your team
664
+ - **Generating `.env.example` files** automatically
665
+ - **Validating configuration** in CI pipelines
666
+ - **Onboarding new developers** quickly
667
+
668
+ ### Generate Documentation for a Single Config
669
+
670
+ ```python
671
+ from dotenvmodel import DotEnvConfig, Field
672
+
673
+ class AppConfig(DotEnvConfig):
674
+ database_url: str = Field(description="PostgreSQL connection string")
675
+ port: int = Field(default=8000, ge=1, le=65535, description="Server port")
676
+ debug: bool = Field(default=False, description="Enable debug mode")
677
+ workers: int = Field(default=4, ge=1, le=16, description="Number of worker processes")
678
+
679
+ # Generate ASCII table (default)
680
+ print(AppConfig.describe())
681
+ ```
682
+
683
+ Output:
684
+
685
+ ```
686
+ AppConfig
687
+ =========
688
+ +--------------+------+----------+---------+---------------------------+----------------+
689
+ | ENV Variable | Type | Required | Default | Description | Constraints |
690
+ +--------------+------+----------+---------+---------------------------+----------------+
691
+ | DATABASE_URL | str | Yes | - | PostgreSQL connection ... | - |
692
+ | PORT | int | No | 8000 | Server port | ge=1, le=65535 |
693
+ | DEBUG | bool | No | False | Enable debug mode | - |
694
+ | WORKERS | int | No | 4 | Number of worker proces...| ge=1, le=16 |
695
+ +--------------+------+----------+---------+---------------------------+----------------+
696
+ ```
697
+
698
+ ### Output Formats
699
+
700
+ **ASCII Table (default)** - Best for terminal output and logging:
701
+
702
+ ```python
703
+ print(AppConfig.describe(output_format="table"))
704
+ ```
705
+
706
+ **Markdown** - Perfect for README files and documentation:
707
+
708
+ ```python
709
+ # Generate markdown documentation
710
+ docs = AppConfig.describe(output_format="markdown")
711
+
712
+ # Save to file
713
+ with open("CONFIG.md", "w") as f:
714
+ f.write(docs)
715
+ ```
716
+
717
+ **JSON** - Ideal for CI validation and programmatic processing:
718
+
719
+ ```python
720
+ import json
721
+
722
+ # Get configuration schema as JSON
723
+ config_spec = AppConfig.describe(output_format="json")
724
+ data = json.loads(config_spec)
725
+
726
+ # Use for validation, code generation, etc.
727
+ print(data["class_name"]) # "AppConfig"
728
+ print(data["fields"][0]["env_var"]) # "DATABASE_URL"
729
+ ```
730
+
731
+ **HTML** - Styled output for web documentation:
732
+
733
+ ```python
734
+ # Generate HTML with styled tables
735
+ html_docs = AppConfig.describe(output_format="html")
736
+
737
+ # Save to file
738
+ with open("config.html", "w") as f:
739
+ f.write(html_docs)
740
+ ```
741
+
742
+ **Dotenv Format** - For generating `.env.example` files:
743
+
744
+ ```python
745
+ # Generate .env.example format
746
+ dotenv_docs = AppConfig.describe(output_format="dotenv")
747
+ print(dotenv_docs)
748
+ ```
749
+
750
+ ### File Export
751
+
752
+ Save documentation directly to files using the `output` parameter:
753
+
754
+ ```python
755
+ # Save as markdown
756
+ AppConfig.describe(output_format="markdown", output="docs/config.md")
757
+
758
+ # Save as HTML
759
+ AppConfig.describe(output_format="html", output="docs/config.html")
760
+
761
+ # Save as JSON
762
+ AppConfig.describe(output_format="json", output="config-schema.json")
763
+ ```
764
+
765
+ ### Generate `.env.example` Files
766
+
767
+ Automatically generate `.env.example` files for onboarding new developers:
768
+
769
+ ```python
770
+ from dotenvmodel import DotEnvConfig, Field, SecretStr
771
+
772
+ class AppConfig(DotEnvConfig):
773
+ env_prefix = "APP_"
774
+
775
+ api_key: str = Field(
776
+ min_length=32,
777
+ max_length=64,
778
+ description="API key for external service"
779
+ )
780
+ port: int = Field(
781
+ default=8000,
782
+ ge=1,
783
+ le=65535,
784
+ description="Server port number"
785
+ )
786
+ database_password: SecretStr = Field(
787
+ default=SecretStr("change_me_in_production"),
788
+ min_length=8,
789
+ description="Database connection password"
790
+ )
791
+ allowed_hosts: list[str] = Field(
792
+ default_factory=list,
793
+ separator=";",
794
+ min_items=1,
795
+ max_items=10,
796
+ description="Allowed hostnames for CORS"
797
+ )
798
+
799
+ # Generate and print .env.example
800
+ print(AppConfig.generate_env_example())
801
+
802
+ # Or save directly to file
803
+ AppConfig.generate_env_example(output=".env.example")
804
+ ```
805
+
806
+ Output in `.env.example`:
807
+
808
+ ```bash
809
+ # Configuration for AppConfig
810
+ # All variables prefixed with: APP_
811
+
812
+ # API key for external service
813
+ # Type: str | Constraints: min_length=32, max_length=64
814
+ # Example: APP_API_KEY=your_value_here
815
+ APP_API_KEY=
816
+
817
+ # Server port number
818
+ # Type: int | Constraints: ge=1, le=65535
819
+ # Example: APP_PORT=8000
820
+ # APP_PORT=8000
821
+
822
+ # Database connection password
823
+ # Type: SecretStr | Constraints: min_length=8
824
+ # APP_DATABASE_PASSWORD=your_secret_here
825
+
826
+ # Allowed hostnames for CORS
827
+ # Type: list[str] | Constraints: min_items=1, max_items=10, separator=';'
828
+ # Example: APP_ALLOWED_HOSTS=[]
829
+ # APP_ALLOWED_HOSTS=[]
830
+ ```
831
+
832
+ The `.env.example` file includes:
833
+
834
+ - **Type information** - Shows the expected Python type
835
+ - **Parsing hints** - Explains how to format complex types (e.g., "comma-separated values" for lists)
836
+ - **Constraints** - Documents validation rules (min/max length, numeric ranges, etc.)
837
+ - **Examples** - Shows example values for required fields
838
+ - **Commented defaults** - Optional fields are commented out with their default values
839
+ - **Secret handling** - SecretStr fields are masked appropriately
840
+
841
+ ### Document Multiple Configurations
842
+
843
+ Use `describe_configs()` to document multiple related configuration classes:
844
+
845
+ ```python
846
+ from dotenvmodel import DotEnvConfig, Field, describe_configs
847
+
848
+ class DatabaseConfig(DotEnvConfig):
849
+ env_prefix = "DB_"
850
+ host: str = Field(description="Database host")
851
+ port: int = Field(default=5432, description="Database port")
852
+
853
+ class RedisConfig(DotEnvConfig):
854
+ env_prefix = "REDIS_"
855
+ host: str = Field(description="Redis host")
856
+ port: int = Field(default=6379, description="Redis port")
857
+
858
+ # Generate documentation for all configs
859
+ all_docs = describe_configs([DatabaseConfig, RedisConfig], output_format="markdown")
860
+ print(all_docs)
861
+ ```
862
+
863
+ ### Practical Use Cases
864
+
865
+ **1. Generate `.env.example` files for onboarding:**
866
+
867
+ ```python
868
+ # Generate .env.example with helpful comments and type information
869
+ AppConfig.generate_env_example(output=".env.example")
870
+
871
+ # Or combine multiple configs
872
+ from dotenvmodel import describe_configs
873
+
874
+ with open(".env.example", "w") as f:
875
+ f.write("# Application Configuration\n\n")
876
+ f.write("# Copy this file to .env and fill in the values\n\n")
877
+ for config_cls in [AppConfig, DatabaseConfig, RedisConfig]:
878
+ f.write(config_cls.generate_env_example())
879
+ f.write("\n\n")
880
+ ```
881
+
882
+ **2. CI Configuration Validation:**
883
+
884
+ ```python
885
+ import json
886
+ import os
887
+
888
+ # Get required environment variables from config schema
889
+ spec = json.loads(AppConfig.describe(output_format="json"))
890
+ required_vars = [f["env_var"] for f in spec["fields"] if f["required"]]
891
+
892
+ # Validate all required vars are set
893
+ missing = [var for var in required_vars if var not in os.environ]
894
+ if missing:
895
+ print(f"ERROR: Missing required environment variables: {', '.join(missing)}")
896
+ exit(1)
897
+ ```
898
+
899
+ **3. Developer Onboarding:**
900
+
901
+ ```python
902
+ import os
903
+
904
+ # Display configuration reference in development mode
905
+ if os.getenv("ENV") == "dev":
906
+ print("\n" + "=" * 80)
907
+ print("CONFIGURATION REFERENCE")
908
+ print("=" * 80)
909
+ print(AppConfig.describe())
910
+ print("=" * 80 + "\n")
911
+ ```
912
+
913
+ **4. Generate Documentation Website:**
914
+
915
+ ```python
916
+ from dotenvmodel import describe_configs
917
+
918
+ # Generate markdown docs for all config classes
919
+ configs = [AppConfig, DatabaseConfig, RedisConfig, CacheConfig]
920
+
921
+ # Save as markdown
922
+ describe_configs(configs, output_format="markdown", output="docs/configuration.md")
923
+
924
+ # Or generate HTML version with styling
925
+ describe_configs(configs, output_format="html", output="docs/configuration.html")
926
+ ```
927
+
928
+ **5. Build Tool Integration:**
929
+
930
+ ```python
931
+ # build_docs.py - Run during build process
932
+ from your_app.config import AppConfig, DatabaseConfig
933
+
934
+ # Generate .env.example for repository
935
+ AppConfig.generate_env_example(output=".env.example")
936
+
937
+ # Generate markdown docs
938
+ AppConfig.describe(output_format="markdown", output="docs/CONFIG.md")
939
+
940
+ # Generate HTML for internal wiki
941
+ AppConfig.describe(output_format="html", output="docs/config.html")
942
+
943
+ print("✓ Configuration documentation generated")
944
+ ```
945
+
653
946
  ## Environment Variable Prefixes
654
947
 
655
948
  Use class-level prefixes to namespace environment variables: