#!/usr/bin/env python3 """ Vue3 Frontend Server - Proxy to gene-family-mas backend """ import os import sys import httpx from pathlib import Path from fastapi import FastAPI, UploadFile, File, HTTPException from fastapi.responses import FileResponse from fastapi.middleware.cors import CORSMiddleware import uvicorn #API_BASE_URL = "http://192.168.1.40:8000" #API_BASE_URL = "http://192.168.10.152:8000" API_BASE_URL = "http://localhost:8000" #API_BASE_URL = "/api" PORT = 3000 FRONTEND_DIR = Path(__file__).parent app = FastAPI(title="Gene Family MAS Frontend") app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) @app.get("/") async def root(): return FileResponse(FRONTEND_DIR / "index.html") @app.get("/kg.html") async def kg_page(): return FileResponse(FRONTEND_DIR / "kg.html") @app.get("/knowledge_graph.json") async def knowledge_graph_json(): return FileResponse(FRONTEND_DIR / "knowledge_graph.json") # 提供所有静态HTML文件 @app.get("/{filename}.html") async def html_files(filename: str): file_path = FRONTEND_DIR / f"{filename}.html" if file_path.exists(): return FileResponse(file_path) raise HTTPException(status_code=404, detail="File not found") # 提供所有静态JSON文件(支持带下划线的文件名) @app.get("/{filename}.json") async def json_files(filename: str): file_path = FRONTEND_DIR / f"{filename}.json" if file_path.exists(): return FileResponse(file_path) raise HTTPException(status_code=404, detail="File not found") # 提供带下划线版本号的JSON文件 @app.get("/knowledge_graph_{version}.json") async def knowledge_graph_versioned(version: str): file_path = FRONTEND_DIR / f"knowledge_graph_{version}.json" if file_path.exists(): return FileResponse(file_path) raise HTTPException(status_code=404, detail="File not found") # 提供包含多组学数据的知识图谱 @app.get("/knowledge_graph_with_omics.json") async def knowledge_graph_with_omics(): file_path = FRONTEND_DIR / "knowledge_graph_with_omics.json" if file_path.exists(): return FileResponse(file_path) raise HTTPException(status_code=404, detail="File not found") @app.post("/api/v1/upload/batch") async def upload_batch(files: list[UploadFile] = File(...)): async with httpx.AsyncClient() as client: form_data = [] for f in files: content = await f.read() form_data.append(("files", (f.filename, content, f.content_type))) response = await client.post(f"{API_BASE_URL}/api/v1/upload/batch", files=form_data) return response.json() @app.post("/api/v1/query") async def query(request: dict): async with httpx.AsyncClient() as client: response = await client.post(f"{API_BASE_URL}/api/v1/query", json=request) return response.json() @app.get("/api/v1/workspace/{job_id}/files") async def get_workspace_files(job_id: str): async with httpx.AsyncClient() as client: response = await client.get(f"{API_BASE_URL}/api/v1/workspace/{job_id}/files") if response.status_code == 404: return {"job_id": job_id, "directory": ".", "files": [], "subdirectories": []} return response.json() @app.get("/api/v1/files/{file_path:path}") async def get_file(file_path: str): async with httpx.AsyncClient() as client: response = await client.get(f"{API_BASE_URL}/api/v1/files/{file_path}") if response.status_code == 200: return response.content raise HTTPException(status_code=response.status_code, detail="File not found") @app.get("/api/v1/tools") async def get_tools(): async with httpx.AsyncClient() as client: response = await client.get(f"{API_BASE_URL}/api/v1/tools") return response.json() @app.get("/health") async def health(): return {"status": "ok", "backend": API_BASE_URL} if __name__ == "__main__": print(f"Starting frontend at http://localhost:{PORT}") print(f"Proxying to backend: {API_BASE_URL}") uvicorn.run(app, host="0.0.0.0", port=PORT)