Skip to content

Specifications

plateforme.core.specs

This module provides utilities for managing schema within the Plateforme framework using Pydantic features.

Spec module-attribute

Spec = TypeVar('Spec', bound='BaseSpec')

A type variable for a specification class.

SpecType module-attribute

SpecType = Type['BaseSpec']

A type alias for a specification class.

SpecFacade

Bases: Protocol

A specification facade protocol.

BaseSpec

Bases: Protocol

The base specification protocol for resources.

This protocol is used to define the specification for resources. It can be derived to define custom model schemas either by specifying static nested model classes within the base specification, or by implementing the __apply__ method to dynamically generate model schemas based on the resource provided by the specification facade or add custom logic.

Those models are then used to define the validation, serialization, and deserialization logic for resources within services.

CRUDSpec

Bases: BaseSpec

The CRUD specification.

apply_spec

apply_spec(spec: SpecType, facade: SpecFacade) -> None

Apply the specification to the facade.

Parameters:

Name Type Description Default
spec SpecType

The specification to apply.

required
facade SpecFacade

The facade to apply the specification to.

required
Source code in .venv/lib/python3.12/site-packages/plateforme/core/specs.py
@with_caller_context
def apply_spec(spec: SpecType, facade: SpecFacade) -> None:
    """Apply the specification to the facade.

    Args:
        spec: The specification to apply.
        facade: The facade to apply the specification to.
    """
    spec.__apply__(facade)

resolve_schema_model

resolve_schema_model(
    annotation: Any,
    *,
    root_schemas: tuple[str, ...] | None = None,
    with_spec: tuple[SpecType, ResourceType] | None = None,
) -> Any

Resolve the schema models from the annotation.

Parameters:

Name Type Description Default
annotation Any

The annotation to resolve.

required
root_schemas tuple[str, ...] | None

The schema model aliases to use as the root schema. When the resolved path is empty, the resolved root type is returned if set to None, otherwise the root schemas are used in order of precedence to match a valid schema model. Defaults to None.

None
with_spec tuple[SpecType, ResourceType] | None

The specification and resource type to use for resolving the schema models. When provided, it should be a tuple containing the specification and the resource type to use for resolving the schema models. When set to None, the schema models within the annotation are resolved for all resources. Defaults to None.

None

Returns:

Type Description
Any

The annotation with the resolved schema models.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/specs.py
def resolve_schema_model(
    annotation: Any,
    *,
    root_schemas: tuple[str, ...] | None = None,
    with_spec: tuple['SpecType', 'ResourceType'] | None = None,
) -> Any:
    """Resolve the schema models from the annotation.

    Args:
        annotation: The annotation to resolve.
        root_schemas: The schema model aliases to use as the root schema. When
            the resolved path is empty, the resolved root type is returned if
            set to ``None``, otherwise the root schemas are used in order of
            precedence to match a valid schema model. Defaults to ``None``.
        with_spec: The specification and resource type to use for resolving
            the schema models. When provided, it should be a tuple containing
            the specification and the resource type to use for resolving the
            schema models. When set to ``None``, the schema models within the
            annotation are resolved for all resources. Defaults to ``None``.

    Returns:
        The annotation with the resolved schema models.
    """
    if with_spec:
        spec, resource = with_spec

    def ann_test(ann: Any) -> tuple[bool, Any]:
        if not isinstance(ann, type):
            return False, ...

        hierarchy = get_cls_hierarchy(ann)
        root = next(iter(hierarchy.values()))
        path = next(reversed(hierarchy.keys()))

        if with_spec:
            return root is spec, (root, path)
        return is_resource(root), (root, path)

    def ann_resolver(_: Any, info: tuple[Any, str]) -> Any:
        root, path = info
        owner = resource if with_spec else root

        if path == '':
            if root_schemas is None:
                return owner
            schema_lookup = root_schemas
        else:
            schema_lookup = (to_name_case(path),)

        for schema_alias in schema_lookup:
            if schema_alias not in owner.resource_schemas:
                continue
            return owner.resource_schemas[schema_alias]

        raise PlateformeError(
            f"Schema owner {owner.__qualname__!r} does not define a valid "
            f"schema model for alias {schema_alias!r}.",
            code='schema-resolution-failed',
        )

    return Annotation.replace(
        annotation, test=ann_test, resolver=ann_resolver,
    )