среда, 12 июня 2024 г.

Pydantic (or Django Ninja) + Timeflake

 So if you want to publish some model to your rest api, and model is declared using Pydantic or Django Ninja (which is using Pydantic under the hood), here is the solution I came with:

from typing import Any, Annotated

from pydantic import GetCoreSchemaHandler, GetJsonSchemaHandler, TypeAdapter
from pydantic.types import AnyType
from pydantic_core import CoreSchema, core_schema
from pydantic.json_schema import JsonSchemaValue


def vld(x: Any) -> Any:
return x

class TimeflakeType:

@classmethod
def __get_pydantic_core_schema__(
cls, source: type[Any], handler: GetCoreSchemaHandler
) -> core_schema.CoreSchema:
serializer = core_schema.plain_serializer_function_ser_schema(cls._serialize, when_used='json')
if cls is source:
return core_schema.no_info_plain_validator_function(
function=vld, serialization=serializer
)
else:
return core_schema.no_info_before_validator_function(
function=vld, schema=handler(source), serialization=serializer
)
@classmethod
def __get_pydantic_json_schema__(cls, cs: CoreSchema, handler: GetJsonSchemaHandler) -> JsonSchemaValue:
return handler(core_schema.str_schema())

@staticmethod
def _serialize(v: Any) -> str:
return str(v)

def __repr__(self) -> str:
return 'Timeflake'

This code is based on ImportString type declaration in standard Pydantic repo.