
    $j'                        d 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
mZ e
rddlmZ edgeeeef         dz           f         Zedgeeeef         dz           f         Z G d	 d
          Z G d de          Z G d de          ZddZdS )a  Composable lifespans for FastMCP servers.

This module provides a `@lifespan` decorator for creating composable server lifespans
that can be combined using the `|` operator.

Example:
    ```python
    from fastmcp import FastMCP
    from fastmcp.server.lifespan import lifespan

    @lifespan
    async def db_lifespan(server):
        conn = await connect_db()
        yield {"db": conn}
        await conn.close()

    @lifespan
    async def cache_lifespan(server):
        cache = await connect_cache()
        yield {"cache": cache}
        await cache.close()

    mcp = FastMCP("server", lifespan=db_lifespan | cache_lifespan)
    ```

To compose with existing `@asynccontextmanager` lifespans, wrap them explicitly:

    ```python
    from contextlib import asynccontextmanager
    from fastmcp.server.lifespan import lifespan, ContextManagerLifespan

    @asynccontextmanager
    async def legacy_lifespan(server):
        yield {"legacy": True}

    @lifespan
    async def new_lifespan(server):
        yield {"new": True}

    # Wrap the legacy lifespan explicitly
    combined = ContextManagerLifespan(legacy_lifespan) | new_lifespan
    ```
    )annotations)AsyncIteratorCallable)AbstractAsyncContextManagerasynccontextmanager)TYPE_CHECKINGAny)FastMCPFastMCP[Any]Nc                  :    e Zd ZdZddZedd
            ZddZdS )LifespanzComposable lifespan wrapper.

    Wraps an async generator function and enables composition via the `|` operator.
    The wrapped function should yield a dict that becomes part of the lifespan context.
    fn
LifespanFnreturnNonec                    || _         dS )zInitialize a Lifespan wrapper.

        Args:
            fn: An async generator function that takes a FastMCP server and yields
                a dict for the lifespan context.
        N_fnselfr   s     _/home/rurouni/.hermes/hermes-agent/venv/lib/python3.11/site-packages/fastmcp/server/lifespan.py__init__zLifespan.__init__D   s         serverr   AsyncIterator[dict[str, Any]]c                  K    t          | j                  |          4 d{V }||ni W V  ddd          d{V  dS # 1 d{V swxY w Y   dS zExecute the lifespan as an async context manager.

        Args:
            server: The FastMCP server instance.

        Yields:
            The lifespan context dict.
        N)r   r   r   r   results      r   __call__zLifespan.__call__M   s       1&tx0088 	7 	7 	7 	7 	7 	7 	7F".&&B6666	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7s   
A
AAotherComposedLifespanc                    t          |t                    s%t          dt          |          j         d          t          | |          S )a  Compose with another lifespan using the | operator.

        Args:
            other: Another Lifespan instance.

        Returns:
            A ComposedLifespan that runs both lifespans.

        Raises:
            TypeError: If other is not a Lifespan instance.
        zCannot compose Lifespan with z@. Use @lifespan decorator or wrap with ContextManagerLifespan().)
isinstancer   	TypeErrortype__name__r"   )r   r!   s     r   __or__zLifespan.__or__Z   s]     %** 	RU0D R R R    e,,,r   N)r   r   r   r   r   r   r   r   )r!   r   r   r"   )r'   
__module____qualname____doc__r   r   r    r(    r   r   r   r   =   sg             
7 
7 
7 
7- - - - - -r   r   c                  >    e Zd ZU dZded<   ddZedd            ZdS )ContextManagerLifespanzLifespan wrapper for already-wrapped context manager functions.

    Use this for functions already decorated with @asynccontextmanager.
    LifespanContextManagerFnr   r   r   r   c                    || _         dS )z3Initialize with a context manager factory function.Nr   r   s     r   r   zContextManagerLifespan.__init__v   s    r   r   r   r   c                  K   |                      |          4 d{V }||ni W V  ddd          d{V  dS # 1 d{V swxY w Y   dS r   r   r   s      r   r    zContextManagerLifespan.__call__z   s       88F## 	7 	7 	7 	7 	7 	7 	7v".&&B6666	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7s   
;
AAN)r   r0   r   r   r)   )r'   r*   r+   r,   __annotations__r   r   r    r-   r   r   r/   r/   n   sc          
 "!!!    7 7 7 7 7 7r   r/   c                  2    e Zd ZdZddZedd            ZdS )r"   zTwo lifespans composed together.

    Enters the left lifespan first, then the right. Exits in reverse order.
    Results are shallow-merged into a single dict.
    leftr   rightr   r   c                "    || _         || _        dS )zInitialize a composed lifespan.

        Args:
            left: The first lifespan to enter.
            right: The second lifespan to enter.
        N_left_right)r   r5   r6   s      r   r   zComposedLifespan.__init__   s     
r   r   r   r   c                 K   |                      |          4 d{V 	 }|                     |          4 d{V 	 }i ||W V  ddd          d{V  n# 1 d{V swxY w Y   ddd          d{V  dS # 1 d{V swxY w Y   dS )zExecute both lifespans, merging their results.

        Args:
            server: The FastMCP server instance.

        Yields:
            The merged lifespan context dict from both lifespans.
        Nr8   )r   r   left_resultright_results       r   r    zComposedLifespan.__call__   s      JJv	2 	2 	2 	2 	2 	2 	2 	2"-KK	2 	2 	2 	2 	2 	2 	2 	2#/1[1L11111		2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2 	2s4   A<
AA<
A"	"A<%A"	&A<<
B	BN)r5   r   r6   r   r   r   r)   )r'   r*   r+   r,   r   r   r    r-   r   r   r"   r"      sS         	 	 	 	 2 2 2 2 2 2r   r"   r   r   r   c                     t          |           S )a  Decorator to create a composable lifespan.

    Use this decorator on an async generator function to make it composable
    with other lifespans using the `|` operator.

    Example:
        ```python
        @lifespan
        async def my_lifespan(server):
            # Setup
            resource = await create_resource()
            yield {"resource": resource}
            # Teardown
            await resource.close()

        mcp = FastMCP("server", lifespan=my_lifespan | other_lifespan)
        ```

    Args:
        fn: An async generator function that takes a FastMCP server and yields
            a dict for the lifespan context.

    Returns:
        A composable Lifespan wrapper.
    )r   )r   s    r   lifespanr?      s    4 B<<r   )r   r   r   r   )r,   
__future__r   collections.abcr   r   
contextlibr   r   typingr   r	   fastmcp.server.serverr
   dictstrr   r0   r   r/   r"   r?   r-   r   r   <module>rG      sq  * *X # " " " " " 3 3 3 3 3 3 3 3 G G G G G G G G % % % % % % % % .------ ~&d38nt6K(LLM
#1$sCx.42GHH 
.- .- .- .- .- .- .- .-b7 7 7 7 7X 7 7 76 2  2  2  2  2x  2  2  2F     r   