annofabcli 1.106.7__py3-none-any.whl → 1.106.8__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.
- annofabcli/annotation/change_annotation_attributes.py +35 -30
- {annofabcli-1.106.7.dist-info → annofabcli-1.106.8.dist-info}/METADATA +1 -1
- {annofabcli-1.106.7.dist-info → annofabcli-1.106.8.dist-info}/RECORD +6 -6
- {annofabcli-1.106.7.dist-info → annofabcli-1.106.8.dist-info}/WHEEL +0 -0
- {annofabcli-1.106.7.dist-info → annofabcli-1.106.8.dist-info}/entry_points.txt +0 -0
- {annofabcli-1.106.7.dist-info → annofabcli-1.106.8.dist-info}/licenses/LICENSE +0 -0
|
@@ -46,7 +46,7 @@ class ChangeAnnotationAttributesMain(CommandLineWithConfirm):
|
|
|
46
46
|
service: annofabapi.Resource,
|
|
47
47
|
*,
|
|
48
48
|
project_id: str,
|
|
49
|
-
|
|
49
|
+
include_completed: bool,
|
|
50
50
|
all_yes: bool,
|
|
51
51
|
) -> None:
|
|
52
52
|
self.service = service
|
|
@@ -54,7 +54,7 @@ class ChangeAnnotationAttributesMain(CommandLineWithConfirm):
|
|
|
54
54
|
CommandLineWithConfirm.__init__(self, all_yes)
|
|
55
55
|
|
|
56
56
|
self.project_id = project_id
|
|
57
|
-
self.
|
|
57
|
+
self.include_completed = include_completed
|
|
58
58
|
|
|
59
59
|
self.dump_annotation_obj = DumpAnnotationMain(service, project_id)
|
|
60
60
|
|
|
@@ -114,9 +114,9 @@ class ChangeAnnotationAttributesMain(CommandLineWithConfirm):
|
|
|
114
114
|
*,
|
|
115
115
|
backup_dir: Optional[Path] = None,
|
|
116
116
|
task_index: Optional[int] = None,
|
|
117
|
-
) -> bool:
|
|
117
|
+
) -> tuple[bool, int]:
|
|
118
118
|
"""
|
|
119
|
-
|
|
119
|
+
タスクに対してアノテーション属性値を変更する。
|
|
120
120
|
|
|
121
121
|
Args:
|
|
122
122
|
project_id:
|
|
@@ -127,23 +127,24 @@ class ChangeAnnotationAttributesMain(CommandLineWithConfirm):
|
|
|
127
127
|
backup_dir: アノテーションをバックアップとして保存するディレクトリ。指定しない場合は、バックアップを取得しない。
|
|
128
128
|
|
|
129
129
|
Returns:
|
|
130
|
-
|
|
130
|
+
tuple[0]: 成功した場合はTrue、失敗した場合はFalse
|
|
131
|
+
tuple[1]: 変更したアノテーションの個数
|
|
131
132
|
"""
|
|
132
133
|
logger_prefix = f"{task_index + 1!s} 件目: " if task_index is not None else ""
|
|
133
134
|
dict_task = self.service.wrapper.get_task_or_none(self.project_id, task_id)
|
|
134
135
|
if dict_task is None:
|
|
135
136
|
logger.warning(f"task_id = '{task_id}' は存在しません。")
|
|
136
|
-
return False
|
|
137
|
+
return False, 0
|
|
137
138
|
|
|
138
139
|
task: Task = Task.from_dict(dict_task)
|
|
139
140
|
if task.status == TaskStatus.WORKING:
|
|
140
141
|
logger.warning(f"task_id='{task_id}': タスクが作業中状態のため、スキップします。")
|
|
141
|
-
return False
|
|
142
|
+
return False, 0
|
|
142
143
|
|
|
143
|
-
if not self.
|
|
144
|
+
if not self.include_completed: # noqa: SIM102
|
|
144
145
|
if task.status == TaskStatus.COMPLETE:
|
|
145
|
-
logger.warning(f"task_id='{task_id}':
|
|
146
|
-
return False
|
|
146
|
+
logger.warning(f"task_id='{task_id}': タスクが完了状態のため、スキップします。完了状態のタスクのアノテーション属性値を変更するには、 ``--include_completed`` を指定してください。")
|
|
147
|
+
return False, 0
|
|
147
148
|
|
|
148
149
|
annotation_list = self.get_annotation_list_for_task(task_id, annotation_query)
|
|
149
150
|
logger.info(
|
|
@@ -151,17 +152,17 @@ class ChangeAnnotationAttributesMain(CommandLineWithConfirm):
|
|
|
151
152
|
)
|
|
152
153
|
if len(annotation_list) == 0:
|
|
153
154
|
logger.info(f"{logger_prefix}task_id='{task_id}'には変更対象のアノテーションが存在しないので、スキップします。")
|
|
154
|
-
return False
|
|
155
|
+
return False, 0
|
|
155
156
|
|
|
156
|
-
if not self.confirm_processing(f"task_id='{task_id}'
|
|
157
|
-
return False
|
|
157
|
+
if not self.confirm_processing(f"task_id='{task_id}' のアノテーション属性値を変更しますか?"):
|
|
158
|
+
return False, 0
|
|
158
159
|
|
|
159
160
|
if backup_dir is not None:
|
|
160
161
|
self.dump_annotation_obj.dump_annotation_for_task(task_id, output_dir=backup_dir)
|
|
161
162
|
|
|
162
163
|
self.change_annotation_attributes(annotation_list, additional_data_list)
|
|
163
164
|
logger.info(f"{logger_prefix}task_id='{task_id}': {len(annotation_list)} 個のアノテーションの属性値を変更しました。")
|
|
164
|
-
return True
|
|
165
|
+
return True, len(annotation_list)
|
|
165
166
|
|
|
166
167
|
def change_attributes_for_task_wrapper(
|
|
167
168
|
self,
|
|
@@ -170,7 +171,7 @@ class ChangeAnnotationAttributesMain(CommandLineWithConfirm):
|
|
|
170
171
|
additional_data_list: list[dict[str, Any]],
|
|
171
172
|
*,
|
|
172
173
|
backup_dir: Optional[Path] = None,
|
|
173
|
-
) -> bool:
|
|
174
|
+
) -> tuple[bool, int]:
|
|
174
175
|
task_index, task_id = tpl
|
|
175
176
|
try:
|
|
176
177
|
return self.change_attributes_for_task(
|
|
@@ -181,8 +182,8 @@ class ChangeAnnotationAttributesMain(CommandLineWithConfirm):
|
|
|
181
182
|
task_index=task_index,
|
|
182
183
|
)
|
|
183
184
|
except Exception: # pylint: disable=broad-except
|
|
184
|
-
logger.warning(f"タスク'{task_id}'
|
|
185
|
-
return False
|
|
185
|
+
logger.warning(f"タスク'{task_id}'のアノテーションの属性値の変更に失敗しました。", exc_info=True)
|
|
186
|
+
return False, 0
|
|
186
187
|
|
|
187
188
|
def change_annotation_attributes_for_task_list(
|
|
188
189
|
self,
|
|
@@ -209,8 +210,9 @@ class ChangeAnnotationAttributesMain(CommandLineWithConfirm):
|
|
|
209
210
|
|
|
210
211
|
if backup_dir is not None:
|
|
211
212
|
backup_dir.mkdir(exist_ok=True, parents=True)
|
|
212
|
-
|
|
213
213
|
success_count = 0
|
|
214
|
+
# 変更したアノテーションの個数
|
|
215
|
+
changed_annotation_count = 0
|
|
214
216
|
if parallelism is not None:
|
|
215
217
|
func = functools.partial(
|
|
216
218
|
self.change_attributes_for_task_wrapper,
|
|
@@ -219,26 +221,28 @@ class ChangeAnnotationAttributesMain(CommandLineWithConfirm):
|
|
|
219
221
|
backup_dir=backup_dir,
|
|
220
222
|
)
|
|
221
223
|
with multiprocessing.Pool(parallelism) as pool:
|
|
222
|
-
|
|
223
|
-
success_count = len([e for e in
|
|
224
|
+
result_tuple_list = pool.map(func, enumerate(task_id_list))
|
|
225
|
+
success_count = len([e for e in result_tuple_list if e[0]])
|
|
226
|
+
changed_annotation_count = sum(e[1] for e in result_tuple_list)
|
|
224
227
|
|
|
225
228
|
else:
|
|
226
229
|
for task_index, task_id in enumerate(task_id_list):
|
|
227
230
|
try:
|
|
228
|
-
result = self.change_attributes_for_task(
|
|
231
|
+
result, sub_changed_annotation_count = self.change_attributes_for_task(
|
|
229
232
|
task_id,
|
|
230
233
|
annotation_query=annotation_query,
|
|
231
234
|
additional_data_list=additional_data_list,
|
|
232
235
|
backup_dir=backup_dir,
|
|
233
236
|
task_index=task_index,
|
|
234
237
|
)
|
|
238
|
+
changed_annotation_count += sub_changed_annotation_count
|
|
235
239
|
if result:
|
|
236
240
|
success_count += 1
|
|
237
241
|
except Exception:
|
|
238
|
-
logger.warning(f"タスク'{task_id}'
|
|
242
|
+
logger.warning(f"タスク'{task_id}'のアノテーションの属性値の変更に失敗しました。", exc_info=True)
|
|
239
243
|
continue
|
|
240
244
|
|
|
241
|
-
logger.info(f"{success_count} / {len(task_id_list)}
|
|
245
|
+
logger.info(f"{success_count} / {len(task_id_list)} 件のタスクに対して {changed_annotation_count} 件のアノテーションの属性値を変更しました。")
|
|
242
246
|
|
|
243
247
|
|
|
244
248
|
class ChangeAttributesOfAnnotation(CommandLine):
|
|
@@ -310,15 +314,15 @@ class ChangeAttributesOfAnnotation(CommandLine):
|
|
|
310
314
|
backup_dir = Path(args.backup)
|
|
311
315
|
|
|
312
316
|
super().validate_project(project_id, [ProjectMemberRole.OWNER, ProjectMemberRole.ACCEPTER])
|
|
313
|
-
if args.
|
|
317
|
+
if args.include_completed: # noqa: SIM102
|
|
314
318
|
if not self.facade.contains_any_project_member_role(project_id, [ProjectMemberRole.OWNER]):
|
|
315
319
|
print( # noqa: T201
|
|
316
|
-
f"{self.COMMON_MESSAGE} argument --
|
|
320
|
+
f"{self.COMMON_MESSAGE} argument --include_completed : '--include_completed' 引数を利用するにはプロジェクトのオーナーロールを持つユーザーで実行する必要があります。",
|
|
317
321
|
file=sys.stderr,
|
|
318
322
|
)
|
|
319
323
|
sys.exit(COMMAND_LINE_ERROR_STATUS_CODE)
|
|
320
324
|
|
|
321
|
-
main_obj = ChangeAnnotationAttributesMain(self.service, project_id=project_id,
|
|
325
|
+
main_obj = ChangeAnnotationAttributesMain(self.service, project_id=project_id, include_completed=args.include_completed, all_yes=args.yes)
|
|
322
326
|
main_obj.change_annotation_attributes_for_task_list(
|
|
323
327
|
task_id_list,
|
|
324
328
|
annotation_query=annotation_query,
|
|
@@ -358,7 +362,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
358
362
|
)
|
|
359
363
|
|
|
360
364
|
parser.add_argument(
|
|
361
|
-
"--
|
|
365
|
+
"--include_completed",
|
|
362
366
|
action="store_true",
|
|
363
367
|
help="完了状態のタスクのアノテーション属性も変更します。ただし、オーナーロールを持つユーザーでしか実行できません。",
|
|
364
368
|
)
|
|
@@ -381,10 +385,11 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
381
385
|
|
|
382
386
|
def add_parser(subparsers: Optional[argparse._SubParsersAction] = None) -> argparse.ArgumentParser:
|
|
383
387
|
subcommand_name = "change_attributes"
|
|
384
|
-
subcommand_help = "
|
|
388
|
+
subcommand_help = "アノテーションの属性値を変更します。"
|
|
385
389
|
description = (
|
|
386
|
-
"
|
|
387
|
-
"
|
|
390
|
+
"アノテーションの属性値を一括で変更します。ただし、作業中状態のタスクに含まれるアノテーションは変更できません。"
|
|
391
|
+
"完了状態のタスクに含まれるアノテーションは、デフォルトでは変更できません。"
|
|
392
|
+
"間違えてアノテーション属性値を変更したときに復元できるようにするため、 ``--backup`` でバックアップ用のディレクトリを指定することを推奨します。"
|
|
388
393
|
)
|
|
389
394
|
epilog = "オーナロールまたはチェッカーロールを持つユーザで実行してください。"
|
|
390
395
|
|
|
@@ -3,7 +3,7 @@ annofabcli/__main__.py,sha256=YfuJE9E43xSo6iHTxVuQPHCz2eBaJS07QnVU42-0znQ,5293
|
|
|
3
3
|
annofabcli/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
annofabcli/annotation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
annofabcli/annotation/annotation_query.py,sha256=VwfPWpLOpVa2SeEJ264LmCKkBGDJvpX8o7GbWIrDE0o,15712
|
|
6
|
-
annofabcli/annotation/change_annotation_attributes.py,sha256=
|
|
6
|
+
annofabcli/annotation/change_annotation_attributes.py,sha256=pCHT12ba5jsT9kqslUXqfy2QriRT8yiAzgHDuL1JkNE,17884
|
|
7
7
|
annofabcli/annotation/change_annotation_attributes_per_annotation.py,sha256=g_SqH1xzAdA8D1Hy1aoOPlpF86nc7F1PENeUX8XftDs,15529
|
|
8
8
|
annofabcli/annotation/change_annotation_properties.py,sha256=Kp_LZ5sSoVmmjGE80ABVO3InxsXBIxiFFvVcIJNsOMk,18309
|
|
9
9
|
annofabcli/annotation/copy_annotation.py,sha256=Pih2k3vvpgfT3Ovb3gZw2L_8fK_ws_wKR7ARYG5hG_8,18407
|
|
@@ -209,8 +209,8 @@ annofabcli/task_history_event/download_task_history_event_json.py,sha256=hQLVbQ0
|
|
|
209
209
|
annofabcli/task_history_event/list_all_task_history_event.py,sha256=EeKMyPUxGwYCFtWQHHW954ZserGm8lUqrwNnV1iX9X4,6830
|
|
210
210
|
annofabcli/task_history_event/list_worktime.py,sha256=Y7Pu5DP7scPf7HPt6CTiTvB1_5_Nfi1bStUIaCpkhII,15507
|
|
211
211
|
annofabcli/task_history_event/subcommand_task_history_event.py,sha256=mJVJoT4RXk4HWnY7-Nrsl4If-gtaIIEXd2z7eFZwM2I,1260
|
|
212
|
-
annofabcli-1.106.
|
|
213
|
-
annofabcli-1.106.
|
|
214
|
-
annofabcli-1.106.
|
|
215
|
-
annofabcli-1.106.
|
|
216
|
-
annofabcli-1.106.
|
|
212
|
+
annofabcli-1.106.8.dist-info/METADATA,sha256=rSWCLpho30p_wsQdKax1vujJoZ3Zlj03RAGDGcth2s8,5286
|
|
213
|
+
annofabcli-1.106.8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
214
|
+
annofabcli-1.106.8.dist-info/entry_points.txt,sha256=C2uSUc-kkLJpoK_mDL5FEMAdorLEMPfwSf8VBMYnIFM,56
|
|
215
|
+
annofabcli-1.106.8.dist-info/licenses/LICENSE,sha256=pcqWYfxFtxBzhvKp3x9MXNM4xciGb2eFewaRhXUNHlo,1081
|
|
216
|
+
annofabcli-1.106.8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|