Skip to content

Commit 82212b6

Browse files
committed
misc testing
1 parent bc050a1 commit 82212b6

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed

azure/functions/decorators/function_app.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
AssistantQueryInput, AssistantPostInput, InputType, EmbeddingsInput, \
4444
semantic_search_system_prompt, \
4545
SemanticSearchInput, EmbeddingsStoreOutput
46-
from .mcp import MCPToolTrigger, MCPToolContext, _TYPE_MAPPING, _extract_type_and_description
46+
from .mcp import MCPToolTrigger, MCPToolContext, _TYPE_MAPPING, _extract_type_and_description, _get_user_function
4747
from .retry_policy import RetryPolicy
4848
from .function_name import FunctionName
4949
from .warmup import WarmUpTrigger
@@ -473,7 +473,8 @@ def mcp_tool(self) -> Callable[[Callable], Callable]:
473473
- Extracts parameters and types for tool properties
474474
- Handles MCPToolContext injection
475475
"""
476-
def decorator(target_func: Callable) -> Callable:
476+
def decorator(user_func: Callable) -> Callable:
477+
target_func = _get_user_function(user_func)
477478
sig = inspect.signature(target_func)
478479
tool_name = target_func.__name__
479480
description = (target_func.__doc__ or "").strip().split("\n")[0]

azure/functions/decorators/mcp.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
from typing import Optional
22
from typing import Any, Dict, Tuple, get_args, get_origin, Annotated
3+
import logging
34

45
from azure.functions.decorators.constants import (
56
MCP_TOOL_TRIGGER
67
)
78
from azure.functions.decorators.core import Trigger, DataType
9+
from azure.functions.decorators.function_app import FunctionBuilder
810

911
# Mapping Python types to MCP property types
1012
_TYPE_MAPPING = {
@@ -46,3 +48,28 @@ def _extract_type_and_description(param_name: str, type_hint: Any) -> Tuple[Any,
4648
param_description = next((a for a in args[1:] if isinstance(a, str)), f"The {param_name} parameter.")
4749
return actual_type, param_description
4850
return type_hint, f"The {param_name} parameter."
51+
52+
def _get_user_function(target_func):
53+
"""
54+
Unwraps decorated or builder-wrapped functions to find the original
55+
user-defined function (the one starting with 'def' or 'async def').
56+
"""
57+
logging.info("HELLO FROM THE SDK")
58+
# Case 1: It's a FunctionBuilder object
59+
if isinstance(target_func, FunctionBuilder):
60+
# Access the internal user function
61+
try:
62+
return target_func._function.get_user_function()
63+
except AttributeError:
64+
pass
65+
66+
# Case 2: It's already the user-defined function
67+
if callable(target_func) and hasattr(target_func, "__name__"):
68+
return target_func
69+
70+
# Case 3: It might be a partially wrapped callable
71+
if hasattr(target_func, "__wrapped__"):
72+
return _get_user_function(target_func.__wrapped__)
73+
74+
# Default fallback
75+
return target_func

0 commit comments

Comments
 (0)