from fastapi import FastAPI, Query, Request, HTTPException from fastapi.responses import JSONResponse, HTMLResponse from rdflib import Graph import os import uvicorn app = FastAPI(title="Cars Knowledge Graph SPARQL Endpoint") # Load the Knowledge Graph g = Graph() GRAPH_FILE = "cars_knowledge_graph.ttl" if os.path.exists(GRAPH_FILE): print(f"Loading Knowledge Graph from {GRAPH_FILE}...") g.parse(GRAPH_FILE, format="turtle") print(f"Graph loaded with {len(g)} triples.") else: print(f"WARNING: {GRAPH_FILE} not found. Please run convert_data.py first.") @app.get("/", response_class=HTMLResponse) async def home(): return """

Cars Knowledge Graph SPARQL Endpoint (FastAPI)

The Knowledge Graph is published and accessible.

Send SPARQL queries to: /sparql

Example Query:

    SELECT ?s ?p ?o WHERE { ?s ?p ?o } LIMIT 10
    

View API Docs at: /docs

""" async def run_query(query: str): if not query: raise HTTPException(status_code=400, detail="No query provided") try: results = g.query(query) # Format results as JSON res_list = [] for row in results: res_dict = {} if getattr(results, "vars", None): for i, var in enumerate(results.vars): if row[i] is not None: res_dict[str(var)] = str(row[i]) res_list.append(res_dict) return {"results": res_list} except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @app.get("/sparql") async def sparql_get(query: str = Query(..., description="SPARQL Query")): return await run_query(query) @app.post("/sparql") async def sparql_post(request: Request): # Handle both form data and raw body content_type = request.headers.get("content-type", "") if "application/x-www-form-urlencoded" in content_type: form = await request.form() query = form.get("query") else: # data = await request.json() # Optional depending on client query = (await request.body()).decode("utf-8") return await run_query(query) if __name__ == "__main__": print("Starting SPARQL Endpoint on http://localhost:8000") uvicorn.run(app, host="0.0.0.0", port=8000)