"""Configure pydantic to allow UTCDateTime attributes on models. """ from datetime import datetime from typing import Any, Callable, Dict, List, Tuple, TypeVar, Union from obspy import UTCDateTime from pydantic.errors import PydanticValueError import pydantic.json import pydantic.schema import pydantic.validators # placeholder type for register_custom_pydantic_type method CustomType = TypeVar("CustomType") def register_custom_pydantic_type( custom_type: CustomType, encoder: Callable[[CustomType], Any], json_schema: Dict, parsers: List[Callable[[Any], CustomType]], ): try: if custom_type.__custom_pydantic_type__: # already registered return except AttributeError: # not registered yet pass # add encoder pydantic.json.ENCODERS_BY_TYPE[custom_type] = encoder # add openapi mapping pydantic.schema.field_class_to_schema += ((custom_type, json_schema),) # add validator pydantic.validators._VALIDATORS.append((custom_type, parsers)) # mark as installed custom_type.__custom_pydantic_type__ = True class UTCDateTimeError(PydanticValueError): msg_template = "invalid date-time format" def format_utcdatetime(o: UTCDateTime) -> str: return o.isoformat() def parse_utcdatetime( value: Union[datetime, float, int, str, UTCDateTime] ) -> UTCDateTime: try: return UTCDateTime(value) except: raise UTCDateTimeError() register_custom_pydantic_type( UTCDateTime, encoder=format_utcdatetime, json_schema={"type": "string", "format": "date-time"}, parsers=[parse_utcdatetime], )