snapquery 0.0.2__tar.gz → 0.0.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {snapquery-0.0.2 → snapquery-0.0.3}/PKG-INFO +1 -1
- snapquery-0.0.3/snapquery/__init__.py +1 -0
- {snapquery-0.0.2 → snapquery-0.0.3}/snapquery/snapquery_cmd.py +11 -5
- {snapquery-0.0.2 → snapquery-0.0.3}/snapquery/snapquery_core.py +75 -4
- snapquery-0.0.3/snapquery/snapquery_view.py +95 -0
- {snapquery-0.0.2 → snapquery-0.0.3}/snapquery/snapquery_webserver.py +58 -12
- {snapquery-0.0.2 → snapquery-0.0.3}/snapquery/version.py +1 -1
- {snapquery-0.0.2 → snapquery-0.0.3}/tests/test_restful_api.py +23 -8
- snapquery-0.0.2/snapquery/__init__.py +0 -1
- {snapquery-0.0.2 → snapquery-0.0.3}/.github/workflows/build.yml +0 -0
- {snapquery-0.0.2 → snapquery-0.0.3}/.github/workflows/upload-to-pypi.yml +0 -0
- {snapquery-0.0.2 → snapquery-0.0.3}/.gitignore +0 -0
- {snapquery-0.0.2 → snapquery-0.0.3}/.project +0 -0
- {snapquery-0.0.2 → snapquery-0.0.3}/.pydevproject +0 -0
- {snapquery-0.0.2 → snapquery-0.0.3}/LICENSE +0 -0
- {snapquery-0.0.2 → snapquery-0.0.3}/README.md +0 -0
- {snapquery-0.0.2 → snapquery-0.0.3}/pyproject.toml +0 -0
- {snapquery-0.0.2 → snapquery-0.0.3}/scripts/blackisort +0 -0
- {snapquery-0.0.2 → snapquery-0.0.3}/scripts/install +0 -0
- {snapquery-0.0.2 → snapquery-0.0.3}/scripts/test +0 -0
- {snapquery-0.0.2 → snapquery-0.0.3}/tests/__init__.py +0 -0
- {snapquery-0.0.2 → snapquery-0.0.3}/tests/test_endpoints.py +0 -0
- {snapquery-0.0.2 → snapquery-0.0.3}/tests/test_namedqueries.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: snapquery
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.3
|
|
4
4
|
Summary: snapquery: Introduce Named Queries and Named Query Middleware to wikidata
|
|
5
5
|
Project-URL: Home, https://github.com/WolfgangFahl/snapquery
|
|
6
6
|
Project-URL: Documentation, https://wiki.bitplan.com/index.php/snapquery
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.0.3"
|
|
@@ -42,6 +42,12 @@ class SnapQueryCmd(WebserverCmd):
|
|
|
42
42
|
action="store_true",
|
|
43
43
|
help="show the list of available endpoints",
|
|
44
44
|
)
|
|
45
|
+
parser.add_argument(
|
|
46
|
+
"--limit", type=int, default=None, help="set limit parameter of query"
|
|
47
|
+
)
|
|
48
|
+
parser.add_argument(
|
|
49
|
+
"--namespace", type=str, default="wikidata-examples", help="namespace to filter queries"
|
|
50
|
+
)
|
|
45
51
|
parser.add_argument("-qn", "--queryName", help="run a named query")
|
|
46
52
|
parser.add_argument("-f", "--format", type=Format, choices=list(Format))
|
|
47
53
|
return parser
|
|
@@ -61,14 +67,14 @@ class SnapQueryCmd(WebserverCmd):
|
|
|
61
67
|
handled = True # Operation handled
|
|
62
68
|
elif self.args.queryName is not None:
|
|
63
69
|
nqm = NamedQueryManager()
|
|
70
|
+
namespace=self.args.namespace
|
|
64
71
|
name = self.args.queryName
|
|
65
72
|
endpoint_name = self.args.endpointName
|
|
66
73
|
r_format = self.args.format
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
return handled
|
|
74
|
+
limit=self.args.limit
|
|
75
|
+
formatted_result=nqm.formatted_query(name, namespace=namespace,endpoint_name=endpoint_name, r_format=r_format,limit=limit)
|
|
76
|
+
print(formatted_result)
|
|
77
|
+
return handled
|
|
72
78
|
|
|
73
79
|
|
|
74
80
|
def main(argv: list = None):
|
|
@@ -4,6 +4,7 @@ Created on 2024-05-03
|
|
|
4
4
|
@author: wf
|
|
5
5
|
"""
|
|
6
6
|
import json
|
|
7
|
+
import re
|
|
7
8
|
import os
|
|
8
9
|
from dataclasses import field
|
|
9
10
|
from pathlib import Path
|
|
@@ -14,6 +15,7 @@ from lodstorage.query import Endpoint, EndpointManager, Format, Query
|
|
|
14
15
|
from lodstorage.sparql import SPARQL
|
|
15
16
|
from lodstorage.sql import SQLDB, EntityInfo
|
|
16
17
|
from lodstorage.yamlable import lod_storable
|
|
18
|
+
from ngwidgets.widgets import Link
|
|
17
19
|
|
|
18
20
|
|
|
19
21
|
@lod_storable
|
|
@@ -50,6 +52,37 @@ class NamedQuery:
|
|
|
50
52
|
"""
|
|
51
53
|
self.query_id = f"{self.namespace}.{self.name}"
|
|
52
54
|
|
|
55
|
+
def as_link(self) -> str:
|
|
56
|
+
url = f"/query/{self.namespace}/{self.name}"
|
|
57
|
+
text = self.name
|
|
58
|
+
tooltip = "query details"
|
|
59
|
+
link = Link.create(url, text, tooltip)
|
|
60
|
+
return link
|
|
61
|
+
|
|
62
|
+
@classmethod
|
|
63
|
+
def from_record(cls, record: Dict) -> "NamedQuery":
|
|
64
|
+
"""
|
|
65
|
+
Class method to instantiate NamedQuery from a dictionary record.
|
|
66
|
+
"""
|
|
67
|
+
return cls(
|
|
68
|
+
namespace=record["namespace"],
|
|
69
|
+
name=record["name"],
|
|
70
|
+
title=record["title"],
|
|
71
|
+
description=record["description"],
|
|
72
|
+
sparql=record["sparql"],
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
def as_viewrecord(self) -> Dict:
|
|
76
|
+
"""
|
|
77
|
+
Return a dictionary representing the NamedQuery with keys ordered as Name, Namespace, Title, Description.
|
|
78
|
+
"""
|
|
79
|
+
return {
|
|
80
|
+
"name": self.as_link(),
|
|
81
|
+
"namespace": self.namespace,
|
|
82
|
+
"title": self.title,
|
|
83
|
+
"description": self.description,
|
|
84
|
+
}
|
|
85
|
+
|
|
53
86
|
|
|
54
87
|
class NamedQueryManager:
|
|
55
88
|
"""
|
|
@@ -72,7 +105,7 @@ class NamedQueryManager:
|
|
|
72
105
|
if db_path is None:
|
|
73
106
|
db_path = NamedQueryManager.get_cache_path()
|
|
74
107
|
self.debug = debug
|
|
75
|
-
self.sql_db = SQLDB(dbname=db_path,check_same_thread=False, debug=debug)
|
|
108
|
+
self.sql_db = SQLDB(dbname=db_path, check_same_thread=False, debug=debug)
|
|
76
109
|
self.endpoints = EndpointManager.getEndpoints(lang="sparql")
|
|
77
110
|
|
|
78
111
|
@classmethod
|
|
@@ -196,6 +229,7 @@ WHERE
|
|
|
196
229
|
name: str,
|
|
197
230
|
namespace: str = "wikidata-examples",
|
|
198
231
|
endpoint_name: str = "wikidata",
|
|
232
|
+
limit:int=None
|
|
199
233
|
):
|
|
200
234
|
"""
|
|
201
235
|
Execute a named SPARQL query using a specified endpoint and return the results.
|
|
@@ -204,6 +238,7 @@ WHERE
|
|
|
204
238
|
name (str): The name of the named query to execute.
|
|
205
239
|
namespace (str): The namespace of the named query, default is 'wikidata-examples'.
|
|
206
240
|
endpoint_name (str): The name of the endpoint to send the SPARQL query to, default is 'wikidata'.
|
|
241
|
+
limit(int): the query limit (if any)
|
|
207
242
|
|
|
208
243
|
Returns:
|
|
209
244
|
Dict[str, Any]: The results of the SPARQL query in JSON format.
|
|
@@ -218,15 +253,52 @@ WHERE
|
|
|
218
253
|
msg = f"Invalid endpoint {endpoint_name}"
|
|
219
254
|
ValueError(msg)
|
|
220
255
|
endpoint = self.endpoints.get(endpoint_name)
|
|
256
|
+
self.query = Query(name=name, query=sparql_query, lang="sparql",limit=limit)
|
|
257
|
+
|
|
221
258
|
sparql = SPARQL(endpoint.endpoint)
|
|
259
|
+
if limit:
|
|
260
|
+
# @TODO - this is to naive for cases where there are
|
|
261
|
+
# SPARQL elements hat have a "limit" in the name e.g. "height_limit"
|
|
262
|
+
if "limit" in sparql_query or "LIMIT" in sparql_query:
|
|
263
|
+
sparql_query = re.sub(
|
|
264
|
+
r"(limit|LIMIT)\s+(\d+)", f"LIMIT {limit}", sparql_query
|
|
265
|
+
)
|
|
266
|
+
else:
|
|
267
|
+
sparql_query += f"\nLIMIT {limit}"
|
|
222
268
|
lod = sparql.queryAsListOfDicts(sparql_query)
|
|
223
269
|
return lod
|
|
270
|
+
|
|
271
|
+
def formatted_query(self,
|
|
272
|
+
name: str,
|
|
273
|
+
namespace: str = "wikidata-examples",
|
|
274
|
+
endpoint_name: str = "wikidata",
|
|
275
|
+
r_format: Format = Format.html,
|
|
276
|
+
limit:int=None)->str:
|
|
277
|
+
"""
|
|
278
|
+
Execute a named SPARQL query using a specified endpoint and return the results formatted .
|
|
279
|
+
|
|
280
|
+
Args:
|
|
281
|
+
name (str): The name of the named query to execute.
|
|
282
|
+
namespace (str): The namespace of the named query, default is 'wikidata-examples'.
|
|
283
|
+
endpoint_name (str): The name of the endpoint to send the SPARQL query to, default is 'wikidata'.
|
|
284
|
+
r_format: (Format): the format to result should be returned in
|
|
285
|
+
limit(int): the query limit (if any)
|
|
286
|
+
Returns:
|
|
287
|
+
str: The results of the SPARQL query in the given format.
|
|
288
|
+
|
|
289
|
+
Raises:
|
|
290
|
+
ValueError: If no named query matches the given name and namespace.
|
|
291
|
+
Exception: If the SPARQL query execution fails or the endpoint returns an error.
|
|
292
|
+
"""
|
|
293
|
+
qlod = self.query(endpoint_name=endpoint_name, name=name,namespace=namespace,limit=limit)
|
|
294
|
+
formatted_result=self.format_result(qlod=qlod, query=self.query, r_format=r_format, endpoint_name=endpoint_name)
|
|
295
|
+
return formatted_result
|
|
224
296
|
|
|
225
297
|
def format_result(
|
|
226
298
|
self,
|
|
227
299
|
qlod: List[Dict[str, Any]],
|
|
228
300
|
query: Query,
|
|
229
|
-
|
|
301
|
+
r_format: Format,
|
|
230
302
|
endpoint_name: str = "wikidata",
|
|
231
303
|
) -> Optional[str]:
|
|
232
304
|
"""
|
|
@@ -235,7 +307,7 @@ WHERE
|
|
|
235
307
|
Args:
|
|
236
308
|
qlod (List[Dict[str, Any]]): The list of dictionaries that represent the query results.
|
|
237
309
|
query (Query): The query object which contains details like the endpoint and the database.
|
|
238
|
-
r_format_str: The format in which to print the results.
|
|
310
|
+
r_format_str(Format): The format in which to print the results.
|
|
239
311
|
endpoint_name (str): The name of the endpoint to be used, defaults to "wikidata".
|
|
240
312
|
|
|
241
313
|
Returns:
|
|
@@ -245,7 +317,6 @@ WHERE
|
|
|
245
317
|
endpointConf = self.endpoints.get(endpoint_name, Endpoint.getDefault())
|
|
246
318
|
query.tryItUrl = endpointConf.website
|
|
247
319
|
query.database = endpointConf.database
|
|
248
|
-
r_format = Format[r_format_str]
|
|
249
320
|
|
|
250
321
|
if r_format == Format.csv:
|
|
251
322
|
csv_output = CSV.toCSV(qlod)
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Created on 2024-05-03
|
|
3
|
+
|
|
4
|
+
@author: wf
|
|
5
|
+
"""
|
|
6
|
+
import asyncio
|
|
7
|
+
from typing import List
|
|
8
|
+
|
|
9
|
+
from ngwidgets.input_webserver import InputWebSolution
|
|
10
|
+
from ngwidgets.lod_grid import ListOfDictsGrid
|
|
11
|
+
from nicegui import ui
|
|
12
|
+
|
|
13
|
+
from snapquery.snapquery_core import NamedQuery
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class NamedQuerySearch:
|
|
17
|
+
"""
|
|
18
|
+
search for namedqueries
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(self, solution: InputWebSolution):
|
|
22
|
+
self.solution = solution
|
|
23
|
+
self.nqm = self.solution.nqm
|
|
24
|
+
self.search_debounce_task = None
|
|
25
|
+
self.keystroke_time = 0.65 # minimum time in seconds to wait between keystrokes before starting searching
|
|
26
|
+
self.setup_ui()
|
|
27
|
+
self.namespace = "wikidata-examples"
|
|
28
|
+
self.name = ""
|
|
29
|
+
|
|
30
|
+
def setup_ui(self):
|
|
31
|
+
"""
|
|
32
|
+
setup my user interface
|
|
33
|
+
"""
|
|
34
|
+
with ui.row() as self.search_row:
|
|
35
|
+
self.namespace_search_input = (
|
|
36
|
+
ui.input(label="namespace", on_change=self.on_search_change)
|
|
37
|
+
.bind_value(self, "namespace")
|
|
38
|
+
.props("size=80")
|
|
39
|
+
)
|
|
40
|
+
self.name_search_input = (
|
|
41
|
+
ui.input(label="name", on_change=self.on_search_change)
|
|
42
|
+
.bind_value(self, "name")
|
|
43
|
+
.props("size=80")
|
|
44
|
+
)
|
|
45
|
+
with ui.row() as self.search_result_row:
|
|
46
|
+
self.search_result_grid = ListOfDictsGrid()
|
|
47
|
+
|
|
48
|
+
async def on_search_change(self, _args):
|
|
49
|
+
"""
|
|
50
|
+
react on changes in the search input
|
|
51
|
+
"""
|
|
52
|
+
# Cancel the existing search task if it's still waiting
|
|
53
|
+
if self.search_debounce_task:
|
|
54
|
+
self.search_debounce_task.cancel()
|
|
55
|
+
|
|
56
|
+
# Create a new task for the new search
|
|
57
|
+
self.search_debounce_task = asyncio.create_task(self.debounced_search())
|
|
58
|
+
|
|
59
|
+
async def debounced_search(self):
|
|
60
|
+
"""
|
|
61
|
+
Waits for a period of inactivity and then performs the search.
|
|
62
|
+
"""
|
|
63
|
+
try:
|
|
64
|
+
# Wait for the debounce period (keystroke_time)
|
|
65
|
+
await asyncio.sleep(self.keystroke_time)
|
|
66
|
+
sql_query = """SELECT
|
|
67
|
+
*
|
|
68
|
+
FROM NamedQuery
|
|
69
|
+
WHERE name LIKE ? and namespace LIKE? """
|
|
70
|
+
name_like = f"{self.name}%"
|
|
71
|
+
namespace_like = f"{self.namespace}%"
|
|
72
|
+
self.q_lod = self.nqm.sql_db.query(sql_query, (name_like, namespace_like))
|
|
73
|
+
self.show_lod(self.q_lod)
|
|
74
|
+
|
|
75
|
+
except asyncio.CancelledError:
|
|
76
|
+
# The search was cancelled because of new input, so just quietly exit
|
|
77
|
+
pass
|
|
78
|
+
except Exception as ex:
|
|
79
|
+
self.solution.handle_exception(ex)
|
|
80
|
+
|
|
81
|
+
def show_lod(self, q_lod: List):
|
|
82
|
+
"""
|
|
83
|
+
show the given list of dicts
|
|
84
|
+
"""
|
|
85
|
+
view_lod = []
|
|
86
|
+
for record in self.q_lod:
|
|
87
|
+
nq = NamedQuery.from_record(record)
|
|
88
|
+
vr = nq.as_viewrecord()
|
|
89
|
+
view_lod.append(vr)
|
|
90
|
+
if self.search_result_row:
|
|
91
|
+
with self.search_result_row:
|
|
92
|
+
ui.notify(f"found {len(q_lod)} queries")
|
|
93
|
+
self.search_result_grid.load_lod(view_lod)
|
|
94
|
+
# self.search_result_grid.set_checkbox_selection("#")
|
|
95
|
+
self.search_result_grid.update()
|
|
@@ -2,14 +2,15 @@
|
|
|
2
2
|
Created on 2024-05-03
|
|
3
3
|
@author: wf
|
|
4
4
|
"""
|
|
5
|
-
from fastapi import
|
|
6
|
-
from fastapi.responses import HTMLResponse
|
|
7
|
-
from lodstorage.query import Query
|
|
5
|
+
from fastapi import HTTPException
|
|
6
|
+
from fastapi.responses import HTMLResponse, PlainTextResponse
|
|
7
|
+
from lodstorage.query import Query, Format
|
|
8
8
|
from ngwidgets.input_webserver import InputWebserver, InputWebSolution, WebserverConfig
|
|
9
9
|
from nicegui import app
|
|
10
10
|
from nicegui.client import Client
|
|
11
11
|
|
|
12
12
|
from snapquery.snapquery_core import NamedQueryManager
|
|
13
|
+
from snapquery.snapquery_view import NamedQuerySearch
|
|
13
14
|
from snapquery.version import Version
|
|
14
15
|
|
|
15
16
|
|
|
@@ -39,8 +40,27 @@ class SnapQueryWebServer(InputWebserver):
|
|
|
39
40
|
InputWebserver.__init__(self, config=SnapQueryWebServer.get_config())
|
|
40
41
|
self.nqm = NamedQueryManager.from_samples()
|
|
41
42
|
|
|
42
|
-
@app.get("/
|
|
43
|
-
def
|
|
43
|
+
@app.get("/sparql/{namespace}/{name}")
|
|
44
|
+
def sparql(namespace: str, name: str) -> PlainTextResponse:
|
|
45
|
+
"""
|
|
46
|
+
Gets a SPARQL query by name within a specified namespace
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
namespace (str): The namespace identifying the group or category of the query.
|
|
50
|
+
name (str): The specific name of the query to be executed.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
HTMLResponse: The plain text SPARQL code
|
|
54
|
+
|
|
55
|
+
Raises:
|
|
56
|
+
HTTPException: If the query cannot be found or fails to execute.
|
|
57
|
+
"""
|
|
58
|
+
endpoint_name = "wikidata"
|
|
59
|
+
sparql_query = self.nqm.get_sparql(name, namespace, endpoint_name)
|
|
60
|
+
return PlainTextResponse(sparql_query)
|
|
61
|
+
|
|
62
|
+
@app.get("/query/{namespace}/{name}")
|
|
63
|
+
def query(namespace: str, name: str) -> HTMLResponse:
|
|
44
64
|
"""
|
|
45
65
|
Executes a SPARQL query by name within a specified namespace, formats the results, and returns them as an HTML response.
|
|
46
66
|
|
|
@@ -54,22 +74,23 @@ class SnapQueryWebServer(InputWebserver):
|
|
|
54
74
|
Raises:
|
|
55
75
|
HTTPException: If the query cannot be found or fails to execute.
|
|
56
76
|
"""
|
|
57
|
-
content=self.query(namespace,name)
|
|
77
|
+
content = self.query(namespace, name)
|
|
58
78
|
if not content:
|
|
59
79
|
raise HTTPException(status_code=500, detail="Could not create result")
|
|
60
80
|
|
|
61
81
|
# Return the content as an HTML response
|
|
62
82
|
return HTMLResponse(content)
|
|
63
|
-
|
|
64
|
-
def query(self,namespace:str,name:str):
|
|
83
|
+
|
|
84
|
+
def query(self, namespace: str, name: str):
|
|
85
|
+
""" """
|
|
65
86
|
endpoint_name = "wikidata"
|
|
66
87
|
# content negotiation
|
|
67
88
|
# Determine response format by extension in the name or Accept header
|
|
68
|
-
if
|
|
69
|
-
|
|
70
|
-
name = name[:name.rfind(
|
|
89
|
+
if "." in name:
|
|
90
|
+
r_format_str = name.split(".")[-1]
|
|
91
|
+
name = name[: name.rfind(".")]
|
|
71
92
|
else:
|
|
72
|
-
|
|
93
|
+
r_format_str = "html"
|
|
73
94
|
|
|
74
95
|
# Retrieve the SPARQL query string using the namespace and name.
|
|
75
96
|
try:
|
|
@@ -83,6 +104,7 @@ class SnapQueryWebServer(InputWebserver):
|
|
|
83
104
|
raise HTTPException(status_code=404, detail=str(e))
|
|
84
105
|
|
|
85
106
|
# Format the results and generate HTML content
|
|
107
|
+
r_format = Format[r_format_str]
|
|
86
108
|
content = self.nqm.format_result(
|
|
87
109
|
qlod, query, r_format, endpoint_name=endpoint_name
|
|
88
110
|
)
|
|
@@ -104,3 +126,27 @@ class SnapQuerySolution(InputWebSolution):
|
|
|
104
126
|
client (Client): The client instance this context is associated with.
|
|
105
127
|
"""
|
|
106
128
|
super().__init__(webserver, client) # Call to the superclass constructor
|
|
129
|
+
self.nqm = self.webserver.nqm
|
|
130
|
+
self.endpoint_name = "wikidata"
|
|
131
|
+
|
|
132
|
+
def configure_settings(self):
|
|
133
|
+
"""
|
|
134
|
+
add additional settings
|
|
135
|
+
"""
|
|
136
|
+
self.add_select("default Endpoint", list(self.nqm.endpoints.keys())).bind_value(
|
|
137
|
+
self, "endpoint_name"
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
def setup_ui(self):
|
|
141
|
+
"""
|
|
142
|
+
setup my user interface
|
|
143
|
+
"""
|
|
144
|
+
self.search = NamedQuerySearch(self)
|
|
145
|
+
|
|
146
|
+
async def home(
|
|
147
|
+
self,
|
|
148
|
+
):
|
|
149
|
+
"""Generates the home page with a selection of examples and
|
|
150
|
+
svg display
|
|
151
|
+
"""
|
|
152
|
+
await self.setup_content_div(self.setup_ui)
|
|
@@ -17,7 +17,7 @@ class Version:
|
|
|
17
17
|
name = "snapquery"
|
|
18
18
|
version = snapquery.__version__
|
|
19
19
|
date = "2024-05-03"
|
|
20
|
-
updated = "2024-05-
|
|
20
|
+
updated = "2024-05-04"
|
|
21
21
|
description = "Introduce Named Queries and Named Query Middleware to wikidata"
|
|
22
22
|
|
|
23
23
|
authors = "Wolfgang Fahl"
|
|
@@ -3,21 +3,22 @@ Created on 2024-05-03
|
|
|
3
3
|
|
|
4
4
|
@author: wf
|
|
5
5
|
"""
|
|
6
|
-
from snapquery.snapquery_webserver import SnapQueryWebServer
|
|
7
|
-
from snapquery.snapquery_cmd import SnapQueryCmd
|
|
8
6
|
from ngwidgets.webserver_test import WebserverTest
|
|
9
7
|
|
|
8
|
+
from snapquery.snapquery_cmd import SnapQueryCmd
|
|
9
|
+
from snapquery.snapquery_webserver import SnapQueryWebServer
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
|
|
12
|
+
class TestRestFulApi(WebserverTest):
|
|
12
13
|
"""
|
|
13
14
|
test endpoint handling according to https://github.com/WolfgangFahl/snapquery/issues/1
|
|
14
15
|
"""
|
|
16
|
+
|
|
15
17
|
def setUp(self, debug=True, profile=True):
|
|
16
18
|
server_class = SnapQueryWebServer
|
|
17
19
|
cmd_class = SnapQueryCmd
|
|
18
20
|
WebserverTest.setUp(self, server_class, cmd_class, debug=debug, profile=profile)
|
|
19
21
|
|
|
20
|
-
|
|
21
22
|
def testDemoWebserver(self):
|
|
22
23
|
"""
|
|
23
24
|
test API docs access
|
|
@@ -25,10 +26,24 @@ class TestRestFullApi(WebserverTest):
|
|
|
25
26
|
# self.debug=True
|
|
26
27
|
html = self.getHtml("/docs")
|
|
27
28
|
self.assertTrue("Swagger" in html)
|
|
28
|
-
|
|
29
|
+
|
|
30
|
+
def testSparqlApi(self):
|
|
31
|
+
"""
|
|
32
|
+
test the plaintext SPARQL API
|
|
33
|
+
"""
|
|
34
|
+
for example in ["cats", "horses"]:
|
|
35
|
+
path = f"/sparql/wikidata-examples/{example}"
|
|
36
|
+
sparql_query = self.getHtml(path)
|
|
37
|
+
if self.debug:
|
|
38
|
+
print(sparql_query)
|
|
39
|
+
self.assertTrue("SELECT" in sparql_query)
|
|
40
|
+
|
|
29
41
|
def testQueryApi(self):
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
42
|
+
"""
|
|
43
|
+
test the RESTFul Query API
|
|
44
|
+
"""
|
|
45
|
+
for r_format in ["mediawiki", "github", "latex", "html"]:
|
|
46
|
+
path = f"/query/wikidata-examples/cats.{r_format}"
|
|
47
|
+
html = self.getHtml(path)
|
|
33
48
|
if self.debug:
|
|
34
49
|
print(html)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.0.2"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|