mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-22 05:24:18 +02:00
Refactor array parameter formatting to reduce code duplication
Extract common array formatting logic into format_array_parameter utility function. Addresses automated review feedback about code duplication between path and query parameter handling.
This commit is contained in:
parent
f14be9ab77
commit
ff0c513611
2 changed files with 64 additions and 68 deletions
|
|
@ -27,6 +27,7 @@ from fastmcp.utilities.logging import get_logger
|
|||
from fastmcp.utilities.openapi import (
|
||||
HTTPRoute,
|
||||
_combine_schemas,
|
||||
format_array_parameter,
|
||||
format_description_with_responses,
|
||||
)
|
||||
|
||||
|
|
@ -296,46 +297,10 @@ class OpenAPITool(Tool):
|
|||
if is_array:
|
||||
# Format array values as comma-separated string
|
||||
# This follows the OpenAPI 'simple' style (default for path)
|
||||
if all(
|
||||
isinstance(item, str | int | float | bool)
|
||||
for item in param_value
|
||||
):
|
||||
# Handle simple array types
|
||||
path = path.replace(
|
||||
f"{{{param_name}}}", ",".join(str(v) for v in param_value)
|
||||
)
|
||||
else:
|
||||
# Handle complex array types (containing objects/dicts)
|
||||
try:
|
||||
# Try to create a simple representation without Python syntax artifacts
|
||||
formatted_parts = []
|
||||
for item in param_value:
|
||||
if isinstance(item, dict):
|
||||
# For objects, serialize key-value pairs
|
||||
item_parts = []
|
||||
for k, v in item.items():
|
||||
item_parts.append(f"{k}:{v}")
|
||||
formatted_parts.append(".".join(item_parts))
|
||||
else:
|
||||
# Fallback for other complex types
|
||||
formatted_parts.append(str(item))
|
||||
|
||||
# Join parts with commas
|
||||
formatted_value = ",".join(formatted_parts)
|
||||
path = path.replace(f"{{{param_name}}}", formatted_value)
|
||||
except Exception as e:
|
||||
logger.warning(
|
||||
f"Failed to format complex array path parameter '{param_name}': {e}"
|
||||
)
|
||||
# Fallback to string representation, but remove Python syntax artifacts
|
||||
str_value = (
|
||||
str(param_value)
|
||||
.replace("[", "")
|
||||
.replace("]", "")
|
||||
.replace("'", "")
|
||||
.replace('"', "")
|
||||
)
|
||||
path = path.replace(f"{{{param_name}}}", str_value)
|
||||
formatted_value = format_array_parameter(
|
||||
param_value, param_name, is_query_parameter=False
|
||||
)
|
||||
path = path.replace(f"{{{param_name}}}", str(formatted_value))
|
||||
continue
|
||||
|
||||
# Default handling for non-array parameters or non-array schemas
|
||||
|
|
@ -365,34 +330,11 @@ class OpenAPITool(Tool):
|
|||
# as multiple parameters with the same name
|
||||
query_params[p.name] = param_value
|
||||
else:
|
||||
# For arrays of simple types (strings, numbers, etc.), join with commas
|
||||
if all(
|
||||
isinstance(item, str | int | float | bool)
|
||||
for item in param_value
|
||||
):
|
||||
query_params[p.name] = ",".join(str(v) for v in param_value)
|
||||
else:
|
||||
# For complex types, try to create a simpler representation
|
||||
try:
|
||||
# Try to create a simple string representation
|
||||
formatted_parts = []
|
||||
for item in param_value:
|
||||
if isinstance(item, dict):
|
||||
# For objects, serialize key-value pairs
|
||||
item_parts = []
|
||||
for k, v in item.items():
|
||||
item_parts.append(f"{k}:{v}")
|
||||
formatted_parts.append(".".join(item_parts))
|
||||
else:
|
||||
formatted_parts.append(str(item))
|
||||
|
||||
query_params[p.name] = ",".join(formatted_parts)
|
||||
except Exception as e:
|
||||
logger.warning(
|
||||
f"Failed to format complex array query parameter '{p.name}': {e}"
|
||||
)
|
||||
# Fallback to string representation
|
||||
query_params[p.name] = param_value
|
||||
# Format array as comma-separated string when explode=False
|
||||
formatted_value = format_array_parameter(
|
||||
param_value, p.name, is_query_parameter=True
|
||||
)
|
||||
query_params[p.name] = formatted_value
|
||||
else:
|
||||
# Non-array parameters are passed as is
|
||||
query_params[p.name] = param_value
|
||||
|
|
|
|||
|
|
@ -39,6 +39,60 @@ ParameterLocation = Literal["path", "query", "header", "cookie"]
|
|||
JsonSchema = dict[str, Any]
|
||||
|
||||
|
||||
def format_array_parameter(
|
||||
values: list, parameter_name: str, is_query_parameter: bool = False
|
||||
) -> str | list:
|
||||
"""
|
||||
Format an array parameter according to OpenAPI specifications.
|
||||
|
||||
Args:
|
||||
values: List of values to format
|
||||
parameter_name: Name of the parameter (for error messages)
|
||||
is_query_parameter: If True, can return list for explode=True behavior
|
||||
|
||||
Returns:
|
||||
String (comma-separated) or list (for query params with explode=True)
|
||||
"""
|
||||
# For arrays of simple types (strings, numbers, etc.), join with commas
|
||||
if all(isinstance(item, str | int | float | bool) for item in values):
|
||||
return ",".join(str(v) for v in values)
|
||||
|
||||
# For complex types, try to create a simpler representation
|
||||
try:
|
||||
# Try to create a simple string representation
|
||||
formatted_parts = []
|
||||
for item in values:
|
||||
if isinstance(item, dict):
|
||||
# For objects, serialize key-value pairs
|
||||
item_parts = []
|
||||
for k, v in item.items():
|
||||
item_parts.append(f"{k}:{v}")
|
||||
formatted_parts.append(".".join(item_parts))
|
||||
else:
|
||||
formatted_parts.append(str(item))
|
||||
|
||||
return ",".join(formatted_parts)
|
||||
except Exception as e:
|
||||
param_type = "query" if is_query_parameter else "path"
|
||||
logger.warning(
|
||||
f"Failed to format complex array {param_type} parameter '{parameter_name}': {e}"
|
||||
)
|
||||
|
||||
if is_query_parameter:
|
||||
# For query parameters, fallback to original list
|
||||
return values
|
||||
else:
|
||||
# For path parameters, fallback to string representation without Python syntax
|
||||
str_value = (
|
||||
str(values)
|
||||
.replace("[", "")
|
||||
.replace("]", "")
|
||||
.replace("'", "")
|
||||
.replace('"', "")
|
||||
)
|
||||
return str_value
|
||||
|
||||
|
||||
class ParameterInfo(FastMCPBaseModel):
|
||||
"""Represents a single parameter for an HTTP operation in our IR."""
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue