mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-22 21:44:18 +02:00
Additional MCP and test clean-up
This commit is contained in:
parent
44b2b17844
commit
22d3e1452c
3 changed files with 29 additions and 29 deletions
|
|
@ -7,29 +7,6 @@ from fastmcp.mcp_config import (
|
|||
)
|
||||
from fastmcp.server.server import FastMCP
|
||||
|
||||
# def composite_server_from_mcp_config(
|
||||
# config: MCPConfig, name_as_prefix: bool = True
|
||||
# ) -> tuple[FastMCP[None], list[ClientTransport]]:
|
||||
# """A utility function to create a composite server from an MCPConfig, returns the underlying
|
||||
# transports for each server.
|
||||
# """
|
||||
# composite_server = FastMCP[None]()
|
||||
|
||||
# transports = mount_mcp_config_into_server(config, composite_server, name_as_prefix)
|
||||
|
||||
# return composite_server, transports
|
||||
|
||||
|
||||
# def mount_mcp_config_into_server(
|
||||
# config: MCPConfig,
|
||||
# server: FastMCP[Any],
|
||||
# name_as_prefix: bool = True,
|
||||
# ) -> None:
|
||||
# """A utility function to mount the servers from an MCPConfig into a FastMCP server, returns the underlying
|
||||
# transports for each server.
|
||||
# """
|
||||
# for name, server_to_mount, transport in mcp_config_to_servers_and_transports(config):
|
||||
# server.mount(server=server_to_mount, prefix=name if name_as_prefix else None)
|
||||
|
||||
def mcp_config_to_servers_and_transports(
|
||||
config: MCPConfig,
|
||||
|
|
@ -40,6 +17,7 @@ def mcp_config_to_servers_and_transports(
|
|||
for name, mcp_server in config.mcpServers.items()
|
||||
]
|
||||
|
||||
|
||||
def mcp_server_type_to_servers_and_transports(
|
||||
name: str,
|
||||
mcp_server: MCPServerTypes,
|
||||
|
|
@ -48,13 +26,12 @@ def mcp_server_type_to_servers_and_transports(
|
|||
from fastmcp.mcp_config import (
|
||||
TransformingRemoteMCPServer,
|
||||
TransformingStdioMCPServer,
|
||||
)
|
||||
)
|
||||
|
||||
server: FastMCP[Any]
|
||||
transport: ClientTransport
|
||||
|
||||
if isinstance(
|
||||
mcp_server, TransformingRemoteMCPServer | TransformingStdioMCPServer
|
||||
):
|
||||
if isinstance(mcp_server, TransformingRemoteMCPServer | TransformingStdioMCPServer):
|
||||
server, transport = mcp_server._to_server_and_transport()
|
||||
else:
|
||||
transport = mcp_server.to_transport()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import asyncio
|
||||
import gc
|
||||
import inspect
|
||||
import os
|
||||
import weakref
|
||||
|
||||
import psutil
|
||||
|
|
@ -10,6 +11,10 @@ from fastmcp import Client
|
|||
from fastmcp.client.transports import PythonStdioTransport, StdioTransport
|
||||
|
||||
|
||||
def running_under_debugger():
|
||||
return os.environ.get("DEBUGPY_RUNNING") == "true"
|
||||
|
||||
|
||||
def gc_collect_harder():
|
||||
gc.collect()
|
||||
gc.collect()
|
||||
|
|
@ -69,6 +74,9 @@ class TestKeepAlive:
|
|||
|
||||
assert pid1 == pid2
|
||||
|
||||
@pytest.mark.skipif(
|
||||
running_under_debugger(), reason="Debugger holds a reference to the transport"
|
||||
)
|
||||
async def test_keep_alive_true_exit_scope_kills_transport(self, stdio_script):
|
||||
transport_weak_ref: weakref.ref[PythonStdioTransport] | None = None
|
||||
|
||||
|
|
@ -83,12 +91,14 @@ class TestKeepAlive:
|
|||
|
||||
gc_collect_harder()
|
||||
|
||||
# When debugging, the debugger holds extra references so this test
|
||||
# will pass when running and fail under the debugger.
|
||||
# This test will fail while debugging because the debugger holds a reference to the underlying transport
|
||||
assert transport_weak_ref
|
||||
transport = transport_weak_ref()
|
||||
assert transport is None
|
||||
|
||||
@pytest.mark.skipif(
|
||||
running_under_debugger(), reason="Debugger holds a reference to the transport"
|
||||
)
|
||||
async def test_keep_alive_true_exit_scope_kills_client(self, stdio_script):
|
||||
pid: int | None = None
|
||||
|
||||
|
|
@ -107,6 +117,8 @@ class TestKeepAlive:
|
|||
|
||||
gc_collect_harder()
|
||||
|
||||
# This test may fail/hang while debugging because the debugger holds a reference to the underlying transport
|
||||
|
||||
with pytest.raises(psutil.NoSuchProcess):
|
||||
while True:
|
||||
psutil.Process(pid)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import asyncio
|
|||
import gc
|
||||
import inspect
|
||||
import logging
|
||||
import os
|
||||
import tempfile
|
||||
from collections.abc import AsyncGenerator
|
||||
from pathlib import Path
|
||||
|
|
@ -32,6 +33,10 @@ from fastmcp.mcp_config import (
|
|||
from fastmcp.tools.tool import Tool as FastMCPTool
|
||||
|
||||
|
||||
def running_under_debugger():
|
||||
return os.environ.get("DEBUGPY_RUNNING") == "true"
|
||||
|
||||
|
||||
def gc_collect_harder():
|
||||
gc.collect()
|
||||
gc.collect()
|
||||
|
|
@ -237,6 +242,9 @@ async def test_multi_client(tmp_path: Path):
|
|||
assert result_2.data == 3
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
running_under_debugger(), reason="Debugger holds a reference to the transport"
|
||||
)
|
||||
async def test_multi_client_lifespan(tmp_path: Path):
|
||||
pid_1: int | None = None
|
||||
pid_2: int | None = None
|
||||
|
|
@ -285,6 +293,8 @@ async def test_multi_client_lifespan(tmp_path: Path):
|
|||
|
||||
gc_collect_harder()
|
||||
|
||||
# This test will fail while debugging because the debugger holds a reference to the underlying transport
|
||||
|
||||
with pytest.raises(psutil.NoSuchProcess):
|
||||
while True:
|
||||
psutil.Process(pid_1)
|
||||
|
|
@ -295,6 +305,7 @@ async def test_multi_client_lifespan(tmp_path: Path):
|
|||
psutil.Process(pid_2)
|
||||
await asyncio.sleep(0.1)
|
||||
|
||||
|
||||
async def test_multi_client_force_close(tmp_path: Path):
|
||||
server_script = inspect.cleandoc("""
|
||||
from fastmcp import FastMCP
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue