Switch to aiohttp for async HTTP requests in server logic

Replaced synchronous requests with aiohttp to enable non-blocking, async HTTP requests. Updated `smd_detail_article` and `smd_research` to utilize asyncio for parallel execution, significantly improving efficiency for handling multiple API calls. Added aiohttp and asyncio dependencies to requirements.txt.
This commit is contained in:
ThomasTaroni 2025-06-21 20:17:59 +02:00
parent 1554d5e4ab
commit 8eda903185
2 changed files with 21 additions and 27 deletions

View file

@ -10,4 +10,6 @@ pydantic>=2.3.0
# Utility dependencies
loguru>=0.7.0
requests~=2.32.3
requests~=2.32.3
aiohttp~=3.11.18
asyncio~=3.4.3

View file

@ -7,6 +7,8 @@ to conduct research and generate reports via the MCP protocol.
import os
import logging
import aiohttp
import asyncio
import requests
from dotenv import load_dotenv
from mcp.server.fastmcp import FastMCP
@ -24,30 +26,24 @@ logger = logging.getLogger(__name__)
# Initialize FastMCP server
mcp = FastMCP("SMD Researcher", host="0.0.0.0", port=8000, timeout_keep_alive=720)
async def smd_detail_article(article_id: str) -> dict:
"""
Get the Details of an article found by the tool smd_research based on the article_id.
Use this tool after smd_research is executed to get all the details of the articles in the result.
Args:
article_id: The ID of the article to get the details for
Returns:
String containing the details of the article
"""
async def smd_detail_article(article_id):
url = f"https://api.swissdox.ch/api/documents/{article_id}"
headers = {
"authorization": f"Bearer {os.getenv('SWISSDOX_BEARER_TOKEN', '')}",
"content-type": "application/json",
}
payload = {"filters": [], "pagination": {"pageSize": 1, "currentPage": 1}}
response = requests.post(url, headers=headers, json=payload)
if response.status_code == 200:
return response.json()
else:
return {
"message": response.text
}
async with aiohttp.ClientSession() as session:
async with session.get(url, headers=headers, payload=payload) as response:
if response.status == 200:
return await response.json() # JSON asynchron lesen
else:
return {
"message": await response.text(),
"article_id": article_id
}
@mcp.tool()
async def smd_research(search_query: str = "Bundesrat", date_from: str = "2024-05-30T22:00:00.000Z", date_to: str = "2025-05-31T21:59:59.999Z") -> dict:
@ -99,20 +95,16 @@ async def smd_research(search_query: str = "Bundesrat", date_from: str = "2024-0
if response.status_code == 200:
result = response.json()
# Artikel-Liste aus der `data`-Struktur der Antwort
articles = result.get("data", [])
# Verschachtelte JSON-Resultate von `smd_detail_article` sammeln
detailed_articles = []
tasks = []
for article in articles:
article_id = article.get("id")
if article_id:
detailed_result = smd_detail_article(article_id)
detailed_articles.append(detailed_result)
# Gesamtantwort mit kombinierter JSON-Struktur
tasks.append(smd_detail_article(article_id))
detailed_articles = await asyncio.gather(*tasks)
return {
"search_result": result,
"original_result": result,
"detailed_articles": detailed_articles
}
else: