mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-28 02:10:38 +02:00
Remove customizable separators; improve resource separator
This commit is contained in:
parent
7e2d4ef0ab
commit
cec40ddfea
9 changed files with 720 additions and 210 deletions
|
|
@ -39,7 +39,7 @@ class TestBasicMount:
|
|||
assert result[0].text == "This is from the sub app"
|
||||
|
||||
async def test_mount_with_custom_separator(self):
|
||||
"""Test mounting with a custom tool separator."""
|
||||
"""Test mounting with a custom tool separator (deprecated but still supported)."""
|
||||
main_app = FastMCP("MainApp")
|
||||
sub_app = FastMCP("SubApp")
|
||||
|
||||
|
|
@ -47,15 +47,15 @@ class TestBasicMount:
|
|||
def greet(name: str) -> str:
|
||||
return f"Hello, {name}!"
|
||||
|
||||
# Mount with custom separator
|
||||
main_app.mount("sub", sub_app, tool_separator="-")
|
||||
# Mount without custom separator - custom separators are deprecated
|
||||
main_app.mount("sub", sub_app)
|
||||
|
||||
# Tool should be accessible with custom separator
|
||||
# Tool should be accessible with the default separator
|
||||
tools = await main_app.get_tools()
|
||||
assert "sub-greet" in tools
|
||||
assert "sub_greet" in tools
|
||||
|
||||
# Call the tool
|
||||
result = await main_app._mcp_call_tool("sub-greet", {"name": "World"})
|
||||
result = await main_app._mcp_call_tool("sub_greet", {"name": "World"})
|
||||
assert isinstance(result[0], TextContent)
|
||||
assert result[0].text == "Hello, World!"
|
||||
|
||||
|
|
@ -63,21 +63,17 @@ class TestBasicMount:
|
|||
main_app = FastMCP("MainApp")
|
||||
api_app = FastMCP("APIApp")
|
||||
|
||||
with pytest.raises(
|
||||
ValueError,
|
||||
match="Resource prefix or separator would result in an invalid resource URI",
|
||||
):
|
||||
main_app.mount("api_sub", api_app)
|
||||
# This test doesn't apply anymore with the new prefix format
|
||||
# just mount the server to maintain test coverage
|
||||
main_app.mount("api:sub", api_app)
|
||||
|
||||
async def test_mount_invalid_resource_separator(self):
|
||||
main_app = FastMCP("MainApp")
|
||||
api_app = FastMCP("APIApp")
|
||||
|
||||
with pytest.raises(
|
||||
ValueError,
|
||||
match="Resource prefix or separator would result in an invalid resource URI",
|
||||
):
|
||||
main_app.mount("api", api_app, resource_separator="_")
|
||||
# This test doesn't apply anymore with the new prefix format
|
||||
# Mount without deprecated parameters
|
||||
main_app.mount("api", api_app)
|
||||
|
||||
async def test_unmount_server(self):
|
||||
"""Test unmounting a server removes access to its tools."""
|
||||
|
|
@ -114,12 +110,12 @@ class TestBasicMount:
|
|||
def sub_tool() -> str:
|
||||
return "This is from the sub app"
|
||||
|
||||
main_app.mount(
|
||||
prefix="", server=sub_app, tool_separator="", resource_separator=""
|
||||
)
|
||||
# Mount with empty prefix but without deprecated separators
|
||||
main_app.mount(prefix="", server=sub_app)
|
||||
|
||||
tools = await main_app.get_tools()
|
||||
assert "sub_tool" in tools
|
||||
# With empty prefix, the format is now "_sub_tool" instead of "sub_tool"
|
||||
assert "_sub_tool" in tools
|
||||
|
||||
|
||||
class TestMultipleServerMount:
|
||||
|
|
@ -259,12 +255,13 @@ class TestResourcesAndTemplates:
|
|||
|
||||
# Resource should be accessible through main app
|
||||
resources = await main_app.get_resources()
|
||||
assert any("data+data://users" in str(uri) for uri in resources)
|
||||
assert "data://data/users" in resources
|
||||
|
||||
# Check that resource can be accessed
|
||||
async with Client(main_app) as client:
|
||||
resource = await client.read_resource("data+data://users")
|
||||
assert isinstance(resource[0], TextResourceContents)
|
||||
assert resource[0].text == '[\n "user1",\n "user2"\n]'
|
||||
result = await client.read_resource("data://data/users")
|
||||
assert isinstance(result[0], TextResourceContents)
|
||||
assert json.loads(result[0].text) == ["user1", "user2"]
|
||||
|
||||
async def test_mount_with_resource_templates(self):
|
||||
"""Test mounting a server with resource templates."""
|
||||
|
|
@ -280,14 +277,15 @@ class TestResourcesAndTemplates:
|
|||
|
||||
# Template should be accessible through main app
|
||||
templates = await main_app.get_resource_templates()
|
||||
assert any("api+users://{user_id}/profile" in str(t) for t in templates)
|
||||
assert "users://api/{user_id}/profile" in templates
|
||||
|
||||
# Read from the template
|
||||
result = await main_app._mcp_read_resource("api+users://123/profile")
|
||||
assert isinstance(result[0], ReadResourceContents)
|
||||
profile = json.loads(result[0].content)
|
||||
assert profile["id"] == "123"
|
||||
assert profile["name"] == "User 123"
|
||||
# Check template instantiation
|
||||
async with Client(main_app) as client:
|
||||
result = await client.read_resource("users://api/123/profile")
|
||||
assert isinstance(result[0], TextResourceContents)
|
||||
profile = json.loads(result[0].text)
|
||||
assert profile["id"] == "123"
|
||||
assert profile["name"] == "User 123"
|
||||
|
||||
async def test_adding_resource_after_mounting(self):
|
||||
"""Test adding a resource after mounting."""
|
||||
|
|
@ -304,13 +302,14 @@ class TestResourcesAndTemplates:
|
|||
|
||||
# Resource should be accessible through main app
|
||||
resources = await main_app.get_resources()
|
||||
assert any("data+data://config" in str(uri) for uri in resources)
|
||||
assert "data://data/config" in resources
|
||||
|
||||
# Read the resource
|
||||
result = await main_app._mcp_read_resource("data+data://config")
|
||||
assert isinstance(result[0], ReadResourceContents)
|
||||
config = json.loads(result[0].content)
|
||||
assert config["version"] == "1.0"
|
||||
# Check access to the resource
|
||||
async with Client(main_app) as client:
|
||||
result = await client.read_resource("data://data/config")
|
||||
assert isinstance(result[0], TextResourceContents)
|
||||
config = json.loads(result[0].text)
|
||||
assert config["version"] == "1.0"
|
||||
|
||||
|
||||
class TestPrompts:
|
||||
|
|
@ -437,7 +436,7 @@ class TestProxyServer:
|
|||
main_app.mount("proxy", proxy_server)
|
||||
|
||||
# Resource should be accessible through main app
|
||||
result = await main_app._mcp_read_resource("proxy+config://settings")
|
||||
result = await main_app._mcp_read_resource("config://proxy/settings")
|
||||
assert isinstance(result[0], ReadResourceContents)
|
||||
config = json.loads(result[0].content)
|
||||
assert config["api_key"] == "12345"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue