o
    i]                  
   @   sL  U d dl Zd dlZd dlZd dlZd dlmZ d dlmZ d dl	m
Z
mZmZmZmZmZmZmZmZmZmZmZmZmZ d dlZd dlZeeZe
rRddlmZ ej dZ!e!rd dl"Z"e#ej Z$e#ej%Z&ded	ej fd
dZ'ded	ej%fddZ(e") 2 e"*de+ d dl,m-Z- d dl.m/Z0 d dl1m2Z2 d dl1m3Z3 d dl1m4Z4 d dl1m5Z5 W d   n1 sw   Y  n0d dl6m(Z( d dl6m'Z' d dl7m-Z- d dl8m/Z0 d dl9m2Z2 d dl9m3Z3 d dl9m4Z4 d dl9m5Z5 ddl:m;Z; ddl<m=Z= d dlm>Z> edZ?edej@dZAdee d	eeeB eeee   f fddZCd ee d!eBd	eee  fd"d#ZDd$eee  d%eBd&ed	eee  fd'd(ZEdee d	eFfd)d*ZGd+d,dee? d	e?fd-d.ZHdee? d/ed	e?fd0d1ZId2ed3eegef d	efd4d5ZJG d6d7 d7ej@ZKd8ee d9ee d	ee fd:d;ZLd8eeBef d9eeBef d	eeBef fd<d=ZMe!rG d>d? d?eKejNZOeOZPe>eQd@< neKZPe>eQd@< dAed	efdBdCZRd ed dDed	dfdEdFZSedGef ZT	HdSdIeFd	eeTgeTf fdJdKZUdSd!eBdIeFd	eeTgeTf fdLdMZVee-ejWjXf ZYd ed d	eeBeYf fdNdOZZdPeYd	efdQdRZ[dS )T    N)defaultdict)asdict)TYPE_CHECKINGAnyCallableClassVarDictListMappingOptionalSetTupleTypeTypeVarUnioncast   )ServerSentEventz2.valuereturnc                 C   s   t | tjr| S t| S N)
isinstancedtdatetime_datetime_adaptervalidate_pythonr    r   T/home/ubuntu/.local/lib/python3.10/site-packages/deepgram/core/pydantic_utilities.pyparse_datetime+   s   
r   c                 C   s.   t | tjr
|  S t | tjr| S t| S r   )r   r   r   date_date_adapterr   r   r   r   r   
parse_date0   s
   
r"   ignore)
ModelField)ENCODERS_BY_TYPE)get_args)
get_origin)is_literal_type)is_union)r"   )r   )serialize_datetime)'convert_and_respect_annotation_metadata)	TypeAliasTModel)boundtype_c                 C   s   t | }|t ju rGt | }t|dkrG|d }d}|dd D ]}t|dr0t|dd} nq!|rGt |}|tu rGtt |}||fS dS )z
    Extract the discriminator field name and union variants from a discriminated union type.
    Supports Annotated[Union[...], Field(discriminator=...)] patterns.
    Returns (discriminator, variants) or (None, None) if not a discriminated union.
       r   Nr   discriminator)NN)	typing_extensionsr'   	Annotatedr&   lenhasattrgetattrr   list)r0   originargs
inner_typer2   
annotationinner_originvariantsr   r   r   _get_discriminator_and_variantsQ   s"   




r?   model
field_namec                 C   sh   t rt| di }||}|rtttt  |jS dS t| di }||}|r2tttt  |jS dS )z9Get the type annotation of a field from a Pydantic model.model_fields
__fields__N)	IS_PYDANTIC_V2r7   getr   r   r   r   r<   outer_type_)r@   rA   fields
field_infor   r   r   _get_field_annotationl   s   

rI   r>   r2   discriminator_valuec                 C   s\   | D ])}t |rt|tjsqt||}|r+t|r+t|}|r+|d |kr+|  S qdS )z<Find the union variant that matches the discriminator value.r   N)inspectisclass
issubclasspydantic	BaseModelrI   r(   r&   )r>   r2   rJ   variantdisc_annotationliteral_argsr   r   r   _find_variant_by_discriminator{   s   
rS   c                 C   sV   | t u rdS t| }|tu r)t| }dd |D }t|dkr)|d t u r)dS dS )z(Check if a type is str or Optional[str].Tc                 S   s   g | ]
}|t d ur|qS r   )type).0ar   r   r   
<listcomp>   s    z#_is_string_type.<locals>.<listcomp>r   r   F)strr3   r'   r   r&   r5   )r0   r9   r:   non_none_argsr   r   r   _is_string_type   s   

rZ   sser   c              
   C   s  t | }t|\}}|du s|du rU|d}t|trP|rPzt|}t||W S  tjyO } zt	
d|t|dkrB|dd n| W Y d}~nd}~ww t||S |d}||v r||}t|||}	|	durt|	d}
|
durt|
st|tr|rzt|}t|}||d< t||W S  tjy } zt	
d|t|dkr|dd n| W Y d}~nd}~ww t||S t|tr|rzt|}t||W S  tjy } zt	
d|t|dkr|dd n| W Y d}~nd}~ww t||S )a  
    Parse a ServerSentEvent into the appropriate type.

    Handles two scenarios based on where the discriminator field is located:

    1. Data-level discrimination: The discriminator (e.g., 'type') is inside the 'data' payload.
       The union describes the data content, not the SSE envelope.
       -> Returns: json.loads(data) parsed into the type

       Example: ChatStreamResponse with discriminator='type'
       Input:  ServerSentEvent(event="message", data='{"type": "content-delta", ...}', id="")
       Output: ContentDeltaEvent (parsed from data, SSE envelope stripped)

    2. Event-level discrimination: The discriminator (e.g., 'event') is at the SSE event level.
       The union describes the full SSE event structure.
       -> Returns: SSE envelope with 'data' field JSON-parsed only if the variant expects non-string

       Example: JobStreamResponse with discriminator='event'
       Input:  ServerSentEvent(event="ERROR", data='{"code": "FAILED", ...}', id="123")
       Output: JobStreamResponse_Error with data as ErrorData object

       But for variants where data is str (like STATUS_UPDATE):
       Input:  ServerSentEvent(event="STATUS_UPDATE", data='{"status": "processing"}', id="1")
       Output: JobStreamResponse_StatusUpdate with data as string (not parsed)

    Args:
        sse: The ServerSentEvent object to parse
        type_: The target discriminated union type

    Returns:
        The parsed object of type T

    Note:
        This function is only available in SDK contexts where http_sse module exists.
    Ndataz4Failed to parse SSE data field as JSON: %s, data: %sd   zSFailed to parse SSE data field as JSON for event-level discrimination: %s, data: %szRFailed to parse SSE data field as JSON for data-level discrimination: %s, data: %s)r   r?   rE   r   rX   jsonloadsparse_obj_asJSONDecodeError_loggerwarningr5   rS   rI   rZ   dict)r[   r0   	sse_eventr2   r>   
data_valueparsed_datae
disc_valuematching_variant	data_type
new_objectr   r   r   parse_sse_obj   sh   $









rm   object_c           
      C   s   t | rbt| tjrbd}tr/t| di  D ]\}}t|dd }|d ur-||kr-d} nqn't| di  D ]}t|dd }t|dd }|d urU|d urU||krUd} nq7|rZ|nt	|| dd}nt	|| dd}trut
| }	|	|S t| |S )	NFrB   aliasTrC   namereadrn   r<   	direction)rK   rL   rM   rN   rO   rD   r7   itemsvaluesr+   TypeAdapterr   r`   )
r0   rn   has_pydantic_aliasesrA   rH   ro   fieldrp   dealiased_objectadapterr   r   r   r`      s2   

r`   objfallback_serializerc                 C   s$   t rddlm} || |dS || S )Nr   )to_jsonable_python)fallback)rD   pydantic_corer}   )r{   r|   r}   r   r   r   to_jsonable_with_fallback%  s   r   c                
       s,  e Zd ZU er4ejddZeej ed< ej	dde
dedefdd	Zejd
dddefddZnG dd dZejdddedefdd	Ze
d"ded deee  deddfddZe
d"ded deee  deddf fddZdedef fddZdedeeef f fd d!Z  ZS )#UniversalBaseModelr   )protected_namespacesmodel_configbeforemoder\   r   c                 C      t |ts|S t| di }i }i }| D ]\}}t|ddp |}|||< ||kr-|||< qt| t| }|D ]}	|	|v rQ||	 |vrQtd|	 dq=t| }
t|}| D ]\}}||krw||
v rw||vrw|	|||< q`|S )z
            Accept Python field names in input by rewriting them to their Pydantic aliases,
            while avoiding silent collisions when a key could refer to multiple fields.
            rB   ro   NAmbiguous input key 'X': it is both a field name and an alias. Provide the explicit alias key to disambiguate.
r   r
   r7   rt   setkeysintersection
ValueErrorrd   pop)clsr\   rG   name_to_aliasalias_to_namerp   rH   ro   ambiguous_keyskeyoriginal_keys	rewrittenr   r   r   _coerce_field_names_to_aliases4  s2   

z1UniversalBaseModel._coerce_field_names_to_aliasesplainr^   )r   	when_usedc                 C   s   |   }dd | D }|S )Nc                 S   s*   i | ]\}}|t |tjrt|n|qS r   )r   r   r   r*   )rU   kvr   r   r   
<dictcomp>\  s   * z6UniversalBaseModel.serialize_model.<locals>.<dictcomp>)rd   rt   )self
serializedr\   r   r   r   serialize_modelY  s   z"UniversalBaseModel.serialize_modelc                   @   s   e Zd ZdZejeiZdS )zUniversalBaseModel.ConfigTN)__name__
__module____qualname__smart_unionr   r   r*   json_encodersr   r   r   r   Configa  s    r   Tpreru   c                 C   r   )zS
            Pydantic v1 equivalent of _coerce_field_names_to_aliases.
            rC   ro   Nr   r   r   )r   ru   rG   r   r   rp   rx   ro   r   r   r   r   r   r   r   r   e  s2   

Nr   r.   _fields_setc                 K   s    t || dd}| j|fi |S Nrq   rr   )r+   	constructr   r   ru   ry   r   r   r   model_construct  s   z"UniversalBaseModel.model_constructc                    s:   t || dd}trt j|fi |S t j|fi |S r   )r+   rD   superr   r   r   	__class__r   r   r     s   zUniversalBaseModel.constructkwargsc                    s6   ddd|}t rt jdi |S t jdi |S )NT)by_aliasexclude_unsetr   )rD   r   model_dump_jsonr^   )r   r   kwargs_with_defaultsr   r   r   r^     s   zUniversalBaseModel.jsonc                    s   t r*i |dddd}i |dddd}tt jd
i |t jd
i |}nG| j }t| j}| D ]'\}}||vr_t	|}	|	dusPd|v r_|d s_|
| |	dur_| j
| q8dd|d|}
t jd
i |
}ttttf t|| jdd	S )z
        Override the default dict method to `exclude_unset` by default. This function patches
        `exclude_unset` to work include fields within non-None default values.
        TF)r   r   exclude_none)r   r   r   Nr   )r   r   includewriterr   r   )rD   deep_union_pydantic_dictsr   
model_dump__fields_set__copy_get_model_fieldsr   rt   _get_field_defaultaddrd   r   r   rX   r   r+   )r   r   "kwargs_with_defaults_exclude_unset!kwargs_with_defaults_exclude_none	dict_dumpr   rG   rp   rx   default1kwargs_with_defaults_exclude_unset_include_fieldsr   r   r   rd     sP   




zUniversalBaseModel.dictr   )r   r   r   rD   rN   
ConfigDictr   r   __annotations__model_validatorclassmethodr   r   model_serializerr   r   root_validatorr   r   r   rX   r   r   r^   r   rd   __classcell__r   r   r   r   r   -  s&   
 
#
!*.&
r   sourcedestinationc                 C   sd   g }t | D ])\}}|| }t|tr|t|| qt|tr*|t|| q|| q|S r   )	enumerater   rd   appendr   r8   _union_list_of_pydantic_dicts)r   r   converted_listiitemdestination_valuer   r   r   r     s   

r   c                 C   sZ   |   D ]&\}}||i }t|trt|| qt|tr&t||||< q|||< q|S r   )rt   
setdefaultr   rd   r   r8   r   )r   r   r   r   noder   r   r   r     s   


r   c                   @   s   e Zd ZdS )V2RootModelN)r   r   r   r   r   r   r   r     s    r   UniversalRootModeloc                 C   st   t t}t D ]\}}||  |f7  < qt| tv r$tt|  | S | D ]\}}t| |r7||   S q(d S r   )r   tupleencoders_by_typert   rT   r   )r   encoders_by_class_tuplesr0   encoderclasses_tupler   r   r   encode_by_type   s   
r   localnsc                 K   s(   t r
| jdd d S | jdi | d S )NF)raise_errorsr   )rD   model_rebuildupdate_forward_refs)r@   r   r   r   r   r     s   r   .Fr   c                    s   dt dt f fdd}|S )Nfuncr   c                    s0   t rtttjdd| S tttj d| S )Nr   r   r   )rD   r   AnyCallablerN   r   r   r   r   r   r   	decorator  s   z+universal_root_validator.<locals>.decoratorr   )r   r   r   r   r   universal_root_validator  s   r   c                    s   dt dt f fdd}|S )Nr   r   c                    s<   t rtttj rdndd| S tttj d| S )Nr   afterr   r   )rD   r   r   rN   field_validator	validatorr   rA   r   r   r   r   %  s    z,universal_field_validator.<locals>.decoratorr   )rA   r   r   r   r   r   universal_field_validator$  s   r   c                 C   s,   t rttttf | jS ttttf | jS r   )rD   r   r
   rX   PydanticFieldrB   rC   )r@   r   r   r   r   0  s   r   rx   c                 C   s@   z|   }W n   | j}Y trddlm} ||krd S |S |S )Nr   )PydanticUndefined)get_defaultr   rD   r   r   )rx   r   r   r   r   r   r   6  s   r   )F)\r   r   rK   r^   loggingcollectionsr   dataclassesr   typingr   r   r   r   r   r	   r
   r   r   r   r   r   r   r   rN   r3   	getLoggerr   rb   http_sse._modelsr   VERSION
startswithrD   warningsrv   r   r    r!   r   r"   catch_warningssimplefilterUserWarningpydantic.v1.fieldsr$   pydantic.v1.jsonr%   r   pydantic.v1.typingr&   r'   r(   r)   pydantic.datetime_parsepydantic.fieldspydantic.jsonpydantic.typingdatetime_utilsr*   serializationr+   r,   r-   rO   r.   rX   r?   rI   rS   boolrZ   rm   r`   r   r   r   r   	RootModelr   r   r   r   r   r   r   r   rG   	FieldInfor   r   r   r   r   r   r   <module>   s   
@

	."


c % "-.
"	