Skip to content
Snippets Groups Projects
pydantic_utcdatetime.py 1.6 KiB
Newer Older
  • Learn to ignore specific revisions
  • """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
    
    Jeremy M Fee's avatar
    Jeremy M Fee committed
        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],
    )