Skip to content

Commit e3f616d

Browse files
committed
🎨 Linting and comment consolidation
Signed-off-by: Evaline Ju <69598118+evaline-ju@users.noreply.github.com>
1 parent b301d4a commit e3f616d

1 file changed

Lines changed: 25 additions & 33 deletions

File tree

mcp/weather_tool/weather_tool.py

Lines changed: 25 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,30 @@
11
"Weather MCP tool example"
22

3+
import asyncio
4+
import functools
35
import json
46
import logging
57
import os
68
import sys
79

8-
import asyncio
9-
import functools
10-
1110
import requests
1211
import uvicorn
1312
from fastmcp import FastMCP
14-
from requests.adapters import HTTPAdapter
15-
from starlette.middleware import Middleware
16-
from starlette.middleware.base import BaseHTTPMiddleware
17-
from urllib3.util.retry import Retry
18-
19-
from opentelemetry import trace, context as otel_context
20-
from opentelemetry.sdk.trace import TracerProvider
21-
from opentelemetry.sdk.trace.export import BatchSpanProcessor
22-
from opentelemetry.sdk.resources import Resource, SERVICE_NAME
13+
from opentelemetry import context as otel_context
14+
from opentelemetry import trace
15+
from opentelemetry.baggage.propagation import W3CBaggagePropagator
2316
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
2417
from opentelemetry.propagate import extract, set_global_textmap
2518
from opentelemetry.propagators.composite import CompositePropagator
26-
from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
27-
from opentelemetry.baggage.propagation import W3CBaggagePropagator
19+
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
20+
from opentelemetry.sdk.trace import TracerProvider
21+
from opentelemetry.sdk.trace.export import BatchSpanProcessor
2822
from opentelemetry.trace import Status, StatusCode
23+
from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
24+
from requests.adapters import HTTPAdapter
25+
from starlette.middleware import Middleware
26+
from starlette.middleware.base import BaseHTTPMiddleware
27+
from urllib3.util.retry import Retry
2928

3029
mcp = FastMCP("Weather")
3130
logger = logging.getLogger(__name__)
@@ -64,8 +63,7 @@ def _build_resilient_session() -> requests.Session:
6463
def setup_tracing() -> None:
6564
"""Initialize OpenTelemetry tracing with W3C trace context propagation."""
6665
otlp_endpoint = os.getenv(
67-
"OTEL_EXPORTER_OTLP_ENDPOINT",
68-
"http://otel-collector.kagenti-system.svc.cluster.local:8335"
66+
"OTEL_EXPORTER_OTLP_ENDPOINT", "http://otel-collector.kagenti-system.svc.cluster.local:8335"
6967
)
7068
service_name = os.getenv("OTEL_SERVICE_NAME", "weather-mcp-tool")
7169

@@ -74,38 +72,33 @@ def setup_tracing() -> None:
7472

7573
resource = Resource(attributes={SERVICE_NAME: service_name})
7674
provider = TracerProvider(resource=resource)
77-
provider.add_span_processor(
78-
BatchSpanProcessor(OTLPSpanExporter(endpoint=otlp_endpoint))
79-
)
75+
provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter(endpoint=otlp_endpoint)))
8076
trace.set_tracer_provider(provider)
8177

82-
set_global_textmap(CompositePropagator([
83-
TraceContextTextMapPropagator(),
84-
W3CBaggagePropagator(),
85-
]))
78+
set_global_textmap(
79+
CompositePropagator(
80+
[
81+
TraceContextTextMapPropagator(),
82+
W3CBaggagePropagator(),
83+
]
84+
)
85+
)
8686

8787
logger.info(f"Tracing initialized: service={service_name} otlp={otlp_endpoint}")
8888

8989

90-
9190
@mcp.tool(annotations={"readOnlyHint": True, "destructiveHint": False, "idempotentHint": True})
9291
async def get_weather(city: str) -> str:
9392
"""Get weather info for a city"""
94-
# Extract W3C traceparent from the incoming MCP HTTP request so this tool's
95-
# span becomes a child of the MCP gateway span (which is itself a child of
96-
# the agent span), giving a full agent → gateway → tool trace chain.
97-
# Enrich FastMCP's own span with gen_ai attributes rather than creating a
98-
# child span — FastMCP already creates a tools/call span, so a second one
99-
# with the same name is misleading. Adding to the current span merges both
100-
# sets of attributes into a single, complete span.
93+
# Enrich FastMCP's span with gen_ai attributes rather than creating a child span.
10194
span = trace.get_current_span()
10295
span.set_attribute("gen_ai.operation.name", "execute_tool")
10396
span.set_attribute("gen_ai.tool.name", "get_weather")
10497
span.set_attribute("gen_ai.tool.call.arguments", json.dumps({"city": city}))
10598

10699
logger.debug(f"Getting weather info for city '{city}'.")
107100

108-
loop = asyncio.get_event_loop()
101+
loop = asyncio.get_running_loop()
109102

110103
try:
111104
base_url = "https://geocoding-api.open-meteo.com/v1/search"
@@ -151,7 +144,6 @@ async def get_weather(city: str) -> str:
151144
raise
152145

153146

154-
155147
async def _trace_propagation_middleware(request, call_next):
156148
"""Extract W3C traceparent from HTTP headers before FastMCP creates its span.
157149

0 commit comments

Comments
 (0)