Fix ty ignore syntax in OpenAPI provider (#3253)

* Fix ty ignore syntax in OpenAPI provider

* Fix flaky rate limiting and ping timing tests

* Assert rate limit error message in flaky test fix

* Catch only ToolError in rate limiting test
This commit is contained in:
Jeremiah Lowin 2026-02-20 18:06:43 -05:00 committed by GitHub
commit 1d7e92ecab
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 20 additions and 14 deletions

View file

@ -122,7 +122,7 @@ class OpenAPIProvider(Provider):
# Create openapi-core Spec and RequestDirector
try:
self._spec = SchemaPath.from_dict(openapi_spec) # type: ignore[arg-type]
self._spec = SchemaPath.from_dict(openapi_spec) # ty: ignore[invalid-argument-type]
self._director = RequestDirector(self._spec)
except Exception as e:
logger.exception("Failed to initialize RequestDirector")

View file

@ -169,10 +169,10 @@ class TestPingLoop:
middleware._active_sessions.add(session_id)
# Run ping loop for a short time then cancel
with anyio.move_on_after(0.15):
with anyio.move_on_after(0.35):
await middleware._ping_loop(mock_session, session_id)
# Should have sent at least 2 pings in 150ms with 50ms interval
# Should have sent at least 2 pings in 350ms with 50ms interval
assert mock_session.send_ping.call_count >= 2
async def test_ping_loop_cleans_up_on_cancellation(self):

View file

@ -306,21 +306,27 @@ class TestRateLimitingMiddlewareIntegration:
async def test_rate_limiting_blocks_rapid_requests(self, rate_limit_server):
"""Test that rate limiting blocks rapid successive requests."""
# Very restrictive rate limit (accounting for initialization and list_tools calls)
# Requests: 1 initialize + 1 list_tools + 4 call_tools = 6 total before limit
# Use a generous burst but near-zero refill rate so tokens never
# replenish. The MCP SDK sends internal messages (initialize,
# notifications, list_tools for validation) whose exact count
# varies, so we give enough burst for init + several calls, then
# keep firing until we hit the limit.
rate_limit_server.add_middleware(
RateLimitingMiddleware(max_requests_per_second=10.0, burst_capacity=6)
RateLimitingMiddleware(max_requests_per_second=0.001, burst_capacity=20)
)
async with Client(rate_limit_server) as client:
# First few should succeed (within burst capacity)
await client.call_tool("quick_action", {"message": "1"})
await client.call_tool("quick_action", {"message": "2"})
await client.call_tool("quick_action", {"message": "3"})
# Next should be rate limited
with pytest.raises(ToolError, match="Rate limit exceeded"):
await client.call_tool("quick_action", {"message": "4"})
# Fire enough calls to exhaust the burst. With near-zero
# refill, we must eventually hit the limit.
hit_limit = False
for i in range(30):
try:
await client.call_tool("quick_action", {"message": str(i)})
except ToolError as exc:
assert "Rate limit exceeded" in str(exc)
hit_limit = True
break
assert hit_limit, "Rate limit was never triggered"
async def test_rate_limiting_with_concurrent_requests(self, rate_limit_server):
"""Test rate limiting behavior with concurrent requests."""