Skip to content

Commit 3159a2a

Browse files
added validation with Pydantic
1 parent d4f825d commit 3159a2a

File tree

6 files changed

+515
-119
lines changed

6 files changed

+515
-119
lines changed

README.md

Lines changed: 48 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@
1313

1414
- Very `lightweight` and `simple` API (currently it contains only one function)
1515
- `Easy` to use
16-
- Based on popular and well-tested libraries (like `camel-converter`, `PyYAML` and `munch`)
16+
- Based on popular and well-tested libraries (like `pydantic`, `camel-converter`, `PyYAML` and `munch`)
1717
- Automatically `merge` default and production configuration files
1818
- Convert keys in configuration files to `snake_case`
19-
19+
- YAML validation with `Pydantic` models
2020

2121
## Installation
2222

@@ -26,11 +26,10 @@ pip install pyya
2626

2727
Or download a specific version from [Releases](https://github.com/shadowy-pycoder/pyya/releases) page and install it with:
2828

29-
```shell
29+
```shell
3030
pip install /path/to/pyya-[version]-py3-none-any.whl
3131
```
3232

33-
3433
## Usage
3534

3635
### Example
@@ -39,38 +38,43 @@ Create YAML configuration files for your project:
3938

4039
```yaml
4140
# default.config.yaml - this file usually goes to version control system
42-
database:
43-
host: localhost
44-
port: 5432
45-
username: postgres
46-
password: postgres
41+
database:
42+
host: localhost
43+
port: 5432
44+
username: postgres
45+
password: postgres
4746

4847
redis:
49-
host: localhost
50-
port: 6379
48+
host: localhost
49+
port: 6379
5150
```
5251
5352
```yaml
5453
# config.yaml - this file for production usage
55-
database:
56-
username: username
57-
password: password
54+
database:
55+
username: username
56+
password: password
5857
```
5958
6059
Import configuration files in your Python code with `pyya`:
6160

6261
```python
6362
import json
6463
65-
from pyya import init_config
64+
from pyya import init_config, logger
65+
66+
logger.setLevel(logging.INFO)
6667
6768
config = init_config(
68-
'config.yaml', 'default.config.yaml',
69+
'config.yaml', 'default.config.yaml',
6970
merge_configs = True,
70-
sections_ignored_on_merge = ['redis'], # do not include redis on your config
71+
sections_ignored_on_merge = ['redis'], # do not include redis in your config
7172
convert_keys_to_snake_case = False,
7273
add_underscore_prefix_to_keywords = False
73-
raise_error_non_identifiers = False)
74+
raise_error_non_identifiers = False,
75+
validate_data_types = True,
76+
allow_extra_sections = True,
77+
)
7478
print(json.dumps(config))
7579
7680
# Output:
@@ -82,31 +86,45 @@ As you can see, `pyya` automatically merges default config file with production
8286

8387
Under the hood `pyya` uses [PyYAML](https://pypi.org/project/PyYAML/) to parse YAML files and [munch](https://pypi.org/project/munch/) library to create attribute-stylish dictionaries.
8488

85-
8689
### Flags
8790

88-
```python
91+
```python
8992
# merge default and production configuration files
9093
# setting to `False` disables other flags and makes default config optional
91-
# `False` means "open config file and apply `ymal.safe_load` and `munchify` with no formatting"
92-
merge_configs=True
94+
# `False` means "open config file and apply `yaml.safe_load` and `munchify` with no formatting"
95+
merge_configs=True
9396
```
97+
9498
```python
9599
# list of sections to ignore when merging configs
96100
# it is useful when you have examples in your default config but do not want to have in the main one
97101
sections_ignored_on_merge: Optional[List[str]] = None
98102
```
99-
```python
103+
104+
```python
100105
# convert `camelCase` or `PascalCase` keys to `snake_case`
101-
convert_keys_to_snake_case=True
102-
```
103-
```python
106+
convert_keys_to_snake_case=False
107+
```
108+
109+
```python
104110
# add underscore prefix to keys that are Python keywords
105-
add_underscore_prefix_to_keywords=True
106-
```
107-
```python
111+
add_underscore_prefix_to_keywords=False
112+
```
113+
114+
```python
108115
# raise error if key name is not valid Python identifier
109-
raise_error_non_identifiers=True
116+
raise_error_non_identifiers=False
117+
```
118+
119+
```python
120+
# raise error if data types in config are not the same as default (makes sense only if merge is enabled)
121+
# validation based on data types inferred from default config
122+
validate_data_types=True
123+
```
124+
125+
```python
126+
# raise error if there are extra sections in config (may break if section name formatting is enabled)
127+
allow_extra_sections=True
110128
```
111129

112130
## Contributing

pyproject.toml

Lines changed: 49 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,33 @@
11
[project]
22
name = "pyya"
3-
version = "0.1.5"
3+
version = "0.1.6"
44
authors = [
5-
{ name="shadowy-pycoder", email="[email protected]" },
5+
{ name = "shadowy-pycoder", email = "[email protected]" },
66
]
77
description = "Convert YAML configuration files to Python objects"
88
readme = "README.md"
99
requires-python = ">=3.8"
1010
classifiers = [
11-
"Programming Language :: Python :: 3",
12-
"Programming Language :: Python :: 3.8",
13-
"Programming Language :: Python :: 3.9",
14-
"Programming Language :: Python :: 3.10",
15-
"Programming Language :: Python :: 3.11",
16-
"Programming Language :: Python :: 3.12",
17-
"Programming Language :: Python :: 3.13",
18-
"License :: OSI Approved :: MIT License",
19-
"Operating System :: MacOS :: MacOS X",
20-
"Operating System :: Microsoft :: Windows",
21-
"Operating System :: POSIX :: Linux",
11+
"Programming Language :: Python :: 3",
12+
"Programming Language :: Python :: 3.8",
13+
"Programming Language :: Python :: 3.9",
14+
"Programming Language :: Python :: 3.10",
15+
"Programming Language :: Python :: 3.11",
16+
"Programming Language :: Python :: 3.12",
17+
"Programming Language :: Python :: 3.13",
18+
"License :: OSI Approved :: MIT License",
19+
"Operating System :: MacOS :: MacOS X",
20+
"Operating System :: Microsoft :: Windows",
21+
"Operating System :: POSIX :: Linux",
2222
]
2323
dependencies = [
24-
"camel-converter>=3.1.2",
25-
"munch>=4.0.0",
26-
"pyyaml>=6.0.2",
27-
"types-pyyaml>=6.0.12.20240917",
24+
"camel-converter>=3.1.2",
25+
"munch>=4.0.0",
26+
"pydantic>=2.5.2",
27+
"pyyaml>=6.0.2",
28+
"types-pyyaml>=6.0.12.20240917",
2829
]
30+
2931
[project.urls]
3032
Homepage = "https://github.com/shadowy-pycoder/pyya"
3133
Repository = "https://github.com/shadowy-pycoder/pyya"
@@ -59,43 +61,43 @@ ignore_missing_imports = true
5961
[tool.pytest.ini_options]
6062
pythonpath = "."
6163
filterwarnings = [
62-
"ignore::DeprecationWarning",
63-
"ignore::PendingDeprecationWarning",
64-
"ignore::ImportWarning",
65-
"ignore::ResourceWarning"
64+
"ignore::DeprecationWarning",
65+
"ignore::PendingDeprecationWarning",
66+
"ignore::ImportWarning",
67+
"ignore::ResourceWarning",
6668
]
6769
asyncio_mode = "auto"
6870
env_files = ".test.env"
6971
env_override_existing_values = true
7072

7173
[tool.ruff]
7274
exclude = [
73-
".bzr",
74-
".direnv",
75-
".eggs",
76-
".git",
77-
".git-rewrite",
78-
".hg",
79-
".ipynb_checkpoints",
80-
".mypy_cache",
81-
".nox",
82-
".pants.d",
83-
".pyenv",
84-
".pytest_cache",
85-
".pytype",
86-
".ruff_cache",
87-
".svn",
88-
".tox",
89-
".venv",
90-
".vscode",
91-
"__pypackages__",
92-
"_build",
93-
"buck-out",
94-
"build",
95-
"dist",
96-
"node_modules",
97-
"site-packages",
98-
"venv",
75+
".bzr",
76+
".direnv",
77+
".eggs",
78+
".git",
79+
".git-rewrite",
80+
".hg",
81+
".ipynb_checkpoints",
82+
".mypy_cache",
83+
".nox",
84+
".pants.d",
85+
".pyenv",
86+
".pytest_cache",
87+
".pytype",
88+
".ruff_cache",
89+
".svn",
90+
".tox",
91+
".venv",
92+
".vscode",
93+
"__pypackages__",
94+
"_build",
95+
"buck-out",
96+
"build",
97+
"dist",
98+
"node_modules",
99+
"site-packages",
100+
"venv",
99101
]
100102
line-length = 120
101103
indent-width = 4

0 commit comments

Comments
 (0)