Add reprs for OpenAPI objects

This commit is contained in:
Jeremiah Lowin 2025-05-14 13:42:20 -04:00
commit ff318e655d
3 changed files with 75 additions and 0 deletions

View file

@ -138,6 +138,10 @@ class OpenAPITool(Tool):
self._route = route
self._timeout = timeout
def __repr__(self) -> str:
"""Custom representation to prevent recursion errors when printing."""
return f"OpenAPITool(name={self.name!r}, method={self._route.method}, path={self._route.path})"
async def _execute_request(self, *args, **kwargs):
"""Execute the HTTP request based on the route configuration."""
context = kwargs.get("context")
@ -287,6 +291,10 @@ class OpenAPIResource(Resource):
self._route = route
self._timeout = timeout
def __repr__(self) -> str:
"""Custom representation to prevent recursion errors when printing."""
return f"OpenAPIResource(name={self.name!r}, uri={self.uri!r}, path={self._route.path})"
async def read(self) -> str | bytes:
"""Fetch the resource data by making an HTTP request."""
try:
@ -397,6 +405,10 @@ class OpenAPIResourceTemplate(ResourceTemplate):
self._route = route
self._timeout = timeout
def __repr__(self) -> str:
"""Custom representation to prevent recursion errors when printing."""
return f"OpenAPIResourceTemplate(name={self.name!r}, uri_template={self.uri_template!r}, path={self._route.path})"
async def create_resource(
self,
uri: str,

View file

@ -1771,3 +1771,49 @@ class TestFastAPIDescriptionPropagation:
"name parameter missing from Tool schema in client API"
)
# We don't test for the description field content as it may not be consistently propagated
class TestReprMethods:
"""Tests for the custom __repr__ methods of OpenAPI objects."""
async def test_openapi_tool_repr(self, fastmcp_openapi_server: FastMCPOpenAPI):
"""Test that OpenAPITool's __repr__ method works without recursion errors."""
tools = fastmcp_openapi_server._tool_manager.list_tools()
tool = next(iter(tools))
# Verify repr doesn't cause recursion and contains expected elements
tool_repr = repr(tool)
assert "OpenAPITool" in tool_repr
assert f"name={tool.name!r}" in tool_repr
assert "method=" in tool_repr
assert "path=" in tool_repr
async def test_openapi_resource_repr(self, fastmcp_openapi_server: FastMCPOpenAPI):
"""Test that OpenAPIResource's __repr__ method works without recursion errors."""
resources = list(
fastmcp_openapi_server._resource_manager.get_resources().values()
)
resource = next(iter(resources))
# Verify repr doesn't cause recursion and contains expected elements
resource_repr = repr(resource)
assert "OpenAPIResource" in resource_repr
assert f"name={resource.name!r}" in resource_repr
assert "uri=" in resource_repr
assert "path=" in resource_repr
async def test_openapi_resource_template_repr(
self, fastmcp_openapi_server: FastMCPOpenAPI
):
"""Test that OpenAPIResourceTemplate's __repr__ method works without recursion errors."""
templates = list(
fastmcp_openapi_server._resource_manager.get_templates().values()
)
template = next(iter(templates))
# Verify repr doesn't cause recursion and contains expected elements
template_repr = repr(template)
assert "OpenAPIResourceTemplate" in template_repr
assert f"name={template.name!r}" in template_repr
assert "uri_template=" in template_repr
assert "path=" in template_repr

View file

@ -520,3 +520,20 @@ def test_duplicate_tags_handling(fastapi_server):
# We'll test both possibilities to be safe
assert "duplicate" in test_route.tags, "Tag 'duplicate' should be present"
assert "items" in test_route.tags, "Tag 'items' should be present"
def test_repr_http_routes(parsed_routes):
"""Test that HTTPRoute objects can be represented without recursion errors."""
# Test repr on all parsed routes
for route in parsed_routes:
route_repr = repr(route)
# Verify repr contains essential information
assert route.method in route_repr, f"Method {route.method} missing from repr"
assert route.path in route_repr, f"Path {route.path} missing from repr"
# If operation_id exists, it should be in the repr
if route.operation_id:
assert route.operation_id in route_repr, (
f"Operation ID {route.operation_id} missing from repr"
)