Aditya Bansal commited on
Commit
c0183df
·
1 Parent(s): 80262aa

Add OpenAPI extensions support to HTTPRoute

Browse files

- Add extensions field to HTTPRoute class to store x-* fields
- Extract extensions from operation's model_extra in parser
- Add test to verify extensions are properly parsed

src/fastmcp/utilities/openapi.py CHANGED
@@ -84,6 +84,7 @@ class HTTPRoute(FastMCPBaseModel):
84
  schema_definitions: dict[str, JsonSchema] = Field(
85
  default_factory=dict
86
  ) # Store component schemas
 
87
 
88
 
89
  # Export public symbols
@@ -591,6 +592,14 @@ class OpenAPIParser(
591
  getattr(operation, "responses", None)
592
  )
593
 
 
 
 
 
 
 
 
 
594
  route = HTTPRoute(
595
  path=path_str,
596
  method=method_upper, # type: ignore[arg-type] # Known valid HTTP method
@@ -602,6 +611,7 @@ class OpenAPIParser(
602
  request_body=request_body_info,
603
  responses=responses,
604
  schema_definitions=schema_definitions,
 
605
  )
606
  routes.append(route)
607
  logger.info(
 
84
  schema_definitions: dict[str, JsonSchema] = Field(
85
  default_factory=dict
86
  ) # Store component schemas
87
+ extensions: dict[str, Any] = Field(default_factory=dict)
88
 
89
 
90
  # Export public symbols
 
592
  getattr(operation, "responses", None)
593
  )
594
 
595
+ extensions = {}
596
+ if hasattr(operation, "model_extra") and operation.model_extra:
597
+ extensions = {
598
+ k: v
599
+ for k, v in operation.model_extra.items()
600
+ if k.startswith("x-")
601
+ }
602
+
603
  route = HTTPRoute(
604
  path=path_str,
605
  method=method_upper, # type: ignore[arg-type] # Known valid HTTP method
 
611
  request_body=request_body_info,
612
  responses=responses,
613
  schema_definitions=schema_definitions,
614
+ extensions=extensions,
615
  )
616
  routes.append(route)
617
  logger.info(
tests/utilities/openapi/test_openapi.py CHANGED
@@ -687,6 +687,29 @@ def test_multiple_tags_preserved(bookstore_schema):
687
  assert len(get_books.tags) == 3
688
 
689
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
690
  # --- Tests for BookStore schema --- #
691
 
692
 
 
687
  assert len(get_books.tags) == 3
688
 
689
 
690
+ def test_openapi_extensions(petstore_schema):
691
+ """Test that OpenAPI extensions (x-*) are correctly parsed from operations."""
692
+ # Add extensions to a route
693
+ petstore_schema["paths"]["/pets"]["get"]["x-rate-limit"] = 100
694
+ petstore_schema["paths"]["/pets"]["get"]["x-custom-auth"] = "bearer"
695
+ petstore_schema["paths"]["/pets"]["get"]["x-internal"] = True
696
+
697
+ # Parse the modified schema
698
+ routes = parse_openapi_to_http_routes(petstore_schema)
699
+
700
+ # Find the GET /pets route
701
+ get_pets = next(
702
+ (r for r in routes if r.method == "GET" and r.path == "/pets"), None
703
+ )
704
+ assert get_pets is not None
705
+
706
+ # Should have extensions
707
+ assert get_pets.extensions["x-rate-limit"] == 100
708
+ assert get_pets.extensions["x-custom-auth"] == "bearer"
709
+ assert get_pets.extensions["x-internal"] is True
710
+ assert len(get_pets.extensions) == 3
711
+
712
+
713
  # --- Tests for BookStore schema --- #
714
 
715