|
|
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") |
|
|
|
|
|
|
|
|
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 """ |
|
|
<h1>Cars Knowledge Graph SPARQL Endpoint (FastAPI)</h1> |
|
|
<p>The Knowledge Graph is published and accessible.</p> |
|
|
<p>Send SPARQL queries to: <code>/sparql</code></p> |
|
|
<h3>Example Query:</h3> |
|
|
<pre> |
|
|
SELECT ?s ?p ?o WHERE { ?s ?p ?o } LIMIT 10 |
|
|
</pre> |
|
|
<p>View API Docs at: <a href="/docs">/docs</a></p> |
|
|
""" |
|
|
|
|
|
async def run_query(query: str): |
|
|
if not query: |
|
|
raise HTTPException(status_code=400, detail="No query provided") |
|
|
|
|
|
try: |
|
|
results = g.query(query) |
|
|
|
|
|
|
|
|
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): |
|
|
|
|
|
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: |
|
|
|
|
|
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) |
|
|
|