style: refactor codebase to adhere to PEP 8 formatting standards throughout all source files
This commit is contained in:
@@ -2,7 +2,12 @@ import json
|
||||
from mcp.server.fastmcp import FastMCP, Context
|
||||
from mcp.types import TextContent, Annotations, EmbeddedResource, TextResourceContents
|
||||
from strava_mcp_server.strava_client import StravaClient
|
||||
from strava_mcp_server.utils import parse_iso_to_unix, format_date_iso, format_date_human
|
||||
from strava_mcp_server.utils import (
|
||||
parse_iso_to_unix,
|
||||
format_date_iso,
|
||||
format_date_human,
|
||||
)
|
||||
|
||||
|
||||
def _resource(uri: str, data) -> EmbeddedResource:
|
||||
"""Helper: return an assistant-facing EmbeddedResource with application/json."""
|
||||
@@ -16,9 +21,13 @@ def _resource(uri: str, data) -> EmbeddedResource:
|
||||
annotations=Annotations(audience=["assistant"]),
|
||||
)
|
||||
|
||||
|
||||
def _user_text(text: str) -> TextContent:
|
||||
"""Helper: return a user-facing TextContent."""
|
||||
return TextContent(type="text", text=text, annotations=Annotations(audience=["user"]))
|
||||
return TextContent(
|
||||
type="text", text=text, annotations=Annotations(audience=["user"])
|
||||
)
|
||||
|
||||
|
||||
def register(mcp: FastMCP, strava: StravaClient) -> None:
|
||||
@mcp.tool()
|
||||
@@ -49,27 +58,39 @@ def register(mcp: FastMCP, strava: StravaClient) -> None:
|
||||
essential_data = []
|
||||
for a in activities:
|
||||
start_date_raw = a.get("start_date")
|
||||
essential_data.append({
|
||||
"id": a["id"],
|
||||
"name": a["name"],
|
||||
"sport_type": a.get("sport_type") or a.get("type"),
|
||||
"start_date": format_date_iso(start_date_raw),
|
||||
"start_date_local": format_date_human(start_date_raw),
|
||||
"distance": f"{a.get('distance', 0) / 1000:.2f} km",
|
||||
"moving_time": f"{a.get('moving_time', 0) / 60:.1f} min",
|
||||
"total_elevation_gain": f"{a.get('total_elevation_gain', 0):.0f} m",
|
||||
"average_heartrate": a.get("average_heartrate"),
|
||||
"gear_id": a.get("gear_id"),
|
||||
})
|
||||
essential_data.append(
|
||||
{
|
||||
"id": a["id"],
|
||||
"name": a["name"],
|
||||
"sport_type": a.get("sport_type") or a.get("type"),
|
||||
"start_date": format_date_iso(start_date_raw),
|
||||
"start_date_local": format_date_human(start_date_raw),
|
||||
"distance": f"{a.get('distance', 0) / 1000:.2f} km",
|
||||
"moving_time": f"{a.get('moving_time', 0) / 60:.1f} min",
|
||||
"total_elevation_gain": f"{a.get('total_elevation_gain', 0):.0f} m",
|
||||
"average_heartrate": a.get("average_heartrate"),
|
||||
"gear_id": a.get("gear_id"),
|
||||
}
|
||||
)
|
||||
|
||||
if not essential_data:
|
||||
markdown_summary = "### 📭 Keine Aktivitäten in diesem Zeitraum gefunden."
|
||||
markdown_summary = (
|
||||
"### 📭 Keine Aktivitäten in diesem Zeitraum gefunden."
|
||||
)
|
||||
else:
|
||||
markdown_summary = f"### 🚴 Aktivitäten (Seite {page})\n"
|
||||
markdown_summary += "| Datum | Sport | Name | Distanz | Zeit | Höhenmeter | Ø HR |\n"
|
||||
markdown_summary += "|-------|-------|------|---------|------|------------|------|\n"
|
||||
markdown_summary += (
|
||||
"| Datum | Sport | Name | Distanz | Zeit | Höhenmeter | Ø HR |\n"
|
||||
)
|
||||
markdown_summary += (
|
||||
"|-------|-------|------|---------|------|------------|------|\n"
|
||||
)
|
||||
for a in essential_data:
|
||||
hr = f"{a['average_heartrate']:.0f} bpm" if a['average_heartrate'] else "-"
|
||||
hr = (
|
||||
f"{a['average_heartrate']:.0f} bpm"
|
||||
if a["average_heartrate"]
|
||||
else "-"
|
||||
)
|
||||
markdown_summary += f"| {a['start_date_local']} | {a['sport_type']} | {a['name']} | {a['distance']} | {a['moving_time']} | {a['total_elevation_gain']} | {hr} |\n"
|
||||
|
||||
return [
|
||||
@@ -106,10 +127,26 @@ def register(mcp: FastMCP, strava: StravaClient) -> None:
|
||||
dist = f"{activity.get('distance', 0) / 1000:.2f} km"
|
||||
time = f"{activity.get('moving_time', 0) / 60:.1f} min"
|
||||
elev = f"{activity.get('total_elevation_gain', 0):.0f} m"
|
||||
avg_hr = f"{activity.get('average_heartrate', 0):.0f} bpm" if activity.get("average_heartrate") else "N/A"
|
||||
max_hr = f"{activity.get('max_heartrate', 0):.0f} bpm" if activity.get("max_heartrate") else "N/A"
|
||||
avg_spd = f"{activity.get('average_speed', 0) * 3.6:.1f} km/h" if activity.get("average_speed") else "N/A"
|
||||
avg_w = f"{activity.get('average_watts', 0):.0f} W" if activity.get("average_watts") else "N/A"
|
||||
avg_hr = (
|
||||
f"{activity.get('average_heartrate', 0):.0f} bpm"
|
||||
if activity.get("average_heartrate")
|
||||
else "N/A"
|
||||
)
|
||||
max_hr = (
|
||||
f"{activity.get('max_heartrate', 0):.0f} bpm"
|
||||
if activity.get("max_heartrate")
|
||||
else "N/A"
|
||||
)
|
||||
avg_spd = (
|
||||
f"{activity.get('average_speed', 0) * 3.6:.1f} km/h"
|
||||
if activity.get("average_speed")
|
||||
else "N/A"
|
||||
)
|
||||
avg_w = (
|
||||
f"{activity.get('average_watts', 0):.0f} W"
|
||||
if activity.get("average_watts")
|
||||
else "N/A"
|
||||
)
|
||||
gear = activity.get("gear_id") or "N/A"
|
||||
n_efforts = len(activity.get("segment_efforts", []))
|
||||
|
||||
@@ -133,7 +170,11 @@ def register(mcp: FastMCP, strava: StravaClient) -> None:
|
||||
_resource(f"internal://activities/{activity_id}", activity),
|
||||
]
|
||||
except Exception as e:
|
||||
return [TextContent(type="text", text=f"Error fetching activity details: {str(e)}")]
|
||||
return [
|
||||
TextContent(
|
||||
type="text", text=f"Error fetching activity details: {str(e)}"
|
||||
)
|
||||
]
|
||||
|
||||
@mcp.tool()
|
||||
async def get_activity_comments(activity_id: int, limit: int = 30):
|
||||
@@ -159,7 +200,10 @@ def register(mcp: FastMCP, strava: StravaClient) -> None:
|
||||
md = f"### 💬 Kommentare ({len(data)})\n"
|
||||
for c in data:
|
||||
md += f"- **{c['athlete']}** ({format_date_human(c['created_at'])}): {c['text']}\n"
|
||||
return [_user_text(md.strip()), _resource(f"internal://activities/{activity_id}/comments", data)]
|
||||
return [
|
||||
_user_text(md.strip()),
|
||||
_resource(f"internal://activities/{activity_id}/comments", data),
|
||||
]
|
||||
except Exception as e:
|
||||
return [TextContent(type="text", text=f"Error fetching comments: {str(e)}")]
|
||||
|
||||
@@ -189,7 +233,10 @@ def register(mcp: FastMCP, strava: StravaClient) -> None:
|
||||
for k in data:
|
||||
loc = ", ".join(filter(None, [k["city"], k["country"]])) or "N/A"
|
||||
md += f"| {k['name']} | {loc} |\n"
|
||||
return [_user_text(md.strip()), _resource(f"internal://activities/{activity_id}/kudoers", data)]
|
||||
return [
|
||||
_user_text(md.strip()),
|
||||
_resource(f"internal://activities/{activity_id}/kudoers", data),
|
||||
]
|
||||
except Exception as e:
|
||||
return [TextContent(type="text", text=f"Error fetching kudoers: {str(e)}")]
|
||||
|
||||
@@ -224,9 +271,16 @@ def register(mcp: FastMCP, strava: StravaClient) -> None:
|
||||
md += "| # | Distanz | Zeit | Ø Speed | Ø HR |\n"
|
||||
md += "|---|---------|------|---------|------|\n"
|
||||
for lap in data:
|
||||
hr = f"{lap['average_heartrate']:.0f} bpm" if lap['average_heartrate'] else "-"
|
||||
hr = (
|
||||
f"{lap['average_heartrate']:.0f} bpm"
|
||||
if lap["average_heartrate"]
|
||||
else "-"
|
||||
)
|
||||
md += f"| {lap['lap_index']} | {lap['distance']} | {lap['moving_time']} | {lap['average_speed']} | {hr} |\n"
|
||||
return [_user_text(md.strip()), _resource(f"internal://activities/{activity_id}/laps", data)]
|
||||
return [
|
||||
_user_text(md.strip()),
|
||||
_resource(f"internal://activities/{activity_id}/laps", data),
|
||||
]
|
||||
except Exception as e:
|
||||
return [TextContent(type="text", text=f"Error fetching laps: {str(e)}")]
|
||||
|
||||
@@ -260,15 +314,26 @@ def register(mcp: FastMCP, strava: StravaClient) -> None:
|
||||
"distribution_buckets": buckets,
|
||||
}
|
||||
data.append(zone_data)
|
||||
label = "Herzfrequenz" if zone_data["type"] == "heartrate" else "Leistung (Power)"
|
||||
label = (
|
||||
"Herzfrequenz"
|
||||
if zone_data["type"] == "heartrate"
|
||||
else "Leistung (Power)"
|
||||
)
|
||||
md += f"#### {label}\n| Zone | Bereich | Zeit |\n|------|---------|------|\n"
|
||||
for b in buckets:
|
||||
max_val = "max" if b["max"] == -1 else str(b["max"])
|
||||
md += f"| {b['zone']} | {b['min']} – {max_val} | {b['time_in_zone']} |\n"
|
||||
md += "\n"
|
||||
return [_user_text(md.strip()), _resource(f"internal://activities/{activity_id}/zones", data)]
|
||||
return [
|
||||
_user_text(md.strip()),
|
||||
_resource(f"internal://activities/{activity_id}/zones", data),
|
||||
]
|
||||
except Exception as e:
|
||||
return [TextContent(type="text", text=f"Error fetching activity zones: {str(e)}")]
|
||||
return [
|
||||
TextContent(
|
||||
type="text", text=f"Error fetching activity zones: {str(e)}"
|
||||
)
|
||||
]
|
||||
|
||||
@mcp.tool()
|
||||
async def get_activity_streams(
|
||||
|
||||
Reference in New Issue
Block a user