ReadTheYAML 1.9.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.
- readtheyaml-1.9.0/LICENSE +21 -0
- readtheyaml-1.9.0/PKG-INFO +273 -0
- readtheyaml-1.9.0/README.md +261 -0
- readtheyaml-1.9.0/ReadTheYAML.egg-info/PKG-INFO +273 -0
- readtheyaml-1.9.0/ReadTheYAML.egg-info/SOURCES.txt +32 -0
- readtheyaml-1.9.0/ReadTheYAML.egg-info/dependency_links.txt +1 -0
- readtheyaml-1.9.0/ReadTheYAML.egg-info/requires.txt +1 -0
- readtheyaml-1.9.0/ReadTheYAML.egg-info/top_level.txt +4 -0
- readtheyaml-1.9.0/pyproject.toml +19 -0
- readtheyaml-1.9.0/readtheyaml/__init__.py +0 -0
- readtheyaml-1.9.0/readtheyaml/exceptions/__init__.py +0 -0
- readtheyaml-1.9.0/readtheyaml/exceptions/format_error.py +14 -0
- readtheyaml-1.9.0/readtheyaml/exceptions/validation_error.py +14 -0
- readtheyaml-1.9.0/readtheyaml/fields/__init__.py +0 -0
- readtheyaml-1.9.0/readtheyaml/fields/bool_field.py +21 -0
- readtheyaml-1.9.0/readtheyaml/fields/composite_field.py +27 -0
- readtheyaml-1.9.0/readtheyaml/fields/enum_field.py +16 -0
- readtheyaml-1.9.0/readtheyaml/fields/field.py +39 -0
- readtheyaml-1.9.0/readtheyaml/fields/field_helpers.py +109 -0
- readtheyaml-1.9.0/readtheyaml/fields/field_registery.py +21 -0
- readtheyaml-1.9.0/readtheyaml/fields/field_validation_helpers.py +35 -0
- readtheyaml-1.9.0/readtheyaml/fields/list_field.py +48 -0
- readtheyaml-1.9.0/readtheyaml/fields/none_field.py +13 -0
- readtheyaml-1.9.0/readtheyaml/fields/numerical_field.py +41 -0
- readtheyaml-1.9.0/readtheyaml/fields/string_field.py +45 -0
- readtheyaml-1.9.0/readtheyaml/fields/tuple_field.py +40 -0
- readtheyaml-1.9.0/readtheyaml/fields/union_field.py +56 -0
- readtheyaml-1.9.0/readtheyaml/schema.py +93 -0
- readtheyaml-1.9.0/readtheyaml/sections.py +96 -0
- readtheyaml-1.9.0/setup.cfg +4 -0
- readtheyaml-1.9.0/tests/__init__.py +0 -0
- readtheyaml-1.9.0/tests/test_composite_fields.py +898 -0
- readtheyaml-1.9.0/tests/test_fields.py +1159 -0
- readtheyaml-1.9.0/tests/test_schema.py +111 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Vincent Martineau
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ReadTheYAML
|
|
3
|
+
Version: 1.9.0
|
|
4
|
+
Summary: Validate and document your YAML config files — so future-you doesn't have to guess.
|
|
5
|
+
Author-email: Vincent Martineau <vincent.martineau.1@ulaval.ca>
|
|
6
|
+
License: MIT
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Requires-Dist: pyyaml>=6.0
|
|
11
|
+
Dynamic: license-file
|
|
12
|
+
|
|
13
|
+
# ReadTheYaml
|
|
14
|
+
|
|
15
|
+
> A lightweight YAML schema validator with just enough structure to stop future-you from asking: "Why the heck did I set this to 42?"
|
|
16
|
+
|
|
17
|
+
## What is this?
|
|
18
|
+
|
|
19
|
+
**ReadTheYaml** is a Python library that helps you define, validate, and document your YAML configuration files. It was built by someone (me) who got tired of forgetting:
|
|
20
|
+
|
|
21
|
+
- Which config values were required vs optional
|
|
22
|
+
- Why a given field was there in the first place
|
|
23
|
+
- What values are valid
|
|
24
|
+
|
|
25
|
+
It enforces structure in your YAML and documents everything along the way.
|
|
26
|
+
|
|
27
|
+
There might be more mature alternatives out there (really!), but this one's small, readable, and purpose-built for when you're tired of guessing your own project settings.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## 📦 Installation
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install ReadTheYaml
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Alternatively, clone the repo and install locally:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
git clone https://github.com/TheRealMarVin/ReadTheYaml.git
|
|
41
|
+
cd ReadTheYaml
|
|
42
|
+
pip install -e .
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## What can it do?
|
|
48
|
+
|
|
49
|
+
### 🔹 Validate YAML config files
|
|
50
|
+
It ensures all required fields are present, types are correct, and defaults are filled in where needed.
|
|
51
|
+
|
|
52
|
+
### 🔹 Support optional and required fields with descriptions
|
|
53
|
+
So future-you (or teammates) know what a setting is for.
|
|
54
|
+
|
|
55
|
+
### 🔹 Provide default values
|
|
56
|
+
Optional fields can define a default that will be added if missing.
|
|
57
|
+
|
|
58
|
+
### 🔹 Define valid numeric or length ranges
|
|
59
|
+
So you don’t accidentally open port `99999` or supply an empty list.
|
|
60
|
+
|
|
61
|
+
### 🔹 Support list validation
|
|
62
|
+
You can define `list(int)`, `list(str)`, or even `list(nested(...))` to validate list content with precision.
|
|
63
|
+
|
|
64
|
+
### 🔹 Define enum fields
|
|
65
|
+
You can restrict values to a fixed set of strings using `EnumField` or `type: enum`.
|
|
66
|
+
|
|
67
|
+
### 🔹 Modular design with `$ref`
|
|
68
|
+
Schemas can include and reuse other schemas stored in separate files.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
## Supported Schema Types
|
|
72
|
+
|
|
73
|
+
ReadTheYAML provides a flexible and expressive way to define and validate data structures using YAML. Below is an overview of the supported types, their syntax, and usage examples. I tried to follow the standard of type hints in Python, but I relaxed some constraints.
|
|
74
|
+
|
|
75
|
+
### 🔹 Basic Types
|
|
76
|
+
|
|
77
|
+
* `None`: Represents None.
|
|
78
|
+
* `int`: Represents integer values.
|
|
79
|
+
* `float`: Represents floating-point numbers.
|
|
80
|
+
* `str`: Represents string values.
|
|
81
|
+
* `bool`: Represents boolean values (`true` or `false`).
|
|
82
|
+
|
|
83
|
+
**Example:**
|
|
84
|
+
|
|
85
|
+
```yaml
|
|
86
|
+
type: int
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### 🔹 Composite Types
|
|
90
|
+
|
|
91
|
+
#### List
|
|
92
|
+
|
|
93
|
+
Defines a list of elements of a specified type.
|
|
94
|
+
|
|
95
|
+
**Syntax:**
|
|
96
|
+
|
|
97
|
+
```yaml
|
|
98
|
+
type: list[<element_type>]
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Example:**
|
|
102
|
+
|
|
103
|
+
```yaml
|
|
104
|
+
type: list[int]
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
#### Tuple
|
|
108
|
+
|
|
109
|
+
Defines a fixed-size sequence of elements, each with a specified type.
|
|
110
|
+
|
|
111
|
+
**Syntax:**
|
|
112
|
+
|
|
113
|
+
```yaml
|
|
114
|
+
type: tuple[<type1>, <type2>, ...]
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Example:**
|
|
118
|
+
|
|
119
|
+
```yaml
|
|
120
|
+
type: tuple[int, str]
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
#### Union
|
|
124
|
+
|
|
125
|
+
Specifies that a value can be of one of several types.
|
|
126
|
+
|
|
127
|
+
**Syntax:**
|
|
128
|
+
|
|
129
|
+
```yaml
|
|
130
|
+
type: union[<type1>, <type2>, ...]
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**Example:**
|
|
134
|
+
|
|
135
|
+
```yaml
|
|
136
|
+
type: union[int, str]
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### 🔹 Optional Types
|
|
140
|
+
|
|
141
|
+
To indicate that a field is optional (i.e., it can be `null`), include `None` in a `union`.
|
|
142
|
+
|
|
143
|
+
**Example:**
|
|
144
|
+
|
|
145
|
+
```yaml
|
|
146
|
+
type: union[int, None]
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Alternatively, you can use the shorthand:
|
|
150
|
+
|
|
151
|
+
```yaml
|
|
152
|
+
type: int | None
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### 🔹 Syntax Variations
|
|
156
|
+
|
|
157
|
+
ReadTheYAML supports both square brackets `[]` and parentheses `()` for defining composite types. However, the opening and closing brackets must match.
|
|
158
|
+
|
|
159
|
+
**Valid:**
|
|
160
|
+
|
|
161
|
+
```yaml
|
|
162
|
+
type: tuple[int, str]
|
|
163
|
+
type: tuple(int, str)
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Invalid:**
|
|
167
|
+
|
|
168
|
+
```yaml
|
|
169
|
+
type: tuple[int, str)
|
|
170
|
+
type: tuple(int, str]
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### 🔹 Nested Types
|
|
174
|
+
|
|
175
|
+
You can nest composite types to define complex structures.
|
|
176
|
+
|
|
177
|
+
**Example:**
|
|
178
|
+
|
|
179
|
+
```yaml
|
|
180
|
+
type: list[tuple[int, str]]
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
This defines a list where each element is a tuple containing an integer and a string.
|
|
184
|
+
|
|
185
|
+
### 🔹 Field Options
|
|
186
|
+
|
|
187
|
+
Fields can have additional options to control validation and behavior:
|
|
188
|
+
|
|
189
|
+
* `description`: Provides a human-readable description of the field. This one is mandatory
|
|
190
|
+
* `required`: Indicates whether the field is mandatory. By default, the value is false (the field is not required).
|
|
191
|
+
* `default`: Specifies a default value if the field is omitted. This is mandatory when required is set to false.
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
**Example:**
|
|
195
|
+
|
|
196
|
+
```yaml
|
|
197
|
+
name:
|
|
198
|
+
type: str
|
|
199
|
+
required: true
|
|
200
|
+
default: Unnamed
|
|
201
|
+
description: The name of the entity.
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Example schema.yaml
|
|
207
|
+
|
|
208
|
+
```yaml
|
|
209
|
+
name: app_config
|
|
210
|
+
|
|
211
|
+
status:
|
|
212
|
+
type: enum
|
|
213
|
+
enum: [pending, approved, rejected]
|
|
214
|
+
required: true
|
|
215
|
+
|
|
216
|
+
retries:
|
|
217
|
+
type: int
|
|
218
|
+
default: 3
|
|
219
|
+
min_value: 0
|
|
220
|
+
max_value: 10
|
|
221
|
+
|
|
222
|
+
servers:
|
|
223
|
+
type: list(nested(Server))
|
|
224
|
+
length_range: [1, 5]
|
|
225
|
+
|
|
226
|
+
tags:
|
|
227
|
+
type: list(str)
|
|
228
|
+
min_length: 1
|
|
229
|
+
|
|
230
|
+
Server:
|
|
231
|
+
host:
|
|
232
|
+
type: str
|
|
233
|
+
required: true
|
|
234
|
+
port:
|
|
235
|
+
type: int
|
|
236
|
+
default: 8080
|
|
237
|
+
min_value: 1
|
|
238
|
+
max_value: 65535
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## How to Use
|
|
244
|
+
|
|
245
|
+
### 1. Validate a file with CLI
|
|
246
|
+
```bash
|
|
247
|
+
python -m ReadTheYaml.cli --schema schema.yaml --config config.yaml
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
You’ll see:
|
|
251
|
+
```
|
|
252
|
+
✅ Config is valid!
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
Or, if something’s off:
|
|
256
|
+
```
|
|
257
|
+
❌ Validation failed: [status] must be one of: pending, approved, rejected
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### 2. Programmatic usage
|
|
261
|
+
```python
|
|
262
|
+
from readtheyaml.schema import Schema
|
|
263
|
+
|
|
264
|
+
try:
|
|
265
|
+
schema = Schema.from_yaml("schema.yaml")
|
|
266
|
+
validated_config = schema.validate_file("config.yaml")
|
|
267
|
+
print(validated_config)
|
|
268
|
+
except Exception as e:
|
|
269
|
+
print(f"⚠️ Failed to load or validate config: {e}")
|
|
270
|
+
```
|
|
271
|
+
---
|
|
272
|
+
## Contributions
|
|
273
|
+
If you try this out and find something confusing or missing — feel free to open an issue or suggestion. This project is a work-in-progress, but built with love and frustration.
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
# ReadTheYaml
|
|
2
|
+
|
|
3
|
+
> A lightweight YAML schema validator with just enough structure to stop future-you from asking: "Why the heck did I set this to 42?"
|
|
4
|
+
|
|
5
|
+
## What is this?
|
|
6
|
+
|
|
7
|
+
**ReadTheYaml** is a Python library that helps you define, validate, and document your YAML configuration files. It was built by someone (me) who got tired of forgetting:
|
|
8
|
+
|
|
9
|
+
- Which config values were required vs optional
|
|
10
|
+
- Why a given field was there in the first place
|
|
11
|
+
- What values are valid
|
|
12
|
+
|
|
13
|
+
It enforces structure in your YAML and documents everything along the way.
|
|
14
|
+
|
|
15
|
+
There might be more mature alternatives out there (really!), but this one's small, readable, and purpose-built for when you're tired of guessing your own project settings.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 📦 Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install ReadTheYaml
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Alternatively, clone the repo and install locally:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
git clone https://github.com/TheRealMarVin/ReadTheYaml.git
|
|
29
|
+
cd ReadTheYaml
|
|
30
|
+
pip install -e .
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## What can it do?
|
|
36
|
+
|
|
37
|
+
### 🔹 Validate YAML config files
|
|
38
|
+
It ensures all required fields are present, types are correct, and defaults are filled in where needed.
|
|
39
|
+
|
|
40
|
+
### 🔹 Support optional and required fields with descriptions
|
|
41
|
+
So future-you (or teammates) know what a setting is for.
|
|
42
|
+
|
|
43
|
+
### 🔹 Provide default values
|
|
44
|
+
Optional fields can define a default that will be added if missing.
|
|
45
|
+
|
|
46
|
+
### 🔹 Define valid numeric or length ranges
|
|
47
|
+
So you don’t accidentally open port `99999` or supply an empty list.
|
|
48
|
+
|
|
49
|
+
### 🔹 Support list validation
|
|
50
|
+
You can define `list(int)`, `list(str)`, or even `list(nested(...))` to validate list content with precision.
|
|
51
|
+
|
|
52
|
+
### 🔹 Define enum fields
|
|
53
|
+
You can restrict values to a fixed set of strings using `EnumField` or `type: enum`.
|
|
54
|
+
|
|
55
|
+
### 🔹 Modular design with `$ref`
|
|
56
|
+
Schemas can include and reuse other schemas stored in separate files.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
## Supported Schema Types
|
|
60
|
+
|
|
61
|
+
ReadTheYAML provides a flexible and expressive way to define and validate data structures using YAML. Below is an overview of the supported types, their syntax, and usage examples. I tried to follow the standard of type hints in Python, but I relaxed some constraints.
|
|
62
|
+
|
|
63
|
+
### 🔹 Basic Types
|
|
64
|
+
|
|
65
|
+
* `None`: Represents None.
|
|
66
|
+
* `int`: Represents integer values.
|
|
67
|
+
* `float`: Represents floating-point numbers.
|
|
68
|
+
* `str`: Represents string values.
|
|
69
|
+
* `bool`: Represents boolean values (`true` or `false`).
|
|
70
|
+
|
|
71
|
+
**Example:**
|
|
72
|
+
|
|
73
|
+
```yaml
|
|
74
|
+
type: int
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 🔹 Composite Types
|
|
78
|
+
|
|
79
|
+
#### List
|
|
80
|
+
|
|
81
|
+
Defines a list of elements of a specified type.
|
|
82
|
+
|
|
83
|
+
**Syntax:**
|
|
84
|
+
|
|
85
|
+
```yaml
|
|
86
|
+
type: list[<element_type>]
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**Example:**
|
|
90
|
+
|
|
91
|
+
```yaml
|
|
92
|
+
type: list[int]
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
#### Tuple
|
|
96
|
+
|
|
97
|
+
Defines a fixed-size sequence of elements, each with a specified type.
|
|
98
|
+
|
|
99
|
+
**Syntax:**
|
|
100
|
+
|
|
101
|
+
```yaml
|
|
102
|
+
type: tuple[<type1>, <type2>, ...]
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**Example:**
|
|
106
|
+
|
|
107
|
+
```yaml
|
|
108
|
+
type: tuple[int, str]
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
#### Union
|
|
112
|
+
|
|
113
|
+
Specifies that a value can be of one of several types.
|
|
114
|
+
|
|
115
|
+
**Syntax:**
|
|
116
|
+
|
|
117
|
+
```yaml
|
|
118
|
+
type: union[<type1>, <type2>, ...]
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
**Example:**
|
|
122
|
+
|
|
123
|
+
```yaml
|
|
124
|
+
type: union[int, str]
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### 🔹 Optional Types
|
|
128
|
+
|
|
129
|
+
To indicate that a field is optional (i.e., it can be `null`), include `None` in a `union`.
|
|
130
|
+
|
|
131
|
+
**Example:**
|
|
132
|
+
|
|
133
|
+
```yaml
|
|
134
|
+
type: union[int, None]
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Alternatively, you can use the shorthand:
|
|
138
|
+
|
|
139
|
+
```yaml
|
|
140
|
+
type: int | None
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### 🔹 Syntax Variations
|
|
144
|
+
|
|
145
|
+
ReadTheYAML supports both square brackets `[]` and parentheses `()` for defining composite types. However, the opening and closing brackets must match.
|
|
146
|
+
|
|
147
|
+
**Valid:**
|
|
148
|
+
|
|
149
|
+
```yaml
|
|
150
|
+
type: tuple[int, str]
|
|
151
|
+
type: tuple(int, str)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**Invalid:**
|
|
155
|
+
|
|
156
|
+
```yaml
|
|
157
|
+
type: tuple[int, str)
|
|
158
|
+
type: tuple(int, str]
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### 🔹 Nested Types
|
|
162
|
+
|
|
163
|
+
You can nest composite types to define complex structures.
|
|
164
|
+
|
|
165
|
+
**Example:**
|
|
166
|
+
|
|
167
|
+
```yaml
|
|
168
|
+
type: list[tuple[int, str]]
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
This defines a list where each element is a tuple containing an integer and a string.
|
|
172
|
+
|
|
173
|
+
### 🔹 Field Options
|
|
174
|
+
|
|
175
|
+
Fields can have additional options to control validation and behavior:
|
|
176
|
+
|
|
177
|
+
* `description`: Provides a human-readable description of the field. This one is mandatory
|
|
178
|
+
* `required`: Indicates whether the field is mandatory. By default, the value is false (the field is not required).
|
|
179
|
+
* `default`: Specifies a default value if the field is omitted. This is mandatory when required is set to false.
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
**Example:**
|
|
183
|
+
|
|
184
|
+
```yaml
|
|
185
|
+
name:
|
|
186
|
+
type: str
|
|
187
|
+
required: true
|
|
188
|
+
default: Unnamed
|
|
189
|
+
description: The name of the entity.
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Example schema.yaml
|
|
195
|
+
|
|
196
|
+
```yaml
|
|
197
|
+
name: app_config
|
|
198
|
+
|
|
199
|
+
status:
|
|
200
|
+
type: enum
|
|
201
|
+
enum: [pending, approved, rejected]
|
|
202
|
+
required: true
|
|
203
|
+
|
|
204
|
+
retries:
|
|
205
|
+
type: int
|
|
206
|
+
default: 3
|
|
207
|
+
min_value: 0
|
|
208
|
+
max_value: 10
|
|
209
|
+
|
|
210
|
+
servers:
|
|
211
|
+
type: list(nested(Server))
|
|
212
|
+
length_range: [1, 5]
|
|
213
|
+
|
|
214
|
+
tags:
|
|
215
|
+
type: list(str)
|
|
216
|
+
min_length: 1
|
|
217
|
+
|
|
218
|
+
Server:
|
|
219
|
+
host:
|
|
220
|
+
type: str
|
|
221
|
+
required: true
|
|
222
|
+
port:
|
|
223
|
+
type: int
|
|
224
|
+
default: 8080
|
|
225
|
+
min_value: 1
|
|
226
|
+
max_value: 65535
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## How to Use
|
|
232
|
+
|
|
233
|
+
### 1. Validate a file with CLI
|
|
234
|
+
```bash
|
|
235
|
+
python -m ReadTheYaml.cli --schema schema.yaml --config config.yaml
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
You’ll see:
|
|
239
|
+
```
|
|
240
|
+
✅ Config is valid!
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Or, if something’s off:
|
|
244
|
+
```
|
|
245
|
+
❌ Validation failed: [status] must be one of: pending, approved, rejected
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### 2. Programmatic usage
|
|
249
|
+
```python
|
|
250
|
+
from readtheyaml.schema import Schema
|
|
251
|
+
|
|
252
|
+
try:
|
|
253
|
+
schema = Schema.from_yaml("schema.yaml")
|
|
254
|
+
validated_config = schema.validate_file("config.yaml")
|
|
255
|
+
print(validated_config)
|
|
256
|
+
except Exception as e:
|
|
257
|
+
print(f"⚠️ Failed to load or validate config: {e}")
|
|
258
|
+
```
|
|
259
|
+
---
|
|
260
|
+
## Contributions
|
|
261
|
+
If you try this out and find something confusing or missing — feel free to open an issue or suggestion. This project is a work-in-progress, but built with love and frustration.
|