mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-27 07:50:43 +02:00
Ensure methods work/are documented
This commit is contained in:
parent
d26a5dffc3
commit
f495de6f3a
6 changed files with 202 additions and 54 deletions
|
|
@ -171,6 +171,9 @@ class FunctionPrompt(Prompt):
|
|||
# if the fn is a callable class, we need to get the __call__ method from here out
|
||||
if not inspect.isroutine(fn):
|
||||
fn = fn.__call__
|
||||
# if the fn is a staticmethod, we need to work with the underlying function
|
||||
if isinstance(fn, staticmethod):
|
||||
fn = fn.__func__
|
||||
|
||||
type_adapter = get_cached_typeadapter(fn)
|
||||
parameters = type_adapter.json_schema()
|
||||
|
|
|
|||
|
|
@ -225,8 +225,12 @@ class FunctionResourceTemplate(ResourceTemplate):
|
|||
|
||||
description = description or fn.__doc__
|
||||
|
||||
# if the fn is a callable class, we need to get the __call__ method from here out
|
||||
if not inspect.isroutine(fn):
|
||||
fn = fn.__call__
|
||||
# if the fn is a staticmethod, we need to work with the underlying function
|
||||
if isinstance(fn, staticmethod):
|
||||
fn = fn.__func__
|
||||
|
||||
type_adapter = get_cached_typeadapter(fn)
|
||||
parameters = type_adapter.json_schema()
|
||||
|
|
|
|||
|
|
@ -589,8 +589,20 @@ class FastMCP(Generic[LifespanResultT]):
|
|||
if isinstance(annotations, dict):
|
||||
annotations = ToolAnnotations(**annotations)
|
||||
|
||||
if isinstance(name_or_fn, classmethod):
|
||||
raise ValueError(
|
||||
inspect.cleandoc(
|
||||
"""
|
||||
To decorate a classmethod, first define the method and then call
|
||||
tool() directly on the method instead of using it as a
|
||||
decorator. See https://gofastmcp.com/patterns/decorating-methods
|
||||
for examples and more information.
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
# Determine the actual name and function based on the calling pattern
|
||||
if callable(name_or_fn):
|
||||
if inspect.isroutine(name_or_fn):
|
||||
# Case 1: @tool (without parens) - function passed directly
|
||||
# Case 2: direct call like tool(fn, name="something")
|
||||
fn = name_or_fn
|
||||
|
|
@ -747,7 +759,7 @@ class FastMCP(Generic[LifespanResultT]):
|
|||
return f"Weather for {city}: {data}"
|
||||
"""
|
||||
# Check if user passed function directly instead of calling decorator
|
||||
if callable(uri):
|
||||
if inspect.isroutine(uri):
|
||||
raise TypeError(
|
||||
"The @resource decorator was used incorrectly. "
|
||||
"Did you forget to call it? Use @resource('uri') instead of @resource"
|
||||
|
|
@ -756,6 +768,18 @@ class FastMCP(Generic[LifespanResultT]):
|
|||
def decorator(fn: AnyFunction) -> Resource | ResourceTemplate:
|
||||
from fastmcp.server.context import Context
|
||||
|
||||
if isinstance(fn, classmethod):
|
||||
raise ValueError(
|
||||
inspect.cleandoc(
|
||||
"""
|
||||
To decorate a classmethod, first define the method and then call
|
||||
resource() directly on the method instead of using it as a
|
||||
decorator. See https://gofastmcp.com/patterns/decorating-methods
|
||||
for examples and more information.
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
# Check if this should be a template
|
||||
has_uri_params = "{" in uri and "}" in uri
|
||||
# check if the function has any parameters (other than injected context)
|
||||
|
|
@ -896,8 +920,21 @@ class FastMCP(Generic[LifespanResultT]):
|
|||
# Direct function call
|
||||
server.prompt(my_function, name="custom_name")
|
||||
"""
|
||||
|
||||
if isinstance(name_or_fn, classmethod):
|
||||
raise ValueError(
|
||||
inspect.cleandoc(
|
||||
"""
|
||||
To decorate a classmethod, first define the method and then call
|
||||
prompt() directly on the method instead of using it as a
|
||||
decorator. See https://gofastmcp.com/patterns/decorating-methods
|
||||
for examples and more information.
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
# Determine the actual name and function based on the calling pattern
|
||||
if callable(name_or_fn):
|
||||
if inspect.isroutine(name_or_fn):
|
||||
# Case 1: @prompt (without parens) - function passed directly as decorator
|
||||
# Case 2: direct call like prompt(fn, name="something")
|
||||
fn = name_or_fn
|
||||
|
|
|
|||
|
|
@ -146,6 +146,9 @@ class FunctionTool(Tool):
|
|||
# if the fn is a callable class, we need to get the __call__ method from here out
|
||||
if not inspect.isroutine(fn):
|
||||
fn = fn.__call__
|
||||
# if the fn is a staticmethod, we need to work with the underlying function
|
||||
if isinstance(fn, staticmethod):
|
||||
fn = fn.__func__
|
||||
|
||||
type_adapter = get_cached_typeadapter(fn)
|
||||
schema = type_adapter.json_schema()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue