| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- from pathlib import Path
- from urllib.parse import urlencode
- from urllib.request import Request, urlopen
- import json
- from fastapi import FastAPI, HTTPException
- from fastapi.responses import FileResponse
- from fastapi.staticfiles import StaticFiles
- app = FastAPI(title="格士立青岛出口本体接口")
- ROOT = Path(__file__).resolve().parents[1]
- QUERIES = ROOT / "queries"
- STATIC = ROOT / "app" / "static"
- FUSEKI_ENDPOINT = "http://localhost:3030/gesli/sparql"
- app.mount("/static", StaticFiles(directory=STATIC), name="static")
- @app.get("/health")
- def health():
- return {"status": "ok"}
- @app.get("/")
- def index():
- return FileResponse(STATIC / "index.html")
- @app.get("/api/orders")
- def orders():
- return query_file("order-status.rq")
- @app.get("/api/risks")
- def risks():
- return query_file("risk-orders.rq")
- @app.get("/api/flow")
- def flow():
- return query_file("operation-flow.rq")
- @app.get("/api/node-times")
- def node_times():
- return query_file("node-time-status.rq")
- @app.get("/api/order-cutoffs")
- def order_cutoffs():
- return query_file("order-cutoff-times.rq")
- @app.get("/api/exception-map")
- def exception_map():
- return query_file("exception-risk-map.rq")
- def query_file(filename: str):
- path = QUERIES / filename
- if not path.exists():
- raise HTTPException(status_code=404, detail=f"Query file not found: {filename}")
- return run_sparql(path.read_text(encoding="utf-8"))
- def run_sparql(query: str):
- data = urlencode({"query": query}).encode("utf-8")
- request = Request(
- FUSEKI_ENDPOINT,
- data=data,
- headers={
- "Accept": "application/sparql-results+json",
- "Content-Type": "application/x-www-form-urlencoded; charset=utf-8",
- },
- method="POST",
- )
- try:
- with urlopen(request, timeout=10) as response:
- payload = json.loads(response.read().decode("utf-8"))
- except Exception as exc:
- raise HTTPException(
- status_code=502,
- detail="无法连接 Fuseki。请确认 Docker 和 http://localhost:3030/gesli/sparql 正常运行。",
- ) from exc
- variables = payload.get("head", {}).get("vars", [])
- rows = []
- for binding in payload.get("results", {}).get("bindings", []):
- rows.append({
- variable: binding.get(variable, {}).get("value", "")
- for variable in variables
- })
- return {"rows": rows}
|