Bases
This package contains base classes you can use to create classes with common functionality.
Base Base
Common bases used by other base classes
- class PydanticBase
a base model we use for all pydantic models, even the other bases
- __iter__() Generator[Tuple[str, Any], None, None]
So dict(model) works.
- classmethod _import_forward_refs() dict
hook provided for convenience when you define a subclass with forward refs, to avoid circular import issue. Overwrite this method to do the imports and add the newly imported objects to a dict.
Notes
If you’re not sure what to import and what keys to use, look at the stuff in the if TYPE_CHECKING: block, paste those exact imports in here and set them equal to their variable name within your current module’s context.
- Returns:
a dict of references to update
- Return type:
dict
- _post_init_setup() None
Overwrite this hook to set perform misc. logic before calling _post_init_validation. Common use case for this is initializing private attributes. Notes: Make sure to call super()._post_init_setup
- _post_init_validation() None
Overwrite this hook to set perform misc. validation logic on the instance, after all other common_validators have been executed. This is also called after the ‘_post_init_setup’ hook is called Notes: Make sure to call super()._post_init_validation
- validator _pydantic_post_init_val_hook » all fields
Pydantic’s hook that gets executed after we initialize an instance. rather than overwrite this, overwrite the ‘_post_init_setup’ and ‘_post_init_validation’ hooks
- json_dict(use_str_fallback: bool = True, **pydantic_kwargs) dict
Converts a pydantic instance to a dict, going through json first. This is a convenience function for when you want a dict, but want to use the json encoders connected to the pydantic object.
- Parameters:
use_str_fallback – if true, we cast anything we cannot encode to a string
**pydantic_kwargs – any kwargs available for pydantic’s json method. see their docs
- Returns:
a natively json-encodeable dict
- Return type:
dict
Examples
simple class with custom date encoder:
class Data(PydanticBase): class Config: json_encoders = { dt.date: lambda date_obj: date_obj.strftime("%d/%m/%Y") } x: int date: dt.date inst = Data(x=1, date=dt.date(year=2023, month=1, day=1)) # regular dict inst.dict() == {"x": 1, "date": dt.date(year=2023, month=1, day=1)} # this method inst.json_dict() == {"x": 1, "date": "01/01/2023"} # note that the date is the json encoding tied to the encoder for this pydantic # class. I just used a familiar string format, it could be whatever is specified
Dispatchable Bases
Base classes that help you create a group of polymorphic pydantic classes with hooks to create pydantic types that build a dispatched union json schema and parse correctly.
- pydantic model DispatchedModelMixin
the entrypoint for creating dispatchable family trees using pydantic’s internal engine for schema generation. Be careful not to inherit from two different dispatchable family trees at once. It will cause weird behavior and there are no checks to protect against this.
- field class_id: _ClassIdStr = None
this is the field we dispatch the different sub-classes on. Concrete classes will constrain this to be only one specific value.
- classmethod __init_subclass__(class_type: str | ClassType | None = None, class_id: str | ClassType | None = None) None
control how this subclass is set up.
- Parameters:
class_type – specifies the class_id for the class. If specified, we’ll use it otherwise it’ll be constructed from the cls.__name__.
class_id – If specified, we’ll ensure it is valid based on the parent class’ ClassType. See table below for more info
Returns: None
Class Type specific behavior Class Type
Behavior
Possible Parents
Possible Children
SUPER_ROOT
- sits above the family tree. Subclass DispatchedModelMixin
of the dispatching for entire trees.
SUPER_ROOT only
SUPER_ROOT or ROOT
ROOT
means a class is not concrete, thus it cannot be instantiated directly
SUPER_ROOT or ROOT
ROOT or CONCRETE
CONCRETE
- means this is a “leaf” in the family tree. This class can be
instantiated, and it should not be subclassed further.
ROOT only
None
- classmethod build_dispatched_ann() Type[SelfTV]
build a type annotation that is equivalent to Union[all concrete subclasses of this class] using class_id as a discriminator. This can be used as an annotation for a field in another pydantic class.
- classmethod build_dispatcher_type_adapter() TypeAdapter[SelfTV]
use the type annotation created by build_dispatched_ann in a pydantic TypeAdapter that allows us to get the “discriminated union” parsing functionality outside a pydantic class context. see pydantic type adapter docs
- classmethod get_all_concrete_subclass_ids() List[ClassId]
- classmethod get_class_id() ClassId
- classmethod get_class_id_path() Tuple[ClassId, ...]
- classmethod get_class_type() ClassType
- classmethod is_concrete() bool
- classmethod iter_concrete_subclasses() Iterator[Type[SelfTV]]
- model_post_init(__context: Any) None
This function is meant to behave like a BaseModel method to initialise private attributes.
It takes context as an argument since that’s what pydantic-core passes when calling it.
- Parameters:
self – The BaseModel instance.
__context – The context.
- classmethod model_validate(obj: Any, *args, **kwargs) SelfTV
Validate a pydantic model instance.
- Parameters:
obj – The object to validate.
strict – Whether to enforce types strictly.
from_attributes – Whether to extract data from object attributes.
context – Additional context to pass to the validator.
- Raises:
ValidationError – If the object could not be validated.
- Returns:
The validated model instance.
- pydantic model DispatchableValueModelBase
convenience class that combines dispatchable model mixin and value model, which is a common use-case for dispatchable models. This has the value model config and the DispatchedModelMixin functionality.
Settings
subclasses pydantic_settings’ base class to allow us to customize behavior.
- pydantic settings SettingsBase
Base class inheriting from v1 version of Pydantic’s BaseSettings. This will be adjusted when we fully move to Pydantic v2.
Notes
use double underscores, __, as the nested delimiter is default behavior
References
- Config:
extra: str = ignore
- classmethod load(use_cls_env_files: bool = True, **kwargs) Self
- model_post_init(__context: Any) None
This function is meant to behave like a BaseModel method to initialise private attributes.
It takes context as an argument since that’s what pydantic-core passes when calling it.
- Parameters:
self – The BaseModel instance.
__context – The context.
Exceptions
Standardized why to specify custom errors that include pydantic classes as error info payloads. These play nice with our loggers especially, but in general output pretty formatted structured error messages.
- exception CustomExceptionBase(detail: str, error_info: ErrorInfoTV | dict, verbose: bool = True, extra_info: dict | None = None)
Base for a custom-built exception class.
Note
the typing for the
- final classmethod get_error_payload_cls() Type[ErrorPayload[ErrorInfoTV]]
Returns: an ErrorPayload class parameterized with the correct concrete subclass of ErrorInfoBase
- final classmethod get_http_response_info_inst(status_code: int, custom_desc: t.Optional[str] = None) _http.HttpErrorResponseInfo
build a HttpErrorResponseInfo inst for this exception class
- pydantic model ErrorInfoBase
base object that holds information about a specific error.
Show JSON schema
{ "title": "ErrorInfoBase", "description": "base object that holds information about a specific error.", "type": "object", "properties": { "extra": { "description": "dict field where you can add extra info. Can include any data types but everything must be json serializable", "title": "Extra", "type": "object" } }, "additionalProperties": false }
- field extra: dict [Optional]
dict field where you can add extra info. Can include any data types but everything must be json serializable
- get_json_data(**pydantic_kwargs) dict
- pydantic model ErrorPayload
Generic payload class holding the error detail string, and the info object. The ErrorInfoTV type var dictates the unique schema information about the concrete class
Show JSON schema
{ "title": "ErrorPayload", "description": "Generic payload class holding the error detail string, and the info object.\nThe ErrorInfoTV type var dictates the unique\nschema information about the concrete class", "type": "object", "properties": { "detail": { "description": "the top line error", "title": "Detail", "type": "string" }, "error_type": { "description": "the name of the error class this payload is connected to", "title": "Error Type", "type": "string" }, "info": { "allOf": [ { "$ref": "#/$defs/ErrorInfoBase" } ], "description": "object containing more detailed information about the error" } }, "$defs": { "ErrorInfoBase": { "additionalProperties": false, "description": "base object that holds information about a specific error.", "properties": { "extra": { "description": "dict field where you can add extra info. Can include any data types but everything must be json serializable", "title": "Extra", "type": "object" } }, "title": "ErrorInfoBase", "type": "object" } }, "additionalProperties": false, "required": [ "detail", "error_type", "info" ] }
- field detail: str [Required]
the top line error
- field error_type: str [Required]
the name of the error class this payload is connected to
- field info: ErrorInfoTV [Required]
object containing more detailed information about the error
- model_post_init(__context: Any) None
This function is meant to behave like a BaseModel method to initialise private attributes.
It takes context as an argument since that’s what pydantic-core passes when calling it.
- Parameters:
self – The BaseModel instance.
__context – The context.
- pydantic model WrappedExternalException
Show JSON schema
{ "title": "WrappedExternalException", "type": "object", "properties": { "type": { "description": "the name of the type of the error", "title": "Type", "type": "string" }, "detail": { "anyOf": [ { "type": "string" }, { "type": "object" } ], "description": "The string representation of the error", "title": "Detail" } }, "additionalProperties": false, "required": [ "type", "detail" ] }
- field detail: t.Union[str, dict] [Required]
The string representation of the error
- field type: str [Required]
the name of the type of the error
- exception CustomExceptionInitializationError(detail: str, caught_exception: Exception)
this is raised when we encounter an exception in our custom exception class
Notes
This is NOT a subclass of our custom exception base class, so if we have a problem with our base class we won’t end up in recursive spiral
Special Str
- class SpecialStrBase(v: str | _CoercibleTV)
makes it convenient to subclass str to let us signify a given str is a special type, like an ID or key. This helps type checking and also allows us to add formatting and validation. This class also hooks into pydantic validation automatically.
- classmethod _format_str_val(root_data: str) str
overwrite this to specify the custom str formatting for this class
- classmethod _parse_non_str(root_data: Any) str
Overwrite this to allow the special str class to parse non-string input. Manually check the root_data type to determine if you want to parse, it and return super()._parse_non_str if you want to avoid handling the data type.
- classmethod _validate_str_val(root_data: str) str
validate that the formatted string data is valid
- special_repr() str
Gives us a special representation indicating the instance is a special string, not just a normal one.
This keeps the regular ‘__repr__’ method is the same as a normal str instance