cmem-cmemc 24.3.3__py3-none-any.whl → 25.1.1__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.
- cmem_cmemc/__init__.py +1 -160
- cmem_cmemc/cli.py +138 -0
- cmem_cmemc/command.py +36 -0
- cmem_cmemc/commands/admin.py +7 -6
- cmem_cmemc/commands/client.py +4 -3
- cmem_cmemc/commands/config.py +3 -2
- cmem_cmemc/commands/dataset.py +18 -17
- cmem_cmemc/commands/graph.py +20 -22
- cmem_cmemc/commands/manual.py +56 -0
- cmem_cmemc/commands/metrics.py +11 -11
- cmem_cmemc/commands/migration.py +4 -3
- cmem_cmemc/commands/project.py +10 -10
- cmem_cmemc/commands/python.py +29 -2
- cmem_cmemc/commands/query.py +31 -14
- cmem_cmemc/commands/resource.py +4 -3
- cmem_cmemc/commands/scheduler.py +4 -4
- cmem_cmemc/commands/store.py +2 -2
- cmem_cmemc/commands/user.py +10 -9
- cmem_cmemc/commands/validation.py +2 -2
- cmem_cmemc/commands/variable.py +1 -1
- cmem_cmemc/commands/vocabulary.py +11 -10
- cmem_cmemc/commands/workflow.py +18 -18
- cmem_cmemc/completion.py +76 -49
- cmem_cmemc/config_parser.py +44 -0
- cmem_cmemc/context.py +168 -99
- cmem_cmemc/exceptions.py +15 -2
- cmem_cmemc/manual_helper/graph.py +2 -0
- cmem_cmemc/manual_helper/multi_page.py +1 -1
- cmem_cmemc/manual_helper/single_page.py +2 -0
- cmem_cmemc/migrations/remove_noop_triple_251.py +50 -0
- cmem_cmemc/migrations/shapes_widget_integrations_243.py +0 -5
- cmem_cmemc/object_list.py +3 -3
- cmem_cmemc/parameter_types/path.py +7 -0
- cmem_cmemc/placeholder.py +69 -0
- cmem_cmemc/utils.py +49 -15
- {cmem_cmemc-24.3.3.dist-info → cmem_cmemc-25.1.1.dist-info}/METADATA +14 -14
- cmem_cmemc-25.1.1.dist-info/RECORD +59 -0
- cmem_cmemc-25.1.1.dist-info/entry_points.txt +3 -0
- cmem_cmemc-24.3.3.dist-info/RECORD +0 -54
- cmem_cmemc-24.3.3.dist-info/entry_points.txt +0 -3
- {cmem_cmemc-24.3.3.dist-info → cmem_cmemc-25.1.1.dist-info}/LICENSE +0 -0
- {cmem_cmemc-24.3.3.dist-info → cmem_cmemc-25.1.1.dist-info}/WHEEL +0 -0
cmem_cmemc/completion.py
CHANGED
|
@@ -3,11 +3,12 @@
|
|
|
3
3
|
# ruff: noqa: ARG001
|
|
4
4
|
import os
|
|
5
5
|
import pathlib
|
|
6
|
+
from collections import OrderedDict
|
|
6
7
|
from contextlib import suppress
|
|
7
8
|
from typing import Any
|
|
8
9
|
|
|
9
10
|
import requests.exceptions
|
|
10
|
-
from click import Context
|
|
11
|
+
from click import ClickException, Context
|
|
11
12
|
from click.parser import Argument, split_arg_string
|
|
12
13
|
from click.shell_completion import CompletionItem
|
|
13
14
|
from cmem.cmempy.dp.authorization.conditions import (
|
|
@@ -38,7 +39,8 @@ from cmem.cmempy.workspace.search import list_items
|
|
|
38
39
|
from natsort import natsorted, ns
|
|
39
40
|
|
|
40
41
|
from cmem_cmemc.constants import NS_ACL, NS_ACTION, NS_GROUP, NS_USER
|
|
41
|
-
from cmem_cmemc.context import
|
|
42
|
+
from cmem_cmemc.context import ApplicationContext
|
|
43
|
+
from cmem_cmemc.placeholder import QueryPlaceholder, get_placeholders_for_query
|
|
42
44
|
from cmem_cmemc.smart_path import SmartPath as Path
|
|
43
45
|
from cmem_cmemc.utils import (
|
|
44
46
|
convert_iri_to_qname,
|
|
@@ -47,6 +49,7 @@ from cmem_cmemc.utils import (
|
|
|
47
49
|
struct_to_table,
|
|
48
50
|
)
|
|
49
51
|
|
|
52
|
+
NOT_SORTED = -1
|
|
50
53
|
SORT_BY_KEY = 0
|
|
51
54
|
SORT_BY_DESC = 1
|
|
52
55
|
|
|
@@ -66,7 +69,7 @@ def finalize_completion(
|
|
|
66
69
|
----
|
|
67
70
|
candidates (list): completion dictionary to filter
|
|
68
71
|
incomplete (str): incomplete string at the cursor
|
|
69
|
-
sort_by (str): SORT_BY_KEY or
|
|
72
|
+
sort_by (str): SORT_BY_KEY, SORT_BY_DESC or NOT_SORTED
|
|
70
73
|
nat_sort (bool): if true, uses the natsort package for sorting
|
|
71
74
|
reverse (bool): if true, sorts in reverse order
|
|
72
75
|
|
|
@@ -76,26 +79,30 @@ def finalize_completion(
|
|
|
76
79
|
|
|
77
80
|
Raises:
|
|
78
81
|
------
|
|
79
|
-
|
|
82
|
+
ClickException in case of wrong sort_by parameter
|
|
80
83
|
|
|
81
84
|
"""
|
|
82
|
-
if sort_by not in (SORT_BY_KEY, SORT_BY_DESC):
|
|
83
|
-
raise
|
|
85
|
+
if sort_by not in (SORT_BY_KEY, SORT_BY_DESC, NOT_SORTED):
|
|
86
|
+
raise ClickException("sort_by should be -1, 0 or 1.")
|
|
84
87
|
incomplete = incomplete.lower()
|
|
85
88
|
if len(candidates) == 0:
|
|
86
89
|
return candidates
|
|
87
|
-
# remove duplicates
|
|
88
|
-
candidates = list(
|
|
90
|
+
# remove duplicates (preserving the order)
|
|
91
|
+
candidates = list(OrderedDict.fromkeys(candidates))
|
|
92
|
+
|
|
89
93
|
if isinstance(candidates[0], str):
|
|
90
94
|
# list of strings filtering and sorting
|
|
91
95
|
filtered_candidates = [
|
|
92
96
|
element for element in candidates if element.lower().find(incomplete) != -1
|
|
93
97
|
]
|
|
98
|
+
if sort_by == NOT_SORTED:
|
|
99
|
+
return filtered_candidates
|
|
94
100
|
if nat_sort:
|
|
95
101
|
return natsorted(seq=filtered_candidates, alg=ns.IGNORECASE, reverse=reverse)
|
|
96
102
|
# this solves that case-insensitive sorting is not stable in ordering
|
|
97
103
|
# of "equal" keys (https://stackoverflow.com/a/57923460)
|
|
98
104
|
return sorted(filtered_candidates, key=lambda x: (str(x).casefold(), x), reverse=reverse)
|
|
105
|
+
|
|
99
106
|
if isinstance(candidates[0], tuple):
|
|
100
107
|
# list of tuples filtering and sorting
|
|
101
108
|
filtered_candidates = [
|
|
@@ -104,7 +111,9 @@ def finalize_completion(
|
|
|
104
111
|
if str(element[0]).lower().find(incomplete) != -1
|
|
105
112
|
or str(element[1]).lower().find(incomplete) != -1
|
|
106
113
|
]
|
|
107
|
-
if
|
|
114
|
+
if sort_by == NOT_SORTED:
|
|
115
|
+
sorted_list = filtered_candidates
|
|
116
|
+
elif nat_sort:
|
|
108
117
|
sorted_list = natsorted(
|
|
109
118
|
seq=filtered_candidates,
|
|
110
119
|
key=lambda k: k[sort_by],
|
|
@@ -121,7 +130,8 @@ def finalize_completion(
|
|
|
121
130
|
CompletionItem(value=element[0].replace(":", r"\:"), help=element[1])
|
|
122
131
|
for element in sorted_list
|
|
123
132
|
]
|
|
124
|
-
|
|
133
|
+
|
|
134
|
+
raise ClickException(
|
|
125
135
|
"Candidates should be a list of strings or a list of tuples." f" Got {candidates}"
|
|
126
136
|
)
|
|
127
137
|
|
|
@@ -156,7 +166,7 @@ def add_metadata_parameter(list_: list | None = None) -> list:
|
|
|
156
166
|
|
|
157
167
|
def acl_ids(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
|
|
158
168
|
"""Prepare a list of access condition identifier"""
|
|
159
|
-
|
|
169
|
+
ApplicationContext.set_connection_from_params(ctx.find_root().params)
|
|
160
170
|
options = []
|
|
161
171
|
acls = fetch_all_acls()
|
|
162
172
|
for access_condition in acls:
|
|
@@ -170,7 +180,7 @@ def acl_ids(ctx: Context, param: Argument, incomplete: str) -> list[CompletionIt
|
|
|
170
180
|
|
|
171
181
|
def acl_actions(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
|
|
172
182
|
"""Prepare a list of access condition actions"""
|
|
173
|
-
|
|
183
|
+
ApplicationContext.set_connection_from_params(ctx.find_root().params)
|
|
174
184
|
options = []
|
|
175
185
|
results = get_actions().json()
|
|
176
186
|
for _ in results:
|
|
@@ -191,7 +201,7 @@ def acl_actions(ctx: Context, param: Argument, incomplete: str) -> list[Completi
|
|
|
191
201
|
|
|
192
202
|
def acl_users(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
|
|
193
203
|
"""Prepare a list of access condition users"""
|
|
194
|
-
|
|
204
|
+
ApplicationContext.set_connection_from_params(ctx.find_root().params)
|
|
195
205
|
options = []
|
|
196
206
|
try:
|
|
197
207
|
for _ in list_users():
|
|
@@ -212,7 +222,7 @@ def acl_users(ctx: Context, param: Argument, incomplete: str) -> list[Completion
|
|
|
212
222
|
|
|
213
223
|
def acl_groups(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
|
|
214
224
|
"""Prepare a list of access condition groups"""
|
|
215
|
-
|
|
225
|
+
ApplicationContext.set_connection_from_params(ctx.find_root().params)
|
|
216
226
|
options = []
|
|
217
227
|
try:
|
|
218
228
|
for _ in list_groups():
|
|
@@ -260,7 +270,7 @@ def add_read_only_and_uri_property_parameters(list_: list | None = None) -> list
|
|
|
260
270
|
|
|
261
271
|
def dataset_parameter(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
|
|
262
272
|
"""Prepare a list of dataset parameters for a dataset type."""
|
|
263
|
-
|
|
273
|
+
ApplicationContext.set_connection_from_params(ctx.find_root().params)
|
|
264
274
|
args = get_completion_args(incomplete)
|
|
265
275
|
incomplete = incomplete.lower()
|
|
266
276
|
# look if cursor is in value position of the -p option and
|
|
@@ -310,7 +320,7 @@ def dataset_parameter(ctx: Context, param: Argument, incomplete: str) -> list[Co
|
|
|
310
320
|
|
|
311
321
|
def dataset_types(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
|
|
312
322
|
"""Prepare a list of dataset types."""
|
|
313
|
-
|
|
323
|
+
ApplicationContext.set_connection_from_params(ctx.find_root().params)
|
|
314
324
|
incomplete = incomplete.lower()
|
|
315
325
|
options = []
|
|
316
326
|
plugins = get_task_plugins()
|
|
@@ -329,7 +339,7 @@ def dataset_types(ctx: Context, param: Argument, incomplete: str) -> list[Comple
|
|
|
329
339
|
|
|
330
340
|
def dataset_ids(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
|
|
331
341
|
"""Prepare a list of projectid:datasetid dataset identifier."""
|
|
332
|
-
|
|
342
|
+
ApplicationContext.set_connection_from_params(ctx.find_root().params)
|
|
333
343
|
results = list_items(item_type="dataset")
|
|
334
344
|
datasets = results["results"]
|
|
335
345
|
options = [(f"{_['projectId']}:{_['id']}", _["label"]) for _ in datasets]
|
|
@@ -368,14 +378,14 @@ def dataset_list_filter(ctx: Context, param: Argument, incomplete: str) -> list[
|
|
|
368
378
|
|
|
369
379
|
def resource_ids(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
|
|
370
380
|
"""Prepare a list of projectid:resourceid resource identifier."""
|
|
371
|
-
|
|
381
|
+
ApplicationContext.set_connection_from_params(ctx.find_root().params)
|
|
372
382
|
options = [_["id"] for _ in get_all_resources()]
|
|
373
383
|
return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
|
|
374
384
|
|
|
375
385
|
|
|
376
386
|
def scheduler_ids(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
|
|
377
387
|
"""Prepare a list of projectid:schedulerid scheduler identifier."""
|
|
378
|
-
|
|
388
|
+
ApplicationContext.set_connection_from_params(ctx.find_root().params)
|
|
379
389
|
options = []
|
|
380
390
|
schedulers = list_items(
|
|
381
391
|
item_type="task",
|
|
@@ -392,7 +402,7 @@ def vocabularies(
|
|
|
392
402
|
ctx: Context, param: Argument, incomplete: str, filter_: str = "all"
|
|
393
403
|
) -> list[CompletionItem]:
|
|
394
404
|
"""Prepare a list of vocabulary graphs for auto-completion."""
|
|
395
|
-
|
|
405
|
+
ApplicationContext.set_connection_from_params(ctx.find_root().params)
|
|
396
406
|
vocabs = get_vocabularies(filter_=filter_)
|
|
397
407
|
options = []
|
|
398
408
|
for _ in vocabs:
|
|
@@ -437,7 +447,7 @@ def file_list(
|
|
|
437
447
|
|
|
438
448
|
def workflow_io_ids(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
|
|
439
449
|
"""Prepare a list of io workflows."""
|
|
440
|
-
|
|
450
|
+
ApplicationContext.set_connection_from_params(ctx.find_root().params)
|
|
441
451
|
options = []
|
|
442
452
|
for _ in get_workflows_io():
|
|
443
453
|
workflow_id = _["projectId"] + ":" + _["id"]
|
|
@@ -453,7 +463,7 @@ def replay_files(ctx: Context, param: Argument, incomplete: str) -> list[Complet
|
|
|
453
463
|
|
|
454
464
|
def installed_package_names(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
|
|
455
465
|
"""Prepare a list of installed packages."""
|
|
456
|
-
|
|
466
|
+
ApplicationContext.set_connection_from_params(ctx.find_root().params)
|
|
457
467
|
options = [(_["name"], _["version"]) for _ in list_packages()]
|
|
458
468
|
return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_KEY)
|
|
459
469
|
|
|
@@ -617,21 +627,47 @@ def triple_files(ctx: Context, param: Argument, incomplete: str) -> list[Complet
|
|
|
617
627
|
)
|
|
618
628
|
|
|
619
629
|
|
|
630
|
+
def sparql_accept_types(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
|
|
631
|
+
"""Prepare a list of commonly used SPARQL accept content types."""
|
|
632
|
+
examples = [
|
|
633
|
+
(
|
|
634
|
+
"text/csv",
|
|
635
|
+
"CSV response, used for SELECT queries, omits language tags and datatypes of literals",
|
|
636
|
+
),
|
|
637
|
+
("application/sparql-results+json", "JSON response, used for SELECT queries"),
|
|
638
|
+
("text/turtle", "Turtle response, used for CONSTRUCT queries"),
|
|
639
|
+
("application/n-triples", "N-Triples response, used for CONSTRUCT queries"),
|
|
640
|
+
]
|
|
641
|
+
return finalize_completion(candidates=examples, incomplete=incomplete)
|
|
642
|
+
|
|
643
|
+
|
|
620
644
|
def placeholder(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
|
|
621
645
|
"""Prepare a list of placeholder from the to-be executed queries."""
|
|
622
|
-
# look if cursor is in value position of the -p option and
|
|
623
|
-
# return nothing in case it is (values are not completed atm)
|
|
624
646
|
args = get_completion_args(incomplete)
|
|
625
|
-
if args[len(args) - 2] in ("-p", "--parameter"):
|
|
626
|
-
return []
|
|
627
647
|
# setup configuration
|
|
628
|
-
|
|
648
|
+
ApplicationContext.set_connection_from_params(ctx.find_root().params)
|
|
629
649
|
# extract placeholder from given queries in the command line
|
|
630
650
|
options = []
|
|
651
|
+
placeholders: dict[str, QueryPlaceholder] = {}
|
|
652
|
+
catalog = QueryCatalog() # fetch all queries
|
|
631
653
|
for _, arg in enumerate(args):
|
|
632
|
-
query =
|
|
654
|
+
query = catalog.get_query(arg)
|
|
633
655
|
if query is not None:
|
|
656
|
+
# collect all placeholder descriptions of existing queries
|
|
657
|
+
placeholders = placeholders | get_placeholders_for_query(iri=query.url)
|
|
658
|
+
# collect all placeholder keys
|
|
634
659
|
options.extend(list(query.get_placeholder_keys()))
|
|
660
|
+
# look if cursor is in value position of the -p option and
|
|
661
|
+
# use placeholder value completion, in case it is
|
|
662
|
+
if args[len(args) - 2] in ("-p", "--parameter"):
|
|
663
|
+
key = args[len(args) - 1]
|
|
664
|
+
if key in placeholders:
|
|
665
|
+
candidates = placeholders[key].complete(incomplete=incomplete)
|
|
666
|
+
return finalize_completion(
|
|
667
|
+
candidates=candidates, incomplete=incomplete, sort_by=NOT_SORTED
|
|
668
|
+
)
|
|
669
|
+
return []
|
|
670
|
+
|
|
635
671
|
# look for already given parameter in the arguments and remove them from
|
|
636
672
|
# the available options
|
|
637
673
|
for num, arg in enumerate(args):
|
|
@@ -642,7 +678,7 @@ def placeholder(ctx: Context, param: Argument, incomplete: str) -> list[Completi
|
|
|
642
678
|
|
|
643
679
|
def remote_queries(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
|
|
644
680
|
"""Prepare a list of query URIs."""
|
|
645
|
-
|
|
681
|
+
ApplicationContext.set_connection_from_params(ctx.find_root().params)
|
|
646
682
|
options = []
|
|
647
683
|
for query in QueryCatalog().get_queries().values():
|
|
648
684
|
url = query.short_url
|
|
@@ -662,7 +698,7 @@ def remote_queries_and_sparql_files(
|
|
|
662
698
|
|
|
663
699
|
def workflow_ids(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
|
|
664
700
|
"""Prepare a list of projectid:taskid workflow identifier."""
|
|
665
|
-
|
|
701
|
+
ApplicationContext.set_connection_from_params(ctx.find_root().params)
|
|
666
702
|
workflows = list_items(item_type="workflow")["results"]
|
|
667
703
|
options = []
|
|
668
704
|
for _ in workflows:
|
|
@@ -676,7 +712,7 @@ def workflow_ids(ctx: Context, param: Argument, incomplete: str) -> list[Complet
|
|
|
676
712
|
|
|
677
713
|
def marshalling_plugins(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
|
|
678
714
|
"""Prepare a list of supported workspace/project import/export plugins."""
|
|
679
|
-
|
|
715
|
+
ApplicationContext.set_connection_from_params(ctx.find_root().params)
|
|
680
716
|
options = get_marshalling_plugins()
|
|
681
717
|
if "description" in options[0]:
|
|
682
718
|
final_options = [(_["id"], _["description"]) for _ in options]
|
|
@@ -691,7 +727,7 @@ def marshalling_plugins(ctx: Context, param: Argument, incomplete: str) -> list[
|
|
|
691
727
|
|
|
692
728
|
def project_ids(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
|
|
693
729
|
"""Prepare a list of project IDs for auto-completion."""
|
|
694
|
-
|
|
730
|
+
ApplicationContext.set_connection_from_params(ctx.find_root().params)
|
|
695
731
|
projects = get_projects()
|
|
696
732
|
options = []
|
|
697
733
|
for _ in projects:
|
|
@@ -712,7 +748,7 @@ def _prepare_graph_options(
|
|
|
712
748
|
skip_selected_iris: bool = True,
|
|
713
749
|
) -> list[tuple[str, str]]:
|
|
714
750
|
"""Prepare a list of graphs with iri and label"""
|
|
715
|
-
|
|
751
|
+
ApplicationContext.set_connection_from_params(ctx.find_root().params)
|
|
716
752
|
graphs = get_graphs(writeable=writeable, readonly=readonly)
|
|
717
753
|
options = []
|
|
718
754
|
for graph in graphs:
|
|
@@ -777,8 +813,8 @@ def graph_uris_with_all_graph_uri(
|
|
|
777
813
|
def connections(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
|
|
778
814
|
"""Prepare a list of config connections for auto-completion."""
|
|
779
815
|
# since ctx does not have an obj here, we re-create the object
|
|
780
|
-
|
|
781
|
-
options =
|
|
816
|
+
app = ApplicationContext.from_params(ctx.find_root().params)
|
|
817
|
+
options = app.get_config().sections()
|
|
782
818
|
return finalize_completion(candidates=options, incomplete=incomplete)
|
|
783
819
|
|
|
784
820
|
|
|
@@ -846,7 +882,7 @@ def graph_list_filter(ctx: Context, param: Argument, incomplete: str) -> list[Co
|
|
|
846
882
|
|
|
847
883
|
def variable_ids(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
|
|
848
884
|
"""Prepare a list of variables IDs for auto-completion."""
|
|
849
|
-
|
|
885
|
+
ApplicationContext.set_connection_from_params(ctx.find_root().params)
|
|
850
886
|
variables = get_all_variables()
|
|
851
887
|
options = []
|
|
852
888
|
for _ in variables:
|
|
@@ -978,14 +1014,14 @@ def status_keys(ctx: Context, param: Argument, incomplete: str) -> list[Completi
|
|
|
978
1014
|
|
|
979
1015
|
def user_ids(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
|
|
980
1016
|
"""Prepare a list of username for admin update/delete/password command."""
|
|
981
|
-
|
|
1017
|
+
ApplicationContext.set_connection_from_params(ctx.find_root().params)
|
|
982
1018
|
options = [_["username"] for _ in list_users()]
|
|
983
1019
|
return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
|
|
984
1020
|
|
|
985
1021
|
|
|
986
1022
|
def user_group_ids(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
|
|
987
1023
|
"""Prepare a list of group name for admin user update --(un)assign-group parameter"""
|
|
988
|
-
|
|
1024
|
+
ApplicationContext.set_connection_from_params(ctx.find_root().params)
|
|
989
1025
|
if not ctx.args:
|
|
990
1026
|
return []
|
|
991
1027
|
users = get_user_by_username(username=str(ctx.args[0]))
|
|
@@ -1011,24 +1047,15 @@ def user_group_ids(ctx: Context, param: Argument, incomplete: str) -> list[Compl
|
|
|
1011
1047
|
|
|
1012
1048
|
def client_ids(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
|
|
1013
1049
|
"""Prepare a list of client ids for admin secret and update command."""
|
|
1014
|
-
|
|
1050
|
+
ApplicationContext.set_connection_from_params(ctx.find_root().params)
|
|
1015
1051
|
options = [_["clientId"] for _ in list_open_id_clients()]
|
|
1016
1052
|
return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
|
|
1017
1053
|
|
|
1018
1054
|
|
|
1019
1055
|
def transformation_task_ids(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
|
|
1020
1056
|
"""Prepare a list of projectId:transformation task identifier."""
|
|
1021
|
-
|
|
1057
|
+
ApplicationContext.set_connection_from_params(ctx.find_root().params)
|
|
1022
1058
|
results = list_items(item_type="transform")
|
|
1023
1059
|
datasets = results["results"]
|
|
1024
1060
|
options = [(f"{_['projectId']}:{_['id']}", _["label"]) for _ in datasets]
|
|
1025
1061
|
return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
def linking_task_ids(ctx: Context, param: Argument, incomplete: str) -> list[CompletionItem]:
|
|
1029
|
-
"""Prepare a list of projectId:linking task identifier."""
|
|
1030
|
-
CONTEXT.set_connection_from_args(ctx.find_root().params)
|
|
1031
|
-
results = list_items(item_type="linking")
|
|
1032
|
-
datasets = results["results"]
|
|
1033
|
-
options = [(_["projectId"] + r"\:" + _["id"], _["label"]) for _ in datasets]
|
|
1034
|
-
return finalize_completion(candidates=options, incomplete=incomplete, sort_by=SORT_BY_DESC)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""Config parser module with a custom configuration parser."""
|
|
2
|
+
|
|
3
|
+
import configparser
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class PureSectionConfigParser(configparser.RawConfigParser):
|
|
7
|
+
"""A configuration parser that retrieves section data without defaults."""
|
|
8
|
+
|
|
9
|
+
_defaults: dict
|
|
10
|
+
|
|
11
|
+
def options(self, section: str) -> list:
|
|
12
|
+
"""Return a list of option names for the given section, excluding defaults.
|
|
13
|
+
|
|
14
|
+
This method temporarily removes default options to ensure only explicitly
|
|
15
|
+
defined options in the given section are returned.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
section (str): The section name.
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
list: A list of option names in the specified section.
|
|
22
|
+
|
|
23
|
+
"""
|
|
24
|
+
_d = self._defaults.copy()
|
|
25
|
+
try:
|
|
26
|
+
self._defaults.clear()
|
|
27
|
+
return super().options(section)
|
|
28
|
+
finally:
|
|
29
|
+
self._defaults.update(_d)
|
|
30
|
+
|
|
31
|
+
def optionxform(self, option: str) -> str:
|
|
32
|
+
"""Preserve the case of option names.
|
|
33
|
+
|
|
34
|
+
By default, `optionxform` in `RawConfigParser` converts option names to lowercase.
|
|
35
|
+
This overridden method ensures that option names remain unchanged.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
option (str): The option name.
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
str: The unmodified option name.
|
|
42
|
+
|
|
43
|
+
"""
|
|
44
|
+
return option
|