cmem-cmemc 23.2__py3-none-any.whl → 23.3.0__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.
@@ -1,5 +1,5 @@
1
1
  """The main command line interface."""
2
-
2
+ from importlib.resources import open_text
3
3
  import os
4
4
  from subprocess import CalledProcessError # nosec
5
5
  import sys
@@ -38,6 +38,12 @@ from cmem.cmemc.cli.commands import CmemcGroup
38
38
 
39
39
  CMEMC_VERSION = get_version()
40
40
 
41
+ # this will output a custom zsh completion function
42
+ if os.environ.get("_CMEMC_COMPLETE", "") == "zsh_source":
43
+ with open_text("cmem.cmemc.cli", "_cmemc.zsh") as zsh_output:
44
+ print(zsh_output.read())
45
+ sys.exit(0)
46
+
41
47
  version = sys.version_info
42
48
  PYTHON_VERSION = f"{version.major}.{version.minor}.{version.micro}"
43
49
  PYTHON_EXPECTED = "3.11"
@@ -65,12 +71,12 @@ CONTEXT_SETTINGS = {
65
71
  @click.option(
66
72
  '-c', '--connection',
67
73
  type=click.STRING,
68
- autocompletion=completion.connections,
74
+ shell_complete=completion.connections,
69
75
  help='Use a specific connection from the config file.'
70
76
  )
71
77
  @click.option(
72
78
  '--config-file',
73
- autocompletion=completion.ini_files,
79
+ shell_complete=completion.ini_files,
74
80
  type=click.Path(
75
81
  readable=True,
76
82
  allow_dash=False,
@@ -0,0 +1,44 @@
1
+ #compdef cmemc
2
+
3
+ _cmemc_completion() {
4
+ local -a completions
5
+ local -a completions_with_descriptions
6
+ local -a response
7
+ (( ! $+commands[cmemc] )) && return 1
8
+
9
+ response=("${(@f)$(env COMP_WORDS="${words[*]}" COMP_CWORD=$((CURRENT-1)) _CMEMC_COMPLETE=zsh_complete cmemc)}")
10
+
11
+ for type key descr in ${response}; do
12
+ if [[ "$type" == "plain" ]]; then
13
+ if [[ "$descr" == "_" ]]; then
14
+ completions+=("$key")
15
+ else
16
+ completions_with_descriptions+=("$key":"$descr")
17
+ fi
18
+ elif [[ "$type" == "dir" ]]; then
19
+ _path_files -/
20
+ elif [[ "$type" == "file" ]]; then
21
+ _path_files -f
22
+ fi
23
+ done
24
+
25
+ if [ -n "$completions_with_descriptions" ]; then
26
+ _describe -V unsorted completions_with_descriptions -U
27
+ fi
28
+
29
+ if [ -n "$completions" ]; then
30
+ compadd -U -V unsorted -a completions
31
+ fi
32
+ # Other than the standard click completion function, we re-added this line
33
+ # in order to have working completions for task IDs
34
+ compstate[insert]="automenu"
35
+ }
36
+
37
+ if [[ $zsh_eval_context[-1] == loadautofunc ]]; then
38
+ # autoload from fpath, call function directly
39
+ _cmemc_completion "$@"
40
+ else
41
+ # eval/source/. command, register function for later
42
+ compdef _cmemc_completion cmemc
43
+ fi
44
+
@@ -61,6 +61,7 @@ class CmemcGroup(HelpColorsGroup, DYMGroup):
61
61
  "cache": COLOR_FOR_COMMAND_GROUPS,
62
62
  "resource": COLOR_FOR_COMMAND_GROUPS,
63
63
  "client": COLOR_FOR_COMMAND_GROUPS,
64
+ "variable": COLOR_FOR_COMMAND_GROUPS,
64
65
  }
65
66
  )
66
67
  super().__init__(*args, **kwargs)
@@ -21,7 +21,7 @@ from cmem.cmempy.health import get_complete_status_info
21
21
  @click.command(cls=CmemcCommand, name="status")
22
22
  @click.option(
23
23
  "--key", "key",
24
- autocompletion=completion.status_keys,
24
+ shell_complete=completion.status_keys,
25
25
  help="Get only specific key(s) from the status / info output. There are "
26
26
  "two special keys available: 'all' will list all available keys in "
27
27
  "the table, 'overall.healthy' with result in UP in case all "
@@ -64,7 +64,7 @@ def list_command(app: ApplicationContext, raw, id_only):
64
64
  @click.command(cls=CmemcCommand, name="secret")
65
65
  @click.argument(
66
66
  "client-id",
67
- autocompletion=completion.client_ids
67
+ shell_complete=completion.client_ids
68
68
  )
69
69
  @click.option(
70
70
  "--generate",
@@ -115,7 +115,7 @@ def secret_command(app: ApplicationContext, client_id, generate, output):
115
115
  nargs=-1,
116
116
  required=False,
117
117
  type=click.STRING,
118
- autocompletion=completion.client_ids
118
+ shell_complete=completion.client_ids
119
119
  )
120
120
  @click.pass_obj
121
121
  def open_command(app: ApplicationContext, client_ids):
@@ -41,7 +41,7 @@ def edit_command(app):
41
41
  "KEY",
42
42
  nargs=1,
43
43
  type=click.Choice(
44
- KNOWN_CONFIG_KEYS.keys(),
44
+ list(KNOWN_CONFIG_KEYS.keys()),
45
45
  case_sensitive=False
46
46
  )
47
47
  )
@@ -6,22 +6,21 @@ import re
6
6
  import click
7
7
 
8
8
  import requests.exceptions
9
+ from click import UsageError
9
10
 
10
11
  from cmem.cmemc.cli import completion
11
12
  from cmem.cmemc.cli.commands import CmemcCommand, CmemcGroup
12
13
  from cmem.cmemc.cli.commands.resource import resource
13
14
  from cmem.cmemc.cli.context import ApplicationContext
14
- from cmem.cmemc.cli.utils import struct_to_table
15
+ from cmem.cmemc.cli.utils import struct_to_table, check_or_select_project
15
16
  from cmem.cmempy.config import get_cmem_base_uri
16
17
  from cmem.cmempy.workspace.search import list_items
17
- from cmem.cmempy.workspace.projects.project import (
18
- get_projects
19
- )
20
18
  from cmem.cmempy.workspace.projects.datasets.dataset import (
21
19
  create_dataset,
22
20
  delete_dataset,
23
21
  get_dataset,
24
- post_resource
22
+ post_resource,
23
+ update_dataset
25
24
  )
26
25
  from cmem.cmempy.workspace.projects.resources.resource import (
27
26
  create_resource,
@@ -312,7 +311,7 @@ def _check_or_set_dataset_type(
312
311
  return dataset_type
313
312
 
314
313
 
315
- def _show_parameter_list(app, dataset_type=None):
314
+ def _show_parameter_list(app, dataset_type):
316
315
  """Output the parameter list for a given dataset type.
317
316
 
318
317
  Args:
@@ -373,45 +372,6 @@ def _show_type_list(app):
373
372
  )
374
373
 
375
374
 
376
- def _check_or_select_project(app, project_id=None):
377
- """Check for given project, select the first one if there is only one.
378
-
379
- Args:
380
- app (ApplicationContext): the click cli app context.
381
- project_id (str): The project ID.
382
-
383
- Raises:
384
- ValueError: if no projects available.
385
- ValueError: if more than one project is.
386
-
387
- Returns:
388
- Maybe project_id if there was no project_id before.
389
- """
390
- if project_id is not None:
391
- return project_id
392
-
393
- projects = get_projects()
394
- if len(projects) == 1:
395
- project_name = projects[0]["name"]
396
- app.echo_warning(
397
- "Missing project (--project) - since there is only one project, "
398
- f"this is selected: {project_name}"
399
- )
400
- return project_name
401
-
402
- if len(projects) == 0:
403
- raise ValueError(
404
- "There are no projects available. "
405
- "Please create a project with 'cmemc project create'."
406
- )
407
-
408
- # more than one project
409
- raise ValueError(
410
- "There is more than one project available so you need to "
411
- "specify the project with '--project'."
412
- )
413
-
414
-
415
375
  def _check_or_select_dataset_type(app, dataset_type):
416
376
  """Test type and return plugin.
417
377
 
@@ -440,7 +400,7 @@ def _check_or_select_dataset_type(app, dataset_type):
440
400
  "--filter", "filter_",
441
401
  type=(str, str),
442
402
  multiple=True,
443
- autocompletion=completion.dataset_list_filter,
403
+ shell_complete=completion.dataset_list_filter,
444
404
  help=DATASET_LIST_FILTER_HELP_TEXT,
445
405
  )
446
406
  @click.option(
@@ -497,7 +457,7 @@ def list_command(app: ApplicationContext, filter_, raw, id_only):
497
457
  @click.option(
498
458
  "--project", "project_id",
499
459
  type=click.STRING,
500
- autocompletion=completion.project_ids,
460
+ shell_complete=completion.project_ids,
501
461
  help="In combination with the '--all' flag, this option allows for "
502
462
  "deletion of all datasets of a certain project. The behaviour is "
503
463
  "similar to the 'dataset list --project' command."
@@ -506,14 +466,14 @@ def list_command(app: ApplicationContext, filter_, raw, id_only):
506
466
  "--filter", "filter_",
507
467
  type=(str, str),
508
468
  multiple=True,
509
- autocompletion=completion.dataset_list_filter,
469
+ shell_complete=completion.dataset_list_filter,
510
470
  help=DATASET_DELETE_FILTER_HELP_TEXT,
511
471
  )
512
472
  @click.argument(
513
473
  "dataset_ids",
514
474
  nargs=-1,
515
475
  type=click.STRING,
516
- autocompletion=completion.dataset_ids
476
+ shell_complete=completion.dataset_ids
517
477
  )
518
478
  @click.pass_obj
519
479
  def delete_command(app, project_id, all_, filter_, dataset_ids):
@@ -577,7 +537,7 @@ def delete_command(app, project_id, all_, filter_, dataset_ids):
577
537
  @click.argument(
578
538
  "dataset_id",
579
539
  type=click.STRING,
580
- autocompletion=completion.dataset_ids
540
+ shell_complete=completion.dataset_ids
581
541
  )
582
542
  @click.argument(
583
543
  "output_path",
@@ -646,12 +606,12 @@ def download_command(app, dataset_id, output_path, replace):
646
606
  @click.argument(
647
607
  "dataset_id",
648
608
  type=click.STRING,
649
- autocompletion=completion.dataset_ids
609
+ shell_complete=completion.dataset_ids
650
610
  )
651
611
  @click.argument(
652
612
  "input_path",
653
613
  required=True,
654
- autocompletion=completion.dataset_files,
614
+ shell_complete=completion.dataset_files,
655
615
  type=click.Path(
656
616
  allow_dash=True,
657
617
  dir_okay=False,
@@ -690,7 +650,7 @@ def upload_command(app, dataset_id, input_path):
690
650
  @click.argument(
691
651
  "dataset_id",
692
652
  type=click.STRING,
693
- autocompletion=completion.dataset_ids
653
+ shell_complete=completion.dataset_ids
694
654
  )
695
655
  @click.option(
696
656
  "--raw",
@@ -722,7 +682,7 @@ def inspect_command(app, dataset_id, raw):
722
682
  @click.argument(
723
683
  "DATASET_FILE",
724
684
  required=False,
725
- autocompletion=completion.dataset_files,
685
+ shell_complete=completion.dataset_files,
726
686
  type=click.Path(
727
687
  allow_dash=False,
728
688
  readable=True,
@@ -734,21 +694,21 @@ def inspect_command(app, dataset_id, raw):
734
694
  "--type", "-t", "dataset_type",
735
695
  multiple=False,
736
696
  type=click.STRING,
737
- autocompletion=completion.dataset_types,
697
+ shell_complete=completion.dataset_types,
738
698
  help="The dataset type of the dataset to create. Example types are 'csv',"
739
699
  "'json' and 'eccencaDataPlatform' (-> Knowledge Graph)."
740
700
  )
741
701
  @click.option(
742
702
  "--project", "project_id",
743
703
  type=click.STRING,
744
- autocompletion=completion.project_ids,
704
+ shell_complete=completion.project_ids,
745
705
  help="The project, where you want to create the dataset in. If there is "
746
706
  "only one project in the workspace, this option can be omitted."
747
707
  )
748
708
  @click.option(
749
709
  "--parameter", "-p",
750
710
  type=(str, str),
751
- autocompletion=completion.dataset_parameter,
711
+ shell_complete=completion.dataset_parameter,
752
712
  multiple=True,
753
713
  help="A set of key/value pairs. Each dataset type has different "
754
714
  "parameters (such as charset, arraySeparator, ignoreBadLines, ...). "
@@ -826,7 +786,7 @@ def create_command(
826
786
  dataset_file=dataset_file
827
787
  )
828
788
 
829
- project_id = _check_or_select_project(app, project_id)
789
+ project_id = check_or_select_project(app, project_id)
830
790
 
831
791
  # file required but not given
832
792
  if "file" in plugin["required"] \
@@ -869,13 +829,97 @@ def create_command(
869
829
  app.echo_success("done")
870
830
 
871
831
 
832
+ @click.command(cls=CmemcCommand, name="update")
833
+ @click.argument(
834
+ "dataset_id",
835
+ type=click.STRING,
836
+ required=True,
837
+ shell_complete=completion.dataset_ids,
838
+ )
839
+ @click.option(
840
+ "--parameter", "-p",
841
+ type=(str, str),
842
+ shell_complete=completion.dataset_parameter,
843
+ multiple=True,
844
+ help="A configuration parameter key/value pair. Each dataset type has different "
845
+ "parameters (such as charset, arraySeparator, ignoreBadLines, ...). "
846
+ "In order to get a list of possible parameter, use the"
847
+ "'--help-parameter' option."
848
+ )
849
+ @click.option(
850
+ "--help-parameter",
851
+ is_flag=True,
852
+ help="Lists all possible (optional and mandatory) configuration parameter for"
853
+ " a given dataset. Note that this option already needs access to the instance."
854
+ )
855
+ @click.pass_obj
856
+ def update_command(
857
+ app, dataset_id, parameter,
858
+ help_parameter
859
+ ):
860
+ """Update a dataset.
861
+
862
+ With this command, you can update the configuration of an existing dataset.
863
+ Similar to the `dataset create` command, you need to use configuration key/value
864
+ pairs on the `--parameter` option.
865
+
866
+ To get more information about the available configuration parameters on a dataset,
867
+ use the `--help-parameter` option.
868
+
869
+ Example: cmemc dataset update my-project:my-csv -p separator ";"
870
+ """
871
+ project_part, dataset_part = _validate_and_split_dataset_id(dataset_id)
872
+ try:
873
+ project = get_dataset(project_part, dataset_part)
874
+ except requests.exceptions.HTTPError as http_exception:
875
+ if http_exception.response.status_code == 404:
876
+ raise UsageError(
877
+ f"Dataset {dataset_part} does not exist in project {project_part}."
878
+ ) from http_exception
879
+ dataset_type = project["data"]["type"]
880
+
881
+ if help_parameter:
882
+ _show_parameter_list(app, dataset_type=dataset_type)
883
+ return
884
+
885
+ if not parameter:
886
+ raise UsageError("You need to use the `--parameter/-p` option at least once,"
887
+ " in order to execute this command.")
888
+
889
+ desc = get_task_plugin_description(dataset_type)
890
+ possible_keys = ["label", "description", "readOnly"]
891
+ possible_keys.extend(desc["properties"])
892
+ possible_keys.extend(desc["required"])
893
+
894
+ # transform the parameter list of tuple to a dictionary
895
+ parameter_dict = {}
896
+ for key, value in parameter:
897
+ if key not in possible_keys:
898
+ raise UsageError(
899
+ f"Configuration key '{key}' is not valid for"
900
+ f" the dataset type '{dataset_type}'."
901
+ )
902
+ parameter_dict[key] = value
903
+
904
+ app.echo_info(f"Updating dataset {dataset_id} ... ", nl=False)
905
+ update_dataset(
906
+ dataset_id=dataset_part,
907
+ project_id=project_part,
908
+ parameters=parameter_dict,
909
+ metadata=_get_metadata_out_of_parameter(parameter_dict),
910
+ read_only=_get_read_only_out_of_parameter(parameter_dict),
911
+ uri_property=parameter_dict.get("uriProperty", "")
912
+ )
913
+ app.echo_success("done")
914
+
915
+
872
916
  @click.command(cls=CmemcCommand, name="open")
873
917
  @click.argument(
874
918
  "dataset_ids",
875
919
  nargs=-1,
876
920
  required=True,
877
921
  type=click.STRING,
878
- autocompletion=completion.dataset_ids
922
+ shell_complete=completion.dataset_ids
879
923
  )
880
924
  @click.pass_obj
881
925
  def open_command(app, dataset_ids):
@@ -925,4 +969,5 @@ dataset.add_command(upload_command)
925
969
  dataset.add_command(inspect_command)
926
970
  dataset.add_command(create_command)
927
971
  dataset.add_command(open_command)
972
+ dataset.add_command(update_command)
928
973
  dataset.add_command(resource)
@@ -371,7 +371,7 @@ def _prepare_tree_output_id_only(iris, graphs):
371
371
  "iris",
372
372
  nargs=-1,
373
373
  type=click.STRING,
374
- autocompletion=completion.graph_uris
374
+ shell_complete=completion.graph_uris
375
375
  )
376
376
  @click.pass_obj
377
377
  def tree_command(app, all_, raw, id_only, iris):
@@ -456,7 +456,7 @@ def tree_command(app, all_, raw, id_only, iris):
456
456
  click.Choice(["access", 'imported-by']),
457
457
  str
458
458
  ]),
459
- autocompletion=completion.graph_list_filter,
459
+ shell_complete=completion.graph_list_filter,
460
460
  default=[None] * 2,
461
461
  help="Filter graphs based on effective access conditions or import "
462
462
  "closure. "
@@ -535,7 +535,7 @@ def list_command(app, raw, id_only, filter_):
535
535
  ),
536
536
  default="-",
537
537
  show_default=True,
538
- autocompletion=completion.triple_files,
538
+ shell_complete=completion.triple_files,
539
539
  help="Export to this file."
540
540
  )
541
541
  @click.option(
@@ -543,7 +543,7 @@ def list_command(app, raw, id_only, filter_):
543
543
  default="{{hash}}",
544
544
  show_default=True,
545
545
  type=click.STRING,
546
- autocompletion=completion.graph_export_templates,
546
+ shell_complete=completion.graph_export_templates,
547
547
  help="Template for the export file name(s). "
548
548
  "Used together with --output-dir. "
549
549
  "Possible placeholders are (Jinja2): "
@@ -565,7 +565,7 @@ def list_command(app, raw, id_only, filter_):
565
565
  "iris",
566
566
  nargs=-1,
567
567
  type=click.STRING,
568
- autocompletion=completion.graph_uris
568
+ shell_complete=completion.graph_uris
569
569
  )
570
570
  @click.pass_obj
571
571
  def export_command(
@@ -660,7 +660,7 @@ def export_command(
660
660
  @click.argument(
661
661
  "input_path",
662
662
  required=True,
663
- autocompletion=completion.triple_files,
663
+ shell_complete=completion.triple_files,
664
664
  type=click.Path(
665
665
  allow_dash=False,
666
666
  readable=True
@@ -670,7 +670,7 @@ def export_command(
670
670
  "iri",
671
671
  type=click.STRING,
672
672
  required=False,
673
- autocompletion=completion.graph_uris
673
+ shell_complete=completion.graph_uris
674
674
  )
675
675
  @click.pass_obj
676
676
  def import_command(app, input_path, replace, skip_existing, iri: tuple[str, ...]):
@@ -752,7 +752,7 @@ def import_command(app, input_path, replace, skip_existing, iri: tuple[str, ...]
752
752
  "iris",
753
753
  nargs=-1,
754
754
  type=click.STRING,
755
- autocompletion=completion.writable_graph_uris
755
+ shell_complete=completion.writable_graph_uris
756
756
  )
757
757
  @click.pass_obj
758
758
  def delete_command(app, all_, include_imports, iris: tuple[str, ...]):
@@ -782,7 +782,7 @@ def delete_command(app, all_, include_imports, iris: tuple[str, ...]):
782
782
  @click.argument(
783
783
  "iri",
784
784
  type=click.STRING,
785
- autocompletion=completion.graph_uris
785
+ shell_complete=completion.graph_uris
786
786
  )
787
787
  @click.pass_obj
788
788
  def open_command(app, iri):
@@ -807,7 +807,7 @@ def open_command(app, iri):
807
807
  "iris",
808
808
  nargs=-1,
809
809
  type=click.STRING,
810
- autocompletion=completion.graph_uris
810
+ shell_complete=completion.graph_uris
811
811
  )
812
812
  @click.pass_obj
813
813
  def count_command(app, all_, summarize, iris: tuple[str, ...]):
@@ -49,7 +49,7 @@ def _filter_samples(family: Metric, label_filter: Tuple[Tuple[str, str], ...]) -
49
49
  "metric_id",
50
50
  required=True,
51
51
  type=click.STRING,
52
- autocompletion=completion.metric_ids
52
+ shell_complete=completion.metric_ids
53
53
  )
54
54
  @click.option(
55
55
  "--job", "job_id",
@@ -61,7 +61,7 @@ def _filter_samples(family: Metric, label_filter: Tuple[Tuple[str, str], ...]) -
61
61
  @click.option(
62
62
  "--filter", "label_filter",
63
63
  type=(str, str),
64
- autocompletion=completion.metric_label_filter,
64
+ shell_complete=completion.metric_label_filter,
65
65
  multiple=True,
66
66
  help="A set of label name/value pairs in order to filter the samples "
67
67
  "of the requested metric family. Each metric has a different set "
@@ -137,7 +137,7 @@ def get_command(app, metric_id, job_id, label_filter, raw, enforce_table):
137
137
  "metric_id",
138
138
  required=True,
139
139
  type=click.STRING,
140
- autocompletion=completion.metric_ids
140
+ shell_complete=completion.metric_ids
141
141
  )
142
142
  @click.option(
143
143
  "--job", "job_id",