qlever 0.5.12__py3-none-any.whl → 0.5.15__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.
Potentially problematic release.
This version of qlever might be problematic. Click here for more details.
- qlever/Qleverfiles/Qleverfile.dblp +1 -1
- qlever/Qleverfiles/Qleverfile.pubchem +102 -26
- qlever/Qleverfiles/Qleverfile.uniprot +48 -16
- qlever/commands/add_text_index.py +2 -1
- qlever/commands/cache_stats.py +1 -1
- qlever/commands/clear_cache.py +4 -2
- qlever/commands/example_queries.py +120 -50
- qlever/commands/get_data.py +1 -1
- qlever/commands/index.py +50 -10
- qlever/commands/index_stats.py +90 -59
- qlever/commands/log.py +12 -2
- qlever/commands/query.py +66 -27
- qlever/commands/setup_config.py +1 -1
- qlever/commands/start.py +9 -3
- qlever/commands/status.py +2 -1
- qlever/commands/stop.py +4 -6
- qlever/commands/system_info.py +1 -1
- qlever/commands/ui.py +3 -1
- qlever/commands/warmup.py +1 -1
- qlever/qlever_main.py +16 -9
- {qlever-0.5.12.dist-info → qlever-0.5.15.dist-info}/METADATA +1 -1
- {qlever-0.5.12.dist-info → qlever-0.5.15.dist-info}/RECORD +26 -26
- {qlever-0.5.12.dist-info → qlever-0.5.15.dist-info}/LICENSE +0 -0
- {qlever-0.5.12.dist-info → qlever-0.5.15.dist-info}/WHEEL +0 -0
- {qlever-0.5.12.dist-info → qlever-0.5.15.dist-info}/entry_points.txt +0 -0
- {qlever-0.5.12.dist-info → qlever-0.5.15.dist-info}/top_level.txt +0 -0
qlever/commands/index.py
CHANGED
|
@@ -99,13 +99,50 @@ class IndexCommand(QleverCommand):
|
|
|
99
99
|
f"Element {i} in `MULTI_INPUT_JSON` must contain a " "key `cmd`",
|
|
100
100
|
input_spec,
|
|
101
101
|
)
|
|
102
|
-
|
|
102
|
+
# If the command contains a `{}` placeholder, we need a `for-each`
|
|
103
|
+
# key` specifying the pattern for the placeholder values, and vice
|
|
104
|
+
# versa.
|
|
105
|
+
if "{}" in input_spec["cmd"] and "for-each" not in input_spec:
|
|
106
|
+
raise self.InvalidInputJson(
|
|
107
|
+
f"Element {i} in `MULTI_INPUT_JSON` must contain a "
|
|
108
|
+
"key `for-each` if the command contains a placeholder "
|
|
109
|
+
"`{}`",
|
|
110
|
+
input_spec,
|
|
111
|
+
)
|
|
112
|
+
if "for-each" in input_spec and "{}" not in input_spec["cmd"]:
|
|
113
|
+
raise self.InvalidInputJson(
|
|
114
|
+
f"Element {i} in `MULTI_INPUT_JSON` contains a "
|
|
115
|
+
"key `for-each`, but the command does not contain a "
|
|
116
|
+
"placeholder `{{}}`",
|
|
117
|
+
input_spec,
|
|
118
|
+
)
|
|
119
|
+
# Get all commands. This is just the value of the `cmd` key if no
|
|
120
|
+
# `for-each` key is specified. Otherwise, we have a command for
|
|
121
|
+
# each file matching the pattern.
|
|
122
|
+
if "for-each" not in input_spec:
|
|
123
|
+
input_cmds = [input_spec["cmd"]]
|
|
124
|
+
else:
|
|
125
|
+
try:
|
|
126
|
+
files = sorted(glob.glob(input_spec["for-each"]))
|
|
127
|
+
except Exception as e:
|
|
128
|
+
raise self.InvalidInputJson(
|
|
129
|
+
f"Element {i} in `MULTI_INPUT_JSON` contains an "
|
|
130
|
+
f"invalid `for-each` pattern: {e}",
|
|
131
|
+
input_spec,
|
|
132
|
+
)
|
|
133
|
+
input_cmds = [input_spec["cmd"].format(file) for file in files]
|
|
103
134
|
# The `format`, `graph`, and `parallel` keys are optional.
|
|
104
135
|
input_format = input_spec.get("format", args.format)
|
|
105
136
|
input_graph = input_spec.get("graph", "-")
|
|
106
137
|
input_parallel = input_spec.get("parallel", "false")
|
|
107
138
|
# There must not be any other keys.
|
|
108
|
-
extra_keys = input_spec.keys() - {
|
|
139
|
+
extra_keys = input_spec.keys() - {
|
|
140
|
+
"cmd",
|
|
141
|
+
"format",
|
|
142
|
+
"graph",
|
|
143
|
+
"parallel",
|
|
144
|
+
"for-each",
|
|
145
|
+
}
|
|
109
146
|
if extra_keys:
|
|
110
147
|
raise self.InvalidInputJson(
|
|
111
148
|
f"Element {i} in `MULTI_INPUT_JSON` must only contain "
|
|
@@ -114,13 +151,16 @@ class IndexCommand(QleverCommand):
|
|
|
114
151
|
input_spec,
|
|
115
152
|
)
|
|
116
153
|
# Add the command-line options for this input stream. We use
|
|
117
|
-
# process substitution `<(...)` as a convenient way to handle
|
|
118
|
-
#
|
|
119
|
-
#
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
f
|
|
123
|
-
|
|
154
|
+
# process substitution `<(...)` as a convenient way to handle an
|
|
155
|
+
# input stream just like a file. This is not POSIX compliant, but
|
|
156
|
+
# supported by various shells, including bash and zsh. If
|
|
157
|
+
# `for-each` is specified, add one command for each matching file.
|
|
158
|
+
for input_cmd in input_cmds:
|
|
159
|
+
input_option = f"-f <({input_cmd}) -g {input_graph}"
|
|
160
|
+
input_option += f" -F {input_format}"
|
|
161
|
+
if input_parallel == "true":
|
|
162
|
+
input_option += " -p true"
|
|
163
|
+
input_options.append(input_option)
|
|
124
164
|
# Return the concatenated command-line options.
|
|
125
165
|
return " ".join(input_options)
|
|
126
166
|
|
|
@@ -200,7 +240,7 @@ class IndexCommand(QleverCommand):
|
|
|
200
240
|
# Show the command line.
|
|
201
241
|
self.show(f"{settings_json_cmd}\n{index_cmd}", only_show=args.show)
|
|
202
242
|
if args.show:
|
|
203
|
-
return
|
|
243
|
+
return True
|
|
204
244
|
|
|
205
245
|
# When running natively, check if the binary exists and works.
|
|
206
246
|
if args.system == "native":
|
qlever/commands/index_stats.py
CHANGED
|
@@ -18,32 +18,45 @@ class IndexStatsCommand(QleverCommand):
|
|
|
18
18
|
pass
|
|
19
19
|
|
|
20
20
|
def description(self) -> str:
|
|
21
|
-
return
|
|
21
|
+
return "Breakdown of the time and space used for the index build"
|
|
22
22
|
|
|
23
23
|
def should_have_qleverfile(self) -> bool:
|
|
24
24
|
return False
|
|
25
25
|
|
|
26
|
-
def relevant_qleverfile_arguments(self) -> dict[str: list[str]]:
|
|
26
|
+
def relevant_qleverfile_arguments(self) -> dict[str : list[str]]:
|
|
27
27
|
return {"data": ["name"]}
|
|
28
28
|
|
|
29
29
|
def additional_arguments(self, subparser) -> None:
|
|
30
|
-
subparser.add_argument(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
subparser.add_argument(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
30
|
+
subparser.add_argument(
|
|
31
|
+
"--only-time",
|
|
32
|
+
action="store_true",
|
|
33
|
+
default=False,
|
|
34
|
+
help="Show only the time used",
|
|
35
|
+
)
|
|
36
|
+
subparser.add_argument(
|
|
37
|
+
"--only-space",
|
|
38
|
+
action="store_true",
|
|
39
|
+
default=False,
|
|
40
|
+
help="Show only the space used",
|
|
41
|
+
)
|
|
42
|
+
subparser.add_argument(
|
|
43
|
+
"--ignore-text-index",
|
|
44
|
+
action="store_true",
|
|
45
|
+
default=False,
|
|
46
|
+
help="Ignore the text index",
|
|
47
|
+
)
|
|
48
|
+
subparser.add_argument(
|
|
49
|
+
"--time-unit",
|
|
50
|
+
choices=["s", "min", "h", "auto"],
|
|
51
|
+
default="auto",
|
|
52
|
+
help="The time unit",
|
|
53
|
+
)
|
|
54
|
+
subparser.add_argument(
|
|
55
|
+
"--size-unit",
|
|
56
|
+
choices=["B", "MB", "GB", "TB", "auto"],
|
|
57
|
+
default="auto",
|
|
58
|
+
help="The size unit",
|
|
59
|
+
)
|
|
47
60
|
|
|
48
61
|
def execute_time(self, args, log_file_name) -> bool:
|
|
49
62
|
"""
|
|
@@ -65,8 +78,9 @@ class IndexStatsCommand(QleverCommand):
|
|
|
65
78
|
with open(text_log_file_name, "r") as text_log_file:
|
|
66
79
|
lines.extend(text_log_file.readlines())
|
|
67
80
|
except Exception as e:
|
|
68
|
-
log.error(
|
|
69
|
-
|
|
81
|
+
log.error(
|
|
82
|
+
f"Problem reading text index log file " f"{text_log_file_name}: {e}"
|
|
83
|
+
)
|
|
70
84
|
return False
|
|
71
85
|
|
|
72
86
|
# Helper function that finds the next line matching the given `regex`,
|
|
@@ -95,12 +109,14 @@ class IndexStatsCommand(QleverCommand):
|
|
|
95
109
|
if regex_match:
|
|
96
110
|
try:
|
|
97
111
|
return datetime.strptime(
|
|
98
|
-
|
|
99
|
-
|
|
112
|
+
re.match(timestamp_regex, line).group(), timestamp_format
|
|
113
|
+
), regex_match
|
|
100
114
|
except Exception as e:
|
|
101
|
-
log.error(
|
|
102
|
-
|
|
103
|
-
|
|
115
|
+
log.error(
|
|
116
|
+
f"Could not parse timestamp of form "
|
|
117
|
+
f'"{timestamp_regex}" from line '
|
|
118
|
+
f' "{line.rstrip()}" ({e})'
|
|
119
|
+
)
|
|
104
120
|
# If we get here, we did not find a matching line.
|
|
105
121
|
if not update_current_line:
|
|
106
122
|
current_line = current_line_backup
|
|
@@ -119,26 +135,32 @@ class IndexStatsCommand(QleverCommand):
|
|
|
119
135
|
# file (old format: "Creating a pair" + names of permutations in
|
|
120
136
|
# line "Writing meta data for ..."; new format: name of
|
|
121
137
|
# permutations already in line "Creating permutations ...").
|
|
122
|
-
perm_begin, _ = find_next_line(
|
|
123
|
-
|
|
138
|
+
perm_begin, _ = find_next_line(
|
|
139
|
+
r"INFO:\s*Creating a pair", update_current_line=False
|
|
140
|
+
)
|
|
124
141
|
if perm_begin is None:
|
|
125
142
|
perm_begin, perm_info = find_next_line(
|
|
126
143
|
r"INFO:\s*Creating permutations ([A-Z]+ and [A-Z]+)",
|
|
127
|
-
update_current_line=False
|
|
144
|
+
update_current_line=False,
|
|
145
|
+
)
|
|
128
146
|
else:
|
|
129
147
|
_, perm_info = find_next_line(
|
|
130
148
|
r"INFO:\s*Writing meta data for ([A-Z]+ and [A-Z]+)",
|
|
131
|
-
update_current_line=False
|
|
149
|
+
update_current_line=False,
|
|
150
|
+
)
|
|
132
151
|
if perm_info is None:
|
|
133
152
|
break
|
|
134
153
|
perm_begin_and_info.append((perm_begin, perm_info))
|
|
135
|
-
convert_end = (
|
|
136
|
-
|
|
154
|
+
convert_end = (
|
|
155
|
+
perm_begin_and_info[0][0] if len(perm_begin_and_info) > 0 else None
|
|
156
|
+
)
|
|
137
157
|
normal_end, _ = find_next_line(r"INFO:\s*Index build completed")
|
|
138
|
-
text_begin, _ = find_next_line(
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
158
|
+
text_begin, _ = find_next_line(
|
|
159
|
+
r"INFO:\s*Adding text index", update_current_line=False
|
|
160
|
+
)
|
|
161
|
+
text_end, _ = find_next_line(
|
|
162
|
+
r"INFO:\s*Text index build comp", update_current_line=False
|
|
163
|
+
)
|
|
142
164
|
if args.ignore_text_index:
|
|
143
165
|
text_begin = text_end = None
|
|
144
166
|
|
|
@@ -147,9 +169,11 @@ class IndexStatsCommand(QleverCommand):
|
|
|
147
169
|
log.error("Missing line that index build has started")
|
|
148
170
|
return False
|
|
149
171
|
if overall_begin and not merge_begin:
|
|
150
|
-
log.error(
|
|
151
|
-
|
|
152
|
-
|
|
172
|
+
log.error(
|
|
173
|
+
"According to the log file, the index build "
|
|
174
|
+
"has started, but is still in its first "
|
|
175
|
+
"phase (parsing the input)"
|
|
176
|
+
)
|
|
153
177
|
return False
|
|
154
178
|
|
|
155
179
|
# Helper function that shows the duration for a phase (if the start and
|
|
@@ -187,22 +211,24 @@ class IndexStatsCommand(QleverCommand):
|
|
|
187
211
|
show_duration("Convert to global IDs", [(convert_begin, convert_end)])
|
|
188
212
|
for i in range(len(perm_begin_and_info)):
|
|
189
213
|
perm_begin, perm_info = perm_begin_and_info[i]
|
|
190
|
-
perm_end =
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
214
|
+
perm_end = (
|
|
215
|
+
perm_begin_and_info[i + 1][0]
|
|
216
|
+
if i + 1 < len(perm_begin_and_info)
|
|
217
|
+
else normal_end
|
|
218
|
+
)
|
|
219
|
+
perm_info_text = (
|
|
220
|
+
perm_info.group(1).replace(" and ", " & ") if perm_info else f"#{i + 1}"
|
|
221
|
+
)
|
|
222
|
+
show_duration(f"Permutation {perm_info_text}", [(perm_begin, perm_end)])
|
|
196
223
|
show_duration("Text index", [(text_begin, text_end)])
|
|
197
224
|
if text_begin and text_end:
|
|
198
225
|
log.info("")
|
|
199
|
-
show_duration(
|
|
200
|
-
|
|
201
|
-
|
|
226
|
+
show_duration(
|
|
227
|
+
"TOTAL time", [(overall_begin, normal_end), (text_begin, text_end)]
|
|
228
|
+
)
|
|
202
229
|
elif normal_end:
|
|
203
230
|
log.info("")
|
|
204
|
-
show_duration("TOTAL time",
|
|
205
|
-
[(overall_begin, normal_end)])
|
|
231
|
+
show_duration("TOTAL time", [(overall_begin, normal_end)])
|
|
206
232
|
return True
|
|
207
233
|
|
|
208
234
|
def execute_space(self, args) -> bool:
|
|
@@ -252,24 +278,29 @@ class IndexStatsCommand(QleverCommand):
|
|
|
252
278
|
return True
|
|
253
279
|
|
|
254
280
|
def execute(self, args) -> bool:
|
|
255
|
-
|
|
281
|
+
return_value = True
|
|
256
282
|
|
|
257
283
|
# The "time" part of the command.
|
|
258
284
|
if not args.only_space:
|
|
259
285
|
log_file_name = f"{args.name}.index-log.txt"
|
|
260
|
-
self.show(
|
|
261
|
-
|
|
262
|
-
|
|
286
|
+
self.show(
|
|
287
|
+
f"Breakdown of the time used for "
|
|
288
|
+
f"building the index, based on the timestamps for key "
|
|
289
|
+
f'lines in "{log_file_name}"',
|
|
290
|
+
only_show=args.show,
|
|
291
|
+
)
|
|
263
292
|
if not args.show:
|
|
264
|
-
|
|
293
|
+
return_value &= self.execute_time(args, log_file_name)
|
|
265
294
|
if not args.only_time:
|
|
266
295
|
log.info("")
|
|
267
296
|
|
|
268
297
|
# The "space" part of the command.
|
|
269
298
|
if not args.only_time:
|
|
270
|
-
self.show(
|
|
271
|
-
|
|
299
|
+
self.show(
|
|
300
|
+
"Breakdown of the space used for building the index",
|
|
301
|
+
only_show=args.show,
|
|
302
|
+
)
|
|
272
303
|
if not args.show:
|
|
273
|
-
|
|
304
|
+
return_value &= self.execute_space(args)
|
|
274
305
|
|
|
275
|
-
return
|
|
306
|
+
return return_value
|
qlever/commands/log.py
CHANGED
|
@@ -47,10 +47,20 @@ class LogCommand(QleverCommand):
|
|
|
47
47
|
log_cmd += f" {log_file}"
|
|
48
48
|
self.show(log_cmd, only_show=args.show)
|
|
49
49
|
if args.show:
|
|
50
|
-
return
|
|
50
|
+
return True
|
|
51
51
|
|
|
52
52
|
# Execute the command.
|
|
53
53
|
log.info(f"Follow log file {log_file}, press Ctrl-C to stop"
|
|
54
54
|
f" following (will not stop the server)")
|
|
55
55
|
log.info("")
|
|
56
|
-
|
|
56
|
+
try:
|
|
57
|
+
subprocess.run(log_cmd, shell=True)
|
|
58
|
+
return True
|
|
59
|
+
except Exception as e:
|
|
60
|
+
log.error(e)
|
|
61
|
+
return False
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
qlever/commands/query.py
CHANGED
|
@@ -18,42 +18,82 @@ class QueryCommand(QleverCommand):
|
|
|
18
18
|
pass
|
|
19
19
|
|
|
20
20
|
def description(self) -> str:
|
|
21
|
-
return
|
|
21
|
+
return "Send a query to a SPARQL endpoint"
|
|
22
22
|
|
|
23
23
|
def should_have_qleverfile(self) -> bool:
|
|
24
24
|
return False
|
|
25
25
|
|
|
26
|
-
def relevant_qleverfile_arguments(self) -> dict[str: list[str]]:
|
|
27
|
-
return {"server": ["port"]}
|
|
26
|
+
def relevant_qleverfile_arguments(self) -> dict[str : list[str]]:
|
|
27
|
+
return {"server": ["port", "access_token"]}
|
|
28
28
|
|
|
29
29
|
def additional_arguments(self, subparser) -> None:
|
|
30
|
-
subparser.add_argument(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
subparser.add_argument(
|
|
44
|
-
|
|
45
|
-
|
|
30
|
+
subparser.add_argument(
|
|
31
|
+
"query",
|
|
32
|
+
type=str,
|
|
33
|
+
nargs="?",
|
|
34
|
+
default="SELECT * WHERE { ?s ?p ?o } LIMIT 10",
|
|
35
|
+
help="SPARQL query to send",
|
|
36
|
+
)
|
|
37
|
+
subparser.add_argument(
|
|
38
|
+
"--pin-to-cache",
|
|
39
|
+
action="store_true",
|
|
40
|
+
default=False,
|
|
41
|
+
help="Pin the query to the cache",
|
|
42
|
+
)
|
|
43
|
+
subparser.add_argument(
|
|
44
|
+
"--sparql-endpoint", type=str, help="URL of the SPARQL endpoint"
|
|
45
|
+
)
|
|
46
|
+
subparser.add_argument(
|
|
47
|
+
"--accept",
|
|
48
|
+
type=str,
|
|
49
|
+
choices=[
|
|
50
|
+
"text/tab-separated-values",
|
|
51
|
+
"text/csv",
|
|
52
|
+
"application/sparql-results+json",
|
|
53
|
+
"application/sparql-results+xml",
|
|
54
|
+
"application/qlever-results+json",
|
|
55
|
+
],
|
|
56
|
+
default="text/tab-separated-values",
|
|
57
|
+
help="Accept header for the SPARQL query",
|
|
58
|
+
)
|
|
59
|
+
subparser.add_argument(
|
|
60
|
+
"--no-time",
|
|
61
|
+
action="store_true",
|
|
62
|
+
default=False,
|
|
63
|
+
help="Do not print the (end-to-end) time taken",
|
|
64
|
+
)
|
|
46
65
|
|
|
47
66
|
def execute(self, args) -> bool:
|
|
67
|
+
# When pinning to the cache, set `send=0` and request media type
|
|
68
|
+
# `application/qlever-results+json` so that we get the result size.
|
|
69
|
+
# Also, we need to provide the access token.
|
|
70
|
+
if args.pin_to_cache:
|
|
71
|
+
args.accept = "application/qlever-results+json"
|
|
72
|
+
curl_cmd_additions = (
|
|
73
|
+
f" --data pinresult=true --data send=0"
|
|
74
|
+
f" --data access-token="
|
|
75
|
+
f"{shlex.quote(args.access_token)}"
|
|
76
|
+
f" | jq .resultsize | numfmt --grouping"
|
|
77
|
+
f" | xargs -I {{}} printf"
|
|
78
|
+
f' "Result pinned to cache,'
|
|
79
|
+
f' number of rows: {{}}\\n"'
|
|
80
|
+
)
|
|
81
|
+
else:
|
|
82
|
+
curl_cmd_additions = ""
|
|
83
|
+
|
|
48
84
|
# Show what the command will do.
|
|
49
|
-
sparql_endpoint = (
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
85
|
+
sparql_endpoint = (
|
|
86
|
+
args.sparql_endpoint if args.sparql_endpoint else f"localhost:{args.port}"
|
|
87
|
+
)
|
|
88
|
+
curl_cmd = (
|
|
89
|
+
f"curl -s {sparql_endpoint}"
|
|
90
|
+
f' -H "Accept: {args.accept}"'
|
|
91
|
+
f" --data-urlencode query={shlex.quote(args.query)}"
|
|
92
|
+
f"{curl_cmd_additions}"
|
|
93
|
+
)
|
|
54
94
|
self.show(curl_cmd, only_show=args.show)
|
|
55
95
|
if args.show:
|
|
56
|
-
return
|
|
96
|
+
return True
|
|
57
97
|
|
|
58
98
|
# Launch query.
|
|
59
99
|
try:
|
|
@@ -62,8 +102,7 @@ class QueryCommand(QleverCommand):
|
|
|
62
102
|
time_msecs = round(1000 * (time.time() - start_time))
|
|
63
103
|
if not args.no_time and args.log_level != "NO_LOG":
|
|
64
104
|
log.info("")
|
|
65
|
-
log.info(f"Query processing time (end-to-end):"
|
|
66
|
-
f" {time_msecs:,d} ms")
|
|
105
|
+
log.info(f"Query processing time (end-to-end):" f" {time_msecs:,d} ms")
|
|
67
106
|
except Exception as e:
|
|
68
107
|
if args.log_level == "DEBUG":
|
|
69
108
|
traceback.print_exc()
|
qlever/commands/setup_config.py
CHANGED
|
@@ -60,7 +60,7 @@ class SetupConfigCommand(QleverCommand):
|
|
|
60
60
|
setup_config_cmd += "> Qleverfile"
|
|
61
61
|
self.show(setup_config_cmd, only_show=args.show)
|
|
62
62
|
if args.show:
|
|
63
|
-
return
|
|
63
|
+
return True
|
|
64
64
|
|
|
65
65
|
# If there is already a Qleverfile in the current directory, exit.
|
|
66
66
|
qleverfile_path = Path("Qleverfile")
|
qlever/commands/start.py
CHANGED
|
@@ -72,7 +72,9 @@ class StartCommand(QleverCommand):
|
|
|
72
72
|
if args.kill_existing_with_same_port:
|
|
73
73
|
args.cmdline_regex = f"^ServerMain.* -p {args.port}"
|
|
74
74
|
args.no_containers = True
|
|
75
|
-
StopCommand().execute(args)
|
|
75
|
+
if not StopCommand().execute(args):
|
|
76
|
+
log.error("Stopping the existing server failed")
|
|
77
|
+
return False
|
|
76
78
|
log.info("")
|
|
77
79
|
|
|
78
80
|
# Construct the command line based on the config file.
|
|
@@ -115,7 +117,7 @@ class StartCommand(QleverCommand):
|
|
|
115
117
|
# Show the command line.
|
|
116
118
|
self.show(start_cmd, only_show=args.show)
|
|
117
119
|
if args.show:
|
|
118
|
-
return
|
|
120
|
+
return True
|
|
119
121
|
|
|
120
122
|
# When running natively, check if the binary exists and works.
|
|
121
123
|
if args.system == "native":
|
|
@@ -192,6 +194,7 @@ class StartCommand(QleverCommand):
|
|
|
192
194
|
run_command(curl_cmd)
|
|
193
195
|
except Exception as e:
|
|
194
196
|
log.error(f"Setting the index description failed ({e})")
|
|
197
|
+
return False
|
|
195
198
|
if args.text_description:
|
|
196
199
|
text_desc = args.text_description
|
|
197
200
|
curl_cmd = (f"curl -Gs http://localhost:{port}/api"
|
|
@@ -202,6 +205,7 @@ class StartCommand(QleverCommand):
|
|
|
202
205
|
run_command(curl_cmd)
|
|
203
206
|
except Exception as e:
|
|
204
207
|
log.error(f"Setting the text description failed ({e})")
|
|
208
|
+
return False
|
|
205
209
|
|
|
206
210
|
# Kill the tail process. NOTE: `tail_proc.kill()` does not work.
|
|
207
211
|
tail_proc.terminate()
|
|
@@ -209,7 +213,9 @@ class StartCommand(QleverCommand):
|
|
|
209
213
|
# Execute the warmup command.
|
|
210
214
|
if args.warmup_cmd and not args.no_warmup:
|
|
211
215
|
log.info("")
|
|
212
|
-
WarmupCommand().execute(args)
|
|
216
|
+
if not WarmupCommand().execute(args):
|
|
217
|
+
log.error("Warmup failed")
|
|
218
|
+
return False
|
|
213
219
|
|
|
214
220
|
# Show cache stats.
|
|
215
221
|
log.info("")
|
qlever/commands/status.py
CHANGED
|
@@ -35,7 +35,7 @@ class StatusCommand(QleverCommand):
|
|
|
35
35
|
f"the command line matches {args.cmdline_regex}"
|
|
36
36
|
f" using Python's psutil library", only_show=args.show)
|
|
37
37
|
if args.show:
|
|
38
|
-
return
|
|
38
|
+
return True
|
|
39
39
|
|
|
40
40
|
# Show the results as a table.
|
|
41
41
|
num_processes_found = 0
|
|
@@ -47,3 +47,4 @@ class StatusCommand(QleverCommand):
|
|
|
47
47
|
num_processes_found += 1
|
|
48
48
|
if num_processes_found == 0:
|
|
49
49
|
print("No processes found")
|
|
50
|
+
return True
|
qlever/commands/stop.py
CHANGED
|
@@ -49,7 +49,7 @@ class StopCommand(QleverCommand):
|
|
|
49
49
|
f"\"{args.server_container}\"")
|
|
50
50
|
self.show(description, only_show=args.show)
|
|
51
51
|
if args.show:
|
|
52
|
-
return
|
|
52
|
+
return True
|
|
53
53
|
|
|
54
54
|
# First check if there is container running and if yes, stop and remove
|
|
55
55
|
# it (unless the user has specified `--no-containers`).
|
|
@@ -90,14 +90,12 @@ class StopCommand(QleverCommand):
|
|
|
90
90
|
return False
|
|
91
91
|
return True
|
|
92
92
|
|
|
93
|
-
#
|
|
93
|
+
# If no matching process found, show a message and the output of the
|
|
94
|
+
# status command.
|
|
94
95
|
message = "No matching process found" if args.no_containers else \
|
|
95
96
|
"No matching process or container found"
|
|
96
97
|
log.error(message)
|
|
97
|
-
|
|
98
|
-
# Show output of status command.
|
|
99
98
|
args.cmdline_regex = "^ServerMain.* -i [^ ]*"
|
|
100
99
|
log.info("")
|
|
101
100
|
StatusCommand().execute(args)
|
|
102
|
-
|
|
103
|
-
return False
|
|
101
|
+
return True
|
qlever/commands/system_info.py
CHANGED
|
@@ -58,7 +58,7 @@ class SystemInfoCommand(QleverCommand):
|
|
|
58
58
|
# Say what the command is doing.
|
|
59
59
|
self.show("Show system information and Qleverfile", only_show=args.show)
|
|
60
60
|
if args.show:
|
|
61
|
-
return
|
|
61
|
+
return True
|
|
62
62
|
|
|
63
63
|
# Show system information.
|
|
64
64
|
show_heading("System Information")
|
qlever/commands/ui.py
CHANGED
|
@@ -70,8 +70,10 @@ class UiCommand(QleverCommand):
|
|
|
70
70
|
"\n".join(["Stop running containers", pull_cmd, run_cmd, exec_cmd]),
|
|
71
71
|
only_show=args.show,
|
|
72
72
|
)
|
|
73
|
-
if qlever_is_running_in_container
|
|
73
|
+
if qlever_is_running_in_container:
|
|
74
74
|
return False
|
|
75
|
+
if args.show:
|
|
76
|
+
return True
|
|
75
77
|
|
|
76
78
|
# Stop running containers.
|
|
77
79
|
for container_system in Containerize.supported_systems():
|
qlever/commands/warmup.py
CHANGED
qlever/qlever_main.py
CHANGED
|
@@ -35,31 +35,38 @@ def main():
|
|
|
35
35
|
log.info("")
|
|
36
36
|
log.info(colored(f"Command: {args.command}", attrs=["bold"]))
|
|
37
37
|
log.info("")
|
|
38
|
-
command_object.execute(args)
|
|
38
|
+
commandWasSuccesful = command_object.execute(args)
|
|
39
39
|
log.info("")
|
|
40
|
+
if not commandWasSuccesful:
|
|
41
|
+
exit(1)
|
|
40
42
|
except KeyboardInterrupt:
|
|
41
43
|
log.info("")
|
|
42
44
|
log.info("Ctrl-C pressed, exiting ...")
|
|
43
45
|
log.info("")
|
|
44
|
-
exit(
|
|
46
|
+
exit(1)
|
|
45
47
|
except Exception as e:
|
|
46
48
|
# Check if it's a certain kind of `AttributeError` and give a hint in
|
|
47
49
|
# that case.
|
|
48
50
|
match_error = re.search(r"object has no attribute '(.+)'", str(e))
|
|
49
|
-
match_trace = re.search(
|
|
50
|
-
|
|
51
|
+
match_trace = re.search(
|
|
52
|
+
r"(qlever/commands/.+\.py)\", line (\d+)", traceback.format_exc()
|
|
53
|
+
)
|
|
51
54
|
if isinstance(e, AttributeError) and match_error and match_trace:
|
|
52
55
|
attribute = match_error.group(1)
|
|
53
56
|
trace_command = match_trace.group(1)
|
|
54
57
|
trace_line = match_trace.group(2)
|
|
55
58
|
log.error(f"{e} in `{trace_command}` at line {trace_line}")
|
|
56
59
|
log.info("")
|
|
57
|
-
log.info(
|
|
58
|
-
|
|
59
|
-
|
|
60
|
+
log.info(
|
|
61
|
+
f"Likely cause: you used `args.{attribute}`, but it was "
|
|
62
|
+
f"neither defined in `relevant_qleverfile_arguments` "
|
|
63
|
+
f"nor in `additional_arguments`"
|
|
64
|
+
)
|
|
60
65
|
log.info("")
|
|
61
|
-
log.info(
|
|
62
|
-
|
|
66
|
+
log.info(
|
|
67
|
+
f"If you did not implement `{trace_command}` yourself, "
|
|
68
|
+
f"please report this issue"
|
|
69
|
+
)
|
|
63
70
|
log.info("")
|
|
64
71
|
else:
|
|
65
72
|
log.error(f"An unexpected error occurred: {e}")
|