refactor: reverse visibility for get_resource/_get_resource methods

This commit is contained in:
Jeremiah Lowin 2026-01-17 14:40:16 -05:00
commit 61d98b41d1
9 changed files with 20 additions and 20 deletions

View file

@ -202,7 +202,7 @@ class AuthMiddleware(Middleware):
)
# Get resource/template (component auth is checked in get_*, raises if unauthorized)
component = await fastmcp.fastmcp._get_resource(str(uri))
component = await fastmcp.fastmcp.get_resource(str(uri))
if component is None:
component = await fastmcp.fastmcp._get_resource_template(str(uri))
if component is None:

View file

@ -159,7 +159,7 @@ class AggregateProvider(Provider):
)
return self._collect_list_results(results, "list_resources")
async def get_resource(
async def _get_resource(
self, uri: str, version: VersionSpec | None = None
) -> Resource | None:
"""Get resource by URI.
@ -170,7 +170,7 @@ class AggregateProvider(Provider):
If specified, returns highest version matching the spec from any provider.
"""
results = await gather(
*[p._get_resource(uri, version) for p in self._providers],
*[p.get_resource(uri, version) for p in self._providers],
return_exceptions=True,
)
return self._get_highest_version_result(results, f"get_resource({uri!r})") # type: ignore[return-value]

View file

@ -153,7 +153,7 @@ class Provider:
return await chain()
async def _get_resource(
async def get_resource(
self, uri: str, version: VersionSpec | None = None
) -> Resource | None:
"""Get resource by transformed URI with all transforms applied.
@ -164,7 +164,7 @@ class Provider:
"""
async def base(u: str, version: VersionSpec | None = None) -> Resource | None:
return await self.get_resource(u, version)
return await self._get_resource(u, version)
chain = base
for transform in self.transforms:
@ -280,12 +280,12 @@ class Provider:
"""
return []
async def get_resource(
async def _get_resource(
self, uri: str, version: VersionSpec | None = None
) -> Resource | None:
"""Get a specific resource by URI.
Default implementation filters list_resources() and returns highest
Default implementation filters _list_resources() and returns highest
version matching the spec.
Args:
@ -295,7 +295,7 @@ class Provider:
Returns:
The Resource if found, or None to continue searching other providers.
"""
resources = await self.list_resources()
resources = await self._list_resources()
matching = [r for r in resources if str(r.uri) == uri]
if version:
matching = [r for r in matching if version.matches(r.version)]

View file

@ -520,16 +520,16 @@ class FastMCPProvider(Provider):
raw_resources = await self.server.get_resources(run_middleware=True)
return [FastMCPProviderResource.wrap(self.server, r) for r in raw_resources]
async def get_resource(
async def _get_resource(
self, uri: str, version: VersionSpec | None = None
) -> Resource | None:
"""Get a concrete resource by URI as a FastMCPProviderResource.
Passes the full VersionSpec to the nested server, which handles both
exact version matching and range filtering. Uses _get_resource to ensure
exact version matching and range filtering. Uses get_resource to ensure
the nested server's transforms are applied.
"""
raw_resource = await self.server._get_resource(uri, version)
raw_resource = await self.server.get_resource(uri, version)
if raw_resource is None:
return None
return FastMCPProviderResource.wrap(self.server, raw_resource)

View file

@ -191,12 +191,12 @@ class FileSystemProvider(LocalProvider):
await self._ensure_loaded()
return await super()._list_resources()
async def get_resource(
async def _get_resource(
self, uri: str, version: VersionSpec | None = None
) -> Resource | None:
"""Get a resource by URI, reloading if in reload mode."""
await self._ensure_loaded()
return await super().get_resource(uri, version)
return await super()._get_resource(uri, version)
async def list_resource_templates(self) -> Sequence[ResourceTemplate]:
"""Return all resource templates, reloading if in reload mode."""

View file

@ -528,7 +528,7 @@ class LocalProvider(Provider):
if isinstance(v, Resource) and self._is_component_enabled(v)
]
async def get_resource(
async def _get_resource(
self, uri: str, version: VersionSpec | None = None
) -> Resource | None:
"""Get a resource by URI.

View file

@ -368,7 +368,7 @@ class OpenAPIProvider(Provider):
"""Return all resources created from the OpenAPI spec."""
return list(self._resources.values())
async def get_resource(
async def _get_resource(
self, uri: str, version: VersionSpec | None = None
) -> Resource | None:
"""Get a resource by URI."""

View file

@ -1223,12 +1223,12 @@ class FastMCP(Provider, Generic[LifespanResultT]):
return _dedupe_with_versions(authorized, lambda r: str(r.uri))
async def get_resource(
async def _get_resource(
self, uri: str, version: VersionSpec | None = None
) -> Resource | None:
"""Get a resource by URI via aggregation from providers.
This is the raw lookup that Provider._get_resource() wraps with transforms.
This is the raw lookup that Provider.get_resource() wraps with transforms.
Aggregates from all sub-providers and applies component-level auth.
Args:
@ -1240,7 +1240,7 @@ class FastMCP(Provider, Generic[LifespanResultT]):
"""
# Aggregate from all sub-providers (each applies their own transforms)
results = await gather(
*[p._get_resource(uri, version) for p in self._providers],
*[p.get_resource(uri, version) for p in self._providers],
return_exceptions=True,
)
@ -1666,7 +1666,7 @@ class FastMCP(Provider, Generic[LifespanResultT]):
resource_uri=uri,
) as span:
# Try concrete resources first (transforms + auth via _get_resource)
resource = await self._get_resource(uri, version=version)
resource = await self.get_resource(uri, version=version)
if resource is not None:
span.set_attributes(resource.get_span_attributes())
if task_meta is not None and task_meta.fn_key is None:

View file

@ -197,7 +197,7 @@ class TestTransformReverseLookup:
layer = Namespace("ns")
async def get_resource(uri: str, version=None):
return await provider.get_resource(uri, version)
return await provider._get_resource(uri, version)
resource = await layer.get_resource("resource://ns/data", get_resource)