
    "<i                        d Z ddlmZ ddlmZ ddlmZ ddlmZ ddl	m
Z
 ddlmZmZ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e          Z G d de          Z G d de          Z G d de          ZdS )ay  EventStore implementation backed by AsyncKeyValue.

This module provides an EventStore implementation that enables SSE polling/resumability
for Streamable HTTP transports. Events are stored using the key_value package's
AsyncKeyValue protocol, allowing users to configure any compatible backend
(in-memory, Redis, etc.) following the same pattern as ResponseCachingMiddleware.
    )annotations)uuid4)PydanticAdapter)AsyncKeyValue)MemoryStore)EventCallbackEventIdEventMessageStreamId)
EventStore)JSONRPCMessage)	BaseModel)
get_loggerc                  2    e Zd ZU dZded<   ded<   ded<   dS )
EventEntryzStored event entry.strevent_id	stream_idzdict | NonemessageN__name__
__module____qualname____doc____annotations__     /Users/kimhansen/Desktop/03 Workspace/ceo-agents/chl-effectiveness/mcp-servers/whoop/.venv/lib/python3.11/site-packages/fastmcp/server/event_store.pyr   r      s6         MMMNNNr   r   c                      e Zd ZU dZded<   dS )StreamEventListzList of event IDs for a stream.z	list[str]	event_idsNr   r   r   r   r    r    "   s$         ))r   r    c                  2    e Zd ZdZ	 	 	 dddZddZddZdS )r   a-  EventStore implementation backed by AsyncKeyValue.

    Enables SSE polling/resumability by storing events that can be replayed
    when clients reconnect. Works with any AsyncKeyValue backend (memory, Redis, etc.)
    following the same pattern as ResponseCachingMiddleware and OAuthProxy.

    Example:
        ```python
        from fastmcp import FastMCP
        from fastmcp.server.event_store import EventStore

        # Default in-memory storage
        event_store = EventStore()

        # Or with a custom backend
        from key_value.aio.stores.redis import RedisStore
        redis_backend = RedisStore(url="redis://localhost")
        event_store = EventStore(storage=redis_backend)

        mcp = FastMCP("MyServer")
        app = mcp.http_app(event_store=event_store, retry_interval=2000)
        ```

    Args:
        storage: AsyncKeyValue backend. Defaults to MemoryStore.
        max_events_per_stream: Maximum events to retain per stream. Default 100.
        ttl: Event TTL in seconds. Default 3600 (1 hour). Set to None for no expiration.
    Nd     storageAsyncKeyValue | Nonemax_events_per_streamintttl
int | Nonec                    |pt                      | _        || _        || _        t	          t
                   | j        t
          d          | _        t	          t                   | j        t          d          | _        d S )Nfastmcp_events)	key_valuepydantic_modeldefault_collectionfastmcp_streams)	r   _storage_max_events_per_stream_ttlr   r   _event_storer    _stream_store)selfr%   r'   r)   s       r   __init__zEventStore.__init__F   s     (/'?+--&;#	 :I9Tm%/:
 :
 :

 @O@
 m*0@
 @
 @
r   r   r   r   JSONRPCMessage | Nonereturnr	   c                  K   t          t                                }t          |||r|                    d          nd          }| j                            ||| j                   d{V  | j                            |           d{V }|r|j	        ng }|
                    |           t          |          | j        k    rD|d| j                  D ]#}| j                            |           d{V  $|| j         d         }| j                            |t          |          | j                   d{V  |S )a  Store an event and return its ID.

        Args:
            stream_id: ID of the stream the event belongs to
            message: The JSON-RPC message to store, or None for priming events

        Returns:
            The generated event ID for the stored event
        json)modeN)r   r   r   )keyvaluer)   r=   )r!   )r   r   r   
model_dumpr4   putr3   r5   getr!   appendlenr2   deleter    )r6   r   r   r   entrystream_datar!   old_ids           r   store_eventzEventStore.store_event^   s      uww<< 7>HG&&F&333D
 
 

 ##49#MMMMMMMMM !.22y2AAAAAAAA-8@K))b	""" y>>D777#$Bt'B&B$BC ; ;'..6.::::::::::!4#>">"@"@AI $$!I666	 % 
 
 	
 	
 	
 	
 	
 	
 	
 r   last_event_idsend_callbackr   StreamId | Nonec                  K   | j                             |           d{V }|s t                              d| d           dS |j        }| j                            |           d{V }|s t                              d| d           dS |j        }	 |                    |          dz   }n1# t          $ r$ t                              d| d|            Y dS w xY w||d         D ]i}| j                             |           d{V }	|	rD|	j	        r=t          j        |	j	                  }
 |t          |
|	j                             d{V  j|S )aO  Replay events that occurred after the specified event ID.

        Args:
            last_event_id: The ID of the last event the client received
            send_callback: A callback function to send events to the client

        Returns:
            The stream ID of the replayed events, or None if the event ID was not found
        r?   Nz	Event ID z not found in storezStream    z not found in stream )r4   rB   loggerwarningr   r5   r!   index
ValueErrorr   r   model_validater
   r   )r6   rJ   rK   rF   r   rG   r!   	start_idxr   eventmsgs              r   replay_events_afterzEventStore.replay_events_after   s      '+++>>>>>>>> 	NNI}IIIJJJ4O	 .22y2AAAAAAAA 	NNCYCCCDDD4)		!66:II 	 	 	NNV}VV9VVWWW44	
 ")**- 	G 	GH+//H/========E G G$3EMBB#mLen$E$EFFFFFFFFFs   B1 1*CC)Nr#   r$   )r%   r&   r'   r(   r)   r*   )r   r   r   r8   r9   r	   )rJ   r	   rK   r   r9   rL   )r   r   r   r   r7   rI   rW   r   r   r   r   r   (   sk         > )-%(	
 
 
 
 
0' ' ' 'R* * * * * *r   r   N)r   
__future__r   uuidr   key_value.aio.adapters.pydanticr   key_value.aio.protocolsr   key_value.aio.stores.memoryr   mcp.server.streamable_httpr   r	   r
   r   r   SDKEventStore	mcp.typesr   pydanticr   fastmcp.utilities.loggingr   r   rO   r   r    r   r   r   <module>rb      sx    # " " " " "       ; ; ; ; ; ; 1 1 1 1 1 1 3 3 3 3 3 3 U U U U U U U U U U U U B B B B B B $ $ $ $ $ $       0 0 0 0 0 0	H		           i   I I I I I I I I I Ir   