cmem-cmemc 24.2.0rc1__py3-none-any.whl → 24.3.0rc1__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 +100 -16
  11. cmem_cmemc/commands/metrics.py +195 -79
  12. cmem_cmemc/commands/migration.py +265 -0
  13. cmem_cmemc/commands/project.py +62 -17
  14. cmem_cmemc/commands/python.py +57 -26
  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 +304 -113
  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 +185 -141
  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 +118 -0
  33. cmem_cmemc/migrations/bootstrap_data.py +30 -0
  34. cmem_cmemc/migrations/shapes_widget_integrations_243.py +194 -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 +77 -0
  43. cmem_cmemc/title_helper.py +41 -0
  44. cmem_cmemc/utils.py +114 -47
  45. {cmem_cmemc-24.2.0rc1.dist-info → cmem_cmemc-24.3.0rc1.dist-info}/LICENSE +1 -1
  46. cmem_cmemc-24.3.0rc1.dist-info/METADATA +89 -0
  47. cmem_cmemc-24.3.0rc1.dist-info/RECORD +53 -0
  48. {cmem_cmemc-24.2.0rc1.dist-info → cmem_cmemc-24.3.0rc1.dist-info}/WHEEL +1 -1
  49. cmem_cmemc-24.2.0rc1.dist-info/METADATA +0 -69
  50. cmem_cmemc-24.2.0rc1.dist-info/RECORD +0 -37
  51. {cmem_cmemc-24.2.0rc1.dist-info → cmem_cmemc-24.3.0rc1.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
- options = [(_.name, f"{_.version}: {_.description}") for _ in get_published_packages()]
485
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_KEY)
463
+ options = [(_.name, f"{_.description}") for _ in get_published_packages()]
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,23 @@ 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="RDF Turtle file")
604
+ + file_list(incomplete=incomplete, suffix=".nt", description="RDF NTriples file")
605
+ + file_list(
606
+ incomplete=incomplete, suffix=".ttl.gz", description="Compressed RDF Turtle file"
607
+ )
608
+ + file_list(
609
+ incomplete=incomplete, suffix=".nt.gz", description="Compressed RDF NTriples file"
610
+ )
611
+ )
607
612
 
608
613
 
609
614
  def placeholder(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
610
615
  """Prepare a list of placeholder from the to-be executed queries."""
611
616
  # look if cursor is in value position of the -p option and
612
617
  # return nothing in case it is (values are not completed atm)
613
- args = _get_completion_args(incomplete)
618
+ args = get_completion_args(incomplete)
614
619
  if args[len(args) - 2] in ("-p", "--parameter"):
615
620
  return []
616
621
  # setup configuration
@@ -618,7 +623,7 @@ def placeholder(ctx: Context, param: Argument, incomplete: str) -> list[Completi
618
623
  # extract placeholder from given queries in the command line
619
624
  options = []
620
625
  for _, arg in enumerate(args):
621
- query = QUERY_CATALOG.get_query(arg)
626
+ query = QueryCatalog().get_query(arg)
622
627
  if query is not None:
623
628
  options.extend(list(query.get_placeholder_keys()))
624
629
  # look for already given parameter in the arguments and remove them from
@@ -626,18 +631,18 @@ def placeholder(ctx: Context, param: Argument, incomplete: str) -> list[Completi
626
631
  for num, arg in enumerate(args):
627
632
  if num - 1 > 0 and args[num - 1] in ("-p", "--parameter"):
628
633
  options.remove(arg)
629
- return _finalize_completion(candidates=options, incomplete=incomplete)
634
+ return finalize_completion(candidates=options, incomplete=incomplete)
630
635
 
631
636
 
632
637
  def remote_queries(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
633
638
  """Prepare a list of query URIs."""
634
639
  CONTEXT.set_connection_from_params(ctx.find_root().params)
635
640
  options = []
636
- for query in QUERY_CATALOG.get_queries().values():
641
+ for query in QueryCatalog().get_queries().values():
637
642
  url = query.short_url
638
643
  label = query.label
639
644
  options.append((url, label))
640
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
645
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
641
646
 
642
647
 
643
648
  def remote_queries_and_sparql_files(
@@ -657,10 +662,10 @@ def workflow_ids(ctx: Context, param: Argument, incomplete: str) -> list[Complet
657
662
  for _ in workflows:
658
663
  workflow = _["projectId"] + ":" + _["id"]
659
664
  label = _["label"]
660
- if _check_option_in_params(workflow, ctx.params.get(param.name)): # type: ignore[attr-defined]
665
+ if check_option_in_params(workflow, ctx.params.get(param.name)): # type: ignore[attr-defined]
661
666
  continue
662
667
  options.append((workflow, label))
663
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
668
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
664
669
 
665
670
 
666
671
  def marshalling_plugins(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
@@ -673,7 +678,7 @@ def marshalling_plugins(ctx: Context, param: Argument, incomplete: str) -> list[
673
678
  # in case, no descriptions are available, labels are fine as well
674
679
  final_options = [(_["id"], _["label"]) for _ in options]
675
680
 
676
- return _finalize_completion(
681
+ return finalize_completion(
677
682
  candidates=final_options, incomplete=incomplete, sort_by=SORT_BY_DESC
678
683
  )
679
684
 
@@ -687,27 +692,59 @@ def project_ids(ctx: Context, param: Argument, incomplete: str) -> list[Completi
687
692
  project_id = _["name"]
688
693
  label = _["metaData"]["label"]
689
694
  # 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]
695
+ if check_option_in_params(project_id, ctx.params.get(param.name)): # type: ignore[attr-defined]
691
696
  continue
692
697
  options.append((project_id, label))
693
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
698
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
694
699
 
695
700
 
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."""
701
+ def _prepare_graph_options(
702
+ ctx: Context,
703
+ param: Argument,
704
+ writeable: bool = True,
705
+ readonly: bool = True,
706
+ skip_selected_iris: bool = True,
707
+ ) -> list[tuple[str, str]]:
708
+ """Prepare a list of graphs with iri and label"""
700
709
  CONTEXT.set_connection_from_params(ctx.find_root().params)
701
- graphs = get_graphs()
710
+ graphs = get_graphs(writeable=writeable, readonly=readonly)
702
711
  options = []
703
- for _ in graphs:
704
- iri = _["iri"]
705
- label = _["label"]["title"]
712
+ for graph in graphs:
713
+ iri = graph["iri"]
714
+ label = graph["label"]["title"]
706
715
  # 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]
716
+ if skip_selected_iris & check_option_in_params(iri, ctx.params.get(param.name)): # type: ignore[attr-defined]
708
717
  continue
709
718
  options.append((iri, label))
710
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
719
+ return options
720
+
721
+
722
+ def graph_uris_skip_check(
723
+ ctx: Context, param: Argument, incomplete: str, writeable: bool = True, readonly: bool = True
724
+ ) -> list[CompletionItem]:
725
+ """Prepare a list of graphs for auto-completion without checking selected IRIs"""
726
+ options = _prepare_graph_options(
727
+ ctx, param, writeable=writeable, readonly=readonly, skip_selected_iris=False
728
+ )
729
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
730
+
731
+
732
+ def graph_uris(
733
+ ctx: Context, param: Argument, incomplete: str, writeable: bool = True, readonly: bool = True
734
+ ) -> list[CompletionItem]:
735
+ """Prepare a list of graphs for auto-completion."""
736
+ options = _prepare_graph_options(ctx, param, writeable=writeable, readonly=readonly)
737
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
738
+
739
+
740
+ def ignore_graph_uris(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
741
+ """Prepare a list of import graphs for auto-completion."""
742
+ data_graph = ctx.args[0]
743
+ import_tree = get_graph_import_tree(data_graph)
744
+ imported_graphs = {iri for values in import_tree["tree"].values() for iri in values}
745
+ options = _prepare_graph_options(ctx, param, writeable=True, readonly=True)
746
+ options = [_ for _ in options if _[0] in imported_graphs]
747
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
711
748
 
712
749
 
713
750
  def writable_graph_uris(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
@@ -718,9 +755,16 @@ def writable_graph_uris(ctx: Context, param: Argument, incomplete: str) -> list[
718
755
  def graph_uris_with_all_graph_uri(
719
756
  ctx: Context, param: Argument, incomplete: str
720
757
  ) -> list[CompletionItem]:
721
- """Please a list of all graphs for acl command auto-completion."""
758
+ """Prepare a list of all graphs for acl command auto-completion."""
722
759
  options = graph_uris(ctx, param, incomplete, writeable=True, readonly=True)
723
- options.append(CompletionItem(value=r"urn\:elds-backend-all-graphs", help="All Graphs"))
760
+ options.append(
761
+ CompletionItem(
762
+ value=r"urn\:elds-backend-all-graphs", help="All Graphs (until 24.2.x, now deprecated)"
763
+ )
764
+ )
765
+ options.append(
766
+ CompletionItem(value=r"https\://vocab.eccenca.com/auth/AllGraphs", help="All Graphs")
767
+ )
724
768
  return options
725
769
 
726
770
 
@@ -729,7 +773,7 @@ def connections(ctx: Context, param: Argument, incomplete: str) -> list[Completi
729
773
  # since ctx does not have an obj here, we re-create the object
730
774
  CONTEXT.set_connection_from_params(ctx.find_root().params)
731
775
  options = CONTEXT.config.sections()
732
- return _finalize_completion(candidates=options, incomplete=incomplete)
776
+ return finalize_completion(candidates=options, incomplete=incomplete)
733
777
 
734
778
 
735
779
  def graph_export_templates(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
@@ -743,7 +787,7 @@ def graph_export_templates(ctx: Context, param: Argument, incomplete: str) -> li
743
787
  "Example: 2021-11-29-mycmem-https__ns_eccenca_com_data_config.ttl",
744
788
  ),
745
789
  ]
746
- return _finalize_completion(candidates=examples, incomplete=incomplete)
790
+ return finalize_completion(candidates=examples, incomplete=incomplete)
747
791
 
748
792
 
749
793
  def project_export_templates(
@@ -751,11 +795,11 @@ def project_export_templates(
751
795
  ) -> list[CompletionItem]:
752
796
  """Prepare a list of example templates for the project export command."""
753
797
  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"),
798
+ ("{{id}}.project", "Example: Plain file name"),
799
+ ("{{date}}-{{connection}}-{{id}}.project", "Example: More descriptive file name"),
800
+ ("dumps/{{connection}}/{{id}}/{{date}}.project", "Example: Whole directory tree"),
757
801
  ]
758
- return _finalize_completion(candidates=examples, incomplete=incomplete)
802
+ return finalize_completion(candidates=examples, incomplete=incomplete)
759
803
 
760
804
 
761
805
  def workspace_export_templates(
@@ -767,7 +811,7 @@ def workspace_export_templates(
767
811
  ("{{date}}-{{connection}}.workspace", "Example: a more descriptive file name"),
768
812
  ("dumps/{{connection}}/{{date}}.workspace", "Example: a whole directory tree"),
769
813
  ]
770
- return _finalize_completion(candidates=examples, incomplete=incomplete)
814
+ return finalize_completion(candidates=examples, incomplete=incomplete)
771
815
 
772
816
 
773
817
  def graph_list_filter(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
@@ -783,12 +827,12 @@ def graph_list_filter(ctx: Context, param: Argument, incomplete: str) -> list[Co
783
827
  ("readonly", "List only graphs which are NOT writable for the current user."),
784
828
  ("writeable", "List only graphs which ARE writeable for the current user."),
785
829
  ]
786
- args = _get_completion_args(incomplete)
830
+ args = get_completion_args(incomplete)
787
831
  options = []
788
832
  if args[len(args) - 1] == "--filter":
789
- options = _finalize_completion(candidates=filter_names, incomplete=incomplete)
833
+ options = finalize_completion(candidates=filter_names, incomplete=incomplete)
790
834
  if args[len(args) - 1] == "access":
791
- options = _finalize_completion(candidates=filter_values_access, incomplete=incomplete)
835
+ options = finalize_completion(candidates=filter_values_access, incomplete=incomplete)
792
836
  if args[len(args) - 1] == "imported-by":
793
837
  options = graph_uris(ctx, param, incomplete)
794
838
  return options
@@ -805,10 +849,10 @@ def variable_ids(ctx: Context, param: Argument, incomplete: str) -> list[Complet
805
849
  if label == "":
806
850
  label = f"Current value: {_['value']}"
807
851
  # 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]
852
+ if check_option_in_params(variable_id, ctx.params.get(param.name)): # type: ignore[attr-defined]
809
853
  continue
810
854
  options.append((variable_id, label))
811
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_KEY)
855
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_KEY)
812
856
 
813
857
 
814
858
  def variable_list_filter(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
@@ -825,11 +869,11 @@ def variable_list_filter(ctx: Context, param: Argument, incomplete: str) -> list
825
869
  ("ending$", "Variables name ends with 'ending'."),
826
870
  ("^starting", "Variables name starts with 'starting'."),
827
871
  ]
828
- args = _get_completion_args(incomplete)
872
+ args = get_completion_args(incomplete)
829
873
  if args[len(args) - 1] == "--filter":
830
874
  return [CompletionItem(value=f[0], help=f[1]) for f in filter_names]
831
875
  if args[len(args) - 1] == "regex":
832
- return _finalize_completion(candidates=filter_values_regex, incomplete=incomplete)
876
+ return finalize_completion(candidates=filter_values_regex, incomplete=incomplete)
833
877
  if args[len(args) - 1] == "project":
834
878
  return project_ids(ctx, param, incomplete)
835
879
  return []
@@ -848,15 +892,15 @@ def resource_list_filter(ctx: Context, param: Argument, incomplete: str) -> list
848
892
  ("csv$", "File resources which name ends with .csv"),
849
893
  ("2021-10-[0-9][0-9]", "File resources which name has a date from 2021-10 in it"),
850
894
  ]
851
- args = _get_completion_args(incomplete)
895
+ args = get_completion_args(incomplete)
852
896
  if args[len(args) - 1] == "--filter":
853
897
  return [CompletionItem(value=f[0], help=f[1]) for f in filter_names]
854
898
  if args[len(args) - 1] == "project":
855
- return _finalize_completion(
899
+ return finalize_completion(
856
900
  candidates=project_ids(ctx, param, incomplete), incomplete=incomplete
857
901
  )
858
902
  if args[len(args) - 1] == "regex":
859
- return _finalize_completion(candidates=filter_values_regex, incomplete=incomplete)
903
+ return finalize_completion(candidates=filter_values_regex, incomplete=incomplete)
860
904
  return []
861
905
 
862
906
 
@@ -882,7 +926,7 @@ def workflow_list_filter(ctx: Context, param: Argument, incomplete: str) -> list
882
926
  ),
883
927
  ]
884
928
  options = []
885
- args = _get_completion_args(incomplete)
929
+ args = get_completion_args(incomplete)
886
930
  if args[len(args) - 1] == "--filter":
887
931
  options = filter_names
888
932
  if args[len(args) - 1] == "io":
@@ -894,7 +938,7 @@ def workflow_list_filter(ctx: Context, param: Argument, incomplete: str) -> list
894
938
  if args[len(args) - 1] == "regex":
895
939
  options = filter_regex
896
940
 
897
- return _finalize_completion(candidates=options, incomplete=incomplete)
941
+ return finalize_completion(candidates=options, incomplete=incomplete)
898
942
 
899
943
 
900
944
  def tag_labels(
@@ -912,7 +956,7 @@ def tag_labels(
912
956
  counts[_tag["label"]] = 1
913
957
  for tag, count in counts.items():
914
958
  options.append((tag, f"{count} item(s): {tag}"))
915
- return _finalize_completion(
959
+ return finalize_completion(
916
960
  candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC, reverse=True
917
961
  )
918
962
 
@@ -923,14 +967,14 @@ def status_keys(ctx: Context, param: Argument, incomplete: str) -> list[Completi
923
967
  status_info = struct_to_table(get_complete_status_info())
924
968
  options = [_[0] for _ in status_info]
925
969
  options.insert(0, "all")
926
- return _finalize_completion(candidates=options, incomplete=incomplete)
970
+ return finalize_completion(candidates=options, incomplete=incomplete)
927
971
 
928
972
 
929
973
  def user_ids(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
930
974
  """Prepare a list of username for admin update/delete/password command."""
931
975
  CONTEXT.set_connection_from_params(ctx.find_root().params)
932
976
  options = [_["username"] for _ in list_users()]
933
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
977
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
934
978
 
935
979
 
936
980
  def user_group_ids(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
@@ -956,14 +1000,14 @@ def user_group_ids(ctx: Context, param: Argument, incomplete: str) -> list[Compl
956
1000
  with suppress(ValueError):
957
1001
  options.remove(arg)
958
1002
 
959
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
1003
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
960
1004
 
961
1005
 
962
1006
  def client_ids(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
963
1007
  """Prepare a list of client ids for admin secret and update command."""
964
1008
  CONTEXT.set_connection_from_params(ctx.find_root().params)
965
1009
  options = [_["clientId"] for _ in list_open_id_clients()]
966
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
1010
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
967
1011
 
968
1012
 
969
1013
  def transformation_task_ids(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
@@ -972,7 +1016,7 @@ def transformation_task_ids(ctx: Context, param: Argument, incomplete: str) -> l
972
1016
  results = list_items(item_type="transform")
973
1017
  datasets = results["results"]
974
1018
  options = [(f"{_['projectId']}:{_['id']}", _["label"]) for _ in datasets]
975
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
1019
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
976
1020
 
977
1021
 
978
1022
  def linking_task_ids(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
@@ -981,4 +1025,4 @@ def linking_task_ids(ctx: Context, param: Argument, incomplete: str) -> list[Com
981
1025
  results = list_items(item_type="linking")
982
1026
  datasets = results["results"]
983
1027
  options = [(_["projectId"] + r"\:" + _["id"], _["label"]) for _ in datasets]
984
- return _finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
1028
+ return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)