U nf9 @sUdZddlmZddlZddlmZddlmZmZm Z m Z m Z m Z ddl mZmZddl mZddlmZmZmZd d lmZd d lmZmZd d lmZejfejd diGdddZejfejd diGdddZerLe e eeefe!eefeefZ"de#d<e ej$e"fZ%e ej&e"fZ'e de%dZ(e de'dZ)e dddddddddddd d!Z*e ddddddd"ddddd#d$d!Z*e ddddddd%dddd&d#d'd!Z*d(ed)dd*dd+dddd,d-d.d!Z*e d/e defdZ+e d/d/d0d1d2Z,e dd)dd3d+ddd4d5d6d2Z,d=d(d)ed3d7d+ddd,d8d9d2Z,e d:Z-ernee-dfZ.nejfejGd;d<d<Z.dS)>zEThis module contains related classes and functions for serialization.) annotationsN) partialmethod) TYPE_CHECKINGAnyCallableTypeVarUnionoverload)PydanticUndefined core_schema)r ) AnnotatedLiteral TypeAlias)PydanticUndefinedAnnotation) _decorators_internal_dataclass)GetCoreSchemaHandlerfrozenTc@sDeZdZUdZded<eZded<dZded<dd d d d d ZdS)PlainSerializeraCPlain serializers use a function to modify the output of serialization. This is particularly helpful when you want to customize the serialization for annotated types. Consider an input of `list`, which will be serialized into a space-delimited string. ```python from typing import List from typing_extensions import Annotated from pydantic import BaseModel, PlainSerializer CustomStr = Annotated[ List, PlainSerializer(lambda x: ' '.join(x), return_type=str) ] class StudentModel(BaseModel): courses: CustomStr student = StudentModel(courses=['Math', 'Chemistry', 'English']) print(student.model_dump()) #> {'courses': 'Math Chemistry English'} ``` Attributes: func: The serializer function. return_type: The return type for the function. If omitted it will be inferred from the type annotation. when_used: Determines when this serializer should be used. Accepts a string with values `'always'`, `'unless-none'`, `'json'`, and `'json-unless-none'`. Defaults to 'always'. zcore_schema.SerializerFunctionfuncr return_typealways>Literal[('always', 'unless-none', 'json', 'json-unless-none')] when_usedrcore_schema.CoreSchema source_typehandlerreturnc Cs||}zt|j|j|}Wn.tk rP}zt||W5d}~XYnX|tkr^dn| |}t j |jt |jd||j d|d<|S)zGets the Pydantic core schema. Args: source_type: The source type. handler: The `GetCoreSchemaHandler` instance. Returns: The Pydantic core schema. NplainfunctionZinfo_arg return_schemar serialization)rget_function_return_typerr_get_types_namespace NameErrorrfrom_name_errorr generate_schemar Z$plain_serializer_function_ser_schemainspect_annotated_serializerrselfrrschemarer#r/M/opt/hc_python/lib/python3.8/site-packages/pydantic/functional_serializers.py__get_pydantic_core_schema__7s"   z,PlainSerializer.__get_pydantic_core_schema__N __name__ __module__ __qualname____doc____annotations__r rrr1r/r/r/r0rs   rc@sDeZdZUdZded<eZded<dZded<dd d d d d ZdS)WrapSerializera Wrap serializers receive the raw inputs along with a handler function that applies the standard serialization logic, and can modify the resulting value before returning it as the final output of serialization. For example, here's a scenario in which a wrap serializer transforms timezones to UTC **and** utilizes the existing `datetime` serialization logic. ```python from datetime import datetime, timezone from typing import Any, Dict from typing_extensions import Annotated from pydantic import BaseModel, WrapSerializer class EventDatetime(BaseModel): start: datetime end: datetime def convert_to_utc(value: Any, handler, info) -> Dict[str, datetime]: # Note that `helper` can actually help serialize the `value` for further custom serialization in case it's a subclass. partial_result = handler(value, info) if info.mode == 'json': return { k: datetime.fromisoformat(v).astimezone(timezone.utc) for k, v in partial_result.items() } return {k: v.astimezone(timezone.utc) for k, v in partial_result.items()} UTCEventDatetime = Annotated[EventDatetime, WrapSerializer(convert_to_utc)] class EventModel(BaseModel): event_datetime: UTCEventDatetime dt = EventDatetime( start='2024-01-01T07:00:00-08:00', end='2024-01-03T20:00:00+06:00' ) event = EventModel(event_datetime=dt) print(event.model_dump()) ''' { 'event_datetime': { 'start': datetime.datetime( 2024, 1, 1, 15, 0, tzinfo=datetime.timezone.utc ), 'end': datetime.datetime( 2024, 1, 3, 14, 0, tzinfo=datetime.timezone.utc ), } } ''' print(event.model_dump_json()) ''' {"event_datetime":{"start":"2024-01-01T15:00:00Z","end":"2024-01-03T14:00:00Z"}} ''' ``` Attributes: func: The serializer function to be wrapped. return_type: The return type for the function. If omitted it will be inferred from the type annotation. when_used: Determines when this serializer should be used. Accepts a string with values `'always'`, `'unless-none'`, `'json'`, and `'json-unless-none'`. Defaults to 'always'. z"core_schema.WrapSerializerFunctionrrrrrrrrrc Cs||}zt|j|j|}Wn.tk rP}zt||W5d}~XYnX|tkr^dn| |}t j |jt |jd||j d|d<|S)zThis method is used to get the Pydantic core schema of the class. Args: source_type: Source type. handler: Core schema handler. Returns: The generated core schema of the class. Nwrapr!r$)rr%rrr&r'rr(r r)r #wrap_serializer_function_ser_schemar*rr+r/r/r0r1s"   z+WrapSerializer.__get_pydantic_core_schema__Nr2r/r/r/r0r8Rs ?  r8r_PartialClsOrStaticMethod_PlainSerializeMethodType)bound_WrapSerializeMethodType.)rr check_fieldsstrrrz bool | Nonez@Callable[[_PlainSerializeMethodType], _PlainSerializeMethodType])fieldfieldsrrr?rcGsdSNr/)rArrr?rBr/r/r0field_serializersrDzLiteral['plain'])rArBmoderrr?rcGsdSrCr/rArErrr?rBr/r/r0rDs zLiteral['wrap']z>Callable[[_WrapSerializeMethodType], _WrapSerializeMethodType]cGsdSrCr/rFr/r/r0rDs r r)rErrr?zLiteral[('plain', 'wrap')]zCallable[[Any], Any])rBrErrr?rcs dddfdd }|S)aDecorator that enables custom field serialization. In the below example, a field of type `set` is used to mitigate duplication. A `field_serializer` is used to serialize the data as a sorted list. ```python from typing import Set from pydantic import BaseModel, field_serializer class StudentModel(BaseModel): name: str = 'Jane' courses: Set[str] @field_serializer('courses', when_used='json') def serialize_courses_in_order(courses: Set[str]): return sorted(courses) student = StudentModel(courses={'Math', 'Chemistry', 'English'}) print(student.model_dump_json()) #> {"name":"Jane","courses":["Chemistry","English","Math"]} ``` See [Custom serializers](../concepts/serialization.md#custom-serializers) for more information. Four signatures are supported: - `(self, value: Any, info: FieldSerializationInfo)` - `(self, value: Any, nxt: SerializerFunctionWrapHandler, info: FieldSerializationInfo)` - `(value: Any, info: SerializationInfo)` - `(value: Any, nxt: SerializerFunctionWrapHandler, info: SerializationInfo)` Args: fields: Which field(s) the method should be called on. mode: The serialization mode. - `plain` means the function will be called instead of the default serialization logic, - `wrap` means the function will be called with an argument to optionally call the default serialization logic. return_type: Optional return type for the function, if omitted it will be inferred from the type annotation. when_used: Determines the serializer will be used for serialization. check_fields: Whether to check that the fields actually exist on the model. Returns: The decorator function. zHCallable[..., Any] | staticmethod[Any, Any] | classmethod[Any, Any, Any](_decorators.PydanticDescriptorProxy[Any]frcs tjd}t||S)N)rBrErrr?)rZFieldSerializerDecoratorInfoPydanticDescriptorProxyrIZdec_infor?rBrErrr/r0decszfield_serializer..decr/)rErrr?rBrMr/rLr0rDs5 FuncType)__frcCsdSrCr/)rOr/r/r0model_serializer$srPrErrzCallable[[FuncType], FuncType])rErrrcCsdSrCr/rQr/r/r0rP(szCallable[..., Any] | None)rIrErrrcs0dddfdd }|dkr$|S||SdS)aDecorator that enables custom model serialization. This is useful when a model need to be serialized in a customized manner, allowing for flexibility beyond just specific fields. An example would be to serialize temperature to the same temperature scale, such as degrees Celsius. ```python from typing import Literal from pydantic import BaseModel, model_serializer class TemperatureModel(BaseModel): unit: Literal['C', 'F'] value: int @model_serializer() def serialize_model(self): if self.unit == 'F': return {'unit': 'C', 'value': int((self.value - 32) / 1.8)} return {'unit': self.unit, 'value': self.value} temperature = TemperatureModel(unit='F', value=212) print(temperature.model_dump()) #> {'unit': 'C', 'value': 100} ``` See [Custom serializers](../concepts/serialization.md#custom-serializers) for more information. Args: f: The function to be decorated. mode: The serialization mode. - `'plain'` means the function will be called instead of the default serialization logic - `'wrap'` means the function will be called with an argument to optionally call the default serialization logic. when_used: Determines when this serializer should be used. return_type: The return type for the function. If omitted it will be inferred from the type annotation. Returns: The decorator function. zCallable[..., Any]rGrHcstjd}t||S)NrErr)rZModelSerializerDecoratorInforJrKrRr/r0rMcszmodel_serializer..decNr/)rIrErrrMr/rRr0rP1s2AnyTypec@s4eZdZdddddZdddddd ZejZd S) SerializeAsAnyr)itemrcCst|tfSrC)r rT)clsrUr/r/r0__class_getitem__{sz SerializeAsAny.__class_getitem__rrrcCsH||}|}|ddkr*|}|d}q tjddtd|d<|S)NtypeZ definitionsr-cSs||SrCr/)xhr/r/r0z=SerializeAsAny.__get_pydantic_core_schema__..)r-r$)copyr r:Z any_schema)r,rrr-Zschema_to_updater/r/r0r1~s   z+SerializeAsAny.__get_pydantic_core_schema__N)r3r4r5rWr1object__hash__r/r/r/r0rTys rT)N)/r6 __future__r dataclasses functoolsrtypingrrrrrr Z pydantic_corer r Z _core_schematyping_extensionsr r rr _internalrrZannotated_handlersr dataclassZ slots_truerr8 classmethod staticmethodr;r7ZSerializerFunctionZ_PlainSerializationFunctionZWrapSerializerFunctionZ_WrapSerializationFunctionr<r>rDrNrPrSrTr/r/r/r0sx      ?_,     D <