marrying pydantic models and tomlkit documents
Project description
tomlantic
[!WARNING]
tomlantic is at 0.2.1 and currently, only i use it myself. it isn't battle tested, so issues may arise.
if you're willing to run into potential bugs and issues, feel free to use it!
marrying pydantic models and tomlkit documents for data validated, style-preserving toml files
uses generics to automagically preserve model types, so you don't lose out on model type information :D
usage
installation
there are three notable methods to use tomlantic with your project:
-
install from pypi
pip install tomlantic
-
install from source
pip install git+https://github.com/markjoshwel/tomlantic
-
directly include tomlantic.py in your project
wget https://raw.githubusercontent.com/markjoshwel/tomlantic/main/tomlantic/tomlantic.py
tomlantic is a single file module and is free and unencumbered software released into the public domain. so, use it however you please!
see the licence section for more information.
quickstart
import pydantic
import tomlkit
from tomlantic import ModelBoundTOML
class Project(pydantic.BaseModel):
model_config = pydantic.ConfigDict(validate_assignment=True)
name: str
description: str
typechecked: bool
class File(pydantic.BaseModel):
model_config = pydantic.ConfigDict(validate_assignment=True)
project: Project
toml_doc = tomlkit.parse(
"[project]\n"
'name = "tomlantic"\n'
'description = "marrying pydantic models and tomlkit documents"\n'
"typechecked = false\n"
)
# where tomlantic comes in handy
toml = ModelBoundTOML(File, toml_doc)
# access the model with .model and change the model freely
model: File = toml.model
model.project.typechecked = True
# dump the model back to a toml document
new_toml_doc = toml.model_dump_toml()
assert new_toml_doc["project"]["typechecked"] == True # type: ignore
print(new_toml_doc.as_string())
validators
tomlantic also comes with a neat set of validators to use with handling pydantic model fields and/or the toml document itself:
- tomlantic.validate_to_specific_type
- tomlantic.validate_to_multiple_types
- tomlantic.validate_homogeneous_collection
- tomlantic.validate_heterogeneous_collection
api reference
- tomlantic.ModelBoundTOML
- tomlantic.Difference
- tomlantic.get_toml_field
- tomlantic.set_toml_field
- tomlantic.TomlanticException
- tomlantic.TOMLBaseSingleError
- tomlantic.TOMLAttributeError
- tomlantic.TOMLFrozenError
- tomlantic.TOMLMissingError
- tomlantic.TOMLValueError
- tomlantic.TOMLValidationError
- tomlantic.validate_to_specific_type
- tomlantic.validate_to_multiple_types
- tomlantic.validate_homogeneous_collection
- tomlantic.validate_heterogeneous_collection
class tomlantic.ModelBoundTOML
tomlantic's magical glue class for pydantic models and tomlkit documents
will handle pydantic.ValidationErrors into more toml-friendly error messages.
set handle_errors
to False
to raise the original
pydantic.ValidationError
-
attributes:
- model:
pydantic.BaseModel
- model:
-
initialisation arguments:
- model:
pydantic.BaseModel
- toml:
tomlkit.TOMLDocument
- human_errors:
bool
=False
- model:
-
raises:
tomlantic.TOMLValidationError
if the document does not validate with the modelpydantic.ValidationError
if the document does not validate with the model andhandle_errors
isFalse
-
methods:
-
usage:
# instantiate the class toml = ModelBoundTOML(YourModel, tomlkit.parse(...)) # access your model with .model toml.model.message = "blowy red vixens fight for a quick jump" # dump the model back to a toml document toml_document = toml.model_dump_toml() # or to a toml string toml_string = toml.model_dump_toml().as_string()
def tomlantic.ModelBoundTOML.model_dump_toml()
method that dumps the model as a style-preserved tomlkit.TOMLDocument
-
signature:
def model_dump_toml(self) -> TOMLDocument:
-
returns
tomlkit.TOMLDocument
def tomlantic.ModelBoundTOML.get_field()
safely retrieve a field by it's location. not recommended for general use due to a lack of type information, but useful when accessing fields programatically
-
signature:
def get_field( self, location: Union[str, Tuple[str, ...]], default: Any = None, ) -> Any: ...
-
arguments:
- location:
Union[str, Tuple[str, ...]]
- default:
Any
=None
- location:
-
returns the field if it exists, otherwise
default
def tomlantic.ModelBoundTOML.set_field()
sets a field by it's location. not recommended for general use due to a lack of type safety, but useful when setting fields programatically
will handle pydantic.ValidationError
into more toml-friendly error messages.
set handle_errors
to False
to raise the original pydantic.ValidationError
-
signature:
def set_field( self, location: Union[str, Tuple[str, ...]], value: Any, handle_errors: bool = True, ) -> None: ...
-
arguments:
- location:
Union[str, Tuple[str, ...]]
- value:
Any
- handle_errors:
bool
= True
- location:
-
raises:
AttributeError
if the field does not existtomlantic.TOMLValidationError
if the document does not validate with the modelpydantic.ValidationError
if the document does not validate with the model andhandle_errors
isFalse
def tomlantic.ModelBoundTOML.difference_between_document()
returns a tomlantic.Difference object of the incoming and outgoing fields that were changed between the model and the comparison_document
-
signature:
def difference_between_document( self, incoming_document: TOMLDocument ) -> Difference: ...
-
arguments:
- incoming_document:
tomlkit.TOMLDocument
- incoming_document:
-
returns
tomlantic.Difference
def tomlantic.ModelBoundTOML.load_from_document()
override fields with those from a new document
by default, this method selectively overrides fields. so fields that have been changed in the model will NOT be overriden by the incoming document
pass False
to the selective
argument to override ALL fields in the model with
the fields of the incoming document
no changes are applied until the incoming document passes all model validations
-
signature:
def load_from_document( self, incoming_document: TOMLDocument, selective: bool = True, ) -> None:
-
arguments:
- incoming_document:
tomlkit.TOMLDocument
- selective:
bool
=False
- incoming_document:
class tomlantic.Difference
a named tuple for the differences between an outgoing tomlantic.ModelBoundTOML and a tomlkit.TOMLDocument
-
signature:
class Difference(NamedTuple): ...
-
attributes:
- incoming_changed_fields:
Tuple[str, ...]
- outgoing_changed_fields:
Tuple[str, ...]
- incoming_changed_fields:
def tomlantic.get_toml_field()
safely retrieve a field by it's location. not recommended for general use due to a lack of type information, but useful when accessing fields programatically
-
signature:
def get_toml_field( document: TOMLDocument, location: Union[str, Tuple[str, ...]], default: Any = None, ) -> Any:
-
arguments:
- document:
TOMLDocument
- location:
Union[str, Tuple[str, ...]]
- default:
Any
=None
- document:
-
returns the field if it exists, otherwise
default
def tomlantic.set_toml_field()
safely retrieve a toml documents field by it's location. not recommended for general use due to a lack of type information, but useful when accessing fields programatically
raises KeyError
if the field does not exist, or a LookupError
if attempting to
set a field in a non-table
if handling for errors, handle KeyError
before LookupError
as LookupError
is
the base class for KeyError
-
signature:
def set_toml_field( document: TOMLDocument, location: Union[str, Tuple[str, ...]], value: Any, ) -> None:
-
arguments:
- document:
TOMLDocument
- location:
Union[str, Tuple[str, ...]]
- value:
Any
- document:
class tomlantic.TomlanticException
base exception class for all tomlantic errors
-
signature:
class TomlanticException(Exception): ...
the hierarchy of exceptions that inherit this class are:
TomlanticException
├── TOMLValidationError
└── TOMLBaseSingleError
├── TOMLAttributeError
├── TOMLFrozenError
├── TOMLMissingError
├── TOMLValueError
└── TOMLValidationError
class tomlantic.TOMLBaseSingleError
base exception class for single errors, e.g. TOMLMissingError, TOMLValueError
inherits TomlanticException
base exception class for all tomlantic errors
-
signature:
class TOMLBaseSingleError(TomlanticException): ...
-
attributes:
-
loc:
Tuple[str, ...]
the location of the error in the toml document
example:('settings', 'name') = settings.name
-
msg:
str
the error 'message' (if any) -
pydantic_error:
pydantic_core.ErrorDetails
the original pydantic error, this is what you see in the list of errors when you handle apydantic.ValidationError
-
class tomlantic.TOMLAttributeError
error raised when an field does not exist, or is an extra field not in the model and the model has forbidden extra fields
inherits TOMLBaseSingleError, go there for attributes
-
signature:
class TOMLAttributeError(TOMLBaseSingleError): ...
class tomlantic.TOMLFrozenError
error raised when assigning a value to a frozen field or value
inherits TOMLBaseSingleError, go there for attributes
-
signature:
class TOMLFrozenError(TOMLBaseSingleError): ...
class tomlantic.TOMLMissingError
raised when a toml document does not contain all the required fields/tables of a model
inherits TOMLBaseSingleError, go there for attributes
-
signature:
class TOMLMissingError(TOMLBaseSingleError): ...
class tomlantic.TOMLValueError
raised when an item in a toml document is invalid for its respective model field
inherits TOMLBaseSingleError, go there for attributes
-
signature:
class TOMLValueError(TOMLBaseSingleError): ...
class tomlantic.TOMLValidationError
a toml-friendly version of pydantic.ValidationError, raised when instantiating tomlantic.ModelBoundTOML
inherits TomlanticException
-
signature:
class TOMLValidationError(TomlanticException): ...
-
attributes:
- errors:
Tuple[TOMLBaseSingleError, ...]
all validation errors raised when validating the toml document with the model
- errors:
def tomlantic.validate_to_specific_type()
validate a value's type to be a specific type
-
signature:
def validate_to_specific_type(v: Any, t: Type[T]) -> T: ...
-
usage:
validate_to_specific_type("hello", str) # returns "hello" validate_to_specific_type(42, str) # raises ValueError
def tomlantic.validate_to_multiple_types()
validate a value's type to be in a tuple of specific types
-
signature:
def validate_to_multiple_types(v: Any, t: Tuple[Type[Ts], ...]) -> Ts:
-
usage:
validate_to_multiple_types("hello", (str, int)) # returns "hello" validate_to_multiple_types(42, (str, int)) # returns 42 validate_to_multiple_types(42.0, (str, int)) # raises ValueError
def tomlantic.validate_homogeneous_collection()
validate values of a collection to a specific type
-
signature:
def validate_homogeneous_collection(v: Any, t: Type[T]) -> Collection[T]:
-
usage:
validate_homogeneous_collection([1, 2, 3], int) # returns [1, 2, 3] validate_homogeneous_collection([1, 2, "3"], int) # raises ValueError
def tomlantic.validate_heterogeneous_collection()
validate values of a collection to a specific type or a tuple of types
-
signature:
def validate_heterogeneous_collection(v: Collection[Any], t: Tuple[Type[Ts], ...]) -> Collection[Ts]: ...
-
usage:
validate_heterogeneous_collection([1, 2, "3"], (int, str)) # returns [1, 2, "3"] validate_heterogeneous_collection([1, 2, "3"], (int, float)) # raises ValueError
licence
tomlantic is free and unencumbered software released into the public domain. for more information, please refer to UNLICENCE, https://unlicense.org, or the python module docstring.
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file tomlantic-0.2.1.tar.gz
.
File metadata
- Download URL: tomlantic-0.2.1.tar.gz
- Upload date:
- Size: 12.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.7.1 CPython/3.11.7 Linux/6.5.0-1015-azure
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 65af53a38dcc5ca1b6a45ec9935998ff178aa1df333926d63b5e182baa45132e |
|
MD5 | 38fa399e0e63ef06cf94dcbb095a6a24 |
|
BLAKE2b-256 | b04e9f92ac75771be96c8a505046c8cb9ab6a34fbb50c147c71248f2837c58c8 |
File details
Details for the file tomlantic-0.2.1-py3-none-any.whl
.
File metadata
- Download URL: tomlantic-0.2.1-py3-none-any.whl
- Upload date:
- Size: 16.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.7.1 CPython/3.11.7 Linux/6.5.0-1015-azure
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | a229e1c7e808e256257cbc8287691a5d576421144fab2ed4c4568874299b6c90 |
|
MD5 | 20639870e166f47e8defee1f431bb4b6 |
|
BLAKE2b-256 | 5556fad671c46ced900681707f5713ce0dfc8bf947c9035c8715a59c332bf959 |