schemez 0.0.1__py3-none-any.whl

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.
schemez/__init__.py ADDED
@@ -0,0 +1,6 @@
1
+ __version__ = "0.0.1"
2
+
3
+
4
+ from schemez.schema import Schema
5
+
6
+ __all__ = ["Schema"]
schemez/helpers.py ADDED
@@ -0,0 +1,35 @@
1
+ """Helpers for BaseModels."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+
7
+ from pydantic import BaseModel
8
+
9
+
10
+ StrPath = str | os.PathLike[str]
11
+
12
+
13
+ def merge_models[T: BaseModel](base: T, overlay: T) -> T:
14
+ """Deep merge two Pydantic models."""
15
+ if not isinstance(overlay, type(base)):
16
+ msg = f"Cannot merge different types: {type(base)} and {type(overlay)}"
17
+ raise TypeError(msg)
18
+
19
+ merged_data = base.model_dump()
20
+ overlay_data = overlay.model_dump(exclude_none=True)
21
+ for field_name, field_value in overlay_data.items():
22
+ base_value = merged_data.get(field_name)
23
+
24
+ match (base_value, field_value):
25
+ case (list(), list()):
26
+ merged_data[field_name] = [
27
+ *base_value,
28
+ *(item for item in field_value if item not in base_value),
29
+ ]
30
+ case (dict(), dict()):
31
+ merged_data[field_name] = base_value | field_value
32
+ case _:
33
+ merged_data[field_name] = field_value
34
+
35
+ return base.__class__.model_validate(merged_data)
schemez/py.typed ADDED
File without changes
schemez/schema.py ADDED
@@ -0,0 +1,67 @@
1
+ """Configuration models for Schemez."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ from typing import Self
7
+
8
+ from pydantic import BaseModel, ConfigDict
9
+ import upath
10
+
11
+
12
+ StrPath = str | os.PathLike[str]
13
+
14
+
15
+ class Schema(BaseModel):
16
+ """Base class configuration models.
17
+
18
+ Provides:
19
+ - Common Pydantic settings
20
+ - YAML serialization
21
+ - Basic merge functionality
22
+ """
23
+
24
+ model_config = ConfigDict(extra="forbid", use_attribute_docstrings=True)
25
+
26
+ def merge(self, other: Self) -> Self:
27
+ """Merge with another instance by overlaying its non-None values."""
28
+ from schemez.helpers import merge_models
29
+
30
+ return merge_models(self, other)
31
+
32
+ @classmethod
33
+ def from_yaml(cls, content: str, inherit_path: StrPath | None = None) -> Self:
34
+ """Create from YAML string."""
35
+ import yamling
36
+
37
+ data = yamling.load_yaml(content, resolve_inherit=inherit_path or False)
38
+ return cls.model_validate(data)
39
+
40
+ def model_dump_yaml(self) -> str:
41
+ """Dump configuration to YAML string."""
42
+ import yamling
43
+
44
+ return yamling.dump_yaml(self.model_dump(exclude_none=True))
45
+
46
+ def save(self, path: StrPath, overwrite: bool = False) -> None:
47
+ """Save configuration to a YAML file.
48
+
49
+ Args:
50
+ path: Path to save the configuration to
51
+ overwrite: Whether to overwrite an existing file
52
+
53
+ Raises:
54
+ OSError: If file cannot be written
55
+ ValueError: If path is invalid
56
+ """
57
+ yaml_str = self.model_dump_yaml()
58
+ try:
59
+ file_path = upath.UPath(path)
60
+ if file_path.exists() and not overwrite:
61
+ msg = f"File already exists: {path}"
62
+ raise FileExistsError(msg) # noqa: TRY301
63
+ file_path.parent.mkdir(parents=True, exist_ok=True)
64
+ file_path.write_text(yaml_str)
65
+ except Exception as exc:
66
+ msg = f"Failed to save configuration to {path}"
67
+ raise ValueError(msg) from exc
@@ -0,0 +1,84 @@
1
+ Metadata-Version: 2.4
2
+ Name: schemez
3
+ Version: 0.0.1
4
+ Summary: Pydantic shim for config stuff
5
+ Project-URL: Documentation, https://phil65.github.io/schemez/
6
+ Project-URL: Source, https://github.com/phil65/schemez
7
+ Project-URL: Issues, https://github.com/phil65/schemez/issues
8
+ Project-URL: Discussions, https://github.com/phil65/schemez/discussions
9
+ Project-URL: Code coverage, https://app.codecov.io/gh/phil65/schemez
10
+ Author-email: Philipp Temminghoff <philipptemminghoff@googlemail.com>
11
+ License: MIT License
12
+
13
+ Copyright (c) 2024, Philipp Temminghoff
14
+
15
+ Permission is hereby granted, free of charge, to any person obtaining a copy
16
+ of this software and associated documentation files (the "Software"), to deal
17
+ in the Software without restriction, including without limitation the rights
18
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19
+ copies of the Software, and to permit persons to whom the Software is
20
+ furnished to do so, subject to the following conditions:
21
+
22
+ The above copyright notice and this permission notice shall be included in all
23
+ copies or substantial portions of the Software.
24
+
25
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31
+ SOFTWARE.
32
+
33
+ License-File: LICENSE
34
+ Classifier: Development Status :: 4 - Beta
35
+ Classifier: Framework :: Pydantic
36
+ Classifier: Framework :: Pydantic :: 2
37
+ Classifier: Intended Audience :: Developers
38
+ Classifier: Operating System :: OS Independent
39
+ Classifier: Programming Language :: Python :: 3
40
+ Classifier: Programming Language :: Python :: 3 :: Only
41
+ Classifier: Programming Language :: Python :: 3.12
42
+ Classifier: Programming Language :: Python :: 3.13
43
+ Classifier: Programming Language :: Python :: 3.14
44
+ Classifier: Topic :: Documentation
45
+ Classifier: Topic :: Software Development
46
+ Classifier: Topic :: Utilities
47
+ Classifier: Typing :: Typed
48
+ Requires-Python: >=3.12
49
+ Requires-Dist: pydantic
50
+ Requires-Dist: universal-pathlib>=0.2.6
51
+ Description-Content-Type: text/markdown
52
+
53
+ # Schemez
54
+
55
+ [![PyPI License](https://img.shields.io/pypi/l/schemez.svg)](https://pypi.org/project/schemez/)
56
+ [![Package status](https://img.shields.io/pypi/status/schemez.svg)](https://pypi.org/project/schemez/)
57
+ [![Daily downloads](https://img.shields.io/pypi/dd/schemez.svg)](https://pypi.org/project/schemez/)
58
+ [![Weekly downloads](https://img.shields.io/pypi/dw/schemez.svg)](https://pypi.org/project/schemez/)
59
+ [![Monthly downloads](https://img.shields.io/pypi/dm/schemez.svg)](https://pypi.org/project/schemez/)
60
+ [![Distribution format](https://img.shields.io/pypi/format/schemez.svg)](https://pypi.org/project/schemez/)
61
+ [![Wheel availability](https://img.shields.io/pypi/wheel/schemez.svg)](https://pypi.org/project/schemez/)
62
+ [![Python version](https://img.shields.io/pypi/pyversions/schemez.svg)](https://pypi.org/project/schemez/)
63
+ [![Implementation](https://img.shields.io/pypi/implementation/schemez.svg)](https://pypi.org/project/schemez/)
64
+ [![Releases](https://img.shields.io/github/downloads/phil65/schemez/total.svg)](https://github.com/phil65/schemez/releases)
65
+ [![Github Contributors](https://img.shields.io/github/contributors/phil65/schemez)](https://github.com/phil65/schemez/graphs/contributors)
66
+ [![Github Discussions](https://img.shields.io/github/discussions/phil65/schemez)](https://github.com/phil65/schemez/discussions)
67
+ [![Github Forks](https://img.shields.io/github/forks/phil65/schemez)](https://github.com/phil65/schemez/forks)
68
+ [![Github Issues](https://img.shields.io/github/issues/phil65/schemez)](https://github.com/phil65/schemez/issues)
69
+ [![Github Issues](https://img.shields.io/github/issues-pr/phil65/schemez)](https://github.com/phil65/schemez/pulls)
70
+ [![Github Watchers](https://img.shields.io/github/watchers/phil65/schemez)](https://github.com/phil65/schemez/watchers)
71
+ [![Github Stars](https://img.shields.io/github/stars/phil65/schemez)](https://github.com/phil65/schemez/stars)
72
+ [![Github Repository size](https://img.shields.io/github/repo-size/phil65/schemez)](https://github.com/phil65/schemez)
73
+ [![Github last commit](https://img.shields.io/github/last-commit/phil65/schemez)](https://github.com/phil65/schemez/commits)
74
+ [![Github release date](https://img.shields.io/github/release-date/phil65/schemez)](https://github.com/phil65/schemez/releases)
75
+ [![Github language count](https://img.shields.io/github/languages/count/phil65/schemez)](https://github.com/phil65/schemez)
76
+ [![Github commits this week](https://img.shields.io/github/commit-activity/w/phil65/schemez)](https://github.com/phil65/schemez)
77
+ [![Github commits this month](https://img.shields.io/github/commit-activity/m/phil65/schemez)](https://github.com/phil65/schemez)
78
+ [![Github commits this year](https://img.shields.io/github/commit-activity/y/phil65/schemez)](https://github.com/phil65/schemez)
79
+ [![Package status](https://codecov.io/gh/phil65/schemez/branch/main/graph/badge.svg)](https://codecov.io/gh/phil65/schemez/)
80
+ [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
81
+ [![PyUp](https://pyup.io/repos/github/phil65/schemez/shield.svg)](https://pyup.io/repos/github/phil65/schemez/)
82
+
83
+ [Read the documentation!](https://phil65.github.io/schemez/)
84
+
@@ -0,0 +1,8 @@
1
+ schemez/__init__.py,sha256=8GownnUkTUVUdUuosh5mCOW9OqoY_9-_66_BmQL9yEM,80
2
+ schemez/helpers.py,sha256=bbmtpB9hz3iyc7u9zpuOPQnUuwj5J751C3RtmXs8PzU,1116
3
+ schemez/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ schemez/schema.py,sha256=6rubAfdwdcmFRP8SfPQpfyuR674uuIy9u3zo7PndlWU,2070
5
+ schemez-0.0.1.dist-info/METADATA,sha256=o78fWu1GlwqnJGwjWGZVNGyVETwb66CWcBMzNsQoYv8,5693
6
+ schemez-0.0.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
7
+ schemez-0.0.1.dist-info/licenses/LICENSE,sha256=AteGCH9r177TxxrOFEiOARrastASsf7yW6MQxlAHdwA,1078
8
+ schemez-0.0.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.27.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024, Philipp Temminghoff
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.
22
+