
    Ki-                         d dl Z d dlmZmZ d dlmZ d dlmZmZm	Z	m
Z
mZ d dlmZmZ d dlmZ d dlmZ d dlmZ d d	lmZ  e j.                  e      Z e
d
      Z G d dee   e      Zy)    N)ABCabstractmethod)Sequence)AnyGenericSupportsFloatTypeVaroverload)DeserializationErrorSerializationError)ValidationError)TypeAdapter)PydanticSerializationError)AsyncKeyValueTc                   &   e Zd ZU dZeed<   eed<   ee   ed<   e	dz  ed<   eed<   e
de	fd	       Zd
ee	ef   dedz  fdZd
edee	ef   fdZeddde	de	dz  dedefd       Zedddde	de	dz  dddedz  fd       Zdddde	de	dz  dedz  dedz  fdZedddee	   de	dz  dedee   fd       Zeddddee	   de	dz  dddeedz     fd       Zddddee	   de	dz  dedz  dee   eedz     z  fdZdddde	d
ede	dz  dedz  ddf
dZddddee	   dee   de	dz  dedz  ddf
dZddde	de	dz  defdZdddee	   de	dz  defdZddde	de	dz  deedz  edz  f   fd Zdddee	   de	dz  deeedz  edz  f      fd!Zy)"BasePydanticAdapteraB  Base adapter using Pydantic TypeAdapter for validation and serialization.

    This abstract base class provides shared functionality for adapters that use
    Pydantic's TypeAdapter for validation and serialization. Concrete subclasses
    must implement _get_model_type_name() to provide appropriate error messages.
    
_key_value_is_list_model_type_adapterN_default_collection_raise_on_validation_errorreturnc                      y)zReturn the model type name for error messages.

        Returns:
            A string describing the model type (e.g., "Pydantic model", "dataclass").
        N )selfs    p/home/jay/workspace/scripts/.codegraph-venv/lib/python3.12/site-packages/key_value/aio/adapters/pydantic/base.py_get_model_type_namez(BasePydanticAdapter._get_model_type_name    s     	    valuec           	         	 | j                   rd|vrd| j                  rd| j                          d}t        |      t        j                  d| j                         | j                         ddd       y	| j                  j                  |d         S | j                  j                  |      S # t        $ r}| j                  r4|j                  d
      }d| j                          d| }t        |      ||j                  d
      }t        j                  d| j                         | j                         t        |      |dd       Y d	}~y	d	}~ww xY w)a  Validate and deserialize a dict into the configured model type.

        This method handles both single models and list models. For list models, it expects the value
        to contain an "items" key with the list data, following the convention used by `_serialize_model`.
        If validation fails and `raise_on_validation_error` is False, returns None instead of raising.

        Args:
            value: The dict to validate and convert to a model.

        Returns:
            The validated model instance, or None if validation fails and errors are suppressed.

        Raises:
            DeserializationError: If validation fails and `raise_on_validation_error` is True.
        itemsInvalid z! payload: missing 'items' wrapperz#Missing 'items' wrapper for list %szmissing 'items' wrapper)
model_typeerrorF)extraexc_infoN)include_input: zValidation failed for %s)r$   error_counterrorsT)r   r   r   r   loggerr%   r   validate_pythonr   r+   len)r   r    msgedetailserror_detailss         r   _validate_modelz#BasePydanticAdapter._validate_model)   sa    '	""%'66 ()B)B)D(EEfg2377 LL=113*.*C*C*E%> "' !   ))99%.II%%55e<< 	..(((7 !:!:!< =RyI*3/Q6 HH5H9MLL*))+"&";";"=#&}#5+
   	 %	s%   A3B/ 6B/ B/ /	E8BEEc                     	 | j                   rd| j                  j                  |d      iS | j                  j                  |d      S # t        $ r'}d| j	                          d| }t        |      |d}~ww xY w)av  Serialize a model to a dict for storage.

        This method handles both single models and list models. For list models, it wraps the serialized
        list in a dict with an "items" key (e.g., {"items": [...]}) to ensure consistent dict-based storage
        format across all value types. This wrapping convention is expected by `_validate_model` during
        deserialization.

        Args:
            value: The model instance to serialize.

        Returns:
            A dict representation of the model suitable for storage.

        Raises:
            SerializationError: If the model cannot be serialized.
        r"   json)moder#   r)   N)r   r   dump_pythonr   r   r   )r   r    r0   r/   s       r   _serialize_modelz$BasePydanticAdapter._serialize_modelb   s    "	1""!3!3!?!?F!?!STT%%11%f1EE) 	1T6689A3?C$S)q0	1s   *A
 A
 
	A:"A55A:)
collectionkeyr9   defaultc                   K   y wNr   r   r:   r9   r;   s       r   getzBasePydanticAdapter.get|   s	     VY   )r9   r;   c                   K   y wr=   r   r>   s       r   r?   zBasePydanticAdapter.get   s	     gjr@   c                   K   |xs | j                   }| j                  j                  ||       d{   }|| j                  |      }||S |S 7 w)a<  Get and validate a model by key.

        Args:
            key: The key to retrieve.
            collection: The collection to use. If not provided, uses the default collection.
            default: The default value to return if the key doesn't exist or validation fails.

        Returns:
            The parsed model instance if found and valid, or the default value if key doesn't exist or validation fails.

        Raises:
            DeserializationError: If the stored data cannot be validated as the model and the adapter is configured to
            raise on validation error.

        Note:
            When raise_on_validation_error=False and validation fails, returns the default value (which may be None).
            When raise_on_validation_error=True and validation fails, raises DeserializationError.
        r:   r9   Nr    )r   r   r?   r3   )r   r:   r9   r;   r    	validateds         r   r?   zBasePydanticAdapter.get   sd     &  ;4#;#;
oo))cj)II,,5,9I$   Js   1AAAkeysc                   K   y wr=   r   r   rF   r9   r;   s       r   get_manyzBasePydanticAdapter.get_many   s	     lor@   c                   K   y wr=   r   rH   s       r   rI   zBasePydanticAdapter.get_many   s      ~Ar@   c                  K   |xs | j                   }| j                  j                  ||       d{   }g }|D ]=  }||j                  |       | j	                  |      }|j                  ||n|       ? |S 7 Jw)a  Batch get and validate models by keys, preserving order.

        Args:
            keys: The list of keys to retrieve.
            collection: The collection to use. If not provided, uses the default collection.
            default: The default value to return for keys that don't exist or fail validation.

        Returns:
            A list of parsed model instances, with default values for missing keys or validation failures.

        Raises:
            DeserializationError: If the stored data cannot be validated as the model and the adapter is configured to
            raise on validation error.

        Note:
            When raise_on_validation_error=False and validation fails for any key, that position in the returned list
            will contain the default value (which may be None). The method returns a complete list matching the order
            and length of the input keys, with defaults substituted for missing or invalid entries.
        rF   r9   NrD   )r   r   rI   appendr3   )r   rF   r9   r;   valuesresultr    rE   s           r   rI   zBasePydanticAdapter.get_many   s     (  ;4#;#;
48OO4L4LRVcm4L4n.n!# 	OE}g& 00u0=	9+@igN	O  /os   1B A>AB )r9   ttlrP   c                   K   |xs | j                   }| j                  |      }| j                  j                  ||||       d{    y7 w)zoSerialize and store a model.

        Propagates SerializationError if the model cannot be serialized.
        rD   )r:   r    r9   rP   N)r   r8   r   put)r   r:   r    r9   rP   
value_dicts         r   rR   zBasePydanticAdapter.put   sM     
  ;4#;#;
%)%:%:%:%G
oo!!c
X[!\\\s   AAAArN   c                   K   |xs | j                   }|D cg c]  }| j                  |       }}| j                  j                  ||||       d{    yc c}w 7 
w)zJSerialize and store multiple models, preserving order alignment with keys.rD   )rF   rN   r9   rP   N)r   r8   r   put_many)r   rF   rN   r9   rP   r    value_dictss          r   rU   zBasePydanticAdapter.put_many   sf       ;4#;#;
]c,dTYT-B-B-B-O,d,doo&&DQ[ad&eee -ees   A!A$A!AA!c                x   K   |xs | j                   }| j                  j                  ||       d{   S 7 w)zGDelete a model by key. Returns True if a value was deleted, else False.rC   N)r   r   delete)r   r:   r9   s      r   rX   zBasePydanticAdapter.delete   s6     ;4#;#;
__++
+KKKK   1:8:c                x   K   |xs | j                   }| j                  j                  ||       d{   S 7 w)zDDelete multiple models by key. Returns the count of deleted entries.rL   N)r   r   delete_many)r   rF   r9   s      r   r[   zBasePydanticAdapter.delete_many   s6     ;4#;#;
__00dz0RRRRrY   c                   K   |xs | j                   }| j                  j                  ||       d{   \  }}|y| j                  |      }|||fS y7 #w)a,  Get a model and its TTL seconds if present.

        Args:
            key: The key to retrieve.
            collection: The collection to use. If not provided, uses the default collection.

        Returns:
            A tuple of (model, ttl_seconds). Returns (None, None) if the key is missing or validation fails.

        Note:
            When validation fails and raise_on_validation_error=False, returns (None, None) even if TTL data exists.
            When validation fails and raise_on_validation_error=True, raises DeserializationError.
        rC   N)NNrD   )r   r   rP   r3   )r   r:   r9   entryttl_infovalidated_models         r   rP   zBasePydanticAdapter.ttl   so       ;4#;#;

 !% 3 3
 3 SSx=..U.;&#X.. Ts   1AA$Ac                   K   |xs | j                   }| j                  j                  ||       d{   }|D cg c]  \  }}|| j                  |      nd|f c}}S 7 /c c}}w w)zKBatch get models with TTLs. Each element is (model|None, ttl_seconds|None).rL   NrD   )r   r   ttl_manyr3   )r   rF   r9   entriesr]   r^   s         r   ra   zBasePydanticAdapter.ttl_many  s}     ;4#;#;
JN//JbJbhl  zDJb  KE  EEt{|apafhpe6G%%E%2TS[\|| EE|s    1A+A#	A+"A%A+%A+)__name__
__module____qualname____doc__r   __annotations__boolr   r   strr   r   dictr   r3   r8   r
   r?   r   listrI   r   rR   rU   rX   intr[   tuplefloatrP   ra   r   r   r   r   r      st    q>!t# $$c  7T#s(^ 7D 7r1a 1DcN 14 >BYSYtYQYSTY Y>BTXjSjtjTj]^ae]ej j>BX\ S t QQUX abeiai : NRo8C=oto]^ocghicjo oNRdh  A8C=  At  A]a  Amqrsvzrzm{  A  ANRhl 8C= t ]^ae]e quvwqx{  AB  EI  AI  |J  rJ B IMjn 	]S 	] 	]3: 	]S`cgSg 	]sw 	] UYvzfSMf+3A;fGJTzf_los_sf	f BF L LC$J L$ L RV Shsm SC$J SZ] S ?C S t uQQUXW\_cWcMcGd < OS }8C= }t }W[\abcfjbjlqtxlxbx\yWz }r   r   )loggingabcr   r   collections.abcr   typingr   r   r   r	   r
   key_value.shared.errorsr   r   pydanticr   pydantic.type_adapterr   pydantic_corer   !key_value.aio.protocols.key_valuer   	getLoggerrc   r,   r   r   r   r   r   <module>ry      sT     # $ A A L $ - 4 ;			8	$CLy}'!*c y}r   