cmem-cmemc 25.5.0rc1__py3-none-any.whl → 25.6.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.
- cmem_cmemc/command_group.py +32 -31
- cmem_cmemc/commands/acl.py +15 -6
- cmem_cmemc/commands/dataset.py +1 -54
- cmem_cmemc/commands/file.py +465 -0
- cmem_cmemc/commands/graph_insights.py +103 -35
- cmem_cmemc/commands/project.py +3 -1
- cmem_cmemc/commands/python.py +1 -1
- cmem_cmemc/commands/vocabulary.py +13 -4
- cmem_cmemc/completion.py +22 -5
- cmem_cmemc/context.py +2 -2
- cmem_cmemc/manual_helper/graph.py +2 -2
- cmem_cmemc/manual_helper/multi_page.py +5 -6
- cmem_cmemc/placeholder.py +2 -2
- cmem_cmemc/string_processor.py +12 -0
- cmem_cmemc/utils.py +1 -1
- {cmem_cmemc-25.5.0rc1.dist-info → cmem_cmemc-25.6.0.dist-info}/METADATA +2 -1
- {cmem_cmemc-25.5.0rc1.dist-info → cmem_cmemc-25.6.0.dist-info}/RECORD +20 -20
- cmem_cmemc/commands/resource.py +0 -220
- {cmem_cmemc-25.5.0rc1.dist-info → cmem_cmemc-25.6.0.dist-info}/WHEEL +0 -0
- {cmem_cmemc-25.5.0rc1.dist-info → cmem_cmemc-25.6.0.dist-info}/entry_points.txt +0 -0
- {cmem_cmemc-25.5.0rc1.dist-info → cmem_cmemc-25.6.0.dist-info}/licenses/LICENSE +0 -0
cmem_cmemc/commands/resource.py
DELETED
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
"""Build dataset resource commands for cmemc."""
|
|
2
|
-
|
|
3
|
-
import re
|
|
4
|
-
|
|
5
|
-
import click
|
|
6
|
-
from click import ClickException, UsageError
|
|
7
|
-
from cmem.cmempy.workspace.projects.resources import get_all_resources
|
|
8
|
-
from cmem.cmempy.workspace.projects.resources.resource import (
|
|
9
|
-
delete_resource,
|
|
10
|
-
get_resource_metadata,
|
|
11
|
-
get_resource_usage_data,
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
from cmem_cmemc import completion
|
|
15
|
-
from cmem_cmemc.command import CmemcCommand
|
|
16
|
-
from cmem_cmemc.command_group import CmemcGroup
|
|
17
|
-
from cmem_cmemc.context import ApplicationContext
|
|
18
|
-
from cmem_cmemc.utils import split_task_id, struct_to_table
|
|
19
|
-
|
|
20
|
-
RESOURCE_FILTER_TYPES = ["project", "regex"]
|
|
21
|
-
RESOURCE_FILTER_TYPES_HIDDEN = ["ids"]
|
|
22
|
-
RESOURCE_FILTER_TEXT = (
|
|
23
|
-
"Filter file resources based on metadata. "
|
|
24
|
-
f"First parameter CHOICE can be one of {RESOURCE_FILTER_TYPES!s}"
|
|
25
|
-
". The second parameter is based on CHOICE, e.g. a project "
|
|
26
|
-
"ID or a regular expression string."
|
|
27
|
-
)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
def _get_resources_filtered(
|
|
31
|
-
resources: list[dict], filter_name: str, filter_value: str | tuple[str, ...]
|
|
32
|
-
) -> list[dict]:
|
|
33
|
-
"""Get file resources but filtered according to name and value."""
|
|
34
|
-
# check for correct filter names (filter ids is used internally only)
|
|
35
|
-
if filter_name not in RESOURCE_FILTER_TYPES + RESOURCE_FILTER_TYPES_HIDDEN:
|
|
36
|
-
raise UsageError(
|
|
37
|
-
f"{filter_name} is an unknown filter name. " f"Use one of {RESOURCE_FILTER_TYPES}."
|
|
38
|
-
)
|
|
39
|
-
# filter by ID list
|
|
40
|
-
if filter_name == "ids":
|
|
41
|
-
return [_ for _ in resources if _["id"] in filter_value]
|
|
42
|
-
# filter by project
|
|
43
|
-
if filter_name == "project":
|
|
44
|
-
return [_ for _ in resources if _["project"] == str(filter_value)]
|
|
45
|
-
# filter by regex
|
|
46
|
-
if filter_name == "regex":
|
|
47
|
-
return [_ for _ in resources if re.search(str(filter_value), _["name"])]
|
|
48
|
-
# return unfiltered list
|
|
49
|
-
return resources
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
@click.command(cls=CmemcCommand, name="list")
|
|
53
|
-
@click.option("--raw", is_flag=True, help="Outputs raw JSON.")
|
|
54
|
-
@click.option(
|
|
55
|
-
"--id-only",
|
|
56
|
-
is_flag=True,
|
|
57
|
-
help="Lists only resource names and no other metadata. "
|
|
58
|
-
"This is useful for piping the IDs into other commands.",
|
|
59
|
-
)
|
|
60
|
-
@click.option(
|
|
61
|
-
"--filter",
|
|
62
|
-
"filters_",
|
|
63
|
-
multiple=True,
|
|
64
|
-
type=(str, str),
|
|
65
|
-
shell_complete=completion.resource_list_filter,
|
|
66
|
-
help=RESOURCE_FILTER_TEXT,
|
|
67
|
-
)
|
|
68
|
-
@click.pass_obj
|
|
69
|
-
def list_command(
|
|
70
|
-
app: ApplicationContext, raw: bool, id_only: bool, filters_: tuple[tuple[str, str], ...]
|
|
71
|
-
) -> None:
|
|
72
|
-
"""List available file resources.
|
|
73
|
-
|
|
74
|
-
Outputs a table or a list of dataset resources (files).
|
|
75
|
-
"""
|
|
76
|
-
resources = get_all_resources()
|
|
77
|
-
for _ in filters_:
|
|
78
|
-
filter_name, filter_value = _
|
|
79
|
-
resources = _get_resources_filtered(resources, filter_name, filter_value)
|
|
80
|
-
if raw:
|
|
81
|
-
app.echo_info_json(resources)
|
|
82
|
-
return
|
|
83
|
-
if id_only:
|
|
84
|
-
for _ in sorted(_["id"] for _ in resources):
|
|
85
|
-
app.echo_result(_)
|
|
86
|
-
return
|
|
87
|
-
# output a user table
|
|
88
|
-
table = []
|
|
89
|
-
headers = ["ID", "Modified", "Size"]
|
|
90
|
-
for _ in resources:
|
|
91
|
-
row = [
|
|
92
|
-
_["id"],
|
|
93
|
-
_["modified"],
|
|
94
|
-
_["size"],
|
|
95
|
-
]
|
|
96
|
-
table.append(row)
|
|
97
|
-
app.echo_info_table(
|
|
98
|
-
table,
|
|
99
|
-
headers=headers,
|
|
100
|
-
sort_column=0,
|
|
101
|
-
empty_table_message="No dataset resources found. "
|
|
102
|
-
"Use the `dataset create` command to create a new file based dataset.",
|
|
103
|
-
)
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
@click.command(cls=CmemcCommand, name="delete")
|
|
107
|
-
@click.argument("resource_ids", nargs=-1, type=click.STRING, shell_complete=completion.resource_ids)
|
|
108
|
-
@click.option("--force", is_flag=True, help="Delete resource even if in use by a task.")
|
|
109
|
-
@click.option(
|
|
110
|
-
"-a",
|
|
111
|
-
"--all",
|
|
112
|
-
"all_",
|
|
113
|
-
is_flag=True,
|
|
114
|
-
help="Delete all resources. " "This is a dangerous option, so use it with care.",
|
|
115
|
-
)
|
|
116
|
-
@click.option(
|
|
117
|
-
"--filter",
|
|
118
|
-
"filters_",
|
|
119
|
-
multiple=True,
|
|
120
|
-
type=(str, str),
|
|
121
|
-
shell_complete=completion.resource_list_filter,
|
|
122
|
-
help=RESOURCE_FILTER_TEXT,
|
|
123
|
-
)
|
|
124
|
-
@click.pass_obj
|
|
125
|
-
def delete_command(
|
|
126
|
-
app: ApplicationContext,
|
|
127
|
-
resource_ids: tuple[str, ...],
|
|
128
|
-
force: bool,
|
|
129
|
-
all_: bool,
|
|
130
|
-
filters_: tuple[tuple[str, str], ...],
|
|
131
|
-
) -> None:
|
|
132
|
-
"""Delete file resources.
|
|
133
|
-
|
|
134
|
-
There are three selection mechanisms: with specific IDs, only those
|
|
135
|
-
specified resources will be deleted; by using --filter, resources based
|
|
136
|
-
on the filter type and value will be deleted; using --all will delete
|
|
137
|
-
all resources.
|
|
138
|
-
"""
|
|
139
|
-
if resource_ids == () and not all_ and filters_ == ():
|
|
140
|
-
raise UsageError(
|
|
141
|
-
"Either specify at least one resource ID or use the --all or "
|
|
142
|
-
"--filter options to specify resources for deletion."
|
|
143
|
-
)
|
|
144
|
-
|
|
145
|
-
resources = get_all_resources()
|
|
146
|
-
if len(resource_ids) > 0:
|
|
147
|
-
for resource_id in resource_ids:
|
|
148
|
-
if resource_id not in [_["id"] for _ in resources]:
|
|
149
|
-
raise ClickException(f"Resource {resource_id} not available.")
|
|
150
|
-
# "filter" by id
|
|
151
|
-
resources = _get_resources_filtered(resources, "ids", resource_ids)
|
|
152
|
-
for _ in filters_:
|
|
153
|
-
resources = _get_resources_filtered(resources, _[0], _[1])
|
|
154
|
-
|
|
155
|
-
# avoid double removal as well as sort IDs
|
|
156
|
-
processed_ids = sorted({_["id"] for _ in resources}, key=lambda v: v.lower())
|
|
157
|
-
count = len(processed_ids)
|
|
158
|
-
for current, resource_id in enumerate(processed_ids, start=1):
|
|
159
|
-
current_string = str(current).zfill(len(str(count)))
|
|
160
|
-
app.echo_info(f"Delete resource {current_string}/{count}: {resource_id} ... ", nl=False)
|
|
161
|
-
project_id, resource_local_id = split_task_id(resource_id)
|
|
162
|
-
usage = get_resource_usage_data(project_id, resource_local_id)
|
|
163
|
-
if len(usage) > 0:
|
|
164
|
-
app.echo_error(f"in use by {len(usage)} task(s)", nl=False)
|
|
165
|
-
if force:
|
|
166
|
-
app.echo_info(" ... ", nl=False)
|
|
167
|
-
else:
|
|
168
|
-
app.echo_info("")
|
|
169
|
-
continue
|
|
170
|
-
delete_resource(project_name=project_id, resource_name=resource_local_id)
|
|
171
|
-
app.echo_success("deleted")
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
@click.command(cls=CmemcCommand, name="inspect")
|
|
175
|
-
@click.argument("resource_id", type=click.STRING, shell_complete=completion.resource_ids)
|
|
176
|
-
@click.option("--raw", is_flag=True, help="Outputs raw JSON.")
|
|
177
|
-
@click.pass_obj
|
|
178
|
-
def inspect_command(app: ApplicationContext, resource_id: str, raw: bool) -> None:
|
|
179
|
-
"""Display all metadata of a file resource."""
|
|
180
|
-
project_id, resource_id = split_task_id(resource_id)
|
|
181
|
-
resource_data = get_resource_metadata(project_id, resource_id)
|
|
182
|
-
if raw:
|
|
183
|
-
app.echo_info_json(resource_data)
|
|
184
|
-
else:
|
|
185
|
-
table = struct_to_table(resource_data)
|
|
186
|
-
app.echo_info_table(table, headers=["Key", "Value"], sort_column=0)
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
@click.command(cls=CmemcCommand, name="usage")
|
|
190
|
-
@click.argument("resource_id", type=click.STRING, shell_complete=completion.resource_ids)
|
|
191
|
-
@click.option("--raw", is_flag=True, help="Outputs raw JSON.")
|
|
192
|
-
@click.pass_obj
|
|
193
|
-
def usage_command(app: ApplicationContext, resource_id: str, raw: bool) -> None:
|
|
194
|
-
"""Display all usage data of a file resource."""
|
|
195
|
-
project_id, resource_id = split_task_id(resource_id)
|
|
196
|
-
usage = get_resource_usage_data(project_id, resource_id)
|
|
197
|
-
if raw:
|
|
198
|
-
app.echo_info_json(usage)
|
|
199
|
-
return
|
|
200
|
-
# output a user table
|
|
201
|
-
table = []
|
|
202
|
-
headers = ["Task ID", "Type", "Label"]
|
|
203
|
-
for _ in usage:
|
|
204
|
-
row = [project_id + ":" + _["id"], _["taskType"], _["label"]]
|
|
205
|
-
table.append(row)
|
|
206
|
-
app.echo_info_table(table, headers=headers, sort_column=2)
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
@click.group(cls=CmemcGroup)
|
|
210
|
-
def resource() -> CmemcGroup: # type: ignore[empty-body]
|
|
211
|
-
"""List, inspect or delete dataset file resources.
|
|
212
|
-
|
|
213
|
-
File resources are identified by their paths and project IDs.
|
|
214
|
-
"""
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
resource.add_command(list_command)
|
|
218
|
-
resource.add_command(delete_command)
|
|
219
|
-
resource.add_command(inspect_command)
|
|
220
|
-
resource.add_command(usage_command)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|