|
@@ -3,6 +3,7 @@
|
|
|
import logging
|
|
|
import re
|
|
|
import arklog
|
|
|
+import pandas as pd
|
|
|
import rdflib
|
|
|
from typing import Any, Dict, List, Optional, Union
|
|
|
from urllib import parse
|
|
@@ -162,6 +163,95 @@ class SparqlEndpoint(FastAPI):
|
|
|
return await sparql_endpoint_get(request, query)
|
|
|
|
|
|
|
|
|
+ # TODO Could also be query parameters
|
|
|
+ # TODO BIG UGLY HACK UPON HACK UPON HACK
|
|
|
+ """
|
|
|
+ PREFIX dtf: <https://ontology.rys.app/dt/function/>
|
|
|
+ SELECT * WHERE {
|
|
|
+ bind(str('http://localhost:8000') as ?base)
|
|
|
+ bind(str('cell') as ?operation)
|
|
|
+ bind(str('example.csv') as ?file)
|
|
|
+ bind(str(0) as ?row)
|
|
|
+ bind(str(0) as ?column)
|
|
|
+ bind(iri(concat(?base, "/", ?operation, "/", ?file, "/", ?row, "/", ?column, "/")) as ?call)
|
|
|
+ SERVICE ?call {?cell ?cell ?cell}
|
|
|
+ }
|
|
|
+
|
|
|
+ PREFIX dtf: <https://ontology.rys.app/dt/function/>
|
|
|
+ SELECT ?cell WHERE {
|
|
|
+ bind(iri(concat("http://localhost:8000/cell/","example.csv/0/0/")) as ?call)
|
|
|
+ SERVICE ?call {}
|
|
|
+ }
|
|
|
+
|
|
|
+ PREFIX dtf: <https://ontology.rys.app/dt/function/>
|
|
|
+ SELECT ?cell WHERE {
|
|
|
+ BIND(uri(<http://localhost:8000/cell/example.csv/0/0/>) AS ?mep)
|
|
|
+ SERVICE ?mep {
|
|
|
+ SELECT * WHERE {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ PREFIX dtf: <https://ontology.rys.app/dt/function/>
|
|
|
+ SELECT * WHERE {
|
|
|
+ BIND("\"example.csv\"" as ?filepath)
|
|
|
+ BIND(0 as ?row)
|
|
|
+ BIND(0 as ?column)
|
|
|
+ BIND(CONCAT(?filepath,"/",STR(?row),"/",STR(?column),"/") as ?params)
|
|
|
+ BIND(uri(CONCAT("<http://localhost:8000/cell/",?params,">")) as ?call)
|
|
|
+ SERVICE ?call {SELECT * WHERE {}}
|
|
|
+ }
|
|
|
+ """
|
|
|
+ @self.get("/cell/{file_name}/{row}/{column}/", name="SPARQL endpoint", description="", responses=api_responses)
|
|
|
+ async def sparql_cell_endpoint_get(request: Request, file_name, row, column, query: Optional[str] = Query(None)) -> Response:
|
|
|
+ logging.debug("Received cell GET request.")
|
|
|
+
|
|
|
+ query=f"""
|
|
|
+ PREFIX dtf: <https://ontology.rys.app/dt/function/>
|
|
|
+ SELECT * WHERE {{BIND(dtf:cell("data/{file_name}", {row}, {column}) AS ?cell)}}
|
|
|
+ """
|
|
|
+
|
|
|
+ graph_ns = {}
|
|
|
+ for prefix, ns_uri in self.graph.namespaces():
|
|
|
+ graph_ns[prefix] = ns_uri
|
|
|
+
|
|
|
+ try:
|
|
|
+ parsed_query = prepareQuery(query, initNs=graph_ns)
|
|
|
+ query_operation = re.sub(r"(\w)([A-Z])", r"\1 \2", parsed_query.algebra.name)
|
|
|
+ except Exception as e:
|
|
|
+ logging.error("Error parsing the SPARQL query: " + str(e))
|
|
|
+ return JSONResponse(
|
|
|
+ status_code=400,
|
|
|
+ content={"message": "Error parsing the SPARQL query"},
|
|
|
+ )
|
|
|
+
|
|
|
+ try:
|
|
|
+ query_results = self.graph.query(query, initNs=graph_ns)
|
|
|
+ except Exception as e:
|
|
|
+ logging.error("Error executing the SPARQL query on the RDFLib Graph: " + str(e))
|
|
|
+ # TODO Send better error which can be parsed as a SPARQL response or check it client side
|
|
|
+ return JSONResponse(
|
|
|
+ status_code=400,
|
|
|
+ content={"message": "Error executing the SPARQL query on the RDFLib Graph"},
|
|
|
+ )
|
|
|
+ output_mime_type = await self.requested_result_type(request, query_operation)
|
|
|
+ logging.debug(f"Returning {output_mime_type}.")
|
|
|
+ try:
|
|
|
+ if self.is_csv_mime_type(output_mime_type):
|
|
|
+ return Response(query_results.serialize(format="csv"), media_type=output_mime_type)
|
|
|
+ elif self.is_json_mime_type(output_mime_type):
|
|
|
+ return Response(query_results.serialize(format="json"), media_type=output_mime_type)
|
|
|
+ elif self.is_xml_mime_type(output_mime_type):
|
|
|
+ return Response(query_results.serialize(format="xml"), media_type=output_mime_type)
|
|
|
+ elif self.is_turtle_mime_type(output_mime_type):
|
|
|
+ return Response(query_results.serialize(format="turtle"), media_type=output_mime_type)
|
|
|
+ return Response(query_results.serialize(format="xml"), media_type="application/sparql-results+xml")
|
|
|
+ except Exception as e:
|
|
|
+ logging.exception(e)
|
|
|
+ return JSONResponse(status_code=400,
|
|
|
+ content={"message": "Error executing the SPARQL query on the RDFLib Graph"})
|
|
|
+
|
|
|
+
|
|
|
def eval_custom_functions(self, ctx: QueryContext, part: CompValue) -> List[Any]:
|
|
|
if part.name != "Extend":
|
|
|
raise NotImplementedError()
|