qlever 0.2.5__py3-none-any.whl → 0.5.41__py3-none-any.whl

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.
Files changed (68) hide show
  1. qlever/Qleverfiles/Qleverfile.dblp +36 -0
  2. qlever/Qleverfiles/Qleverfile.dblp-plus +33 -0
  3. qlever/Qleverfiles/Qleverfile.dbpedia +30 -0
  4. qlever/Qleverfiles/Qleverfile.default +51 -0
  5. qlever/Qleverfiles/Qleverfile.dnb +40 -0
  6. qlever/Qleverfiles/Qleverfile.fbeasy +29 -0
  7. qlever/Qleverfiles/Qleverfile.freebase +28 -0
  8. qlever/Qleverfiles/Qleverfile.imdb +36 -0
  9. qlever/Qleverfiles/Qleverfile.ohm-planet +41 -0
  10. qlever/Qleverfiles/Qleverfile.olympics +31 -0
  11. qlever/Qleverfiles/Qleverfile.orkg +30 -0
  12. qlever/Qleverfiles/Qleverfile.osm-country +39 -0
  13. qlever/Qleverfiles/Qleverfile.osm-planet +39 -0
  14. qlever/Qleverfiles/Qleverfile.osm-planet-from-pbf +42 -0
  15. qlever/Qleverfiles/Qleverfile.pubchem +131 -0
  16. qlever/Qleverfiles/Qleverfile.scientists +29 -0
  17. qlever/Qleverfiles/Qleverfile.uniprot +74 -0
  18. qlever/Qleverfiles/Qleverfile.vvz +31 -0
  19. qlever/Qleverfiles/Qleverfile.wikidata +42 -0
  20. qlever/Qleverfiles/Qleverfile.wikipathways +40 -0
  21. qlever/Qleverfiles/Qleverfile.yago-4 +33 -0
  22. qlever/__init__.py +44 -1380
  23. qlever/command.py +87 -0
  24. qlever/commands/__init__.py +0 -0
  25. qlever/commands/add_text_index.py +115 -0
  26. qlever/commands/benchmark_queries.py +1019 -0
  27. qlever/commands/cache_stats.py +125 -0
  28. qlever/commands/clear_cache.py +88 -0
  29. qlever/commands/extract_queries.py +120 -0
  30. qlever/commands/get_data.py +48 -0
  31. qlever/commands/index.py +333 -0
  32. qlever/commands/index_stats.py +306 -0
  33. qlever/commands/log.py +66 -0
  34. qlever/commands/materialized_view.py +110 -0
  35. qlever/commands/query.py +142 -0
  36. qlever/commands/rebuild_index.py +176 -0
  37. qlever/commands/reset_updates.py +59 -0
  38. qlever/commands/settings.py +115 -0
  39. qlever/commands/setup_config.py +97 -0
  40. qlever/commands/start.py +336 -0
  41. qlever/commands/status.py +50 -0
  42. qlever/commands/stop.py +90 -0
  43. qlever/commands/system_info.py +130 -0
  44. qlever/commands/ui.py +271 -0
  45. qlever/commands/update.py +90 -0
  46. qlever/commands/update_wikidata.py +1204 -0
  47. qlever/commands/warmup.py +41 -0
  48. qlever/config.py +223 -0
  49. qlever/containerize.py +167 -0
  50. qlever/log.py +55 -0
  51. qlever/qlever_main.py +79 -0
  52. qlever/qleverfile.py +530 -0
  53. qlever/util.py +330 -0
  54. qlever-0.5.41.dist-info/METADATA +127 -0
  55. qlever-0.5.41.dist-info/RECORD +59 -0
  56. {qlever-0.2.5.dist-info → qlever-0.5.41.dist-info}/WHEEL +1 -1
  57. qlever-0.5.41.dist-info/entry_points.txt +2 -0
  58. qlever-0.5.41.dist-info/top_level.txt +1 -0
  59. build/lib/qlever/__init__.py +0 -1383
  60. build/lib/qlever/__main__.py +0 -4
  61. qlever/__main__.py +0 -4
  62. qlever-0.2.5.dist-info/METADATA +0 -277
  63. qlever-0.2.5.dist-info/RECORD +0 -12
  64. qlever-0.2.5.dist-info/entry_points.txt +0 -2
  65. qlever-0.2.5.dist-info/top_level.txt +0 -4
  66. src/qlever/__init__.py +0 -1383
  67. src/qlever/__main__.py +0 -4
  68. {qlever-0.2.5.dist-info → qlever-0.5.41.dist-info/licenses}/LICENSE +0 -0
qlever/util.py ADDED
@@ -0,0 +1,330 @@
1
+ from __future__ import annotations
2
+
3
+ import errno
4
+ import re
5
+ import secrets
6
+ import shlex
7
+ import shutil
8
+ import socket
9
+ import string
10
+ import subprocess
11
+ from datetime import date, datetime
12
+ from pathlib import Path
13
+ from typing import Any, Optional
14
+
15
+ import psutil
16
+
17
+ from qlever.log import log
18
+
19
+
20
+ def get_total_file_size(patterns: list[str]) -> int:
21
+ """
22
+ Helper function that gets the total size of all files mathing the given
23
+ patterns in bytes.
24
+ """
25
+
26
+ total_size = 0
27
+ search_dir = Path.cwd()
28
+ for pattern in patterns:
29
+ for file in search_dir.glob(pattern):
30
+ total_size += file.stat().st_size
31
+ return total_size
32
+
33
+
34
+ def run_command(
35
+ cmd: str,
36
+ return_output: bool = False,
37
+ show_output: bool = False,
38
+ show_stderr: bool = False,
39
+ use_popen: bool = False,
40
+ ) -> Optional[str | subprocess.Popen]:
41
+ """
42
+ Run the given command and throw an exception if the exit code is non-zero.
43
+ If `return_output` is `True`, return what the command wrote to `stdout`.
44
+
45
+ NOTE: The `set -o pipefail` ensures that the exit code of the command is
46
+ non-zero if any part of the pipeline fails (not just the last part).
47
+
48
+ TODO: Find the executable for `bash` in `__init__.py`.
49
+ """
50
+
51
+ subprocess_args = {
52
+ "executable": shutil.which("bash"),
53
+ "shell": True,
54
+ "text": True,
55
+ "stdout": None if show_output else subprocess.PIPE,
56
+ "stderr": None if show_stderr else subprocess.PIPE,
57
+ }
58
+
59
+ # With `Popen`, the command runs in the current shell and a process object
60
+ # is returned (which can be used, e.g., to kill the process).
61
+ if use_popen:
62
+ if return_output:
63
+ raise Exception("Cannot return output if `use_popen` is `True`")
64
+ return subprocess.Popen(f"set -o pipefail; {cmd}", **subprocess_args)
65
+
66
+ # With `run`, the command runs in a subshell and the output is captured.
67
+ result = subprocess.run(f"set -o pipefail; {cmd}", **subprocess_args)
68
+
69
+ # If the exit code is non-zero, throw an exception. If something was
70
+ # written to `stderr`, use that as the exception message. Otherwise, use a
71
+ # generic message (which is also what `subprocess.run` does with
72
+ # `check=True`).
73
+ if result.returncode != 0:
74
+ if len(result.stderr) > 0:
75
+ raise Exception(result.stderr.replace("\n", " ").strip())
76
+ else:
77
+ raise Exception(
78
+ f"Command failed with exit code {result.returncode}, "
79
+ f" nothing written to stderr (stdout: {result.stdout})"
80
+ )
81
+ # Optionally, return what was written to `stdout`.
82
+ if return_output:
83
+ return result.stdout
84
+
85
+
86
+ def run_curl_command(
87
+ url: str,
88
+ headers: dict[str, str] = {},
89
+ params: dict[str, str] = {},
90
+ result_file: Optional[str] = None,
91
+ ) -> str:
92
+ """
93
+ Run `curl` with the given `url`, `headers`, and `params`. If `result_file`
94
+ is `None`, return the output, otherwise, write the output to the given file
95
+ and return the HTTP code. If the `curl` command fails, throw an exception.
96
+
97
+ """
98
+ # Construct and run the `curl` command.
99
+ default_result_file = "/tmp/qlever.curl.result"
100
+ actual_result_file = result_file if result_file else default_result_file
101
+ curl_cmd = (
102
+ f'curl -Ls -o "{actual_result_file}"'
103
+ f' -w "%{{http_code}}\n" {url}'
104
+ + "".join([f' -H "{key}: {value}"' for key, value in headers.items()])
105
+ + "".join(
106
+ [
107
+ f" --data-urlencode {key}={shlex.quote(value)}"
108
+ for key, value in params.items()
109
+ ]
110
+ )
111
+ )
112
+ result = subprocess.run(
113
+ curl_cmd,
114
+ shell=True,
115
+ text=True,
116
+ stdout=subprocess.PIPE,
117
+ stderr=subprocess.PIPE,
118
+ )
119
+ # Case 1: An error occurred, raise an exception.
120
+ if result.returncode != 0:
121
+ if len(result.stderr) > 0:
122
+ raise Exception(result.stderr)
123
+ else:
124
+ raise Exception(
125
+ f"curl command failed with exit code "
126
+ f"{result.returncode}, stderr is empty"
127
+ )
128
+ # Case 2: Return output (read from `default_result_file`).
129
+ if result_file is None:
130
+ result_file_path = Path(default_result_file)
131
+ result = result_file_path.read_text()
132
+ result_file_path.unlink()
133
+ return result
134
+ # Case 3: Return HTTP code.
135
+ return result.stdout
136
+
137
+
138
+ def is_qlever_server_alive(endpoint_url: str) -> bool:
139
+ """
140
+ Helper function that checks if a QLever server is running on the given
141
+ endpoint. Return `True` if the server is alive, `False` otherwise.
142
+ """
143
+
144
+ message = "from the `qlever` CLI"
145
+ curl_cmd = (
146
+ f"curl -s {endpoint_url}/ping"
147
+ f" --data-urlencode msg={shlex.quote(message)}"
148
+ )
149
+ log.debug(curl_cmd)
150
+ try:
151
+ run_command(curl_cmd)
152
+ return True
153
+ except Exception:
154
+ return False
155
+
156
+
157
+ def get_existing_index_files(basename: str) -> list[str]:
158
+ """
159
+ Helper function that returns a list of all index files for `basename` in
160
+ the current working directory.
161
+ """
162
+ existing_index_files = []
163
+ existing_index_files.extend(Path.cwd().glob(f"{basename}.index.*"))
164
+ existing_index_files.extend(Path.cwd().glob(f"{basename}.text.*"))
165
+ existing_index_files.extend(Path.cwd().glob(f"{basename}.vocabulary.*"))
166
+ existing_index_files.extend(Path.cwd().glob(f"{basename}.meta-data.json"))
167
+ existing_index_files.extend(Path.cwd().glob(f"{basename}.prefixes"))
168
+ # Return only the file names, not the full paths.
169
+ return [path.name for path in existing_index_files]
170
+
171
+
172
+ def show_process_info(psutil_process, cmdline_regex, show_heading=True):
173
+ """
174
+ Helper function that shows information about a process if information
175
+ about the process can be retrieved and the command line matches the
176
+ given regex (in which case the function returns `True`). The heading is
177
+ only shown if `show_heading` is `True` and the function returns `True`.
178
+ """
179
+
180
+ # Helper function that shows a line of the process table.
181
+ def show_table_line(pid, user, start_time, rss, cmdline):
182
+ log.info(f"{pid:<8} {user:<8} {start_time:>5} {rss:>5} {cmdline}")
183
+
184
+ try:
185
+ pinfo = psutil_process.as_dict(
186
+ attrs=["pid", "username", "create_time", "memory_info", "cmdline"]
187
+ )
188
+ # Note: pinfo[`cmdline`] is `None` if the process is a zombie.
189
+ cmdline = " ".join(pinfo["cmdline"] or [])
190
+ if len(cmdline) == 0 or not re.search(cmdline_regex, cmdline):
191
+ return False
192
+ pid = pinfo["pid"]
193
+ user = pinfo["username"] if pinfo["username"] else ""
194
+ start_time = datetime.fromtimestamp(pinfo["create_time"])
195
+ if start_time.date() == date.today():
196
+ start_time = start_time.strftime("%H:%M")
197
+ else:
198
+ start_time = start_time.strftime("%b%d")
199
+ rss = f"{pinfo['memory_info'].rss / 1e9:.0f}G"
200
+ if show_heading:
201
+ show_table_line("PID", "USER", "START", "RSS", "COMMAND")
202
+ show_table_line(pid, user, start_time, rss, cmdline)
203
+ return True
204
+ except Exception as e:
205
+ log.error(f"Could not get process info: {e}")
206
+ return False
207
+
208
+
209
+ def get_random_string(length: int) -> str:
210
+ """
211
+ Helper function that returns a randomly chosen string of the given
212
+ length. Take the current time as seed.
213
+ """
214
+ characters = string.ascii_letters + string.digits
215
+ return "".join(secrets.choice(characters) for _ in range(length))
216
+
217
+
218
+ def is_port_used(port: int) -> bool:
219
+ """
220
+ Try to bind to the port on all interfaces to check if the port is already in use.
221
+ If the port is already in use, `socket.bind` will raise an `OSError` with errno EADDRINUSE.
222
+ """
223
+ try:
224
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
225
+ # Ensure that the port is not blocked after the check.
226
+ sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
227
+ sock.bind(("", port))
228
+ sock.close()
229
+ return False
230
+ except OSError as err:
231
+ if err.errno != errno.EADDRINUSE:
232
+ log.warning(f"Failed to determine if port is used: {err}")
233
+ return True
234
+
235
+
236
+ def format_size(bytes, suffix="B"):
237
+ """
238
+ Scale bytes to its proper format
239
+ e.g:
240
+ 1253656 => '1.20MB'
241
+ 1253656678 => '1.17GB'
242
+ """
243
+ factor = 1024
244
+ for unit in ["", "K", "M", "G", "T", "P"]:
245
+ if bytes < factor:
246
+ return f"{bytes:.2f} {unit}{suffix}"
247
+ bytes /= factor
248
+
249
+
250
+ def stop_process(proc: psutil.Process, pinfo: dict[str, Any]) -> bool:
251
+ """
252
+ Try to kill the given process, return True iff it was killed
253
+ successfully. The process_info is used for logging.
254
+ """
255
+ try:
256
+ proc.kill()
257
+ log.info(f"Killed process {pinfo['pid']}")
258
+ return True
259
+ except Exception as e:
260
+ log.error(
261
+ f"Could not kill process with PID "
262
+ f"{pinfo['pid']} ({e}) ... try to kill it "
263
+ f"manually"
264
+ )
265
+ log.info("")
266
+ show_process_info(proc, "", show_heading=True)
267
+ return False
268
+
269
+
270
+ def stop_process_with_regex(cmdline_regex: str) -> list[bool] | None:
271
+ """
272
+ Given a cmdline_regex for a native process, try to kill the processes that
273
+ match the regex and return a list of their stopped status (bool).
274
+ Show the matched processes as log info.
275
+ """
276
+ stop_process_results = []
277
+ for proc in psutil.process_iter():
278
+ try:
279
+ pinfo = proc.as_dict(
280
+ attrs=[
281
+ "pid",
282
+ "username",
283
+ "create_time",
284
+ "memory_info",
285
+ "cmdline",
286
+ ]
287
+ )
288
+ cmdline = " ".join(pinfo["cmdline"])
289
+ except Exception as e:
290
+ # For some processes (e.g., zombies), getting info may fail.
291
+ log.debug(f"Error getting process info: {e}")
292
+ continue
293
+ if re.search(cmdline_regex, cmdline):
294
+ log.info(
295
+ f"Found process {pinfo['pid']} from user "
296
+ f"{pinfo['username']} with command line: {cmdline}"
297
+ )
298
+ log.info("")
299
+ stop_process_results.append(stop_process(proc, pinfo))
300
+ return stop_process_results
301
+
302
+
303
+ def binary_exists(binary: str, cmd_arg: str) -> bool:
304
+ """
305
+ When a command is run natively, check if the binary exists on the system
306
+ """
307
+ try:
308
+ run_command(f"{binary} --help")
309
+ return True
310
+ except Exception as e:
311
+ log.error(
312
+ f'Running "{binary}" failed, '
313
+ f"set `--{cmd_arg}` to a different binary or "
314
+ f"set `--system to a container system`"
315
+ )
316
+ log.info("")
317
+ log.info(f"The error message was: {e}")
318
+ return False
319
+
320
+
321
+ def is_server_alive(url: str) -> bool:
322
+ """
323
+ Check if the server is already alive at the given endpoint url
324
+ """
325
+ check_server_cmd = f"curl -s {url}"
326
+ try:
327
+ run_command(check_server_cmd)
328
+ return True
329
+ except Exception:
330
+ return False
@@ -0,0 +1,127 @@
1
+ Metadata-Version: 2.4
2
+ Name: qlever
3
+ Version: 0.5.41
4
+ Summary: Command-line tool for using the QLever graph database
5
+ Author-email: Hannah Bast <bast@cs.uni-freiburg.de>
6
+ License-Expression: Apache-2.0
7
+ Project-URL: homepage, https://github.com/ad-freiburg/qlever
8
+ Project-URL: documentation, https://docs.qlever.dev
9
+ Project-URL: repository, https://github.com/ad-freiburg/qlever.git
10
+ Project-URL: bugtracker, https://github.com/ad-freiburg/qlever/issues
11
+ Keywords: Graph database,Triplestore,Knowledge graphs,SPARQL,RDF
12
+ Classifier: Topic :: Database :: Database Engines/Servers
13
+ Classifier: Topic :: Database :: Front-Ends
14
+ Requires-Python: >=3.8
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE
17
+ Requires-Dist: psutil
18
+ Requires-Dist: termcolor
19
+ Requires-Dist: argcomplete
20
+ Requires-Dist: pyyaml
21
+ Requires-Dist: rdflib
22
+ Requires-Dist: requests-sse
23
+ Requires-Dist: tqdm
24
+ Dynamic: license-file
25
+
26
+ # QLever
27
+
28
+ This repository provides a self-documenting and easy-to-use command-line tool
29
+ for QLever (pronounced "Clever"), a graph database implementing the
30
+ [RDF](https://www.w3.org/TR/rdf11-concepts/) and
31
+ [SPARQL](https://www.w3.org/TR/sparql11-overview/) standards.
32
+ For a detailed description of what QLever is and what it can do, see
33
+ [here](https://github.com/ad-freiburg/qlever).
34
+
35
+ # Installation
36
+
37
+ Simply do `pip install qlever` and make sure that the directory where `pip`
38
+ installs the package is in your `PATH`. Typically, `pip` will warn you when
39
+ that is not the case and tell you what to do. If you encounter an "Externally
40
+ managed Environment" error, try `pipx` instead of `pip`.
41
+
42
+ Type `qlever` without arguments to check that the installation worked. When
43
+ using it for the first time, you will see a warning at the top with
44
+ instructions on how to enable autocompletion. Do it, it makes using `qlever`
45
+ so much easier (`pip` cannot do that for you automatically, sorry).
46
+
47
+ # Usage
48
+
49
+ Create an empty directory, with a name corresponding to the dataset you want to
50
+ work with. For the following example, take `olympics`. Go to that directory
51
+ and do the following.
52
+
53
+ ```
54
+ qlever setup-config olympics # Get Qleverfile (config file) for this dataset
55
+ qlever get-data # Download the dataset
56
+ qlever index # Build index data structures for this dataset
57
+ qlever start # Start a QLever server using that index
58
+ qlever query # Launch an example query
59
+ qlever ui # Launch the QLever UI
60
+ ```
61
+
62
+ This will create a SPARQL endpoint for the [120 Years of
63
+ Olympics](https://github.com/wallscope/olympics-rdf) dataset. It is a great
64
+ dataset for getting started because it is small, but not trivial (around 2
65
+ million triples), and the downloading and indexing should only take a few
66
+ seconds.
67
+
68
+ Each command will also show you the command line it uses. That way you can
69
+ learn, on the side, how QLever works internally. If you just want to know the
70
+ command line for a particular command, without executing it, you can append
71
+ `--show` like this:
72
+
73
+ ```
74
+ qlever index --show
75
+ ```
76
+
77
+ There are many more commands and options, see `qlever --help` for general help,
78
+ `qlever <command> --help` for help on a specific command, or just use the
79
+ autocompletion.
80
+
81
+ # Use on macOS and Windows
82
+
83
+ By default, `qlever` uses [QLever's official Docker
84
+ image](https://hub.docker.com/r/adfreiburg/qlever). In principle, that image
85
+ runs on Linux, macOS, and Windows. On Linux, Docker runs natively
86
+ and incurs only a relatively small overhead regarding performance and RAM
87
+ consumption. On macOS and Windows, Docker runs in a virtual machine, which
88
+ incurs a significant and sometimes unpredictable overhead. For example, `qlever
89
+ index` might abort prematurely (without a proper error message) because the
90
+ virtual machine runs out of RAM.
91
+
92
+ For optimal performance, compile QLever from source on your machine. For Linux,
93
+ this is relatively straightforward: just follow the `RUN` instructions in the
94
+ [Dockerfile](https://github.com/ad-freiburg/qlever/blob/master/Dockerfile). For
95
+ macOS, this is more complicated, see [this
96
+ workflow](https://github.com/ad-freiburg/qlever/blob/master/.github/workflows/macos.yml).
97
+
98
+ # Use with your own dataset
99
+
100
+ To use QLever with your own dataset, you need a `Qleverfile`, like in the
101
+ example above. The easiest way to write a `Qleverfile` is to get one of the
102
+ existing ones (using `qlever setup-config ...` as explained above) and then
103
+ change it according to your needs (the variable names should be
104
+ self-explanatory). Pick one for a dataset that is similar to yours and when in
105
+ doubt, pick `olympics`.
106
+
107
+ # For developers
108
+
109
+ The (Python) code for the script is in the `*.py` files in `src/qlever`. The
110
+ preconfigured Qleverfiles are in `src/qlever/Qleverfiles`.
111
+
112
+ If you want to make changes to the script, or add new commands, do as follows:
113
+
114
+ ```
115
+ git clone https://github.com/ad-freiburg/qlever-control
116
+ cd qlever-control
117
+ pip install -e .
118
+ ```
119
+
120
+ Then you can use `qlever` just as if you had installed it via `pip install
121
+ qlever`. Note that you don't have to rerun `pip install -e .` when you modify
122
+ any of the `*.py` files and not even when you add new commands in
123
+ `src/qlever/commands`. The exceutable created by `pip` simply links and refers
124
+ to the files in your working copy.
125
+
126
+ If you have bug fixes or new useful features or commands, please open a pull
127
+ request. If you have questions or suggestions, please open an issue.
@@ -0,0 +1,59 @@
1
+ qlever/__init__.py,sha256=ZbzivHALRlzAUoFBBSbbkKFcvATBX7yVR6Q9JyEQ8ig,1631
2
+ qlever/command.py,sha256=QTg1SOiVc8_v0RYxwu74dv9FhVJs85RKMfAZuklEw6o,2766
3
+ qlever/config.py,sha256=gNw2_-jj1TjzhzqLOuUI_Dh19q_ViCiArrtrgXL2F4E,10354
4
+ qlever/containerize.py,sha256=QK2CylUnbZ0r-YCCnJMjxupE5ZBIlQZmS1Vn0-3PiI4,5496
5
+ qlever/log.py,sha256=WLscWV4fFF_w_uXSOfvWzhyzRM7t_61inE2ks3zf6Gw,1317
6
+ qlever/qlever_main.py,sha256=QlVXq7azyuAG0QhH_pER2fdZL8el2mG0I6d9r0dGgOA,2593
7
+ qlever/qleverfile.py,sha256=hNn_tmJxlLWrkp7pl9hOaKkVRVLO22bZUh9MfSklng4,20083
8
+ qlever/util.py,sha256=86v5tyoPoCiWqWOu8pLB7M2GwQO251hhbKF2cN0-vCY,11036
9
+ qlever/Qleverfiles/Qleverfile.dblp,sha256=y4AyUg8Dk2NHV972aeqnj77GZzWbgwV-zRD1qcdwhQE,1246
10
+ qlever/Qleverfiles/Qleverfile.dblp-plus,sha256=TJHxp8I1P6JKJjbuAllEpB32-huuY1gH0FlenqPVJ5g,1334
11
+ qlever/Qleverfiles/Qleverfile.dbpedia,sha256=aaNZZayE-zVePGSwPzXemkX__Ns8-kP_E7DNNKZPnqg,1160
12
+ qlever/Qleverfiles/Qleverfile.default,sha256=Kj-J1Kkv8PWN7wuMdZU6DUUlEuBIcSNysJCE-R63we8,2407
13
+ qlever/Qleverfiles/Qleverfile.dnb,sha256=43w_CVi00yf7FHdDvBtHHQR3yU1d-JCNnD_uxYZJOvk,1803
14
+ qlever/Qleverfiles/Qleverfile.fbeasy,sha256=CYmbxRnb4OFAagwoVfciyFR_26G-Ohk1ObBL6duSfuE,936
15
+ qlever/Qleverfiles/Qleverfile.freebase,sha256=Kol5ffUjJ5cXIWRxdY-SotOG1kGm82gZ3S8OV4BnrJA,1036
16
+ qlever/Qleverfiles/Qleverfile.imdb,sha256=iEzJuDU1AaC7-EZYfocaoEb32VH-QvbBiXhnzwWmGaQ,1756
17
+ qlever/Qleverfiles/Qleverfile.ohm-planet,sha256=Cr0MI0mSDnfaDI1iDyKhA2wO4XjdMmewlUc4Ge4Gc5c,2735
18
+ qlever/Qleverfiles/Qleverfile.olympics,sha256=5w9BOFwEBhdSzPz-0LRxwhv-7Gj6xbF539HOXr3cqD0,1088
19
+ qlever/Qleverfiles/Qleverfile.orkg,sha256=Uizz-RhlSeExgfckWztewa4l_v3zMN8IR7NaGYKrqt4,937
20
+ qlever/Qleverfiles/Qleverfile.osm-country,sha256=4Y2zCetMSxfRa23LPv-uYXJHMtIhl8lwOSbZgU_eIQc,1843
21
+ qlever/Qleverfiles/Qleverfile.osm-planet,sha256=fbP0y_OAx1-eOAA1PaEjaDwL-5QIrctBDJnxh_1D084,1758
22
+ qlever/Qleverfiles/Qleverfile.osm-planet-from-pbf,sha256=62IGpXkw0RyLyi0boyf2W3LEh3o_QtRM8o15QV1OPL4,2207
23
+ qlever/Qleverfiles/Qleverfile.pubchem,sha256=7RvCNJXxxyuhVpzaHVY03Rsoeml3cTkkKeonp9fiHek,14474
24
+ qlever/Qleverfiles/Qleverfile.scientists,sha256=9eZ2c6P9a3E3VHa3RR7LdOQbF4k3oyyrn56Z3u4LZYs,1164
25
+ qlever/Qleverfiles/Qleverfile.uniprot,sha256=s27n8yoNlQsIOO-vqgBkvmTn-s-dq7_wYthReAo57f0,6273
26
+ qlever/Qleverfiles/Qleverfile.vvz,sha256=cLzm85erKoFCDllH5eFcSi35MdR6Tahj1MgtvGRxanM,922
27
+ qlever/Qleverfiles/Qleverfile.wikidata,sha256=KLal5FjAzcEU0aqUDC5muFunm_Lti8is4RGu4IOQuMg,2061
28
+ qlever/Qleverfiles/Qleverfile.wikipathways,sha256=GENI4KYtrn_4M9mnGnfGPNkKy_lAPfO2LwnzbOx3fCE,1982
29
+ qlever/Qleverfiles/Qleverfile.yago-4,sha256=hAS_2ZmC1zxNsKXip7t1F_iqu3CC-6O7v6HZhuFbnWY,1819
30
+ qlever/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
+ qlever/commands/add_text_index.py,sha256=8Ri9e2cfJmsWLjD-iEB5jkbm4toEME0bccMJJkyx_sU,3819
32
+ qlever/commands/benchmark_queries.py,sha256=znT4pCCtvSgyXNWOEBJcRZ6lR_4zUDG4YphvUyzM2Zw,39204
33
+ qlever/commands/cache_stats.py,sha256=7JL1P4SX0F8xyN5VTiOSG5E1reCcM1rPaQsqllHuFTM,4366
34
+ qlever/commands/clear_cache.py,sha256=R0jRn_76A7dvyQyWgHld0THoYbohiVVEFAjBjOV3Uy4,2807
35
+ qlever/commands/extract_queries.py,sha256=1l59ipbNNJIesOXQOf3b8xWYu4-tPP73dHl2qP8LR48,4281
36
+ qlever/commands/get_data.py,sha256=nHOHMjv0tSLWJDOR0ba_LK-Bk-mcGnphb8hbqcVYFhE,1411
37
+ qlever/commands/index.py,sha256=IOvT8GqrBXcb5JPQ82359Mf1cD5EgzTQoRro-3w5HRw,13395
38
+ qlever/commands/index_stats.py,sha256=qNbDMogB83Ni5fGXPOZQO9VZQ_x2096vFyCCJ0jEuYw,11719
39
+ qlever/commands/log.py,sha256=vLqkgtx1udnQqoUBMWB5G9rwr-l7UKrDpyFYSMuoXWw,1987
40
+ qlever/commands/materialized_view.py,sha256=F9caIEfQbjDm2U-5iKelUiRkb8MceAesJiB2_zG6Mko,3523
41
+ qlever/commands/query.py,sha256=QJpr_sxNL03OBXq9LIPiuhMoSVamgz-RF9uevbQ61QM,4652
42
+ qlever/commands/rebuild_index.py,sha256=Iow3If0xhOQ2GYfRLuX5dXS5sk8wPdTicS_XTWjL_hk,6496
43
+ qlever/commands/reset_updates.py,sha256=uJvfKPCbgp-9247Ievyb292nR1VvOcaAIcVM-EalP7o,1879
44
+ qlever/commands/settings.py,sha256=YBob1LiYTSHTIZ6vIQcWc7hIWImP60HQCoacJu8XY2M,4001
45
+ qlever/commands/setup_config.py,sha256=mFO-GWPBOI47IS4W4v56NSdA5SEncEHG2vZjG9lP6_4,3343
46
+ qlever/commands/start.py,sha256=Moi1zbACmCxr3Fj3DzrEn-2W6dxB10GR0t7snIksgEo,11613
47
+ qlever/commands/status.py,sha256=TtnBqcdkF3zTDKft07zpVcIX7kFu7d_nOy9b6Ohh9vQ,1650
48
+ qlever/commands/stop.py,sha256=5BNKArOzoJ8kYiTVAmtN81w7nQ42fkxISgsxL-qJpO0,3463
49
+ qlever/commands/system_info.py,sha256=16HMl-MSQITfesuupuRE7gajVcahhCxeA7NCOaKCiKk,4659
50
+ qlever/commands/ui.py,sha256=QRSN-aO5jfG_97hz8lvo1x-SYWx_56zr78kVx6P8DWU,9810
51
+ qlever/commands/update.py,sha256=9EAPuUct5gQvwEimpBsqxefYWVUezufAa90jzClAE7Q,2710
52
+ qlever/commands/update_wikidata.py,sha256=VpYdgLetlNXk-FUTBV_evnw2hW00PQTzHEaI-1eKS-0,53540
53
+ qlever/commands/warmup.py,sha256=kJHzS7HJo8pD2CphJuaXDj_CYP02YDo2DVM-pun3A80,1029
54
+ qlever-0.5.41.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
55
+ qlever-0.5.41.dist-info/METADATA,sha256=g6rZUghOc1_4SesMiCvSEByeELZ-i0GPZIkYFrNuHhc,5373
56
+ qlever-0.5.41.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
57
+ qlever-0.5.41.dist-info/entry_points.txt,sha256=U_1U6SFIEZ-AnNlvk2nzcL0e4jnjEpuSbxYZ_E0XpEg,51
58
+ qlever-0.5.41.dist-info/top_level.txt,sha256=kd3zsYqiFd0--Czh5XTVkfEq6XR-XgRFW35X0v0GT-c,7
59
+ qlever-0.5.41.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.42.0)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ qlever = qlever.qlever_main:main
@@ -0,0 +1 @@
1
+ qlever