From 86e73d70d6d7e3d6e40a57342f9ad2d0ccc28679 Mon Sep 17 00:00:00 2001 From: Sabrina Tso <316314148+SabrinaTso@users.noreply.github.com> Date: Sun, 23 Aug 2026 06:26:51 +0800 Subject: [PATCH 1/2] fix: remediate audited dependency vulnerabilities --- requirements.txt | 10 +++++----- src/data_api/core/settings.py | 5 ----- tests/test_mcp_tools.py | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/requirements.txt b/requirements.txt index 21bd10c..ff99d8d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,19 +1,19 @@ # Server -fastapi==0.122.0 +fastapi==0.141.1 uvicorn==0.38.0 # Environment -python-dotenv==1.2.1 -pydantic_settings==2.12.0 +python-dotenv==1.2.3 +pydantic_settings==2.15.0 truststore==0.10.4 # Crawlers httpx[http2]==0.28.1 beautifulsoup4==4.14.2 xmltodict==1.0.2 pandas==2.3.3 -lxml==6.0.2 +lxml==6.1.2 # Search jieba==0.42.1 python-Levenshtein==0.27.3 thefuzz==0.22.1 # MCP -fastmcp==2.13.1 \ No newline at end of file +fastmcp==3.2.0 diff --git a/src/data_api/core/settings.py b/src/data_api/core/settings.py index bddd8b6..5e459ec 100644 --- a/src/data_api/core/settings.py +++ b/src/data_api/core/settings.py @@ -4,8 +4,6 @@ Settings are loaded from environment variables and .env file. """ -import os - from pydantic import Field from pydantic_settings import BaseSettings, SettingsConfigDict @@ -40,8 +38,5 @@ class Settings(BaseSettings): ) -# FastMCP 要開啟實驗性功能(但之後會變正式版本),不然 openapi.json 解析會有問題 -os.environ["FASTMCP_EXPERIMENTAL_ENABLE_NEW_OPENAPI_PARSER"] = "true" - # Global settings instance settings = Settings() diff --git a/tests/test_mcp_tools.py b/tests/test_mcp_tools.py index 792bf6a..097b1a4 100644 --- a/tests/test_mcp_tools.py +++ b/tests/test_mcp_tools.py @@ -1,5 +1,10 @@ """Tests for MCP tools.""" +import json + +from httpx import ASGITransport, AsyncClient + +from data_api.api.api import app from data_api.mcp.tools.announcements import _get_announcements from data_api.mcp.tools.buses import _get_bus_stops, _get_next_buses from data_api.mcp.tools.campus import _search_campus @@ -13,6 +18,34 @@ class TestMCPTools: """Tests for MCP tools functionality.""" + async def test_mcp_http_initialize(self): + """Test the mounted MCP endpoint accepts an initialize request.""" + request = { + "jsonrpc": "2.0", + "id": 1, + "method": "initialize", + "params": { + "protocolVersion": "2025-11-25", + "capabilities": {}, + "clientInfo": {"name": "test-client", "version": "1.0"}, + }, + } + + async with app.router.lifespan_context(app): + async with AsyncClient( + transport=ASGITransport(app=app), base_url="http://test" + ) as client: + response = await client.post( + "/mcp", + headers={"Accept": "application/json, text/event-stream"}, + json=request, + ) + + assert response.status_code == 200 + assert response.headers["content-type"].startswith("text/event-stream") + payload = json.loads(response.text.split("data: ", maxsplit=1)[1]) + assert payload["result"]["serverInfo"]["name"] == "NTHU Campus Assistant" + async def test_search_campus(self): """Test campus search tool.""" result = await _search_campus(query="教務處") From f9e451c7a9d3670bf10424a73925f02313a0dbfd Mon Sep 17 00:00:00 2001 From: Sabrina Tso <316314148+SabrinaTso@users.noreply.github.com> Date: Sun, 23 Aug 2026 06:52:48 +0800 Subject: [PATCH 2/2] chore: exclude local artifacts from Docker context --- .dockerignore | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.dockerignore b/.dockerignore index 98ebc9a..bf73c8e 100644 --- a/.dockerignore +++ b/.dockerignore @@ -3,5 +3,12 @@ __pycache__ *.pyc *.log venv/ +.venv/ .env -tests/ \ No newline at end of file +.env.* +tests/ +.pytest_cache/ +.coverage +.coverage.* +htmlcov/ +.mypy_cache/