Address CodeRabbit suggestions

- Add return type annotation to main() in run_with_tracing.py
- Use spread operator for argv construction
- Add type annotations to docs test example
- Use async httpx client and asyncio.sleep in diagnostics server
- Improve subprocess termination handling with timeout fallback

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Chris Guidry 2026-01-14 09:48:07 -05:00
commit 33f952fc48
4 changed files with 22 additions and 14 deletions

View file

@ -231,6 +231,7 @@ For testing, use the in-memory exporter:
```python
import pytest
from collections.abc import Generator
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import SimpleSpanProcessor
@ -239,7 +240,7 @@ from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanE
from fastmcp import FastMCP
@pytest.fixture
def trace_exporter():
def trace_exporter() -> Generator[InMemorySpanExporter, None, None]:
exporter = InMemorySpanExporter()
provider = TracerProvider()
provider.add_span_processor(SimpleSpanProcessor(exporter))
@ -247,7 +248,7 @@ def trace_exporter():
yield exporter
exporter.clear()
async def test_tool_creates_span(trace_exporter):
async def test_tool_creates_span(trace_exporter: InMemorySpanExporter) -> None:
mcp = FastMCP("test")
@mcp.tool()

View file

@ -1,8 +1,8 @@
"""FastMCP Diagnostics Server - for testing tracing, errors, and observability."""
import asyncio
import os
import subprocess
import time
from collections.abc import AsyncIterator
from contextlib import asynccontextmanager
from pathlib import Path
@ -43,13 +43,16 @@ async def lifespan(server: FastMCP) -> AsyncIterator[None]:
stderr=subprocess.PIPE,
)
# Wait for server to be ready
for _ in range(50):
try:
httpx.get(f"http://localhost:{ECHO_SERVER_PORT}/sse", timeout=0.1)
break
except Exception:
time.sleep(0.1)
# Wait for server to be ready (async to avoid blocking event loop)
async with httpx.AsyncClient() as client:
for _ in range(50):
try:
await client.get(
f"http://localhost:{ECHO_SERVER_PORT}/sse", timeout=0.1
)
break
except Exception:
await asyncio.sleep(0.1)
# Mount proxy to the running echo server
echo_proxy = create_proxy(ECHO_SERVER_URL, name="Echo Proxy")
@ -59,7 +62,11 @@ async def lifespan(server: FastMCP) -> AsyncIterator[None]:
yield
finally:
proc.terminate()
proc.wait(timeout=5)
try:
proc.wait(timeout=5)
except subprocess.TimeoutExpired:
proc.kill()
proc.wait()
mcp = FastMCP("Diagnostics Server", lifespan=lifespan)

View file

@ -19,7 +19,7 @@ import os
import sys
def main():
def main() -> None:
if len(sys.argv) < 2:
print(__doc__)
sys.exit(1)
@ -51,7 +51,7 @@ def main():
# Now run fastmcp CLI
from fastmcp.cli.cli import app
sys.argv = ["fastmcp", "run"] + sys.argv[1:]
sys.argv = ["fastmcp", "run", *sys.argv[1:]]
app()

View file

@ -288,7 +288,7 @@ max_lines = 1019
[[rules]]
path = "src/fastmcp/server/server.py"
max_lines = 3500
max_lines = 3000
[[rules]]
path = "tests/deprecated/test_import_server.py"