o
    i                     @  s   d dl mZ d dlZd dlmZ d dl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Zd dlZd	d
lmZmZ d	dlmZmZ ddlmZmZmZmZmZm Z m!Z!mZm"Z" e
G dd dee!ef Z#dddZ$dS )    )annotationsN)AsyncIterator)AsyncExitStackasynccontextmanager)	dataclassfield)Path)perf_counter)Any   )_utils
exceptions)BaseNodeEnd   )	BaseStatePersistenceEndSnapshotNodeSnapshotRunEndTSnapshotSnapshotStatusStateTr    build_snapshot_list_type_adapterc                   @  s   e Zd ZU dZded< 	 eddddZded< dDddZdEddZdFddZ	e
dGddZdHddZdId d!ZdJd&d'ZdKd)d*ZdKd+d,ZdLd1d2ZdMd4d5ZdMd6d7Zd8d9dNd=d>Ze
d?d@dOdBdCZdS )PFileStatePersistencezFFile based state persistence that hold graph run state in a JSON file.r   	json_fileNF)defaultinitreprz<pydantic.TypeAdapter[list[Snapshot[StateT, RunEndT]]] | None_snapshots_type_adapterstater   	next_nodeBaseNode[StateT, Any, RunEndT]returnNonec                      |  t||dI d H  d S )Nr   node)_append_saver   )selfr   r     r)   e/var/www/html/karishye-ai-python/venv/lib/python3.10/site-packages/pydantic_graph/persistence/file.pysnapshot_node6      z"FileStatePersistence.snapshot_nodesnapshot_idstrc              	     s   |   4 I d H 7 |  I d H }t fdd|D s5| jt||dddI d H  W d   I d H  d S W d   I d H  d S 1 I d H sFw   Y  d S )Nc                 3  s    | ]}|j  kV  qd S Nid.0sr-   r)   r*   	<genexpr>>   s    z<FileStatePersistence.snapshot_node_if_new.<locals>.<genexpr>r%   Flock)_lockload_allanyr'   r   )r(   r-   r   r    	snapshotsr)   r5   r*   snapshot_node_if_new9   s   .z)FileStatePersistence.snapshot_node_if_newendEnd[RunEndT]c                   r$   )N)r   result)r'   r   )r(   r   r>   r)   r)   r*   snapshot_endA   r,   z!FileStatePersistence.snapshot_endAsyncIterator[None]c                  s  |   4 I d H T |  I d H }zt fdd|D }W n ty2 } ztd |d }~ww t|ts<J dtj	|j
 d|_
t |_| |I d H  W d   I d H  n1 I d H scw   Y  t }zd V  W n7 ty   t | }|   4 I d H  t| j |dI d H  W d   I d H   1 I d H sw   Y   w t | |_|   4 I d H  t| j |jdI d H  W d   I d H  d S 1 I d H sw   Y  d S )Nc                 3      | ]
}|j  kr|V  qd S r/   r0   r2   r5   r)   r*   r6   I       z2FileStatePersistence.record_run.<locals>.<genexpr>zNo snapshot found with id=!Only NodeSnapshot can be recordedrunningerrorsuccess)r9   r:   nextStopIterationLookupError
isinstancer   r   GraphNodeStatusErrorcheckstatusr   now_utcstart_ts_saver	   	Exception_graph_utilsrun_in_executor_after_run_syncduration)r(   r-   r<   snapshotestartrW   r)   r5   r*   
record_runD   s>   
(

.zFileStatePersistence.record_run$NodeSnapshot[StateT, RunEndT] | Nonec              	     s   |   4 I d H 6 |  I d H }tdd |D d  }r4d|_| |I d H  |W  d   I d H  S W d   I d H  d S 1 I d H sEw   Y  d S )Nc                 s  s(    | ]}t |tr|jd kr|V  qdS )createdN)rL   r   rO   r2   r)   r)   r*   r6   c   s   & z1FileStatePersistence.load_next.<locals>.<genexpr>pending)r9   r:   rI   rO   rR   )r(   r<   rX   r)   r)   r*   	load_next`   s   .zFileStatePersistence.load_nextboolc                 C  s
   | j du S )zWhether types need to be set.N)r   r(   r)   r)   r*   should_set_typesh   s   
z%FileStatePersistence.should_set_types
state_typetype[StateT]run_end_typetype[RunEndT]c                 C  s   t ||| _d S r/   )r   r   )r(   rc   re   r)   r)   r*   	set_typesl   s   zFileStatePersistence.set_typeslist[Snapshot[StateT, RunEndT]]c                   s   t | jI d H S r/   )rT   rU   
_load_syncra   r)   r)   r*   r:   o   s   zFileStatePersistence.load_allc                 C  sD   | j d us	J dz| j }W n ty   g  Y S w | j |S N"snapshots type adapter must be set)r   r   
read_bytesFileNotFoundErrorvalidate_json)r(   contentr)   r)   r*   ri   r   s   zFileStatePersistence._load_syncrW   floatrO   r   c                   sJ   |   }t fdd|D }t|tsJ d||_||_| | d S )Nc                 3  rC   r/   r0   r2   r5   r)   r*   r6   }   rD   z7FileStatePersistence._after_run_sync.<locals>.<genexpr>rE   )ri   rI   rL   r   rW   rO   
_save_sync)r(   r-   rW   rO   r<   rX   r)   r5   r*   rV   {   s   z$FileStatePersistence._after_run_syncr<   c                   s   t | j|I d H  d S r/   )rT   rU   rq   r(   r<   r)   r)   r*   rR      s   zFileStatePersistence._savec                 C  s.   | j d us	J d| j| j j|dd d S )Nrk   r   )indent)r   r   write_bytes	dump_jsonrr   r)   r)   r*   rq      s   zFileStatePersistence._save_syncTr7   rX   Snapshot[StateT, RunEndT]r8   c             	     s   | j d us
J dt 4 I d H ,}|r||  I d H  |  I d H }|| | |I d H  W d   I d H  d S 1 I d H sCw   Y  d S rj   )r   r   enter_async_contextr9   r:   appendrR   )r(   rX   r8   stackr<   r)   r)   r*   r'      s   
.z!FileStatePersistence._append_saveg      ?)timeoutrz   c             
   C s   | j j| j j d }t  }t|  t||I dH s0t	dI dH  t||I dH r W d   n1 s:w   Y  zdV  W t
j|jddI dH  dS t
j|jddI dH  w )zLock a file by checking and writing a `.pydantic-graph-persistence-lock` to it.

        Args:
            timeout: how long to wait for the lock

        Returns: an async context manager that holds the lock
        z .pydantic-graph-persistence-lockNg{Gz?T)
missing_ok)r   parentnamesecretstoken_urlsafeencodeanyio
fail_after_file_append_checksleeprT   rU   unlink)r(   rz   	lock_filelock_idr)   r)   r*   r9      s   	2zFileStatePersistence._lock)r   r   r    r!   r"   r#   )r-   r.   r   r   r    r!   r"   r#   )r   r   r>   r?   r"   r#   )r-   r.   r"   rB   )r"   r\   )r"   r`   )rc   rd   re   rf   r"   r#   )r"   rh   )r-   r.   rW   rp   rO   r   r"   r#   )r<   rh   r"   r#   )rX   rv   r8   r`   r"   r#   )rz   rp   r"   rB   )__name__
__module____qualname____doc____annotations__r   r   r+   r=   rA   r   r[   r_   rb   rg   r:   ri   rV   rR   rq   r'   r9   r)   r)   r)   r*   r      s.   
 








	

	r   filer   ro   bytesr"   r`   c              	     s   t | }| I d H rdS t j|ddI d H 4 I d H }||d I d H  W d   I d H  n1 I d H s8w   Y  | I d H |S )NFab)mode   
)r   r   exists	open_filewriterl   
startswith)r   ro   pathfr)   r)   r*   r      s   
(r   )r   r   ro   r   r"   r`   )%
__future__r   _annotationsr~   collections.abcr   
contextlibr   r   dataclassesr   r   pathlibr   timer	   typingr
   r   pydantic r   rT   r   nodesr   r   r   r   r   r   r   r   r   r   r   r   r)   r)   r)   r*   <module>   s"    , 