
    i'                        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y)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                  2    e Zd ZdZddZedd       ZddZy)	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.
    c                    || _         y)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selffns     g/Users/bowang/.openclaw/workspace/ChatDev/.venv/lib/python3.12/site-packages/fastmcp/server/lifespan.py__init__zLifespan.__init__D   s         c                  K    t        | j                        |      4 d{   }||ni  ddd      d{    y7 7 # 1 d{  7  sw Y   yxY wwzExecute the lifespan as an async context manager.

        Args:
            server: The FastMCP server instance.

        Yields:
            The lifespan context dict.
        N)r   r   r   serverresults      r   __call__zLifespan.__call__M   sG      1&txx088F".&B6 9888888sA    AAA
AAAAAAAAAc                ~    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__ComposedLifespan)r   others     r   __or__zLifespan.__or__Z   sI     %*/U0D0D/E FQ R   e,,r   N)r   
LifespanFnreturnNoner   r   r&   zAsyncIterator[dict[str, Any]])r#   r   r&   r"   )r!   
__module____qualname____doc__r   r   r   r$    r   r   r   r   =   s%     
7 
7-r   r   c                  6    e Zd ZU dZded<   ddZedd       Zy)	ContextManagerLifespanzLifespan wrapper for already-wrapped context manager functions.

    Use this for functions already decorated with @asynccontextmanager.
    LifespanContextManagerFnr   c                    || _         y)z3Initialize with a context manager factory function.Nr   r   s     r   r   zContextManagerLifespan.__init__v   s	    r   c                  K   | j                  |      4 d{   }||ni  ddd      d{    y7 7 # 1 d{  7  sw Y   yxY wwr   r   r   s      r   r   zContextManagerLifespan.__call__z   s?      88F##v".&B6 $######s<   A7A
;A9AAAAA	AN)r   r/   r&   r'   r(   )r!   r)   r*   r+   __annotations__r   r   r   r,   r   r   r.   r.   n   s(    
 
"! 7 7r   r.   c                  *    e Zd ZdZddZedd       Zy)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.
    c                     || _         || _        y)zInitialize a composed lifespan.

        Args:
            left: The first lifespan to enter.
            right: The second lifespan to enter.
        N_left_right)r   leftrights      r   r   zComposedLifespan.__init__   s     
r   c               *  K   | j                  |      4 d{   }| j                  |      4 d{   }i || ddd      d{    ddd      d{    y7 H7 07 # 1 d{  7  sw Y   )xY w7  # 1 d{  7  sw Y   yxY ww)zExecute both lifespans, merging their results.

        Args:
            server: The FastMCP server instance.

        Yields:
            The merged lifespan context dict from both lifespans.
        Nr5   )r   r   left_resultright_results       r   r   zComposedLifespan.__call__   so      JJv+KK<1[1L11    s   BA!BA>A#A>
A' A>A%A>BA<B#A>%A>'A9	-A0.A9	5A><B>BBBBN)r8   r   r9   r   r&   r'   r(   )r!   r)   r*   r+   r   r   r   r,   r   r   r"   r"      s     	 2 2r   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%   r/   r   r.   r"   r>   r,   r   r   <module>rF      s   *X # 3 G %- ~&d38nt6K(LLM
#1$sCx.42GHH 
.- .-b7X 76 2x  2Fr   