modelity.api
An all-in-one import helper.
- class modelity.api.Comparable(*args, **kwargs)
Bases:
ProtocolProtocol describing generic comparable type.
Added in version 0.33.0.
- __abstractmethods__ = frozenset({})
- __init__(*args, **kwargs)
- __parameters__ = ()
- __protocol_attrs__ = {'__ge__', '__gt__', '__le__', '__lt__'}
- classmethod __subclasshook__(other)
Abstract classes can override this to customize issubclass().
This is invoked early on by abc.ABCMeta.__subclasscheck__(). It should return True, False or NotImplemented. If it returns NotImplemented, the normal algorithm is used. Otherwise, it overrides the normal algorithm (and the outcome is cached).
- class modelity.api.Constraint
Bases:
ABCBase class for constraints.
Constraints are used to define parsing- and validation-time criteria that must be met for successful parsing/validation. Instances of this base class are used with types wrapped with
typing.Annotated.Added in version 0.36.0: Replaced
modelity.interface.IConstraintused earlier.- __abstractmethods__ = frozenset({'__call__', '__repr__'})
- abstractmethod __call__(errors: list[Error], loc: Loc, value: Any) bool
Run all checks against given value.
Returns True and does not modify error list if value satisfies the constraint.
Returns False and adds one or more errors to error list if value does not satisfy the constraint.
- Parameters:
errors – Mutable list of errors.
loc – The current location in the model.
value – The validated value.
- class modelity.api.DumpVisitor(out: dict)
Bases:
EmptyVisitorVisitor that dumps model to dict without type narrowing or any kind of value formatting.
It basically produces same structure as the model has, but based on Python collection types (dicts, lists, tuples and sets) instead of Modelity built-in ones.
Important
This visitor assumes that use of its API is done by
modelity.model.Model.accept()method that keeps the right order of method calling. It may not work correctly if used manually.Added in version 0.31.0.
- __abstractmethods__ = frozenset({})
- visit_any(loc: Loc, value: Any)
Visit any value.
This is called for values from untyped containers, fields marked with
typing.Anyor typed containers wheretyping.Anyis used as a type hint.This method, unlike
visit_scalar(), can also be called with elements that are containers, not scalars.Implementations are responsible for deciding whether to recurse into the value if it is a container.
- Parameters:
loc – The location of the visited value.
value – The visited value.
- visit_mapping_begin(loc: Loc, value: Mapping)
Start visiting a mapping object.
- Parameters:
loc – The location of the visited mapping object.
value – The visited mapping object.
- visit_mapping_end(loc: Loc, value: Mapping)
Finish visiting a mapping object.
- Parameters:
loc – The location of the visited mapping object.
value – The visited mapping object.
- visit_model_begin(loc: Loc, value: Model)
Start visiting model object.
- Parameters:
loc – The location of the visited model.
value – The visited model object.
- visit_model_end(loc: Loc, value: Model)
Finish visiting model object.
- Parameters:
loc – The location of the visited model.
value – The visited model object.
- visit_none(loc: Loc, value: None)
Visit a
Nonevalue.Called when
Noneobject is found.- Parameters:
loc – The location of the visited value.
value – The visited value.
- visit_scalar(loc: Loc, value: Any)
Visit scalar object.
Scalars are primitive objects that are neither containers, nor model objects. All Python primitive types (ints, floats, strings, booleans, enums, datetimes etc.) are scalars from the Modelity point of view.
- Parameters:
loc – The location of the visited value.
value – The visited value.
- visit_sequence_begin(loc: Loc, value: Sequence)
Start visiting a sequence object.
- Parameters:
loc – The location of the visited sequence object.
value – The visited sequence object.
- visit_sequence_end(loc: Loc, value: Sequence)
Finish visiting a sequence object.
- Parameters:
loc – The location of the visited sequence object.
value – The visited sequence object.
- visit_set_begin(loc: Loc, value: Set)
Start visiting a set object.
- Parameters:
loc – The location of the visited set object.
value – The visited set object.
- visit_set_end(loc: Loc, value: Set)
Finish visiting a set object.
- Parameters:
loc – The location of the visited set object.
value – The visited set object.
- visit_unset(loc: Loc, value: UnsetType)
Visit an
Unsetvalue.Called when
modelity.unset.Unsetobject is found.- Parameters:
loc – The location of the visited value.
value – The visited value.
- class modelity.api.EmptyVisitor
Bases:
ModelVisitorA visitor that simply implements
modelity.interface.IModelVisitorinterface with methods doing nothing.It is meant to be used as a base for other visitors, especially ones that do not need to overload all methods.
Changed in version 0.34.0: Restored the whole set of
modelity.interface.IModelVisitorinterface methods to get rid of linter warnings in subclasses.- __abstractmethods__ = frozenset({})
- visit_any(loc: Loc, value: Any)
Visit any value.
This is called for values from untyped containers, fields marked with
typing.Anyor typed containers wheretyping.Anyis used as a type hint.This method, unlike
visit_scalar(), can also be called with elements that are containers, not scalars.Implementations are responsible for deciding whether to recurse into the value if it is a container.
- Parameters:
loc – The location of the visited value.
value – The visited value.
- visit_mapping_begin(loc: Loc, value: Mapping) bool | None
Start visiting a mapping object.
- Parameters:
loc – The location of the visited mapping object.
value – The visited mapping object.
- visit_mapping_end(loc: Loc, value: Mapping)
Finish visiting a mapping object.
- Parameters:
loc – The location of the visited mapping object.
value – The visited mapping object.
- visit_model_begin(loc: Loc, value: Model) bool | None
Start visiting model object.
- Parameters:
loc – The location of the visited model.
value – The visited model object.
- visit_model_end(loc: Loc, value: Model)
Finish visiting model object.
- Parameters:
loc – The location of the visited model.
value – The visited model object.
- visit_model_field_begin(loc: Loc, value: Any, field: Field) bool | None
Start visiting model field.
This is called for every field in a model no matter if the field is set or not.
- Parameters:
loc – The location of the visited value.
value – The visited field value.
field – The visited field metadata.
- visit_model_field_end(loc: Loc, value: Any, field: Field)
Finish visiting model field.
- Parameters:
loc – The location of the visited value.
value – The visited field value.
field – The visited field metadata.
- visit_none(loc: Loc, value: None)
Visit a
Nonevalue.Called when
Noneobject is found.- Parameters:
loc – The location of the visited value.
value – The visited value.
- visit_scalar(loc: Loc, value: Any)
Visit scalar object.
Scalars are primitive objects that are neither containers, nor model objects. All Python primitive types (ints, floats, strings, booleans, enums, datetimes etc.) are scalars from the Modelity point of view.
- Parameters:
loc – The location of the visited value.
value – The visited value.
- visit_sequence_begin(loc: Loc, value: Sequence) bool | None
Start visiting a sequence object.
- Parameters:
loc – The location of the visited sequence object.
value – The visited sequence object.
- visit_sequence_end(loc: Loc, value: Sequence)
Finish visiting a sequence object.
- Parameters:
loc – The location of the visited sequence object.
value – The visited sequence object.
- visit_set_begin(loc: Loc, value: Set) bool | None
Start visiting a set object.
- Parameters:
loc – The location of the visited set object.
value – The visited set object.
- visit_set_end(loc: Loc, value: Set)
Finish visiting a set object.
- Parameters:
loc – The location of the visited set object.
value – The visited set object.
- visit_unset(loc: Loc, value: UnsetType)
Visit an
Unsetvalue.Called when
modelity.unset.Unsetobject is found.- Parameters:
loc – The location of the visited value.
value – The visited value.
- class modelity.api.Error(loc: ~modelity.loc.Loc, code: str, msg: str, value: ~typing.Any = Unset, data: dict = <factory>)
Bases:
objectObject containing details of the single error.
It is used for both parsing and validation stages of the model processing.
- __eq__(other)
Return self==value.
- __hash__ = None
- __init__(loc: ~modelity.loc.Loc, code: str, msg: str, value: ~typing.Any = Unset, data: dict = <factory>) None
- __match_args__ = ('loc', 'code', 'msg', 'value', 'data')
- __repr__()
Return repr(self).
- code: str
Error code.
This is a short description of the error. Check
ErrorCodefor the list of Modelity built-in error code constants and their meaning.
- data: dict
Additional error data.
This property, along with
code, can be used to render custom error messages. It is recommended to always use same structure for same error code.For built-in errors, this property will get filled with any extra arguments passed to factory functions defined in
ErrorFactoryclass.
- msg: str
Formatted error message.
Contains human-readable error description based on
codeanddata.
- value: Any = Unset
The incorrect value, if present, or
modelity.unset.Unsetotherwise.
- class modelity.api.ErrorCode
Bases:
objectClass defining all built-in error codes.
- CONVERSION_ERROR = 'modelity.CONVERSION_ERROR'
Used when it was not possible to automatically convert allowed input value type into expected type.
For example, a
setcannot be created fromlistif the list contains unhashable elements.Use by
ErrorFactory.conversion_error()to create errors with this code.
- DECODE_ERROR = 'modelity.DECODE_ERROR'
Used when bytes could not be decoded into string using any of the provided encoding.
Use
ErrorFactory.decode_error()to create errors with this code.
- EXCEPTION = 'modelity.EXCEPTION'
Used to wrap user exception caught during parsing or validation stage.
This error code is used to wrap
TypeError(and its subclasses) raised during parsing stage orValueError(and its subclasses) raised during validation stage by user-defined hook.Use
ErrorFactory.exception()to create errors with this code.
- INVALID_DATETIME_FORMAT = 'modelity.INVALID_DATETIME_FORMAT'
Used when datetime field gets text input that has invalid datetime format.
Used
ErrorFactory.invalid_datetime_format()to create errors with this code.
- INVALID_DATE_FORMAT = 'modelity.INVALID_DATE_FORMAT'
Same as for
INVALID_DATETIME_FORMAT, but for dates.Use
ErrorFactory.invalid_date_format()to create errors with this code.
- INVALID_ENUM_VALUE = 'modelity.INVALID_ENUM_VALUE'
Similar to
INVALID_VALUE, but used with enumerated values andenum.Enumtype.Use
ErrorFactory.invalid_enum_value()to create errors with this code.
- INVALID_LENGTH = 'modelity.INVALID_LENGTH'
Used to signal value length range errors.
Use
invalid_length()to create errors with this code.
- INVALID_STRING_FORMAT = 'modelity.INVALID_STRING_FORMAT'
Used to inform that the input value string has incorrect format.
For example, input expects data matching some regular expression pattern, but the input value does not match the pattern.
Use
invalid_string_format()to create errors with this code.
- INVALID_TUPLE_LENGTH = 'modelity.INVALID_TUPLE_LENGTH'
Used for fixed-length tuple types where input value is a tuple that does not have the exact number of elements.
Use
ErrorFactory.invalid_tuple()to create errors with this code.
- INVALID_TYPE = 'modelity.INVALID_TYPE'
Used when type of the input value does not match the expected type and it cannot be automatically converted.
Use
ErrorFactory.invalid_type()to create errors with this code.
- INVALID_VALUE = 'modelity.INVALID_VALUE'
Used when input value was not one of the expected values.
For example, field accepts literals
Literal[1, 2, "3"], but the input was"2"which is not one of the allowed literals.Use
ErrorFactory.invalid_value()to create errors with this code.
- NONE_NOT_ALLOWED = 'modelity.NONE_NOT_ALLOWED'
Reported during parsing of
modelity.typing.StrictOptionalwrapped fields ifNoneis used as input value.Strict optional fields require the field to either be set to instance of type T, or not set at all (unlike
typing.Optional, which allowsNone). Modelity needs to provide such clean separation to make sure that model satisfies all type constraints after validation.Important
This error is reserved for
modelity.typing.StrictOptionalwrapper and should not be used elsewhere.Use
ErrorFactory.none_not_allowed()to create errors with this code.Added in version 0.29.0.
- OUT_OF_RANGE = 'modelity.OUT_OF_RANGE'
Used to signal value range errors.
Use
out_of_range()to create error with this code.
- PARSE_ERROR = 'modelity.PARSE_ERROR'
Used when Modelity could not parse input value to an expected type.
For example, string “abc” cannot be parsed as integer number.
Use
ErrorFactory.parse_error()to create errors with this code.
- REQUIRED_MISSING = 'modelity.REQUIRED_MISSING'
Signals that the field is required but is not present in the model.
Use
ErrorFactory.required_missing()to create errors with this code.
- UNSET_NOT_ALLOWED = 'modelity.UNSET_NOT_ALLOWED'
Reported during validation for
typing.Optionalfields that remain unset during validation.To allow usage of
Unsetplease usemodelity.typing.StrictOptionalormodelity.typing.LooseOptionaltype wrappers. Check their docs for more details.This error can be avoided by setting default values for optional fields.
Use
ErrorFactory.unset_not_allowed()to create errors with this code.Added in version 0.29.0.
- USER_ERROR = 'modelity.USER_ERROR'
Default error code for the
modelity.exc.UserErrorexception.Added in version 0.30.0.
- class modelity.api.ErrorFactory
Bases:
objectClass grouping factory methods for creating built-in errors.
- static conversion_error(loc: Loc, value: Any, expected_type: type, /, reason: str | None = None, *, msg: str | None = None, **extra_data) Error
Create conversion error.
This signals that value could not be converted into instance of expected_type due to the reason explained in error message.
Important
This error is reserved only for failing conversion where input value is non-string. If input value is string or bytes then it is better to use
parse_error()factory instead.- Parameters:
loc – Error location in the model.
value – Input value that could not be converted.
expected_type – Expected value type.
reason – The optional reason text.
msg –
The optional message to override built-in one.
Added in version 0.33.0.
**extra_data –
The optional extra error data.
This will be placed inside
modelity.error.Error.datadict of a created error object.Added in version 0.33.0.
- static decode_error(loc: Loc, value: bytes, expected_encodings: list[str], /) Error
Create decode error.
- Parameters:
loc – Error location in the model.
value – Input bytes that could not be decoded into string.
expected_encodings – List of expected encodings.
- static exception(loc: Loc, value: Any, exc: Exception, /) Error
Create error from a user exception.
- Parameters:
loc – Error location in the model.
value – The incorrect value.
exc – The exception object.
- static invalid_date_format(loc: Loc, value: str, expected_formats: list[str], /)
Create invalid date format error.
- Parameters:
loc – Error location in the model.
value – Incorrect input string.
expected_formats – List with expected date formats.
- static invalid_datetime_format(loc: Loc, value: str, expected_formats: list[str], /) Error
Create invalid datetime format error.
- Parameters:
loc – Error location in the model.
value – Incorrect input string.
expected_formats – List with expected datetime formats.
- static invalid_enum_value(loc: Loc, value: Any, expected_enum_type: type[Enum], /) Error
Create invalid enum value error.
- Parameters:
loc – Error location in the model.
value – Input value from outside of expected enumerated values set.
expected_enum_type – Expected enum type.
- static invalid_length(loc: Loc, value: Sized, /, min_length: int | None = None, max_length: int | None = None, *, msg: str | None = None) Error
Create invalid length error.
This error is reported for containers or other sized types when length constraints are not satisfied.
Important
The built-in message composer requires at least one length range parameter to be provided.
- Parameters:
loc – Error location in the model.
value – Incorrect input value.
min_length – Minimum length.
max_length – Maximum length.
msg –
The optional message to override built-in one.
When custom message is provided then length range parameters, although still recommended, become optional.
Added in version 0.33.0.
- static invalid_string_format(loc: Loc, value: str, expected_pattern: str, /, *, msg: str | None = None) Error
Create invalid string format error.
Changed in version 0.33.0: Now loc, value and expected_pattern are positional-only arguments, while msg is keyword-only argument. This was changed for compliance with other methods.
- Parameters:
loc – Error location in the model.
value – Incorrect input string.
expected_pattern – Expected string pattern (f.e. regex pattern).
msg – Optional user-defined message to use instead of built-in one.
- static invalid_tuple_length(loc: Loc, value: tuple, expected_tuple: tuple[type, ...], /) Error
Create invalid tuple length error.
- Parameters:
loc – Error location in the model.
value – Incorrect input tuple.
expected_tuple – Expected tuple shape.
- static invalid_type(loc: Loc, value: Any, expected_types: list[type], /, allowed_types: list[type] | None = None, forbidden_types: list[type] | None = None, *, msg: str | None = None, **extra_data) Error
Create invalid type error.
- Parameters:
loc – Error location in the model.
value – Incorrect input value.
expected_types – List with expected type or types.
allowed_types –
Optional list with allowed types.
This is information that if one of these types is used as type of the input value then it will be accepted and converted to one of expected types.
For example, a set can be constructed from set, list or tuple of items.
forbidden_types –
Optional list of forbidden types.
This is used to specify types that are arbitrary forbidden and will fail value processing immediately when encountered.
msg –
The optional message to override built-in one.
Added in version 0.33.0.
**extra_data –
The optional extra error data.
This will be placed inside
modelity.error.Error.datadict of a created error object.Added in version 0.33.0.
- static invalid_value(loc: Loc, value: Any, expected_values: list, /, *, msg: str | None = None, **extra_data) Error
Create invalid value error.
- Parameters:
loc – Error location in the model.
value – Input value from outside of expected values set.
expected_values – List with expected values.
msg –
The optional message to override built-in one.
Added in version 0.32.0.
**extra_data –
The optional extra error data.
This will be placed inside
modelity.error.Error.datadict of a created error object.Added in version 0.33.0.
- static none_not_allowed(loc: Loc, expected_type: Any, /) Error
Create
NONE_NOT_ALLOWEDerror.See
ErrorCode.NONE_NOT_ALLOWEDfor more details.Added in version 0.29.0.
- Parameters:
loc – Error location in the model.
expected_types – The expected type.
- static out_of_range(loc: Loc, value: T, /, min_inclusive: T | None = None, min_exclusive: T | None = None, max_inclusive: T | None = None, max_exclusive: T | None = None, *, msg: str | None = None) Error
Create out of range error.
This is a generic error factory for all kind of value range errors.
Important
The built-in message composer requires at least one range parameter to be provided.
- Parameters:
loc – Error location in the model.
value – Incorrect input value.
min_inclusive – Minimum value (inclusive).
min_exclusive – Minimum value (exclusive).
max_inclusive – Maximum value (inclusive).
max_exclusive – Maximum value (exclusive).
msg –
The optional message to override built-in one.
When custom message is provided then range parameters, although still recommended, become optional.
Added in version 0.33.0.
- static parse_error(loc: Loc, value: Any, expected_type: type, /, *, msg: str | None = None, **extra_data) Error
Create parse error.
- Parameters:
loc – Error location in the model.
value – Input value that could not be parsed.
expected_type – Expected value type.
msg – The optional message to override built-in one.
**extra_data –
The optional extra error data.
This will be placed inside
modelity.error.Error.datadict of a created error object.
- static required_missing(loc: Loc, /)
Create required missing error.
- Parameters:
loc – The location of a missing field.
- static unset_not_allowed(loc: Loc, expected_type: Any, /) Error
Create
UNSET_NOT_ALLOWEDerror.See
ErrorCode.UNSET_NOT_ALLOWEDfor more details.Added in version 0.29.0.
- Parameters:
loc – Error location in the model.
expected_types – The expected type.
- class modelity.api.ErrorWriter(out: TextIO, indent_string: str = ' ', indent_level: int = 0, show_code: bool = False, show_value: bool = False, show_value_type: bool = False, show_data: bool = False)
Bases:
objectClass that formats errors as string and appends to the end of provided text buffer.
- Parameters:
out – The output text buffer.
indent_string – Indentation string.
indent_level – Indentation level.
show_code – Display error code.
show_value – Display input value.
show_value_type – Display input value type.
show_data – Display additional error data.
Added in version 0.28.0.
- class modelity.api.Field(name: str, typ: Any, type_handler: TypeHandler, *, field_info: FieldInfo | None = None, construction_required: bool = False, validation_required: bool = False, unsettable: bool = False)
Bases:
objectDataclass containing data parsed from field’s type annotation.
- __eq__(other)
Return self==value.
- __hash__ = None
- __init__(name: str, typ: Any, type_handler: TypeHandler, *, field_info: FieldInfo | None = None, construction_required: bool = False, validation_required: bool = False, unsettable: bool = False) None
- __match_args__ = ('name', 'typ', 'type_handler')
- __repr__()
Return repr(self).
- construction_required: bool = False
Flag telling if this field is required during model construction.
Fields that are construction-required will cause model construction failure (with
modelity.error.ErrorCode.REQUIRED_MISSINGerror code) if those are missing in model’s constructor and have no default values set.Note
Fields that are construction-required are also implicitly validation-required; if construction-required fields are removed from a model object after it was successfully created, the validation step will still report same error.
Added in version 0.37.0.
- field_info: FieldInfo | None = None
The additional metadata assigned for this field.
Everything declared using
field_info()goes into here.
- property required: bool
Flag telling if this field is required.
A field is required if at least one of
construction_requiredandvalidation_requiredattributes is set toTrue.
- type_handler: TypeHandler
The type handler set for this field.
It is derived from field’s type annotation set as
typ.
- unsettable: bool = False
Flag telling if
modelity.unset.Unsetis a valid value for this field.This is used both during construction and validation stages and will eventually cause
modelity.error.ErrorCode.UNSET_NOT_ALLOWEDerror if field is left unset. For example, fields marked withtyping.Optionalcannot be unset; you have to initialize with either value, or aNone.Changed in version 0.37.0: Now this is also checked during model construction in addition to validation.
- validation_required: bool = False
Flag telling if this field is required during model validation.
Such fields can be skipped during model construction (the model construction will not fail), but are required to be set before validation takes place. This is used by
modelity.typing.Deferredtype wrapper.Note
This flag is automatically set to
Truefor construction-required fields.Added in version 0.37.0.
- class modelity.api.FieldInfo(default: ~typing.Any = Unset, default_factory: ~typing.Callable[[], ~typing.Any] | ~modelity.unset.UnsetType = Unset, title: str | None = None, description: str | None = None, examples: list | None = None, type_opts: dict = <factory>)
Bases:
objectClass for setting field metadata.
- __eq__(other)
Return self==value.
- __hash__ = None
- __init__(default: ~typing.Any = Unset, default_factory: ~typing.Callable[[], ~typing.Any] | ~modelity.unset.UnsetType = Unset, title: str | None = None, description: str | None = None, examples: list | None = None, type_opts: dict = <factory>) None
- __match_args__ = ('default', 'default_factory', 'title', 'description', 'examples', 'type_opts')
- __repr__()
Return repr(self).
- default_factory: Callable[[], Any] | UnsetType = Unset
Default value factory function.
Allows to create default values that are evaluated each time the model is created, and therefore producing different default values for different model instances.
- description: str | None = None
The description of this field.
This is a long description, to be used when
titleis not sufficient.Added in version 0.19.0.
- examples: list | None = None
The example values for this field.
This is not used directly in any way by the library, but 3rd party tools may use it f.e. to create random valid objects for tests.
Added in version 0.19.0.
- class modelity.api.FixupVisitor(root: Model, ctx: Any = None)
Bases:
EmptyVisitorVisitor performing model fixups.
It is implicitly used by
modelity.helpers.fixup()helper.Added in version 0.36.0.
- __abstractmethods__ = frozenset({})
- class modelity.api.Ge(min_inclusive: int | float)
Bases:
ConstraintGreater-or-equal constraint.
Used to specify minimum inclusive value for a numeric field.
- __abstractmethods__ = frozenset({})
- __call__(errors: list[Error], loc: Loc, value: Any) bool
Run all checks against given value.
Returns True and does not modify error list if value satisfies the constraint.
Returns False and adds one or more errors to error list if value does not satisfy the constraint.
- Parameters:
errors – Mutable list of errors.
loc – The current location in the model.
value – The validated value.
- __delattr__(name)
Implement delattr(self, name).
- __eq__(other)
Return self==value.
- __hash__()
Return hash(self).
- __match_args__ = ('min_inclusive',)
- __repr__()
Return text representation of the constraint.
This is used when rendering constraints in error messages.
- __setattr__(name, value)
Implement setattr(self, name, value).
- class modelity.api.Gt(min_exclusive: int | float)
Bases:
ConstraintGreater-than constraint.
Used to specify minimum exclusive value for a numeric field.
- __abstractmethods__ = frozenset({})
- __call__(errors: list[Error], loc: Loc, value: Any) bool
Run all checks against given value.
Returns True and does not modify error list if value satisfies the constraint.
Returns False and adds one or more errors to error list if value does not satisfy the constraint.
- Parameters:
errors – Mutable list of errors.
loc – The current location in the model.
value – The validated value.
- __delattr__(name)
Implement delattr(self, name).
- __eq__(other)
Return self==value.
- __hash__()
Return hash(self).
- __match_args__ = ('min_exclusive',)
- __repr__()
Return text representation of the constraint.
This is used when rendering constraints in error messages.
- __setattr__(name, value)
Implement setattr(self, name, value).
- class modelity.api.JsonDumpVisitorProxy(target: ModelVisitor, /, exclude_unset: bool = False, exclude_none: bool = False, bytes_format: str | Literal['base64'] = 'utf-8', datetime_format: str = 'YYYY-MM-DDThh:mm:ss.ffffffZZZZ', date_format: str = 'YYYY-MM-DD', default_encoder: Callable[[Loc, Any], Any] | None = None)
Bases:
objectProxy visitor that narrows down value types to closest JSON-compatible type: dict, list, str, int, float, bool or None.
Added in version 0.31.0.
- Parameters:
target – Target dump visitor, e.g.
DumpVisitorobject.exclude_unset – Exclude model fields equal to
modelity.unset.Unsetobject.exclude_none –
Exclude model fields equal to
None.This does not affect
Nonevalues used in nested containers, only model fields, typed with e.g.Optional[T], are affected.bytes_format –
The format used to encode
bytesobjects.Supports either encoding name (f.e.
utf-8orascii) or one of predefined encodings (f.e.base64).datetime_format –
The format to use to encode
datetime.datetimeobjects.Following placeholders are supported:
YYYY for 4-digit years
MM for 2-digit months in range [01..12]
DD for 2-digit days in range [01..31]
hh for 2-digit hours in range [00..23]
mm for 2-digit minutes in range [00..59]
ss for 2-digit seconds in range [00..59]
ffffff for 6-digit microseconds in range [000000..999999]
ZZZZ for timezone
date_format –
The format to use to encode
datetime.dateobjects.Following placeholders are supported:
YYYY for 4-digit years
MM for 2-digit months in range [01..12]
DD for 2-digit days in range [01..31]
default_encoder –
The default encoder to use if there is no dedicated type encoder found.
If not given, then
stris used as a default.Changed in version 0.34.0: Parameter was renamed from default_converter.
- __getattr__(name)
- __init__(target: ModelVisitor, /, exclude_unset: bool = False, exclude_none: bool = False, bytes_format: str | Literal['base64'] = 'utf-8', datetime_format: str = 'YYYY-MM-DDThh:mm:ss.ffffffZZZZ', date_format: str = 'YYYY-MM-DD', default_encoder: Callable[[Loc, Any], Any] | None = None)
- register_type_encoder(typ: type[T], func: Callable[[Loc, T], Any])
Register or override type encoder.
Important
Only model field values, nested model instances or container elements encoding can be customized using this method. Containers like dicts, sets or lists cannot be customized.
Added in version 0.34.0.
- Parameters:
typ – The type to set converter function for.
func –
The conversion function.
Takes
(loc, value)as input and returns encoded value.
- class modelity.api.Le(max_inclusive: Any)
Bases:
ConstraintLess-or-equal constraint.
Used to set maximum inclusive value for a numeric field.
- __abstractmethods__ = frozenset({})
- __call__(errors: list[Error], loc: Loc, value: Any) bool
Run all checks against given value.
Returns True and does not modify error list if value satisfies the constraint.
Returns False and adds one or more errors to error list if value does not satisfy the constraint.
- Parameters:
errors – Mutable list of errors.
loc – The current location in the model.
value – The validated value.
- __delattr__(name)
Implement delattr(self, name).
- __eq__(other)
Return self==value.
- __hash__()
Return hash(self).
- __match_args__ = ('max_inclusive',)
- __repr__()
Return text representation of the constraint.
This is used when rendering constraints in error messages.
- __setattr__(name, value)
Implement setattr(self, name, value).
- class modelity.api.LenRange(min_length: int, max_length: int)
Bases:
ConstraintLength range constraint.
Combines both minimum and maximum length constraints.
Added in version 0.28.0.
- __abstractmethods__ = frozenset({})
- __call__(errors: list[Error], loc: Loc, value: Any) bool
Run all checks against given value.
Returns True and does not modify error list if value satisfies the constraint.
Returns False and adds one or more errors to error list if value does not satisfy the constraint.
- Parameters:
errors – Mutable list of errors.
loc – The current location in the model.
value – The validated value.
- __delattr__(name)
Implement delattr(self, name).
- __eq__(other)
Return self==value.
- __hash__()
Return hash(self).
- __match_args__ = ('min_length', 'max_length')
- __repr__()
Return text representation of the constraint.
This is used when rendering constraints in error messages.
- __setattr__(name, value)
Implement setattr(self, name, value).
- class modelity.api.Loc(*path: Any)
Bases:
SequenceA tuple-like type that stores location of the value (or error) in the model tree.
Examples:
>>> from modelity.loc import Loc >>> root = Loc("root") >>> nested = root + Loc("nested") >>> nested Loc('root', 'nested') >>> nested += Loc(0) >>> nested Loc('root', 'nested', 0) >>> str(nested) 'root.nested.0' >>> nested[0] 'root' >>> nested[-1] 0
- Parameters:
*args – The positional arguments composing location’s path.
- __abstractmethods__ = frozenset({})
- __add__(other)
- __getitem__(index)
- __orig_bases__ = (typing.Sequence,)
- __parameters__ = ()
- __slots__ = ('_data',)
- classmethod irrelevant() Loc
Return a special location value indicating that the exact location is irrelevant.
This is equivalent to
Loc("_")and is typically used in containers like sets or unordered structures, where the concept of position or path does not apply.For example, when comparing or storing elements where their precise placement is not semantically meaningful, this sentinel location can be used to fulfill API requirements without implying an actual location.
Added in version 0.17.0.
- is_parent_of(other: Loc) bool
Check if this location is parent (prefix) of given other location.
- Parameters:
other – The other location object.
- suffix_match(pattern: Loc) bool
Check if suffix of this location matches given pattern.
Examples:
>>> Loc("foo").suffix_match(Loc("foo")) True >>> Loc("foo").suffix_match(Loc("foo", "bar")) False >>> Loc("foo", "bar").suffix_match(Loc("foo", "bar")) True >>> Loc("foo", "bar").suffix_match(Loc("foo", "*")) True >>> Loc("foo", 3, "bar").suffix_match(Loc("foo", "*", "bar")) True >>> Loc("foo", 3, "bar").suffix_match(Loc("foo", "*", "baz")) False
Added in version 0.27.0.
- class modelity.api.Lt(max_exclusive: Any)
Bases:
ConstraintLess-than constraint.
Used to set maximum exclusive value for a numeric field.
- __abstractmethods__ = frozenset({})
- __call__(errors: list[Error], loc: Loc, value: Any) bool
Run all checks against given value.
Returns True and does not modify error list if value satisfies the constraint.
Returns False and adds one or more errors to error list if value does not satisfy the constraint.
- Parameters:
errors – Mutable list of errors.
loc – The current location in the model.
value – The validated value.
- __delattr__(name)
Implement delattr(self, name).
- __eq__(other)
Return self==value.
- __hash__()
Return hash(self).
- __match_args__ = ('max_exclusive',)
- __repr__()
Return text representation of the constraint.
This is used when rendering constraints in error messages.
- __setattr__(name, value)
Implement setattr(self, name, value).
- class modelity.api.MaxLen(max_length: int)
Bases:
ConstraintMaximum length constraint.
Can be used with sized types, like containers,
byteorstr.- __abstractmethods__ = frozenset({})
- __call__(errors: list[Error], loc: Loc, value: Any) bool
Run all checks against given value.
Returns True and does not modify error list if value satisfies the constraint.
Returns False and adds one or more errors to error list if value does not satisfy the constraint.
- Parameters:
errors – Mutable list of errors.
loc – The current location in the model.
value – The validated value.
- __delattr__(name)
Implement delattr(self, name).
- __eq__(other)
Return self==value.
- __hash__()
Return hash(self).
- __match_args__ = ('max_length',)
- __repr__()
Return text representation of the constraint.
This is used when rendering constraints in error messages.
- __setattr__(name, value)
Implement setattr(self, name, value).
- class modelity.api.MinLen(min_length: int)
Bases:
ConstraintMinimum length constraint.
Can be used with sized types, like containers,
byteorstr.- __abstractmethods__ = frozenset({})
- __call__(errors: list[Error], loc: Loc, value: Any) bool
Run all checks against given value.
Returns True and does not modify error list if value satisfies the constraint.
Returns False and adds one or more errors to error list if value does not satisfy the constraint.
- Parameters:
errors – Mutable list of errors.
loc – The current location in the model.
value – The validated value.
- __delattr__(name)
Implement delattr(self, name).
- __eq__(other)
Return self==value.
- __hash__()
Return hash(self).
- __match_args__ = ('min_length',)
- __repr__()
Return text representation of the constraint.
This is used when rendering constraints in error messages.
- __setattr__(name, value)
Implement setattr(self, name, value).
- class modelity.api.Model(**kwargs)
Bases:
objectBase class for data models.
All models created using Modelity must inherit from this base class and provide zero or more fields using type annotations in similar way as when using Python dataclasses.
Here’s a simple example:
from typing import Optional from modelity.api import Model, Deferred, LooseOptional, StrictOptional, Unset, validate class Dummy(Model): foo: int # <- required; must be given in constructor xyz: float = 3.14 # <- required; optional in constructor, as it has default value set bar: Deferred[bool] = Unset # <- deferred; must be set before validation baz: Optional[str] = None # <- optional; can be `None` but cannot be `Unset` spam: LooseOptional[str] = Unset # <- optional; can be set to `None` or `Unset` more_spam: StrictOptional[str] = Unset # <- optional; can be `Unset` but cannot be `None`
>>> dummy = Dummy(foo='123') # Construct model instance; Modelity will try to parse input to expected type >>> dummy Dummy(foo=123, xyz=3.14, bar=Unset, baz=None, spam=Unset, more_spam=Unset) >>> validate(dummy) # Validation will fail; deferred field `bar` is missing Traceback (most recent call last): ... modelity.exc.ValidationError: Found 1 validation error for model 'Dummy': bar: This field is required [code=modelity.REQUIRED_MISSING] >>> dummy.bar = True # Now let's set a value to `bar` field (models are mutable) >>> validate(dummy) # And now the model is valid >>> dummy Dummy(foo=123, xyz=3.14, bar=True, baz=None, spam=Unset, more_spam=Unset)
- __contains__(name)
- __delattr__(name)
Implement delattr(self, name).
- __eq__(value)
Return self==value.
- __hash__ = None
- __iter__()
- __model_fields__: Mapping[str, Field] = {}
A per-instance view of the
ModelMeta.__model_fields__attribute.
- __repr__()
Return repr(self).
- __slots__ = ()
- accept(visitor: ModelVisitor, loc: Loc)
Accept visitor on this model.
- Parameters:
visitor – The visitor to accept.
loc – The location of this model or empty location if this is the root model.
- exception modelity.api.ModelError(typ: type, errors: tuple[Error, ...])
Bases:
ModelityErrorCommon base class for errors raised during either data parsing or model validation stages.
It can be used by library clients to catch both parsing and validation errors in one place, which can help avoid unexpected leaking of exceptions the user was not aware of.
- Parameters:
typ – The type for which this error has happened.
errors – Tuple of errors to initialize exception with.
- typ: type
The type for which this error has happened.
Changed in version 0.28.0: Moved from
ParsingErrorclass and now made available for all subclasses for ease of use.
- class modelity.api.ModelFieldPruningVisitorProxy(target: ModelVisitor, /, exclude_if: Callable[[Loc, Any], bool])
Bases:
objectVisitor proxy that skips model fields if provided exclude function returns
True.Important
This proxy only skips model fields and does not affect container elements in any way.
- Parameters:
target – The wrapped model visitor.
exclude_if –
The exclusion function.
Takes
(loc, value)as arguments and must returnTrueto skip the matched model field orFalseto leave it.
- __getattr__(name)
- class modelity.api.ModelLoader(model_type: type[MT], ctx: Any = None)
Bases:
Generic[MT]Similar to
load()function, but allows to create loader for given model type and then create instances of that model using keyword args.Example use:
from modelity.base import Model from modelity.helpers import ModelLoader class Dummy(Model): a: int b: str DummyLoader = ModelLoader(Dummy)
>>> one = DummyLoader(a=1, b="spam") >>> one Dummy(a=1, b='spam')
Added in version 0.17.0.
- Parameters:
model_type – The model type.
ctx – The user-defined validation context.
- __call__(**kwargs) MT
Create and validate instance of the given model type.
On success, valid model instance is returned.
On failure,
modelity.exc.ModelErrorexception is raised.- Parameters:
**kwargs – Named arguments for model’s constructor.
- __orig_bases__ = (typing.Generic[~MT],)
- __parameters__ = (~MT,)
- class modelity.api.ModelMeta(name: str, bases: tuple, attrs: dict)
Bases:
typeMetaclass for models.
The role of this metaclass is to provide field initialization, type descriptor lookup and inheritance handling.
It is used as a metaclass by
Modelbase class and all methods and properties it provides can be accessed via__class__attribute of theModelclass instances.
- class modelity.api.ModelVisitor
Bases:
ABCBase class for model data visitors.
This mechanism allows to traverse through Modelity models in a deterministic way and, depending on the implementation, serialize or validate it.
Added in version 0.36.0: Replaced
modelity.interface.IModelVisitorused earlier.- __abstractmethods__ = frozenset({'visit_any', 'visit_mapping_begin', 'visit_mapping_end', 'visit_model_begin', 'visit_model_end', 'visit_model_field_begin', 'visit_model_field_end', 'visit_none', 'visit_scalar', 'visit_sequence_begin', 'visit_sequence_end', 'visit_set_begin', 'visit_set_end', 'visit_unset'})
- abstractmethod visit_any(loc: Loc, value: Any)
Visit any value.
This is called for values from untyped containers, fields marked with
typing.Anyor typed containers wheretyping.Anyis used as a type hint.This method, unlike
visit_scalar(), can also be called with elements that are containers, not scalars.Implementations are responsible for deciding whether to recurse into the value if it is a container.
- Parameters:
loc – The location of the visited value.
value – The visited value.
- abstractmethod visit_mapping_begin(loc: Loc, value: Mapping) bool | None
Start visiting a mapping object.
- Parameters:
loc – The location of the visited mapping object.
value – The visited mapping object.
- abstractmethod visit_mapping_end(loc: Loc, value: Mapping)
Finish visiting a mapping object.
- Parameters:
loc – The location of the visited mapping object.
value – The visited mapping object.
- abstractmethod visit_model_begin(loc: Loc, value: Model) bool | None
Start visiting model object.
- Parameters:
loc – The location of the visited model.
value – The visited model object.
- abstractmethod visit_model_end(loc: Loc, value: Model)
Finish visiting model object.
- Parameters:
loc – The location of the visited model.
value – The visited model object.
- abstractmethod visit_model_field_begin(loc: Loc, value: Any, field: Field) bool | None
Start visiting model field.
This is called for every field in a model no matter if the field is set or not.
- Parameters:
loc – The location of the visited value.
value – The visited field value.
field – The visited field metadata.
- abstractmethod visit_model_field_end(loc: Loc, value: Any, field: Field)
Finish visiting model field.
- Parameters:
loc – The location of the visited value.
value – The visited field value.
field – The visited field metadata.
- abstractmethod visit_none(loc: Loc, value: None)
Visit a
Nonevalue.Called when
Noneobject is found.- Parameters:
loc – The location of the visited value.
value – The visited value.
- abstractmethod visit_scalar(loc: Loc, value: Any)
Visit scalar object.
Scalars are primitive objects that are neither containers, nor model objects. All Python primitive types (ints, floats, strings, booleans, enums, datetimes etc.) are scalars from the Modelity point of view.
- Parameters:
loc – The location of the visited value.
value – The visited value.
- abstractmethod visit_sequence_begin(loc: Loc, value: Sequence) bool | None
Start visiting a sequence object.
- Parameters:
loc – The location of the visited sequence object.
value – The visited sequence object.
- abstractmethod visit_sequence_end(loc: Loc, value: Sequence)
Finish visiting a sequence object.
- Parameters:
loc – The location of the visited sequence object.
value – The visited sequence object.
- abstractmethod visit_set_begin(loc: Loc, value: Set) bool | None
Start visiting a set object.
- Parameters:
loc – The location of the visited set object.
value – The visited set object.
- abstractmethod visit_set_end(loc: Loc, value: Set)
Finish visiting a set object.
- Parameters:
loc – The location of the visited set object.
value – The visited set object.
- abstractmethod visit_unset(loc: Loc, value: UnsetType)
Visit an
Unsetvalue.Called when
modelity.unset.Unsetobject is found.- Parameters:
loc – The location of the visited value.
value – The visited value.
- exception modelity.api.ModelityError
Bases:
ExceptionBase class for every Modelity-specific exception.
- exception modelity.api.ParsingError(typ: type, errors: tuple[Error, ...])
Bases:
ModelErrorException raised at parsing stage when input data could not be parsed into model instance.
When this exception is raised, no model is created.
- class modelity.api.Range(min: Gt | Ge, max: Lt | Le)
Bases:
ConstraintRange constraint.
Used to set allowed value range for a numeric field using one of
LtorGtfor minimum value, and one ofLtorLefor maximum value.Added in version 0.28.0.
- __abstractmethods__ = frozenset({})
- __call__(errors: list[Error], loc: Loc, value: Any) bool
Run all checks against given value.
Returns True and does not modify error list if value satisfies the constraint.
Returns False and adds one or more errors to error list if value does not satisfy the constraint.
- Parameters:
errors – Mutable list of errors.
loc – The current location in the model.
value – The validated value.
- __delattr__(name)
Implement delattr(self, name).
- __eq__(other)
Return self==value.
- __hash__()
Return hash(self).
- __match_args__ = ('min', 'max')
- __repr__() str
Return text representation of the constraint.
This is used when rendering constraints in error messages.
- __setattr__(name, value)
Implement setattr(self, name, value).
- class modelity.api.Regex(pattern: str)
Bases:
ConstraintRegular expression constraint.
Allows values matching given regular expression and reject all other. Can only operate on strings.
- __abstractmethods__ = frozenset({})
- __call__(errors: list[Error], loc: Loc, value: str) bool
Run all checks against given value.
Returns True and does not modify error list if value satisfies the constraint.
Returns False and adds one or more errors to error list if value does not satisfy the constraint.
- Parameters:
errors – Mutable list of errors.
loc – The current location in the model.
value – The validated value.
- __delattr__(name)
Implement delattr(self, name).
- __eq__(other)
Return self==value.
- __hash__()
Return hash(self).
- __match_args__ = ('pattern',)
- __repr__()
Return text representation of the constraint.
This is used when rendering constraints in error messages.
- __setattr__(name, value)
Implement setattr(self, name, value).
- class modelity.api.TypeHandler
Bases:
ABCBase class for type handlers.
Type handlers are used by Modelity to provide type-specific runtime logic to models. Type handlers are constructed from type object or type annotations when model type is created and then used by model instances to handle user data.
Added in version 0.36.0: Replaced
modelity.interface.ITypeDescriptorused earlier.- __abstractmethods__ = frozenset({'accept', 'parse'})
- abstractmethod accept(visitor: ModelVisitor, loc: Loc, value: Any, /)
Accept given model visitor.
This method is meant to provide visitor accepting logic for handled type. Basically, this method will call the most adequate visitor method, or (for complex types) sequence of visitor methods. See
ModelVisitorfor more details.- Parameters:
visitor – The visitor to accept.
loc – The visited location in the model.
value –
The value to process.
It can be assumed that this value has the right type already.
- abstractmethod parse(errors: list[Error], loc: Loc, value: Any, /) Any | UnsetType
Parse given value as instance of handled type.
Successful parsing must return instance of handled type, which can be unchanged value if it already has desired type.
Failure must be reported by one or more errors added to errors list, and
modelity.unset.Unsetvalue returned.- Parameters:
errors – Mutable list of errors.
loc – The current location in the model.
value – The input value.
- class modelity.api.TypeHandlerFactory(*args, **kwargs)
Bases:
ProtocolProtocol describing type handler factories.
Added in version Replaced:
modelity.interface.ITypeDescriptorFactoryused earlier.- __abstractmethods__ = frozenset({})
- __call__(typ: Any, /, **type_opts) TypeHandler
Create a type handler for the provided type and options.
- Parameters:
typ – The type or special form to create a handler for.
type_opts – Optional type-specific options passed to the handler.
- __init__(*args, **kwargs)
- __parameters__ = ()
- __protocol_attrs__ = {'__call__'}
- classmethod __subclasshook__(other)
Abstract classes can override this to customize issubclass().
This is invoked early on by abc.ABCMeta.__subclasscheck__(). It should return True, False or NotImplemented. If it returns NotImplemented, the normal algorithm is used. Otherwise, it overrides the normal algorithm (and the outcome is cached).
- class modelity.api.TypeHandlerWithValidation
Bases:
TypeHandlerBase class for type handlers that need to run additional type-specific validation when model is validated.
For example, this base class is used by type handler for
typing.Annotatedtypes to ensure that constraints are still satisfied when model is validated, which is impossible to ensure only during parsing stage for mutable types.Added in version 0.36.0: Replaced
modelity.interface.IValidatableTypeDescriptorused earlier.- __abstractmethods__ = frozenset({'accept', 'parse', 'validate'})
- abstractmethod validate(errors: list[Error], loc: Loc, value: Any) bool
Validate the value.
Returns True and does not modify error list if the value is valid.
Returns False and adds one or more errors to the errors list if the value is not valid.
- Parameters:
errors – Mutable list of errors.
loc – The current location in the model.
value – The validated value.
- class modelity.api.UnsetType
Bases:
objectSingleton type for representing unset or undefined values.
It has only one global instance to allow fast is-a tests in the code and always evaluates to
False.- __bool__()
- static __new__(cls)
- __repr__()
Return repr(self).
- exception modelity.api.UnsupportedTypeError(typ: type)
Bases:
ModelityErrorRaised when model is declared with a field of a type that is not supported by the current version of Modelity library.
- exception modelity.api.UserError(msg: str, *, code: str = 'modelity.USER_ERROR', loc: Loc | None = None, value: Any = Unset, data: dict | None = None, skip: bool = False)
Bases:
ModelityErrorException raised by user-defined hooks to report a single error.
When raised inside a hook, this exception is intercepted by Modelity and converted into a
modelity.error.Errorinstance during the parsing or validation stage (depending on the hook type; seemodelity.hooks).Using this exception is optional - hooks may also report errors using other supported mechanisms.
Added in version 0.30.0.
- __init__(msg: str, *, code: str = 'modelity.USER_ERROR', loc: Loc | None = None, value: Any = Unset, data: dict | None = None, skip: bool = False)
- __message_template__: str | None = '{self.msg} [code={self.code!r}, loc={self.loc!r}, value={self.value!r}, data={self.data!r}, skip={self.skip!r}]'
Message template string.
Used as default error message when specified. Properties of the current exception object can be provided via
selfplaceholder.
- code: str
Error code.
By default,
modelity.error.ErrorCode.USER_ERRORis used.
- data: dict | None
Additional error data.
Optional dictionary with extra context (e.g.
{"min": 0, "max": 10}).
- loc: Loc | None
Error location.
If not set, then the current location from the hook context is used.
- skip: bool
Skipping flag.
Some validators (e.g.
modelity.hooks.model_prevalidator()) can return booleanTrueto skip other validators for the current model instance. This flag allows to enable that feature.
- exception modelity.api.ValidationError(model: Any, errors: tuple[Error, ...])
Bases:
ModelErrorException raised at model validation stage when one or model specific constraint are broken.
This exception may only be raised for existing models.
- Parameters:
model –
The model for which validation has failed.
This will be the root model, i.e. the one for which
modelity.model.Model.validate()method was called.errors – Tuple containing all validation errors.
- class modelity.api.ValidationVisitor(root: Model, errors: list[Error], ctx: Any = None)
Bases:
EmptyVisitorVisitor that performs model validation.
Added in version 0.31.0: Replaced DefaultValidationVisitor used earlier.
- Parameters:
root – The root model.
errors –
The list of errors.
Will be populated with validation errors (if any).
ctx –
User-defined validation context.
It is shared across all validation hooks and can be used as a source of external data needed during validation but not directly available in the model.
- __abstractmethods__ = frozenset({})
- visit_any(loc: Loc, value: Any)
Visit any value.
This is called for values from untyped containers, fields marked with
typing.Anyor typed containers wheretyping.Anyis used as a type hint.This method, unlike
visit_scalar(), can also be called with elements that are containers, not scalars.Implementations are responsible for deciding whether to recurse into the value if it is a container.
- Parameters:
loc – The location of the visited value.
value – The visited value.
- visit_mapping_end(loc: Loc, value: Mapping)
Finish visiting a mapping object.
- Parameters:
loc – The location of the visited mapping object.
value – The visited mapping object.
- visit_model_begin(loc: Loc, value: Model)
Start visiting model object.
- Parameters:
loc – The location of the visited model.
value – The visited model object.
- visit_model_end(loc: Loc, value: Model)
Finish visiting model object.
- Parameters:
loc – The location of the visited model.
value – The visited model object.
- visit_model_field_begin(loc: Loc, value: Any, field: Field)
Start visiting model field.
This is called for every field in a model no matter if the field is set or not.
- Parameters:
loc – The location of the visited value.
value – The visited field value.
field – The visited field metadata.
- visit_model_field_end(loc: Loc, value: Any, field: Field)
Finish visiting model field.
- Parameters:
loc – The location of the visited value.
value – The visited field value.
field – The visited field metadata.
- visit_none(loc: Loc, value: None)
Visit a
Nonevalue.Called when
Noneobject is found.- Parameters:
loc – The location of the visited value.
value – The visited value.
- visit_scalar(loc: Loc, value: Any)
Visit scalar object.
Scalars are primitive objects that are neither containers, nor model objects. All Python primitive types (ints, floats, strings, booleans, enums, datetimes etc.) are scalars from the Modelity point of view.
- Parameters:
loc – The location of the visited value.
value – The visited value.
- modelity.api.after_field_set(*field_names: str)
Decorate method to be executed after any of given fields (or all, if no name was provided) is set or updated in the model with a successfully parsed value.
This hook can be used to set derived field(-s) in the model, e.g. to also set
modifiedwhencreatedis set. However, if field is set to an incorrect value, this hook will not be called.The decorated method can be defined with no arguments, or with any subsequence of the following arguments:
- cls
The current model type.
- self
The current model object.
- loc
The location in the model.
Useful to check which field is currently being set when hook is meant to be used for several fields.
- value
The final value of a field set.
This will be the output of type parser for a current field, or a last field postprocessor (if any).
Added in version 0.36.0.
- modelity.api.create_type_handler(typ: Any, /, **type_opts)
Create type handler for provided type.
This method is using cache internally so it returns same handler if called again with same type.
- Parameters:
typ – The type to create or get handler for.
**type_opts – The optional type options to use.
- modelity.api.dump(model: Model, /, exclude_unset: bool = False, exclude_none: bool = False, exclude_if: Callable[[Loc, Any], bool] | None = None, datetime_format: str = 'YYYY-MM-DDThh:mm:ss.ffffffZZZZ', date_format: str = 'YYYY-MM-DD') dict
Serialize given model to a dict.
This helper is designed to handle most common dump scenarios, like skipping unset fields or optional field set to
None. More advanced behavior can be achieved by implementing custommodelity.interface.IModelVisitorinterface and runningmodelity.model.Model.accept()method directly.- Parameters:
model – The model to serialize.
exclude_unset – Exclude unset fields.
exclude_none – Exclude fields set to
None.exclude_if –
Conditional function executed for every model location and value.
Should return
Trueto drop the value from resulting dict, orFalseto leave it. Can be used to achieve exclusion based on location and/or value.datetime_format –
The format to use for
datetime.datetimeobjects.Added in version 0.31.0.
date_format –
The format to use for
datetime.dateobjects.Added in version 0.31.0.
- modelity.api.field_info(*, default: T | UnsetType = Unset, default_factory: Callable[[], T] | UnsetType = Unset, title: str | None = None, description: str | None = None, examples: list | None = None, **type_opts) T
Helper for creating
FieldInfoobjects in a way that will satisfy code linters.Check
FieldInfoclass documentation to get help on available parameters.Changed in version 0.19.0: Added title, description and examples parameters.
Added in version 0.16.0.
- modelity.api.field_postprocessor(*field_names: str)
Decorate model’s method as a field-level postprocessing hook.
Field postprocessors are only executed after successful preprocessing and parsing stages for the field they are declared for. Use this hook to perform additional per-field validation (executed when field is set or modified), or data normalization. Input value received by this hook is already parsed to a valid type and no other checking regarding this matter needs to take place.
Value returned by this kind of hook is either passed to a next postprocessor (if any), or stored as model’s field final value. No additional type checking takes place after postprocessing stage, so the user must pay attention to this.
The decorated method can be defined with no arguments, or with any subsequence of the following arguments:
- cls
The model type.
- errors
Mutable list of errors.
Can be extended by the postprocessor if postprocessing phase fails. Alternatively, postprocessor can raise
TypeErrorexception that will automatically be converted into error and added to this list.- loc
The currently preprocessed model location.
This is instance of the
modelity.loc.Loctype.- value
The input value for this postprocessor.
This will either be the output value of the type parser, or the output value of previous postprocessor (if any).
Here’s an example use:
from modelity.base import Model from modelity.hooks import field_postprocessor class FieldPostprocessorExample(Model): foo: str @field_postprocessor("foo") def _strip_white_characters(value): return value.strip() # The 'value' is guaranteed to be str when this gets called
- Parameters:
*field_names –
List of field names.
This can be left empty if the hook needs to be run for every field.
Since hooks are inherited, this also includes subclasses of the model the hook was declared in and it is not checked in any way if field names are correct.
Changed in version 0.37.0: Removed self argument; use
field_fixup()hook instead.
- modelity.api.field_preprocessor(*field_names: str)
Decorate model’s method as a field-level preprocessing hook.
Field preprocessors are used to filter input value on a field-specific basis before it is parsed to a target type. For example, this hook can be used to strip string input from white characters.
Value returned by preprocessor is either passed to the next preprocessor (if any) or to the type parser assigned for the field that is being set or modified.
The decorated method can be defined with no arguments, or with any subsequence of the following arguments:
- cls
The model type.
- errors
Mutable list of errors.
Can be extended by the preprocessor if preprocessing phase fails. Alternatively, preprocessor can raise
TypeErrorexception that will automatically be converted into error and added to this list.- loc
The currently preprocessed model location.
This is instance of the
modelity.loc.Loctype.- value
The input value for this preprocessor.
This will either be user’s input value, or the output value of previous preprocessor (if any).
Here’s an example use:
from modelity.base import Model from modelity.hooks import field_preprocessor class Dummy(Model): foo: str @field_preprocessor("foo") def _strip_white_characters(value): if isinstance(value, str): return value.strip() return value
>>> dummy = Dummy(foo=' spam ') >>> dummy Dummy(foo='spam')
- Parameters:
*field_names –
List of field names.
This can be left empty if the hook needs to be run for every field.
Since hooks are inherited, this also includes subclasses of the model the hook was declared in and it is not checked in any way if field names are correct.
- modelity.api.field_validator(*field_names: str)
Decorate model’s method as a field-level validator.
This hook is executed for given field names only (or all fields, if the list of names is empty), if and only if the field is set and always in between model-level pre- and postvalidators.
- cls
The model type.
- self
The current model.
Different than root means that this is a nested model.
- root
The root model instance.
This is the model for which
modelity.helpers.validate()was called. Can be used to access entire model when performing validation.- ctx
The user-defined validation context.
Check guide-validation-using_context for more details.
- errors
Mutable list of errors.
Can be extended by this hook to signal validation errors. Alternatively,
ValueErrorexception can be raised and will automatically be converted into error and added to this list.- loc
The location of the currently validated model.
Will be empty if this is a root model, or non-empty if this model is nested inside another model.
This is instance of the
modelity.loc.Loctype.- value
Field’s value to validate.
- modelity.api.fixup(model: Model, ctx: Any = None)
Perform fixup on given model.
This helper runs all
modelity.hooks.model_fixup()hooks defined for a model and also recurses into nested models. Performing fixup allows to run some post-parsing and pre-validation user-defined logic to fill in the model with derived or missing information.- Parameters:
model – The model to fixup.
ctx –
The user-defined context object to be shared by all fixup hooks.
Can be used to pass some additional data to model, like results of API calls etc.
Changed in version 0.37.0: Added ctx argument.
Added in version 0.36.0.
- modelity.api.has_fields_set(model: Model) bool
Check if model has at least one field set.
- Parameters:
model – The model object.
- modelity.api.is_any_optional(typ: Any) bool
Check if given type is any of the optional types supported by Modelity.
- Parameters:
tp – The type to check.
- modelity.api.is_deferred(typ: Any) bool
Check if given type is a deferred type.
Deferred types in Modelity are used to declare model fields as required but only during validation stage. This means that the field can be unset when model is created, but must later be set to pass validation.
Added in version 0.35.0.
- Parameters:
tp – The type to check.
- modelity.api.is_loose_optional(typ: Any) bool
Check if given type is
LooseOptional[T].Added in version 0.36.0.
- Parameters:
tp – The type to check.
- modelity.api.is_optional(typ: Any) bool
Check if given type is
Optional[T].Added in version 0.36.0.
- Parameters:
tp – The type to check.
- modelity.api.is_strict_optional(typ: Any) bool
Check if given type is
StrictOptional[T].Added in version 0.36.0.
- Parameters:
tp – The type to check.
- modelity.api.is_unset(obj: object) TypeIs[UnsetType]
Check if obj is instance of
UnsetTypetype.Changed in version 0.31.0: Now uses
typing_extensions.TypeIsfor type narrowing.Added in version 0.17.0.
- modelity.api.is_unsettable(typ: Any) bool
Check if given type annotation allows
modelity.unset.Unsetas valid value.Added in version 0.35.0.
- Parameters:
typ – The type to investigate.
- modelity.api.load(model_type: type[MT], data: dict, ctx: Any = None) MT
Parse and validate given raw data using provided model type.
This is a helper function meant to be used to create models from data that is coming from an untrusted source, like API request, JSON file etc.
On success, this function returns new instance of the given model_type.
On failure, this function raises
modelity.exc.ModelError.Here’s an example:
from modelity.base import Model from modelity.helpers import load class Example(Model): foo: int bar: int
>>> untrusted_data = {"foo": "123", "bar": "456"} >>> example = load(Example, untrusted_data) >>> example Example(foo=123, bar=456)
- Parameters:
model_type – The model type to parse data with.
data – The data to be parsed.
ctx – The user-defined validation context.
- modelity.api.location_validator(*patterns: str)
Decorate model’s method as a location validator.
This validator is meant to be used when model validation requires access to nested models, collections of models etc. It runs for every value that is set in the model and its location suffix matches given pattern, which also supports wildcards via
*(star) character.For example:
from modelity.api import Model, location_validator, validate class Dummy(Model): class Nested(Model): foo: int nested: Nested @location_validator("nested.foo") # This is matched to location's suffix def _validate_nested_foo(loc, value): if value < 0: raise ValueError(f"value at {loc} must be >= 0")
>>> dummy = Dummy(nested=Dummy.Nested(foo=-1)) >>> validate(dummy) Traceback (most recent call last): ... modelity.exc.ValidationError: Found 1 validation error for model 'Dummy': nested.foo: value at nested.foo must be >= 0 [code=modelity.EXCEPTION, exc_type=ValueError]
Thanks to this validator it is now possible to define entire validation logic for a model in one place without affecting nested models which may have different constraints if are used in another parent model.
Following arguments can be used in decorated function:
- cls
The model type.
This is the type this decorator is declared in.
- self
The instance of cls for which this decorator runs.
- root
The root model instance.
If different than self then this validator runs for a nested model.
- ctx
The user-defined validation context.
Check guide-validation-using_context for more details.
- errors
Mutable list of errors.
Can be extended by this hook to signal validation errors. Alternatively,
ValueErrorexception can be raised and will automatically be converted into error and added to this list.- loc
The location of the currently validated value.
This validator runs if and only if the suffix of this location matches one of patterns defined.
- value
The validated value.
Added in version 0.27.0.
- Parameters:
*patterns –
Location patterns to run this validator for.
These are relative to the model where this decorator was used, so first element in each pattern refers to model’s fields, second (if any) to nested models or collection items etc.
Following wildcards are supported:
?- matches exactly one location element (e.g.foo.?.barwill matchfoo.0.bar, but notfoo.0.0.bar)*- matches one or more location elements (e.g.foo.*.bazwill matchfoo.bar.0.baz, but notfoo.baz)**- matches zero or more location elements (e.g.foo.**.bazwill match bothfoo.bar.0.bazandfoo.baz)
- modelity.api.model_fixup()
Decorate model’s method as a model-level fixup function.
Fixup hooks can be run for a given model using
modelity.helpers.fixup()helper. This functionality can be used to perform some user-defined updates in the model tree before validation takes place and only after successful parsing. Fixup hooks can be fed with user-defined context object, and therefore it is possible to pass external data to set in the model before validation takes place.The decorated method can be defined with no arguments, or with any subsequence of the following arguments:
- cls
The current model type.
- self
The current model object.
- root
The root model.
This is the one for which
modelity.helpers.fixup()was originally called.- ctx
The user-defined fixup context.
This can be used to pass some external data (e.g. API call results) to the model and use those during fixup. The type and structure is completely up to the user, Modelity will simply pass this to the user-defined fixup hooks and will not perform any additional checks.
- loc
The location in the model tree.
Will be empty for root model, or non-empty for nested one.
Changed in version 0.37.0:
Now these hooks can only be called on demand via
modelity.helpers.fixup()helper or dedicated visitor.Added root and ctx arguments.
Added in version 0.36.0.
- modelity.api.model_postvalidator()
Decorate model’s method as a model-level postvalidation hook.
Model postvalidators are executed as the final validation step, after model prevalidators, built-in validators and field-level validators.
The arguments for the decorated method are exactly the same as for
model_prevalidator()hook.
- modelity.api.model_prevalidator()
Decorate model’s method as a model-level prevalidation hook.
Model prevalidators are executed as the initial validation step, before any other validators, including built-in ones.
Model prevalidators can be used to skip other validators for the current model. This feature can be used either conditionally disable validation, or to replace it with custom one. To skip other validators,
Truemust be returned. ReturningTrueonly applies to the instances of the model where model prevalidator returningTrueis defined.Important
Returning
Trueand skipping other validators also applies to built-in ones. For example, required fields validation will also be skipped ifTrueis returned.The decorated method can be defined with no arguments, or with any subsequence of the following arguments:
- cls
The model type.
- self
The current model.
Different than root means that this is a nested model.
- root
The root model instance.
This is the model for which
modelity.helpers.validate()was called. Can be used to access entire model when performing validation.- ctx
The user-defined validation context.
Check guide-validation-using_context for more details.
- errors
Mutable list of errors.
Can be extended by this hook to signal validation errors. Alternatively,
ValueErrorexception can be raised and will automatically be converted into error and added to this list.- loc
The location of the currently validated model.
Will be empty if this is a root model, or non-empty if this model is nested inside another model.
This is instance of the
modelity.loc.Loctype.
- modelity.api.register_type_handler_factory(typ: Any, factory: TypeHandlerFactory)
Register custom type handler factory for given type.
This method can be used to register custom types so Modelity could understand those, or to overwrite built-in type handlers.
- Parameters:
typ – The type to register type handler for.
factory – The type handler factory function to use for provided type.
- modelity.api.validate(model: Model, ctx: Any = None)
Validate provided model.
On success, this method raises no exception and returns
None.On failure,
modelity.exc.ValidationErrorexception is raised.- Parameters:
model – The model to validate.
ctx – The user-defined validation context.