beda-software / fhir-py-types

Convert FHIR StructureDefinition into Python type annotations
BSD 3-Clause "New" or "Revised" License
15 stars 1 forks source link

Allow for custom Pydantic BaseModel #4

Closed axelv closed 1 year ago

axelv commented 1 year ago

What?

I would like add an argument to the CLI to customize the BaseModel that is used in the code generation.

Why?

This would allow me to add custom features to the models like an improved repr, and automatic exclusion of empty (None or []) elements when serializing to dict or json. Maybe also some smart behavior with extensions

An example of a custom BaseModel

from typing import TYPE_CHECKING, Sequence, Tuple, Optional, Any, Union, AbstractSet, Mapping
from pydantic import BaseModel as PydanticBaseModel
from pydantic.utils import sequence_like

if TYPE_CHECKING:
    ReprArgs = Sequence[Tuple[Optional[str], Any]]
    AbstractSetIntStr = AbstractSet[Union[int, str]]
    MappingIntStrAny = Mapping[Union[int, str], Any]

def _is_not_empty(value: Any) -> bool:
    try:
        return len(value) > 0
    except TypeError:
        return value is not None

class BaseModel(PydanticBaseModel):
    def __repr_args__(self) -> 'ReprArgs':
        return [
            (k, v)
            for k, v in super().__repr_args__() if (k not in self.__fields__ or self.__fields__[k].field_info.extra.get("summary", True)) and _is_not_empty(v)
        ]

    @classmethod
    def _get_value(
        cls,
        v: Any,
        to_dict: bool,
        by_alias: bool,
        include: Optional[Union['AbstractSetIntStr', 'MappingIntStrAny']],
        exclude: Optional[Union['AbstractSetIntStr', 'MappingIntStrAny']],
        exclude_unset: bool,
        exclude_defaults: bool,
        exclude_none: bool,
        **kwds: Any,
    ) -> Any:
        if sequence_like(v) and exclude_none and len(v) == 0:
            return None
        else:
            return super()._get_value(v=v, to_dict=to_dict,by_alias=by_alias,include=include,exclude=exclude,exclude_unset=exclude_unset,exclude_defaults=exclude_defaults,exclude_none=exclude_none, **kwds)
m0rl commented 1 year ago

Thanks for helping us making this project more flexible in its configuration!

axelv commented 1 year ago

Awesome!