Spaces:
Sleeping
Sleeping
| import os | |
| import json | |
| import httpx | |
| from fastapi import FastAPI, HTTPException, APIRouter | |
| from datetime import datetime, timedelta | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from fastmcp.server import FastMCP | |
| from contextlib import asynccontextmanager | |
| from typing import List, Dict, Optional | |
| # 初始化 MCP 服务器(必须在 FastAPI 之前) | |
| mcp_server = FastMCP(name="GitHubTrendingAPI") | |
| async def lifespan(app: FastAPI): | |
| await fetch_github_trending() | |
| yield | |
| app = FastAPI(lifespan=lifespan) | |
| # CORS 配置 | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| # 缓存变量 | |
| cached_trending = [] | |
| last_updated = None | |
| async def fetch_github_trending(): | |
| global cached_trending, last_updated | |
| headers = {"Accept": "application/vnd.github.v3+json"} | |
| if token := os.getenv("GITHUB_TOKEN"): | |
| headers["Authorization"] = f"token {token}" | |
| try: | |
| async with httpx.AsyncClient() as client: | |
| r = await client.get( | |
| "https://api.github.com/search/repositories", | |
| params={"q": "stars:>1000", "sort": "stars", "per_page": 10}, | |
| headers=headers | |
| ) | |
| r.raise_for_status() | |
| cached_trending = [ | |
| { | |
| "name": repo["full_name"], | |
| "url": repo["html_url"], | |
| "stars": repo["stargazers_count"] | |
| } | |
| for repo in r.json()["items"] | |
| ] | |
| last_updated = datetime.now() | |
| except Exception as e: | |
| print(f"Fetch error: {e}") | |
| if not cached_trending: | |
| raise HTTPException(500, "Failed to fetch data") | |
| async def get_trending_repos(num: int = 10) -> dict: | |
| if not last_updated or (datetime.now() - last_updated) > timedelta(minutes=30): | |
| await fetch_github_trending() | |
| return {"trending": cached_trending[:num]} | |
| # 关键修改:正确挂载MCP路由 | |
| # 方案1:直接挂载整个MCP应用 | |
| app.mount("/mcp", mcp_server.http_app()) | |
| # 方案2:或者使用APIRouter(如果方案1不行) | |
| # mcp_router = APIRouter() | |
| # mcp_router.include_router(mcp_server.http_app().router, prefix="") | |
| # app.include_router(mcp_router, prefix="/mcp") | |
| # 添加MCP健康检查路由 | |
| async def mcp_health_check(): | |
| return {"status": "ok", "mcp_version": "1.0"} | |
| async def root(): | |
| # 添加更多有用的调试信息 | |
| return { | |
| "message": "API is running", | |
| "endpoints": { | |
| "mcp_tool": "/mcp/tool/get_trending_repos", | |
| "mcp_schema": "/mcp/schema", | |
| "mcp_health": "/mcp/health", | |
| "trending": "/trending" | |
| } | |
| } | |
| async def get_trending(num: int = 10): | |
| if not cached_trending: | |
| await fetch_github_trending() | |
| return {"trending": cached_trending[:num]} | |
| # 在app.py中添加 | |
| async def mcp_root(): | |
| return { | |
| "message": "MCP API root", | |
| "endpoints": { | |
| "tools": "/mcp/tool", | |
| "schema": "/mcp/schema" | |
| } | |
| } |