mirror of
https://github.com/tiennm99/litellm.git
synced 2026-07-20 06:19:51 +00:00
refactor: extract http request helper for mcp openapi tools
This commit is contained in:
@@ -42,6 +42,80 @@ def _sanitize_path_parameter_value(param_value: Any, param_name: str) -> str:
|
||||
return quote(value_str, safe="")
|
||||
|
||||
|
||||
async def _invoke_openapi_operation(
|
||||
*,
|
||||
method: str,
|
||||
base_url: str,
|
||||
path: str,
|
||||
headers: Dict[str, str],
|
||||
path_params: list,
|
||||
query_params: list,
|
||||
body_params: list,
|
||||
provided_params: Dict[str, Any],
|
||||
) -> str:
|
||||
"""Execute the OpenAPI operation using provided parameters."""
|
||||
|
||||
url = base_url + path
|
||||
|
||||
# Replace path parameters with sanitized values
|
||||
for param_name in path_params:
|
||||
param_value = provided_params.get(param_name, "")
|
||||
if param_value:
|
||||
try:
|
||||
safe_value = _sanitize_path_parameter_value(param_value, param_name)
|
||||
except ValueError as exc:
|
||||
return "Invalid path parameter: " + str(exc)
|
||||
url = url.replace("{" + param_name + "}", safe_value)
|
||||
|
||||
# Build query params
|
||||
params: Dict[str, Any] = {}
|
||||
for param_name in query_params:
|
||||
param_value = provided_params.get(param_name, "")
|
||||
if param_value:
|
||||
params[param_name] = param_value
|
||||
|
||||
# Build request body
|
||||
json_body = None
|
||||
if body_params:
|
||||
body_value = provided_params.get("body", {})
|
||||
if isinstance(body_value, dict):
|
||||
json_body = body_value
|
||||
elif body_value:
|
||||
import json as json_module
|
||||
|
||||
try:
|
||||
json_body = (
|
||||
json_module.loads(body_value)
|
||||
if isinstance(body_value, str)
|
||||
else {"data": body_value}
|
||||
)
|
||||
except Exception:
|
||||
json_body = {"data": body_value}
|
||||
|
||||
async with httpx.AsyncClient() as client:
|
||||
method_lower = method.lower()
|
||||
if method_lower == "get":
|
||||
response = await client.get(url, params=params, headers=headers)
|
||||
elif method_lower == "post":
|
||||
response = await client.post(
|
||||
url, params=params, json=json_body, headers=headers
|
||||
)
|
||||
elif method_lower == "put":
|
||||
response = await client.put(
|
||||
url, params=params, json=json_body, headers=headers
|
||||
)
|
||||
elif method_lower == "delete":
|
||||
response = await client.delete(url, params=params, headers=headers)
|
||||
elif method_lower == "patch":
|
||||
response = await client.patch(
|
||||
url, params=params, json=json_body, headers=headers
|
||||
)
|
||||
else:
|
||||
return f"Unsupported HTTP method: {method}"
|
||||
|
||||
return response.text
|
||||
|
||||
|
||||
def load_openapi_spec(filepath: str) -> Dict[str, Any]:
|
||||
"""Load OpenAPI specification from JSON file."""
|
||||
with open(filepath, "r") as f:
|
||||
@@ -160,59 +234,19 @@ def create_tool_function(
|
||||
func_code = f'''
|
||||
async def tool_function({params_str}) -> str:
|
||||
"""Dynamically generated tool function."""
|
||||
url = base_url + path
|
||||
|
||||
# Replace path parameters
|
||||
path_param_names = {path_params}
|
||||
for param_name in path_param_names:
|
||||
param_value = locals().get(param_name, "")
|
||||
if param_value:
|
||||
# url = url.replace("{{" + param_name + "}}", str(param_value))
|
||||
try:
|
||||
safe_value = _sanitize_path_parameter_value(param_value, param_name)
|
||||
except ValueError as exc:
|
||||
return "Invalid path parameter: " + str(exc)
|
||||
url = url.replace("{{" + param_name + "}}", safe_value)
|
||||
|
||||
# Build query params
|
||||
query_param_names = {query_params}
|
||||
params = {{}}
|
||||
for param_name in query_param_names:
|
||||
param_value = locals().get(param_name, "")
|
||||
if param_value:
|
||||
params[param_name] = param_value
|
||||
|
||||
# Build request body
|
||||
body_param_names = {body_params}
|
||||
json_body = None
|
||||
if body_param_names:
|
||||
body_value = locals().get("body", {{}})
|
||||
if isinstance(body_value, dict):
|
||||
json_body = body_value
|
||||
elif body_value:
|
||||
# If it's a string, try to parse as JSON
|
||||
import json as json_module
|
||||
try:
|
||||
json_body = json_module.loads(body_value) if isinstance(body_value, str) else {{"data": body_value}}
|
||||
except:
|
||||
json_body = {{"data": body_value}}
|
||||
|
||||
# Make HTTP request
|
||||
async with httpx.AsyncClient() as client:
|
||||
if "{method.lower()}" == "get":
|
||||
response = await client.get(url, params=params, headers=headers)
|
||||
elif "{method.lower()}" == "post":
|
||||
response = await client.post(url, params=params, json=json_body, headers=headers)
|
||||
elif "{method.lower()}" == "put":
|
||||
response = await client.put(url, params=params, json=json_body, headers=headers)
|
||||
elif "{method.lower()}" == "delete":
|
||||
response = await client.delete(url, params=params, headers=headers)
|
||||
elif "{method.lower()}" == "patch":
|
||||
response = await client.patch(url, params=params, json=json_body, headers=headers)
|
||||
else:
|
||||
return "Unsupported HTTP method: {method}"
|
||||
|
||||
return response.text
|
||||
provided_params = {{}}
|
||||
for param_name in {all_params}:
|
||||
provided_params[param_name] = locals().get(param_name, "")
|
||||
return await _invoke_openapi_operation(
|
||||
method="{method}",
|
||||
base_url=base_url,
|
||||
path=path,
|
||||
headers=headers,
|
||||
path_params={path_params},
|
||||
query_params={query_params},
|
||||
body_params={body_params},
|
||||
provided_params=provided_params,
|
||||
)
|
||||
'''
|
||||
|
||||
# Execute the function code to create the actual function
|
||||
@@ -222,7 +256,7 @@ async def tool_function({params_str}) -> str:
|
||||
"base_url": base_url,
|
||||
"path": path,
|
||||
"method": method,
|
||||
"_sanitize_path_parameter_value": _sanitize_path_parameter_value,
|
||||
"_invoke_openapi_operation": _invoke_openapi_operation,
|
||||
}
|
||||
exec(func_code, local_vars)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user