1616import urllib .parse
1717
1818# Third-Party
19- from fastapi import APIRouter , Depends , Request
19+ from fastapi import APIRouter , Body , Depends
2020from fastapi .responses import JSONResponse
2121import httpx
22+ from pydantic import BaseModel , Field
2223
2324# First-Party
24- from mcpgateway .admin import _read_request_json
2525from mcpgateway .common .validators import SecurityValidator
2626from mcpgateway .middleware .rbac import get_current_user_with_permissions , require_permission
2727from mcpgateway .services .openapi_service import fetch_and_extract_schemas
3232logger = logging .getLogger (__name__ )
3333
3434
35- @router .post ("/generate-schema-from-openapi" )
35+ class GenerateSchemaRequest (BaseModel ):
36+ """Request body for generating schemas from OpenAPI specification."""
37+
38+ url : str = Field (..., description = "The tool URL (e.g., http://localhost:8100/calculate)" )
39+ request_type : str = Field ("GET" , description = "HTTP method (GET, POST, etc.)" )
40+ openapi_url : str = Field ("" , description = "Direct OpenAPI spec URL (optional, auto-discovered if empty)" )
41+
42+
43+ @router .post ("/generate-schemas-from-openapi" )
3644@require_permission ("tools.create" , allow_admin_bypass = False )
37- async def generate_schema_from_openapi (
38- request : Request ,
45+ async def generate_schemas_from_openapi (
46+ body : GenerateSchemaRequest = Body (...) ,
3947 _user = Depends (get_current_user_with_permissions ),
4048) -> JSONResponse :
4149 """
@@ -45,65 +53,24 @@ async def generate_schema_from_openapi(
4553 admin UI access. It delegates to the same service logic as the admin
4654 endpoint but without CSRF protection.
4755
48- Expects JSON body with:
49- - url: The tool URL (e.g., http://localhost:8100/calculate)
50- - request_type: HTTP method (GET, POST, etc.) - defaults to GET
51- - openapi_url: (optional) Direct OpenAPI spec URL
52-
5356 Args:
54- request: FastAPI Request object containing JSON body
57+ body: Request body with url, request_type, and openapi_url
5558 _user: Authenticated user from RBAC dependency
5659
5760 Returns:
5861 JSONResponse with generated schemas or error message.
5962 """
60- # Read and validate request body
61- try :
62- body = await _read_request_json (request )
63- except Exception :
64- return ORJSONResponse (
65- content = {"message" : "Invalid JSON in request body" , "success" : False },
66- status_code = 400 ,
67- )
68-
69- if not isinstance (body , dict ):
70- return ORJSONResponse (
71- content = {"message" : "Request body must be a JSON object" , "success" : False },
72- status_code = 400 ,
73- )
74-
75- # Extract and validate fields
76- tool_url = body .get ("url" , "" )
77- request_type = body .get ("request_type" , "GET" )
78- openapi_url = body .get ("openapi_url" , "" )
79-
80- if not isinstance (tool_url , str ) or not isinstance (request_type , str ) or not isinstance (openapi_url , str ):
81- return ORJSONResponse (
82- content = {"message" : "'url', 'request_type', and 'openapi_url' must be strings" , "success" : False },
83- status_code = 400 ,
84- )
85-
86- tool_url = tool_url .strip ()
87- request_type = request_type .strip ()
88- openapi_url = openapi_url .strip ()
89-
90- if not tool_url :
91- return ORJSONResponse (
92- content = {"message" : "'url' is required to identify the API path and base URL" , "success" : False },
93- status_code = 400 ,
94- )
95-
9663 # Security validation
9764 try :
98- SecurityValidator .validate_url (tool_url , "Tool URL" )
65+ SecurityValidator .validate_url (body . url , "Tool URL" )
9966 except ValueError as e :
10067 return ORJSONResponse (
10168 content = {"message" : str (e ), "success" : False },
10269 status_code = 400 ,
10370 )
10471
10572 # Parse URL to extract base and path
106- parsed = urllib .parse .urlparse (tool_url )
73+ parsed = urllib .parse .urlparse (body . url )
10774 base_url = f"{ parsed .scheme } ://{ parsed .netloc } "
10875 tool_path = parsed .path
10976
@@ -112,8 +79,8 @@ async def generate_schema_from_openapi(
11279 input_schema , output_schema , spec_url = await fetch_and_extract_schemas (
11380 base_url = base_url ,
11481 path = tool_path ,
115- method = request_type ,
116- openapi_url = openapi_url ,
82+ method = body . request_type ,
83+ openapi_url = body . openapi_url or "" ,
11784 timeout = 10.0 ,
11885 )
11986 except ValueError as e :
@@ -155,5 +122,3 @@ async def generate_schema_from_openapi(
155122 },
156123 status_code = 200 ,
157124 )
158-
159- # Made with Bob
0 commit comments