cmem-cmemc 24.2.0rc2__py3-none-any.whl → 24.3.0rc2__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 (51) hide show
  1. cmem_cmemc/__init__.py +7 -12
  2. cmem_cmemc/command.py +20 -0
  3. cmem_cmemc/command_group.py +70 -0
  4. cmem_cmemc/commands/__init__.py +0 -81
  5. cmem_cmemc/commands/acl.py +118 -62
  6. cmem_cmemc/commands/admin.py +46 -35
  7. cmem_cmemc/commands/client.py +2 -1
  8. cmem_cmemc/commands/config.py +3 -1
  9. cmem_cmemc/commands/dataset.py +27 -24
  10. cmem_cmemc/commands/graph.py +160 -19
  11. cmem_cmemc/commands/metrics.py +195 -79
  12. cmem_cmemc/commands/migration.py +267 -0
  13. cmem_cmemc/commands/project.py +62 -17
  14. cmem_cmemc/commands/python.py +56 -25
  15. cmem_cmemc/commands/query.py +23 -14
  16. cmem_cmemc/commands/resource.py +10 -2
  17. cmem_cmemc/commands/scheduler.py +10 -2
  18. cmem_cmemc/commands/store.py +118 -14
  19. cmem_cmemc/commands/user.py +8 -2
  20. cmem_cmemc/commands/validation.py +165 -78
  21. cmem_cmemc/commands/variable.py +10 -2
  22. cmem_cmemc/commands/vocabulary.py +48 -29
  23. cmem_cmemc/commands/workflow.py +86 -59
  24. cmem_cmemc/commands/workspace.py +27 -8
  25. cmem_cmemc/completion.py +190 -140
  26. cmem_cmemc/constants.py +2 -0
  27. cmem_cmemc/context.py +88 -42
  28. cmem_cmemc/manual_helper/graph.py +1 -0
  29. cmem_cmemc/manual_helper/multi_page.py +3 -1
  30. cmem_cmemc/migrations/__init__.py +1 -0
  31. cmem_cmemc/migrations/abc.py +84 -0
  32. cmem_cmemc/migrations/access_conditions_243.py +122 -0
  33. cmem_cmemc/migrations/bootstrap_data.py +28 -0
  34. cmem_cmemc/migrations/shapes_widget_integrations_243.py +274 -0
  35. cmem_cmemc/migrations/workspace_configurations.py +28 -0
  36. cmem_cmemc/object_list.py +53 -22
  37. cmem_cmemc/parameter_types/__init__.py +1 -0
  38. cmem_cmemc/parameter_types/path.py +69 -0
  39. cmem_cmemc/smart_path/__init__.py +94 -0
  40. cmem_cmemc/smart_path/clients/__init__.py +63 -0
  41. cmem_cmemc/smart_path/clients/http.py +65 -0
  42. cmem_cmemc/string_processor.py +83 -0
  43. cmem_cmemc/title_helper.py +41 -0
  44. cmem_cmemc/utils.py +100 -45
  45. {cmem_cmemc-24.2.0rc2.dist-info → cmem_cmemc-24.3.0rc2.dist-info}/LICENSE +1 -1
  46. cmem_cmemc-24.3.0rc2.dist-info/METADATA +89 -0
  47. cmem_cmemc-24.3.0rc2.dist-info/RECORD +53 -0
  48. {cmem_cmemc-24.2.0rc2.dist-info → cmem_cmemc-24.3.0rc2.dist-info}/WHEEL +1 -1
  49. cmem_cmemc-24.2.0rc2.dist-info/METADATA +0 -69
  50. cmem_cmemc-24.2.0rc2.dist-info/RECORD +0 -37
  51. {cmem_cmemc-24.2.0rc2.dist-info → cmem_cmemc-24.3.0rc2.dist-info}/entry_points.txt +0 -0
cmem_cmemc/completion.py CHANGED
@@ -1,27 +1,28 @@
1
1
  """Utility functions for CLI auto-completion functionality."""
2
+
2
3
  # ruff: noqa: ARG001
3
4
  import os
5
+ import pathlib
4
6
  from contextlib import suppress
5
- from pathlib import Path
6
7
  from typing import Any
7
8
 
8
9
  import requests.exceptions
9
10
  from click import Context
10
11
  from click.parser import Argument, split_arg_string
11
12
  from click.shell_completion import CompletionItem
12
- from cmem.cmempy.dp.admin import get_prometheus_data
13
13
  from cmem.cmempy.dp.authorization.conditions import (
14
14
  fetch_all_acls,
15
15
  get_actions,
16
16
  get_groups,
17
17
  get_users,
18
18
  )
19
+ from cmem.cmempy.dp.proxy.graph import get_graph_import_tree
19
20
  from cmem.cmempy.health import get_complete_status_info
20
21
  from cmem.cmempy.keycloak.client import list_open_id_clients
21
22
  from cmem.cmempy.keycloak.group import list_groups
22
23
  from cmem.cmempy.keycloak.user import get_user_by_username, list_users, user_groups
23
24
  from cmem.cmempy.plugins.marshalling import get_marshalling_plugins
24
- from cmem.cmempy.queries import QUERY_CATALOG
25
+ from cmem.cmempy.queries import QueryCatalog
25
26
  from cmem.cmempy.vocabularies import get_vocabularies
26
27
  from cmem.cmempy.workflow.workflows import get_workflows_io
27
28
  from cmem.cmempy.workspace import (
@@ -35,16 +36,14 @@ from cmem.cmempy.workspace.projects.variables import get_all_variables
35
36
  from cmem.cmempy.workspace.python import list_packages
36
37
  from cmem.cmempy.workspace.search import list_items
37
38
  from natsort import natsorted, ns
38
- from prometheus_client.parser import text_string_to_metric_families
39
39
 
40
- from cmem_cmemc.constants import NS_ACL, NS_USER
40
+ from cmem_cmemc.constants import NS_ACL, NS_ACTION, NS_GROUP, NS_USER
41
41
  from cmem_cmemc.context import CONTEXT
42
+ from cmem_cmemc.smart_path import SmartPath as Path
42
43
  from cmem_cmemc.utils import (
43
44
  convert_iri_to_qname,
44
45
  get_graphs,
45
46
  get_published_packages,
46
- metric_get_labels,
47
- metrics_get_dict,
48
47
  struct_to_table,
49
48
  )
50
49
 
@@ -52,7 +51,7 @@ SORT_BY_KEY = 0
52
51
  SORT_BY_DESC = 1
53
52
 
54
53
 
55
- def _finalize_completion(
54
+ def finalize_completion(
56
55
  candidates: list,
57
56
  incomplete: str = "",
58
57
  sort_by: int = SORT_BY_KEY,
@@ -127,7 +126,7 @@ def _finalize_completion(
127
126
  )
128
127
 
129
128
 
130
- def _get_completion_args(incomplete: str) -> list[str]:
129
+ def get_completion_args(incomplete: str) -> list[str]:
131
130
  """Get completion args
132
131
 
133
132
  This is a workaround to get partial tuple options in a completion function
@@ -139,13 +138,11 @@ def _get_completion_args(incomplete: str) -> list[str]:
139
138
  return args
140
139
 
141
140
 
142
- def _check_option_in_params(option: str, params: Any) -> bool: # noqa: ANN401
141
+ def check_option_in_params(option: str, params: Any) -> bool: # noqa: ANN401
143
142
  """Check if the given 'option' is present in the 'params' dictionary or any of its values."""
144
143
  if hasattr(params, "__iter__") and option in params:
145
144
  return True
146
- if option == params:
147
- return True
148
- return False
145
+ return bool(option == params)
149
146
 
150
147
 
151
148
  def add_metadata_parameter(list_: list | None = None) -> list:
@@ -165,10 +162,10 @@ def acl_ids(ctx: Context, param: Argument, incomplete: str) -> list[CompletionIt
165
162
  for access_condition in acls:
166
163
  iri = convert_iri_to_qname(access_condition.get("iri"), default_ns=NS_ACL)
167
164
  label = access_condition.get("name")
168
- if _check_option_in_params(iri, ctx.params.get(param.name)): # type: ignore[attr-defined]
165
+ if check_option_in_params(iri, ctx.params.get(param.name)): # type: ignore[attr-defined]
169
166
  continue
170
167
  options.append((iri, label))
171
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
168
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
172
169
 
173
170
 
174
171
  def acl_actions(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
@@ -177,10 +174,19 @@ def acl_actions(ctx: Context, param: Argument, incomplete: str) -> list[Completi
177
174
  options = []
178
175
  results = get_actions().json()
179
176
  for _ in results:
180
- if _check_option_in_params(_["iri"], ctx.params.get(param.name)): # type: ignore[attr-defined]
177
+ try:
178
+ iri = _["iri"]
179
+ name = _["name"]
180
+ except (KeyError, TypeError):
181
+ return []
182
+ qname = convert_iri_to_qname(iri, default_ns=NS_ACTION)
183
+ if check_option_in_params(qname, ctx.params.get(param.name)): # type: ignore[attr-defined]
181
184
  continue
182
- options.append((_["iri"], _["name"]))
183
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
185
+ if check_option_in_params(iri, ctx.params.get(param.name)): # type: ignore[attr-defined]
186
+ continue
187
+ options.append((qname, name))
188
+ options.append(("urn:elds-backend-all-actions", "All Actions (until 24.2.x, now deprecated)"))
189
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
184
190
 
185
191
 
186
192
  def acl_users(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
@@ -189,7 +195,7 @@ def acl_users(ctx: Context, param: Argument, incomplete: str) -> list[Completion
189
195
  options = []
190
196
  try:
191
197
  for _ in list_users():
192
- if _check_option_in_params(_["username"], ctx.params.get(param.name)): # type: ignore[attr-defined]
198
+ if check_option_in_params(_["username"], ctx.params.get(param.name)): # type: ignore[attr-defined]
193
199
  continue
194
200
  options.append(_["username"])
195
201
  except requests.exceptions.HTTPError:
@@ -197,11 +203,11 @@ def acl_users(ctx: Context, param: Argument, incomplete: str) -> list[Completion
197
203
  results = get_users().json()
198
204
  for _ in results:
199
205
  username = _.replace(NS_USER, "")
200
- if _check_option_in_params(username, ctx.params.get(param.name)) or username in options: # type: ignore[attr-defined]
206
+ if check_option_in_params(username, ctx.params.get(param.name)) or username in options: # type: ignore[attr-defined]
201
207
  continue
202
208
  options.append(username)
203
209
 
204
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
210
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
205
211
 
206
212
 
207
213
  def acl_groups(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
@@ -210,17 +216,18 @@ def acl_groups(ctx: Context, param: Argument, incomplete: str) -> list[Completio
210
216
  options = []
211
217
  try:
212
218
  for _ in list_groups():
213
- if _check_option_in_params(_["name"], ctx.params.get(param.name)): # type: ignore[attr-defined]
219
+ if check_option_in_params(_["name"], ctx.params.get(param.name)): # type: ignore[attr-defined]
214
220
  continue
215
221
  options.append(_["name"])
216
222
  except requests.exceptions.HTTPError:
217
223
  pass
218
224
  results = get_groups().json()
219
225
  for _ in results:
220
- if _check_option_in_params(_, ctx.params.get(param.name)) or _ in options: # type: ignore[attr-defined]
226
+ _ = _.replace(NS_GROUP, "") if _.startswith(NS_GROUP) else _
227
+ if check_option_in_params(_, ctx.params.get(param.name)) or _ in options: # type: ignore[attr-defined]
221
228
  continue
222
229
  options.append(_)
223
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
230
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
224
231
 
225
232
 
226
233
  def add_read_only_and_uri_property_parameters(list_: list | None = None) -> list:
@@ -254,7 +261,7 @@ def add_read_only_and_uri_property_parameters(list_: list | None = None) -> list
254
261
  def dataset_parameter(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
255
262
  """Prepare a list of dataset parameters for a dataset type."""
256
263
  CONTEXT.set_connection_from_params(ctx.find_root().params)
257
- args = _get_completion_args(incomplete)
264
+ args = get_completion_args(incomplete)
258
265
  incomplete = incomplete.lower()
259
266
  # look if cursor is in value position of the -p option and
260
267
  # return nothing in case it is (values are not completed atm)
@@ -317,7 +324,7 @@ def dataset_types(ctx: Context, param: Argument, incomplete: str) -> list[Comple
317
324
  or option.lower().find(incomplete.lower()) != -1
318
325
  ):
319
326
  options.append((plugin_id, option))
320
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
327
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
321
328
 
322
329
 
323
330
  def dataset_ids(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
@@ -326,7 +333,7 @@ def dataset_ids(ctx: Context, param: Argument, incomplete: str) -> list[Completi
326
333
  results = list_items(item_type="dataset")
327
334
  datasets = results["results"]
328
335
  options = [(f"{_['projectId']}:{_['id']}", _["label"]) for _ in datasets]
329
- return _finalize_completion(candidates=options, incomplete=incomplete)
336
+ return finalize_completion(candidates=options, incomplete=incomplete)
330
337
 
331
338
 
332
339
  def dataset_list_filter(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
@@ -345,9 +352,9 @@ def dataset_list_filter(ctx: Context, param: Argument, incomplete: str) -> list[
345
352
  ),
346
353
  ]
347
354
  options = []
348
- args = _get_completion_args(incomplete)
355
+ args = get_completion_args(incomplete)
349
356
  if args[len(args) - 1] == "--filter":
350
- options = _finalize_completion(candidates=filter_names, incomplete=incomplete)
357
+ options = finalize_completion(candidates=filter_names, incomplete=incomplete)
351
358
  if args[len(args) - 1] == "type":
352
359
  options = dataset_types(ctx, param, incomplete)
353
360
  if args[len(args) - 1] == "project":
@@ -355,7 +362,7 @@ def dataset_list_filter(ctx: Context, param: Argument, incomplete: str) -> list[
355
362
  if args[len(args) - 1] == "tag":
356
363
  options = tag_labels(ctx, param, incomplete, "dataset")
357
364
  if args[len(args) - 1] == "regex":
358
- options = _finalize_completion(candidates=filter_regex, incomplete=incomplete)
365
+ options = finalize_completion(candidates=filter_regex, incomplete=incomplete)
359
366
  return options
360
367
 
361
368
 
@@ -363,7 +370,7 @@ def resource_ids(ctx: Context, param: Argument, incomplete: str) -> list[Complet
363
370
  """Prepare a list of projectid:resourceid resource identifier."""
364
371
  CONTEXT.set_connection_from_params(ctx.find_root().params)
365
372
  options = [_["id"] for _ in get_all_resources()]
366
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
373
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
367
374
 
368
375
 
369
376
  def scheduler_ids(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
@@ -375,38 +382,10 @@ def scheduler_ids(ctx: Context, param: Argument, incomplete: str) -> list[Comple
375
382
  facets=[{"facetId": "taskType", "keywordIds": ["Scheduler"], "type": "keyword"}],
376
383
  )["results"]
377
384
  for _ in schedulers:
378
- if _check_option_in_params(_["projectId"] + ":" + _["id"], ctx.params.get(param.name)): # type: ignore[attr-defined]
385
+ if check_option_in_params(_["projectId"] + ":" + _["id"], ctx.params.get(param.name)): # type: ignore[attr-defined]
379
386
  continue
380
387
  options.append((_["projectId"] + ":" + _["id"], _["label"]))
381
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
382
-
383
-
384
- def metric_ids(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
385
- """Prepare a list of metric identifier."""
386
- CONTEXT.set_connection_from_params(ctx.find_root().params)
387
- data = get_prometheus_data().text
388
- options = [
389
- (family.name, family.documentation) for family in text_string_to_metric_families(data)
390
- ]
391
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_KEY)
392
-
393
-
394
- def metric_label_filter(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
395
- """Prepare a list of label name or values."""
396
- CONTEXT.set_connection_from_params(ctx.find_root().params)
397
- args = _get_completion_args(incomplete)
398
- incomplete = incomplete.lower()
399
- options: list[str] = []
400
- metric_id = ctx.args[0]
401
- labels = metric_get_labels(metrics_get_dict()[metric_id])
402
- if args[len(args) - 1] in "--filter":
403
- # we are in the name position
404
- options = list(labels.keys())
405
- if args[len(args) - 2] in "--filter":
406
- label_name = args[len(args) - 1]
407
- # we are in the value position
408
- options = labels[label_name]
409
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_KEY)
388
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
410
389
 
411
390
 
412
391
  def vocabularies(
@@ -418,7 +397,7 @@ def vocabularies(
418
397
  options = []
419
398
  for _ in vocabs:
420
399
  url = _["iri"]
421
- if _check_option_in_params(url, ctx.params.get(param.name)): # type: ignore[attr-defined]
400
+ if check_option_in_params(url, ctx.params.get(param.name)): # type: ignore[attr-defined]
422
401
  continue
423
402
  url = _["iri"]
424
403
  try:
@@ -426,7 +405,7 @@ def vocabularies(
426
405
  except (KeyError, TypeError):
427
406
  label = "Vocabulary in graph " + url
428
407
  options.append((url, label))
429
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
408
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
430
409
 
431
410
 
432
411
  def installed_vocabularies(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
@@ -445,7 +424,7 @@ def file_list(
445
424
  incomplete: str = "", suffix: str = "", description: str = "", prefix: str = ""
446
425
  ) -> list[CompletionItem]:
447
426
  """Prepare a list of files with specific parameter."""
448
- directory = str(Path().cwd())
427
+ directory = str(pathlib.Path().cwd())
449
428
  options = [
450
429
  (file_name, description)
451
430
  for file_name in os.listdir(directory)
@@ -453,7 +432,7 @@ def file_list(
453
432
  Path(file_name).exists() and file_name.endswith(suffix) and file_name.startswith(prefix)
454
433
  )
455
434
  ]
456
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_KEY)
435
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_KEY)
457
436
 
458
437
 
459
438
  def workflow_io_ids(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
@@ -464,7 +443,7 @@ def workflow_io_ids(ctx: Context, param: Argument, incomplete: str) -> list[Comp
464
443
  workflow_id = _["projectId"] + ":" + _["id"]
465
444
  label = _["label"]
466
445
  options.append((workflow_id, label))
467
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
446
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
468
447
 
469
448
 
470
449
  def replay_files(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
@@ -476,13 +455,13 @@ def installed_package_names(ctx: Context, param: Argument, incomplete: str) -> l
476
455
  """Prepare a list of installed packages."""
477
456
  CONTEXT.set_connection_from_args(ctx.find_root().params)
478
457
  options = [(_["name"], _["version"]) for _ in list_packages()]
479
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_KEY)
458
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_KEY)
480
459
 
481
460
 
482
461
  def published_package_names(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
483
462
  """List of plugin packages scraped from pypi.org."""
484
463
  options = [(_.name, f"{_.version}: {_.description}") for _ in get_published_packages()]
485
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_KEY)
464
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_KEY)
486
465
 
487
466
 
488
467
  def python_package_files(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
@@ -542,32 +521,51 @@ def workflow_io_output_files(
542
521
  )
543
522
 
544
523
 
545
- def dataset_files(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
546
- """Prepare a list of SPARQL files."""
547
- return (
548
- file_list(incomplete=incomplete, suffix=".csv", description="CSV Dataset resource")
549
- + file_list(incomplete=incomplete, suffix=".xlsx", description="Excel Dataset resource")
550
- + file_list(incomplete=incomplete, suffix=".xml", description="XML Dataset resource")
551
- + file_list(incomplete=incomplete, suffix=".json", description="JSON Dataset resource")
552
- + file_list(
553
- incomplete=incomplete, suffix=".jsonl", description="JSON Lines Dataset resource"
554
- )
555
- + file_list(incomplete=incomplete, suffix=".ttl", description="RDF file Dataset resource")
556
- + file_list(incomplete=incomplete, suffix=".zip", description="multiCsv Dataset resource")
557
- + file_list(incomplete=incomplete, suffix=".orc", description="Apache ORC Dataset resource")
558
- + file_list(incomplete=incomplete, suffix=".yaml", description="YAML Document")
559
- + file_list(incomplete=incomplete, suffix=".yml", description="YAML Document")
560
- )
524
+ def get_dataset_file_mapping() -> dict[str, dict[str, str]]:
525
+ """Return file extension to type and description mapping"""
526
+ return {
527
+ ".csv": {"description": "CSV Dataset resource", "type": "csv"},
528
+ ".csv.zip": {"description": "CSV Dataset resource (zipped)", "type": "csv"},
529
+ ".xlsx": {"description": "Excel Dataset resource", "type": "excel"},
530
+ ".xml": {"description": "XML Dataset resource", "type": "xml"},
531
+ ".xml.zip": {"description": "XML Dataset resource (zipped)", "type": "xml"},
532
+ ".json": {"description": "JSON Dataset resource", "type": "json"},
533
+ ".json.zip": {"description": "JSON Dataset resource (zipped)", "type": "json"},
534
+ ".jsonl": {"description": "JSON Lines Dataset resource", "type": "json"},
535
+ ".jsonl.zip": {"description": "JSON Lines Dataset resource (zipped)", "type": "json"},
536
+ ".yaml": {"description": "YAML Document", "type": "text"},
537
+ ".yaml.zip": {"description": "YAML Document (zipped)", "type": "text"},
538
+ ".yml": {"description": "YAML Document", "type": "text"},
539
+ ".yml.zip": {"description": "YAML Document (zipped)", "type": "text"},
540
+ ".ttl": {"description": "RDF file Dataset resource", "type": "file"},
541
+ ".orc": {"description": "Apache ORC Dataset resource", "type": "orc"},
542
+ ".txt": {"description": "Text dataset resource", "type": "text"},
543
+ ".txt.zip": {"description": "Text dataset resource (zipped)", "type": "text"},
544
+ ".zip": {"description": "multiCsv Dataset resource", "type": "multiCsv"},
545
+ }
561
546
 
562
547
 
563
- def graph_backup_files(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
564
- """Prepare a list of workspace files."""
565
- return file_list(
548
+ def dataset_files(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
549
+ """Prepare a list of dataset files."""
550
+ files = []
551
+ for extension, info in get_dataset_file_mapping().items():
552
+ # handle zip extension separately.
553
+ if extension != ".zip":
554
+ files += file_list(
555
+ incomplete=incomplete, suffix=extension, description=info["description"]
556
+ )
557
+
558
+ multicsv = file_list(
566
559
  incomplete=incomplete,
567
- suffix=".graphs.zip",
568
- description="eccenca Corporate Memory graph backup file",
560
+ suffix=".zip",
561
+ description=get_dataset_file_mapping()[".zip"]["description"],
569
562
  )
570
563
 
564
+ list_of_file_names = {item.value for item in files}
565
+ filtered_multicsv = [item for item in multicsv if item.value not in list_of_file_names]
566
+
567
+ return files + filtered_multicsv
568
+
571
569
 
572
570
  def project_files(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
573
571
  """Prepare a list of workspace files."""
@@ -601,16 +599,29 @@ def sparql_files(ctx: Context, param: Argument, incomplete: str) -> list[Complet
601
599
 
602
600
  def triple_files(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
603
601
  """Prepare a list of triple files."""
604
- return file_list(
605
- incomplete=incomplete, suffix=".ttl", description="RDF Turtle file"
606
- ) + file_list(incomplete=incomplete, suffix=".nt", description="RDF NTriples file")
602
+ return (
603
+ file_list(incomplete=incomplete, suffix=".ttl", description="Turtle file")
604
+ + file_list(incomplete=incomplete, suffix=".nt", description="NTriples file")
605
+ + file_list(incomplete=incomplete, suffix=".rdf", description="RDF/XML file")
606
+ + file_list(incomplete=incomplete, suffix=".jsonld", description="JSON-LD file")
607
+ + file_list(incomplete=incomplete, suffix=".ttl.gz", description="Turtle file (compressed)")
608
+ + file_list(
609
+ incomplete=incomplete, suffix=".nt.gz", description="NTriples file (compressed)"
610
+ )
611
+ + file_list(
612
+ incomplete=incomplete, suffix=".rdf.gz", description="RDF/XML file (compressed)"
613
+ )
614
+ + file_list(
615
+ incomplete=incomplete, suffix=".jsonld.gz", description="JSON-LD file (compressed)"
616
+ )
617
+ )
607
618
 
608
619
 
609
620
  def placeholder(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
610
621
  """Prepare a list of placeholder from the to-be executed queries."""
611
622
  # look if cursor is in value position of the -p option and
612
623
  # return nothing in case it is (values are not completed atm)
613
- args = _get_completion_args(incomplete)
624
+ args = get_completion_args(incomplete)
614
625
  if args[len(args) - 2] in ("-p", "--parameter"):
615
626
  return []
616
627
  # setup configuration
@@ -618,7 +629,7 @@ def placeholder(ctx: Context, param: Argument, incomplete: str) -> list[Completi
618
629
  # extract placeholder from given queries in the command line
619
630
  options = []
620
631
  for _, arg in enumerate(args):
621
- query = QUERY_CATALOG.get_query(arg)
632
+ query = QueryCatalog().get_query(arg)
622
633
  if query is not None:
623
634
  options.extend(list(query.get_placeholder_keys()))
624
635
  # look for already given parameter in the arguments and remove them from
@@ -626,18 +637,18 @@ def placeholder(ctx: Context, param: Argument, incomplete: str) -> list[Completi
626
637
  for num, arg in enumerate(args):
627
638
  if num - 1 > 0 and args[num - 1] in ("-p", "--parameter"):
628
639
  options.remove(arg)
629
- return _finalize_completion(candidates=options, incomplete=incomplete)
640
+ return finalize_completion(candidates=options, incomplete=incomplete)
630
641
 
631
642
 
632
643
  def remote_queries(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
633
644
  """Prepare a list of query URIs."""
634
645
  CONTEXT.set_connection_from_params(ctx.find_root().params)
635
646
  options = []
636
- for query in QUERY_CATALOG.get_queries().values():
647
+ for query in QueryCatalog().get_queries().values():
637
648
  url = query.short_url
638
649
  label = query.label
639
650
  options.append((url, label))
640
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
651
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
641
652
 
642
653
 
643
654
  def remote_queries_and_sparql_files(
@@ -657,10 +668,10 @@ def workflow_ids(ctx: Context, param: Argument, incomplete: str) -> list[Complet
657
668
  for _ in workflows:
658
669
  workflow = _["projectId"] + ":" + _["id"]
659
670
  label = _["label"]
660
- if _check_option_in_params(workflow, ctx.params.get(param.name)): # type: ignore[attr-defined]
671
+ if check_option_in_params(workflow, ctx.params.get(param.name)): # type: ignore[attr-defined]
661
672
  continue
662
673
  options.append((workflow, label))
663
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
674
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
664
675
 
665
676
 
666
677
  def marshalling_plugins(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
@@ -673,7 +684,7 @@ def marshalling_plugins(ctx: Context, param: Argument, incomplete: str) -> list[
673
684
  # in case, no descriptions are available, labels are fine as well
674
685
  final_options = [(_["id"], _["label"]) for _ in options]
675
686
 
676
- return _finalize_completion(
687
+ return finalize_completion(
677
688
  candidates=final_options, incomplete=incomplete, sort_by=SORT_BY_DESC
678
689
  )
679
690
 
@@ -687,27 +698,59 @@ def project_ids(ctx: Context, param: Argument, incomplete: str) -> list[Completi
687
698
  project_id = _["name"]
688
699
  label = _["metaData"]["label"]
689
700
  # do not add project if already in the command line
690
- if _check_option_in_params(project_id, ctx.params.get(param.name)): # type: ignore[attr-defined]
701
+ if check_option_in_params(project_id, ctx.params.get(param.name)): # type: ignore[attr-defined]
691
702
  continue
692
703
  options.append((project_id, label))
693
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
704
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
694
705
 
695
706
 
696
- def graph_uris(
697
- ctx: Context, param: Argument, incomplete: str, writeable: bool = True, readonly: bool = True
698
- ) -> list[CompletionItem]:
699
- """Prepare a list of graphs for auto-completion."""
707
+ def _prepare_graph_options(
708
+ ctx: Context,
709
+ param: Argument,
710
+ writeable: bool = True,
711
+ readonly: bool = True,
712
+ skip_selected_iris: bool = True,
713
+ ) -> list[tuple[str, str]]:
714
+ """Prepare a list of graphs with iri and label"""
700
715
  CONTEXT.set_connection_from_params(ctx.find_root().params)
701
- graphs = get_graphs()
716
+ graphs = get_graphs(writeable=writeable, readonly=readonly)
702
717
  options = []
703
- for _ in graphs:
704
- iri = _["iri"]
705
- label = _["label"]["title"]
718
+ for graph in graphs:
719
+ iri = graph["iri"]
720
+ label = graph["label"]["title"]
706
721
  # do not add graph if already in the command line
707
- if _check_option_in_params(iri, ctx.params.get(param.name)): # type: ignore[attr-defined]
722
+ if skip_selected_iris & check_option_in_params(iri, ctx.params.get(param.name)): # type: ignore[attr-defined]
708
723
  continue
709
724
  options.append((iri, label))
710
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
725
+ return options
726
+
727
+
728
+ def graph_uris_skip_check(
729
+ ctx: Context, param: Argument, incomplete: str, writeable: bool = True, readonly: bool = True
730
+ ) -> list[CompletionItem]:
731
+ """Prepare a list of graphs for auto-completion without checking selected IRIs"""
732
+ options = _prepare_graph_options(
733
+ ctx, param, writeable=writeable, readonly=readonly, skip_selected_iris=False
734
+ )
735
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
736
+
737
+
738
+ def graph_uris(
739
+ ctx: Context, param: Argument, incomplete: str, writeable: bool = True, readonly: bool = True
740
+ ) -> list[CompletionItem]:
741
+ """Prepare a list of graphs for auto-completion."""
742
+ options = _prepare_graph_options(ctx, param, writeable=writeable, readonly=readonly)
743
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
744
+
745
+
746
+ def ignore_graph_uris(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
747
+ """Prepare a list of import graphs for auto-completion."""
748
+ data_graph = ctx.args[0]
749
+ import_tree = get_graph_import_tree(data_graph)
750
+ imported_graphs = {iri for values in import_tree["tree"].values() for iri in values}
751
+ options = _prepare_graph_options(ctx, param, writeable=True, readonly=True)
752
+ options = [_ for _ in options if _[0] in imported_graphs]
753
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
711
754
 
712
755
 
713
756
  def writable_graph_uris(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
@@ -718,9 +761,16 @@ def writable_graph_uris(ctx: Context, param: Argument, incomplete: str) -> list[
718
761
  def graph_uris_with_all_graph_uri(
719
762
  ctx: Context, param: Argument, incomplete: str
720
763
  ) -> list[CompletionItem]:
721
- """Please a list of all graphs for acl command auto-completion."""
764
+ """Prepare a list of all graphs for acl command auto-completion."""
722
765
  options = graph_uris(ctx, param, incomplete, writeable=True, readonly=True)
723
- options.append(CompletionItem(value=r"urn\:elds-backend-all-graphs", help="All Graphs"))
766
+ options.append(
767
+ CompletionItem(
768
+ value=r"urn\:elds-backend-all-graphs", help="All Graphs (until 24.2.x, now deprecated)"
769
+ )
770
+ )
771
+ options.append(
772
+ CompletionItem(value=r"https\://vocab.eccenca.com/auth/AllGraphs", help="All Graphs")
773
+ )
724
774
  return options
725
775
 
726
776
 
@@ -729,7 +779,7 @@ def connections(ctx: Context, param: Argument, incomplete: str) -> list[Completi
729
779
  # since ctx does not have an obj here, we re-create the object
730
780
  CONTEXT.set_connection_from_params(ctx.find_root().params)
731
781
  options = CONTEXT.config.sections()
732
- return _finalize_completion(candidates=options, incomplete=incomplete)
782
+ return finalize_completion(candidates=options, incomplete=incomplete)
733
783
 
734
784
 
735
785
  def graph_export_templates(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
@@ -743,7 +793,7 @@ def graph_export_templates(ctx: Context, param: Argument, incomplete: str) -> li
743
793
  "Example: 2021-11-29-mycmem-https__ns_eccenca_com_data_config.ttl",
744
794
  ),
745
795
  ]
746
- return _finalize_completion(candidates=examples, incomplete=incomplete)
796
+ return finalize_completion(candidates=examples, incomplete=incomplete)
747
797
 
748
798
 
749
799
  def project_export_templates(
@@ -751,11 +801,11 @@ def project_export_templates(
751
801
  ) -> list[CompletionItem]:
752
802
  """Prepare a list of example templates for the project export command."""
753
803
  examples = [
754
- ("{{id}}", "Example: a plain file name"),
755
- ("{{date}}-{{connection}}-{{id}}.project", "Example: a more descriptive file name"),
756
- ("dumps/{{connection}}/{{id}}/{{date}}.project", "Example: a whole directory tree"),
804
+ ("{{id}}.project", "Example: Plain file name"),
805
+ ("{{date}}-{{connection}}-{{id}}.project", "Example: More descriptive file name"),
806
+ ("dumps/{{connection}}/{{id}}/{{date}}.project", "Example: Whole directory tree"),
757
807
  ]
758
- return _finalize_completion(candidates=examples, incomplete=incomplete)
808
+ return finalize_completion(candidates=examples, incomplete=incomplete)
759
809
 
760
810
 
761
811
  def workspace_export_templates(
@@ -767,7 +817,7 @@ def workspace_export_templates(
767
817
  ("{{date}}-{{connection}}.workspace", "Example: a more descriptive file name"),
768
818
  ("dumps/{{connection}}/{{date}}.workspace", "Example: a whole directory tree"),
769
819
  ]
770
- return _finalize_completion(candidates=examples, incomplete=incomplete)
820
+ return finalize_completion(candidates=examples, incomplete=incomplete)
771
821
 
772
822
 
773
823
  def graph_list_filter(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
@@ -783,12 +833,12 @@ def graph_list_filter(ctx: Context, param: Argument, incomplete: str) -> list[Co
783
833
  ("readonly", "List only graphs which are NOT writable for the current user."),
784
834
  ("writeable", "List only graphs which ARE writeable for the current user."),
785
835
  ]
786
- args = _get_completion_args(incomplete)
836
+ args = get_completion_args(incomplete)
787
837
  options = []
788
838
  if args[len(args) - 1] == "--filter":
789
- options = _finalize_completion(candidates=filter_names, incomplete=incomplete)
839
+ options = finalize_completion(candidates=filter_names, incomplete=incomplete)
790
840
  if args[len(args) - 1] == "access":
791
- options = _finalize_completion(candidates=filter_values_access, incomplete=incomplete)
841
+ options = finalize_completion(candidates=filter_values_access, incomplete=incomplete)
792
842
  if args[len(args) - 1] == "imported-by":
793
843
  options = graph_uris(ctx, param, incomplete)
794
844
  return options
@@ -805,10 +855,10 @@ def variable_ids(ctx: Context, param: Argument, incomplete: str) -> list[Complet
805
855
  if label == "":
806
856
  label = f"Current value: {_['value']}"
807
857
  # do not add project if already in the command line
808
- if _check_option_in_params(variable_id, ctx.params.get(param.name)): # type: ignore[attr-defined]
858
+ if check_option_in_params(variable_id, ctx.params.get(param.name)): # type: ignore[attr-defined]
809
859
  continue
810
860
  options.append((variable_id, label))
811
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_KEY)
861
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_KEY)
812
862
 
813
863
 
814
864
  def variable_list_filter(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
@@ -825,11 +875,11 @@ def variable_list_filter(ctx: Context, param: Argument, incomplete: str) -> list
825
875
  ("ending$", "Variables name ends with 'ending'."),
826
876
  ("^starting", "Variables name starts with 'starting'."),
827
877
  ]
828
- args = _get_completion_args(incomplete)
878
+ args = get_completion_args(incomplete)
829
879
  if args[len(args) - 1] == "--filter":
830
880
  return [CompletionItem(value=f[0], help=f[1]) for f in filter_names]
831
881
  if args[len(args) - 1] == "regex":
832
- return _finalize_completion(candidates=filter_values_regex, incomplete=incomplete)
882
+ return finalize_completion(candidates=filter_values_regex, incomplete=incomplete)
833
883
  if args[len(args) - 1] == "project":
834
884
  return project_ids(ctx, param, incomplete)
835
885
  return []
@@ -848,15 +898,15 @@ def resource_list_filter(ctx: Context, param: Argument, incomplete: str) -> list
848
898
  ("csv$", "File resources which name ends with .csv"),
849
899
  ("2021-10-[0-9][0-9]", "File resources which name has a date from 2021-10 in it"),
850
900
  ]
851
- args = _get_completion_args(incomplete)
901
+ args = get_completion_args(incomplete)
852
902
  if args[len(args) - 1] == "--filter":
853
903
  return [CompletionItem(value=f[0], help=f[1]) for f in filter_names]
854
904
  if args[len(args) - 1] == "project":
855
- return _finalize_completion(
905
+ return finalize_completion(
856
906
  candidates=project_ids(ctx, param, incomplete), incomplete=incomplete
857
907
  )
858
908
  if args[len(args) - 1] == "regex":
859
- return _finalize_completion(candidates=filter_values_regex, incomplete=incomplete)
909
+ return finalize_completion(candidates=filter_values_regex, incomplete=incomplete)
860
910
  return []
861
911
 
862
912
 
@@ -882,7 +932,7 @@ def workflow_list_filter(ctx: Context, param: Argument, incomplete: str) -> list
882
932
  ),
883
933
  ]
884
934
  options = []
885
- args = _get_completion_args(incomplete)
935
+ args = get_completion_args(incomplete)
886
936
  if args[len(args) - 1] == "--filter":
887
937
  options = filter_names
888
938
  if args[len(args) - 1] == "io":
@@ -894,7 +944,7 @@ def workflow_list_filter(ctx: Context, param: Argument, incomplete: str) -> list
894
944
  if args[len(args) - 1] == "regex":
895
945
  options = filter_regex
896
946
 
897
- return _finalize_completion(candidates=options, incomplete=incomplete)
947
+ return finalize_completion(candidates=options, incomplete=incomplete)
898
948
 
899
949
 
900
950
  def tag_labels(
@@ -912,7 +962,7 @@ def tag_labels(
912
962
  counts[_tag["label"]] = 1
913
963
  for tag, count in counts.items():
914
964
  options.append((tag, f"{count} item(s): {tag}"))
915
- return _finalize_completion(
965
+ return finalize_completion(
916
966
  candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC, reverse=True
917
967
  )
918
968
 
@@ -923,14 +973,14 @@ def status_keys(ctx: Context, param: Argument, incomplete: str) -> list[Completi
923
973
  status_info = struct_to_table(get_complete_status_info())
924
974
  options = [_[0] for _ in status_info]
925
975
  options.insert(0, "all")
926
- return _finalize_completion(candidates=options, incomplete=incomplete)
976
+ return finalize_completion(candidates=options, incomplete=incomplete)
927
977
 
928
978
 
929
979
  def user_ids(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
930
980
  """Prepare a list of username for admin update/delete/password command."""
931
981
  CONTEXT.set_connection_from_params(ctx.find_root().params)
932
982
  options = [_["username"] for _ in list_users()]
933
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
983
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
934
984
 
935
985
 
936
986
  def user_group_ids(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
@@ -956,14 +1006,14 @@ def user_group_ids(ctx: Context, param: Argument, incomplete: str) -> list[Compl
956
1006
  with suppress(ValueError):
957
1007
  options.remove(arg)
958
1008
 
959
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
1009
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
960
1010
 
961
1011
 
962
1012
  def client_ids(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
963
1013
  """Prepare a list of client ids for admin secret and update command."""
964
1014
  CONTEXT.set_connection_from_params(ctx.find_root().params)
965
1015
  options = [_["clientId"] for _ in list_open_id_clients()]
966
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
1016
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
967
1017
 
968
1018
 
969
1019
  def transformation_task_ids(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
@@ -972,7 +1022,7 @@ def transformation_task_ids(ctx: Context, param: Argument, incomplete: str) -> l
972
1022
  results = list_items(item_type="transform")
973
1023
  datasets = results["results"]
974
1024
  options = [(f"{_['projectId']}:{_['id']}", _["label"]) for _ in datasets]
975
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
1025
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
976
1026
 
977
1027
 
978
1028
  def linking_task_ids(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
@@ -981,4 +1031,4 @@ def linking_task_ids(ctx: Context, param: Argument, incomplete: str) -> list[Com
981
1031
  results = list_items(item_type="linking")
982
1032
  datasets = results["results"]
983
1033
  options = [(_["projectId"] + r"\:" + _["id"], _["label"]) for _ in datasets]
984
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
1034
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)