Source code for fsh_lib.transformers

"""Body→kwargs transformer helpers shared by generated builders.

Generated update builders one-line through :func:`build_patch_kwargs`
to read ``body.model_fields_set`` and emit a column-kwargs dict the
SQL ``update(...).values(**...)`` consumes.  The same one-shot
extraction would otherwise be repeated per resource as a chain of
``if "<field>" in body.model_fields_set: out["<field>"] = ...`` lines
in every transformer module.
"""

from __future__ import annotations

from typing import TYPE_CHECKING, Any

if TYPE_CHECKING:
    from collections.abc import Iterable

    from pydantic import BaseModel


[docs] def build_patch_kwargs( body: BaseModel, fields: Iterable[str], ) -> dict[str, Any]: """Project the explicitly-set subset of *fields* off *body* into a dict. PATCH semantics: a field that the client *did not* send must not appear in the returned dict, so the SQL ``UPDATE`` only touches columns the client meant to change. ``body.model_fields_set`` is pydantic's record of which attributes were populated from input (vs. left at their default), so iterating it is the correct gate -- a ``None`` *value* the client explicitly sent still passes through. Args: body: The parsed pydantic request model. fields: Field names the caller wants to consider. Names absent from *body*'s declared fields are ignored. Returns: A ``dict`` mapping each set field to its value on *body*. The caller typically annotates the receiving variable with the per-resource ``{Resource}UpdateKwargs`` ``TypedDict`` (``total=False``) so type-checkers see the result as the expected partial shape. """ set_fields = body.model_fields_set return {name: getattr(body, name) for name in fields if name in set_fields}
__all__ = ["build_patch_kwargs"]