Spaces:
Running
Running
itaru2622 commited on
fix: experimental FastMCPOpenAPI server lost headers in request when __init__(client with headers) (#1254)
Browse files
src/fastmcp/experimental/server/openapi/components.py
CHANGED
|
@@ -68,6 +68,13 @@ class OpenAPITool(Tool):
|
|
| 68 |
else "http://localhost"
|
| 69 |
)
|
| 70 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 71 |
# Build the request using RequestDirector
|
| 72 |
request = self._director.build(self._route, arguments, base_url)
|
| 73 |
|
|
@@ -82,6 +89,17 @@ class OpenAPITool(Tool):
|
|
| 82 |
for key, value in mcp_headers.items():
|
| 83 |
request.headers[key] = value
|
| 84 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 85 |
# Execute the request
|
| 86 |
# Note: httpx.AsyncClient.send() doesn't accept timeout parameter
|
| 87 |
# The timeout should be configured on the client itself
|
|
@@ -210,6 +228,14 @@ class OpenAPIResource(Resource):
|
|
| 210 |
headers = {}
|
| 211 |
mcp_headers = get_http_headers()
|
| 212 |
headers.update(mcp_headers)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 213 |
|
| 214 |
response = await self._client.request(
|
| 215 |
method=self._route.method,
|
|
|
|
| 68 |
else "http://localhost"
|
| 69 |
)
|
| 70 |
|
| 71 |
+
# Get Headers from client
|
| 72 |
+
cli_headers = (
|
| 73 |
+
self._client.headers
|
| 74 |
+
if hasattr(self._client, "headers") and self._client.headers
|
| 75 |
+
else {}
|
| 76 |
+
)
|
| 77 |
+
|
| 78 |
# Build the request using RequestDirector
|
| 79 |
request = self._director.build(self._route, arguments, base_url)
|
| 80 |
|
|
|
|
| 89 |
for key, value in mcp_headers.items():
|
| 90 |
request.headers[key] = value
|
| 91 |
|
| 92 |
+
if cli_headers:
|
| 93 |
+
# Merge with existing headers, _client headers take precedence
|
| 94 |
+
if request.headers:
|
| 95 |
+
request.headers.update(cli_headers)
|
| 96 |
+
else:
|
| 97 |
+
# Create new headers from cli_headers
|
| 98 |
+
for key, value in cli_headers.items():
|
| 99 |
+
request.headers[key] = value
|
| 100 |
+
# print logger
|
| 101 |
+
logger.debug(f"run - sending request; headers: {request.headers}")
|
| 102 |
+
|
| 103 |
# Execute the request
|
| 104 |
# Note: httpx.AsyncClient.send() doesn't accept timeout parameter
|
| 105 |
# The timeout should be configured on the client itself
|
|
|
|
| 228 |
headers = {}
|
| 229 |
mcp_headers = get_http_headers()
|
| 230 |
headers.update(mcp_headers)
|
| 231 |
+
# Get Headers from client
|
| 232 |
+
cli_headers = (
|
| 233 |
+
self._client.headers
|
| 234 |
+
if hasattr(self._client, "headers") and self._client.headers
|
| 235 |
+
else {}
|
| 236 |
+
)
|
| 237 |
+
# Merge with existing headers, _client headers take precedence
|
| 238 |
+
headers.update(cli_headers)
|
| 239 |
|
| 240 |
response = await self._client.request(
|
| 241 |
method=self._route.method,
|
tests/experimental/server/openapi/test_comprehensive.py
CHANGED
|
@@ -468,6 +468,7 @@ class TestOpenAPIComprehensive:
|
|
| 468 |
# Create a mock client that tracks requests
|
| 469 |
mock_client = Mock(spec=httpx.AsyncClient)
|
| 470 |
mock_client.base_url = "https://api.example.com"
|
|
|
|
| 471 |
|
| 472 |
# Mock successful response
|
| 473 |
mock_response = Mock(spec=Response)
|
|
@@ -509,6 +510,7 @@ class TestOpenAPIComprehensive:
|
|
| 509 |
"""Test complex request with both parameters and body."""
|
| 510 |
mock_client = Mock(spec=httpx.AsyncClient)
|
| 511 |
mock_client.base_url = "https://api.example.com"
|
|
|
|
| 512 |
|
| 513 |
mock_response = Mock(spec=Response)
|
| 514 |
mock_response.status_code = 201
|
|
@@ -557,6 +559,7 @@ class TestOpenAPIComprehensive:
|
|
| 557 |
"""Test query parameter handling."""
|
| 558 |
mock_client = Mock(spec=httpx.AsyncClient)
|
| 559 |
mock_client.base_url = "https://api.example.com"
|
|
|
|
| 560 |
|
| 561 |
mock_response = Mock(spec=Response)
|
| 562 |
mock_response.status_code = 200
|
|
@@ -595,6 +598,7 @@ class TestOpenAPIComprehensive:
|
|
| 595 |
"""Test error handling for HTTP errors."""
|
| 596 |
mock_client = Mock(spec=httpx.AsyncClient)
|
| 597 |
mock_client.base_url = "https://api.example.com"
|
|
|
|
| 598 |
|
| 599 |
# Mock HTTP error response
|
| 600 |
mock_response = Mock(spec=Response)
|
|
|
|
| 468 |
# Create a mock client that tracks requests
|
| 469 |
mock_client = Mock(spec=httpx.AsyncClient)
|
| 470 |
mock_client.base_url = "https://api.example.com"
|
| 471 |
+
mock_client.headers = None
|
| 472 |
|
| 473 |
# Mock successful response
|
| 474 |
mock_response = Mock(spec=Response)
|
|
|
|
| 510 |
"""Test complex request with both parameters and body."""
|
| 511 |
mock_client = Mock(spec=httpx.AsyncClient)
|
| 512 |
mock_client.base_url = "https://api.example.com"
|
| 513 |
+
mock_client.headers = None
|
| 514 |
|
| 515 |
mock_response = Mock(spec=Response)
|
| 516 |
mock_response.status_code = 201
|
|
|
|
| 559 |
"""Test query parameter handling."""
|
| 560 |
mock_client = Mock(spec=httpx.AsyncClient)
|
| 561 |
mock_client.base_url = "https://api.example.com"
|
| 562 |
+
mock_client.headers = None
|
| 563 |
|
| 564 |
mock_response = Mock(spec=Response)
|
| 565 |
mock_response.status_code = 200
|
|
|
|
| 598 |
"""Test error handling for HTTP errors."""
|
| 599 |
mock_client = Mock(spec=httpx.AsyncClient)
|
| 600 |
mock_client.base_url = "https://api.example.com"
|
| 601 |
+
mock_client.headers = None
|
| 602 |
|
| 603 |
# Mock HTTP error response
|
| 604 |
mock_response = Mock(spec=Response)
|