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.

pydantic model DispatchedClassContainer

convenience wrapper allowing you to specify a dispatched family root class as the class parameter, and it’ll build the correct discriminated union type under the hood for you.

field root: DispatchedClsTV [Required]

the underlying concrete class instance

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