Skip to content

Commit

Permalink
move the logic to handle the SPARQL request out of the GET method, to…
Browse files Browse the repository at this point in the history
… a separate function
  • Loading branch information
vemonet committed Dec 8, 2023
1 parent 79c7c55 commit 5392e88
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 20 deletions.
1 change: 1 addition & 0 deletions example/app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ def most_similar(query_results, ctx, part, eval_part):
cors_enabled=True,
example_query=example_query,
example_queries=example_queries,
enable_update=True,
)

## Uncomment to run it directly with python app/main.py
Expand Down
47 changes: 27 additions & 20 deletions src/rdflib_endpoint/sparql_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,7 @@ def _parse_preference(qpref: str) -> float:
qparts = qpref.split("=")
try:
return float(qparts[1].strip())
except ValueError:
pass
except IndexError:
except (ValueError, IndexError):
pass
return 1.0

Expand Down Expand Up @@ -197,22 +195,10 @@ def __init__(
elif len(self.functions) > 0:
rdflib.plugins.sparql.CUSTOM_EVALS["evalCustomFunctions"] = self.eval_custom_functions

# TODO: use add_api_route? https://github.com/tiangolo/fastapi/blob/d666ccb62216e45ca78643b52c235ba0d2c53986/fastapi/routing.py#L548
@self.get(
self.path,
name="SPARQL endpoint",
description=self.example_markdown,
responses=api_responses,
)
async def sparql_endpoint(
request: Request, query: Optional[str] = Query(None), update: Optional[str] = None # Not supported for GET
async def handle_sparql_request(
request: Request, query: Optional[str] = None, update: Optional[str] = None
) -> Response:
"""
Send a SPARQL query to be executed through HTTP GET operation.
:param request: The HTTP GET request
:param query: SPARQL query input.
"""
"""Handle SPARQL requests to the GET and POST endpoints"""
if query and update:
return JSONResponse(
status_code=400,
Expand Down Expand Up @@ -295,7 +281,7 @@ async def sparql_endpoint(
status_code=400,
content={"message": "Error executing the SPARQL query on the RDFLib Graph"},
)
else: # update
else: # Update
if not self.enable_update:
return JSONResponse(
status_code=403, content={"message": "INSERT and DELETE queries are not allowed."}
Expand All @@ -319,6 +305,25 @@ async def sparql_endpoint(
content={"message": "Error executing the SPARQL update on the RDFLib Graph"},
)

# TODO: use add_api_route? https://github.com/tiangolo/fastapi/blob/d666ccb62216e45ca78643b52c235ba0d2c53986/fastapi/routing.py#L548
@self.get(
self.path,
name="SPARQL endpoint",
description=self.example_markdown,
responses=api_responses,
)
async def get_sparql_endpoint(
request: Request,
query: Optional[str] = Query(None),
) -> Response:
"""
Send a SPARQL query to be executed through HTTP GET operation.
:param request: The HTTP GET request
:param query: SPARQL query input.
"""
return await handle_sparql_request(request, query=query)

@self.post(
path,
name="SPARQL endpoint",
Expand All @@ -345,11 +350,13 @@ async def post_sparql_endpoint(request: Request) -> Response:
query = parse.unquote(query_params[0]) if query_params else None
update_params = [kvp[1] for kvp in request_params if kvp[0] == "update"]
update = parse.unquote(update_params[0]) if update_params else None
# TODO: handle params `using-graph-uri` and `using-named-graph-uri`
# https://www.w3.org/TR/sparql11-protocol/#update-operation
else:
# Response with the service description
query = None
update = None
return await sparql_endpoint(request, query, update)
return await handle_sparql_request(request, query, update)

def eval_custom_functions(self, ctx: QueryContext, part: CompValue) -> List[Any]:
"""Retrieve variables from a SPARQL-query, then execute registered SPARQL functions
Expand Down
1 change: 1 addition & 0 deletions tests/test_parse_accept.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
("text/xml", "text/xml"),
("text/rdf+xml, text/xml, */*", "text/rdf+xml"),
("text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8", "text/html"),
("text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=", "text/html"),
("text/html;q=0.3, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8", "application/xhtml+xml"),
(
'text/turtle;q=0.9;profile="urn:example:profile-1", text/turtle;q=0.7;profile="urn:example:profile-2"',
Expand Down
5 changes: 5 additions & 0 deletions tests/test_rdflib_endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ def test_sparql_update(api_key, key_provided, param_method, monkeypatch):
assert (subject, RDFS.label, Literal("bar")) not in graph


def test_sparql_query_update_fail():
response = endpoint.post("/", data={"update": label_patch, "query": label_patch})
assert response.status_code == 400


def test_multiple_accept_return_json():
response = endpoint.get(
"/",
Expand Down

0 comments on commit 5392e88

Please sign in to comment.