ModelClassFactory

The ModelClassFactory can be used to cast OpenAPIModel objects to instances of dataclass or attrs classes

Source code in src/alpha/factories/model_class_factory.py
class ModelClassFactory:
    """The ModelClassFactory can be used to cast OpenAPIModel objects to
    instances of dataclass or attrs classes
    """

    def __init__(
        self,
        typing_classes: dict[object, ClassFactory] = TYPING_CLASSES,
        factory_classes: FactoryClasses = FACTORY_CLASSES,
    ) -> None:
        """Initializing and setting the self.typing_classes class variable
        which contains typing classes and references to the corresponding
        factory classes. The set of typing classes depend on the python minor
        version.

        Parameters
        ----------
        typing_classes
            A collection of class types, by default TYPING_CLASSES
        factory_classes
            An instance of FactoryClasses which acts as a toolbox of Factory
            classes, by default FACTORY_CLASSES
        """
        self.typing_classes = typing_classes
        self.factory_classes = factory_classes

        # Set the model_class_factory reference in factory_classes to self if
        # it is not already set
        if self.factory_classes.model_class_factory is None:
            self.factory_classes.model_class_factory = self  # type: ignore

    def process(
        self,
        obj: OpenAPIModel,
        cls: DataclassInstance | AttrsInstance | PydanticInstance | Any,
    ) -> DataclassInstance | AttrsInstance | PydanticInstance | None:
        """Creating a new cls instance from a OpenAPIModel object. This class
        uses a compatibele ClassFactory, from the self.typing_classes
        collection, per cls field to process each value.

        Parameters
        ----------
        obj
            OpenAPIModel object
        cls
            A dataclass, attrs, or pydantic class to create a new instance

        Returns
        -------
        DataclassInstance | AttrsInstance | PydanticInstance | None
            Dataclass, attrs, or pydantic instance

        Raises
        ------
        exceptions.ModelClassFactoryException
            When cls is not a dataclass, attrs, or pydantic decorated class
        KeyError
            When the class type is not present in self.typing_classes
        """

        try:
            fields = FieldIterator(cls)
        except TypeError:
            raise exceptions.ModelClassFactoryException(
                "cls argument has to be a dataclass or attrs decorated class"
            )

        params: dict[str, Any] = {}

        for field in [f for f in fields if f.init]:
            type_class: type | str = "Unknown"
            try:
                type_class = field.type.__class__
                class_factory = self.typing_classes[type_class]
                value: Any = class_factory.process(
                    obj=obj,
                    field=field,
                    factory_classes=self.factory_classes,
                )
            except KeyError as exc:
                raise exceptions.ModelClassFactoryException(
                    "The class of this dataclass field is not supported. "
                    f"{field.name=}; "
                    f"{field.type=}; "
                    f"{field.type.__class__=}; "
                ) from exc
            params[field.name] = value
        return cls(**params)  # type: ignore

Methods:

__init__

__init__(typing_classes=TYPING_CLASSES, factory_classes=FACTORY_CLASSES)

Initializing and setting the self.typing_classes class variable which contains typing classes and references to the corresponding factory classes. The set of typing classes depend on the python minor version.

Parameters:
  • typing_classes (dict[object, ClassFactory], default: TYPING_CLASSES ) –

    A collection of class types, by default TYPING_CLASSES

  • factory_classes (FactoryClasses, default: FACTORY_CLASSES ) –

    An instance of FactoryClasses which acts as a toolbox of Factory classes, by default FACTORY_CLASSES

Source code in src/alpha/factories/model_class_factory.py
def __init__(
    self,
    typing_classes: dict[object, ClassFactory] = TYPING_CLASSES,
    factory_classes: FactoryClasses = FACTORY_CLASSES,
) -> None:
    """Initializing and setting the self.typing_classes class variable
    which contains typing classes and references to the corresponding
    factory classes. The set of typing classes depend on the python minor
    version.

    Parameters
    ----------
    typing_classes
        A collection of class types, by default TYPING_CLASSES
    factory_classes
        An instance of FactoryClasses which acts as a toolbox of Factory
        classes, by default FACTORY_CLASSES
    """
    self.typing_classes = typing_classes
    self.factory_classes = factory_classes

    # Set the model_class_factory reference in factory_classes to self if
    # it is not already set
    if self.factory_classes.model_class_factory is None:
        self.factory_classes.model_class_factory = self  # type: ignore

process

process(obj, cls)

Creating a new cls instance from a OpenAPIModel object. This class uses a compatibele ClassFactory, from the self.typing_classes collection, per cls field to process each value.

Parameters:
Returns:
Raises:
  • ModelClassFactoryException

    When cls is not a dataclass, attrs, or pydantic decorated class

  • KeyError

    When the class type is not present in self.typing_classes

Source code in src/alpha/factories/model_class_factory.py
def process(
    self,
    obj: OpenAPIModel,
    cls: DataclassInstance | AttrsInstance | PydanticInstance | Any,
) -> DataclassInstance | AttrsInstance | PydanticInstance | None:
    """Creating a new cls instance from a OpenAPIModel object. This class
    uses a compatibele ClassFactory, from the self.typing_classes
    collection, per cls field to process each value.

    Parameters
    ----------
    obj
        OpenAPIModel object
    cls
        A dataclass, attrs, or pydantic class to create a new instance

    Returns
    -------
    DataclassInstance | AttrsInstance | PydanticInstance | None
        Dataclass, attrs, or pydantic instance

    Raises
    ------
    exceptions.ModelClassFactoryException
        When cls is not a dataclass, attrs, or pydantic decorated class
    KeyError
        When the class type is not present in self.typing_classes
    """

    try:
        fields = FieldIterator(cls)
    except TypeError:
        raise exceptions.ModelClassFactoryException(
            "cls argument has to be a dataclass or attrs decorated class"
        )

    params: dict[str, Any] = {}

    for field in [f for f in fields if f.init]:
        type_class: type | str = "Unknown"
        try:
            type_class = field.type.__class__
            class_factory = self.typing_classes[type_class]
            value: Any = class_factory.process(
                obj=obj,
                field=field,
                factory_classes=self.factory_classes,
            )
        except KeyError as exc:
            raise exceptions.ModelClassFactoryException(
                "The class of this dataclass field is not supported. "
                f"{field.name=}; "
                f"{field.type=}; "
                f"{field.type.__class__=}; "
            ) from exc
        params[field.name] = value
    return cls(**params)  # type: ignore