mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-09 15:19:10 +02:00
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:
parent
473b0e36ec
commit
33f952fc48
4 changed files with 22 additions and 14 deletions
|
|
@ -231,6 +231,7 @@ For testing, use the in-memory exporter:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
import pytest
|
import pytest
|
||||||
|
from collections.abc import Generator
|
||||||
from opentelemetry import trace
|
from opentelemetry import trace
|
||||||
from opentelemetry.sdk.trace import TracerProvider
|
from opentelemetry.sdk.trace import TracerProvider
|
||||||
from opentelemetry.sdk.trace.export import SimpleSpanProcessor
|
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
|
from fastmcp import FastMCP
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def trace_exporter():
|
def trace_exporter() -> Generator[InMemorySpanExporter, None, None]:
|
||||||
exporter = InMemorySpanExporter()
|
exporter = InMemorySpanExporter()
|
||||||
provider = TracerProvider()
|
provider = TracerProvider()
|
||||||
provider.add_span_processor(SimpleSpanProcessor(exporter))
|
provider.add_span_processor(SimpleSpanProcessor(exporter))
|
||||||
|
|
@ -247,7 +248,7 @@ def trace_exporter():
|
||||||
yield exporter
|
yield exporter
|
||||||
exporter.clear()
|
exporter.clear()
|
||||||
|
|
||||||
async def test_tool_creates_span(trace_exporter):
|
async def test_tool_creates_span(trace_exporter: InMemorySpanExporter) -> None:
|
||||||
mcp = FastMCP("test")
|
mcp = FastMCP("test")
|
||||||
|
|
||||||
@mcp.tool()
|
@mcp.tool()
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
"""FastMCP Diagnostics Server - for testing tracing, errors, and observability."""
|
"""FastMCP Diagnostics Server - for testing tracing, errors, and observability."""
|
||||||
|
|
||||||
|
import asyncio
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import time
|
|
||||||
from collections.abc import AsyncIterator
|
from collections.abc import AsyncIterator
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -43,13 +43,16 @@ async def lifespan(server: FastMCP) -> AsyncIterator[None]:
|
||||||
stderr=subprocess.PIPE,
|
stderr=subprocess.PIPE,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Wait for server to be ready
|
# Wait for server to be ready (async to avoid blocking event loop)
|
||||||
for _ in range(50):
|
async with httpx.AsyncClient() as client:
|
||||||
try:
|
for _ in range(50):
|
||||||
httpx.get(f"http://localhost:{ECHO_SERVER_PORT}/sse", timeout=0.1)
|
try:
|
||||||
break
|
await client.get(
|
||||||
except Exception:
|
f"http://localhost:{ECHO_SERVER_PORT}/sse", timeout=0.1
|
||||||
time.sleep(0.1)
|
)
|
||||||
|
break
|
||||||
|
except Exception:
|
||||||
|
await asyncio.sleep(0.1)
|
||||||
|
|
||||||
# Mount proxy to the running echo server
|
# Mount proxy to the running echo server
|
||||||
echo_proxy = create_proxy(ECHO_SERVER_URL, name="Echo Proxy")
|
echo_proxy = create_proxy(ECHO_SERVER_URL, name="Echo Proxy")
|
||||||
|
|
@ -59,7 +62,11 @@ async def lifespan(server: FastMCP) -> AsyncIterator[None]:
|
||||||
yield
|
yield
|
||||||
finally:
|
finally:
|
||||||
proc.terminate()
|
proc.terminate()
|
||||||
proc.wait(timeout=5)
|
try:
|
||||||
|
proc.wait(timeout=5)
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
proc.kill()
|
||||||
|
proc.wait()
|
||||||
|
|
||||||
|
|
||||||
mcp = FastMCP("Diagnostics Server", lifespan=lifespan)
|
mcp = FastMCP("Diagnostics Server", lifespan=lifespan)
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main() -> None:
|
||||||
if len(sys.argv) < 2:
|
if len(sys.argv) < 2:
|
||||||
print(__doc__)
|
print(__doc__)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
@ -51,7 +51,7 @@ def main():
|
||||||
# Now run fastmcp CLI
|
# Now run fastmcp CLI
|
||||||
from fastmcp.cli.cli import app
|
from fastmcp.cli.cli import app
|
||||||
|
|
||||||
sys.argv = ["fastmcp", "run"] + sys.argv[1:]
|
sys.argv = ["fastmcp", "run", *sys.argv[1:]]
|
||||||
app()
|
app()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
2
loq.toml
2
loq.toml
|
|
@ -288,7 +288,7 @@ max_lines = 1019
|
||||||
|
|
||||||
[[rules]]
|
[[rules]]
|
||||||
path = "src/fastmcp/server/server.py"
|
path = "src/fastmcp/server/server.py"
|
||||||
max_lines = 3500
|
max_lines = 3000
|
||||||
|
|
||||||
[[rules]]
|
[[rules]]
|
||||||
path = "tests/deprecated/test_import_server.py"
|
path = "tests/deprecated/test_import_server.py"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue