annofabcli 1.102.0__py3-none-any.whl → 1.103.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.
- annofabcli/annotation/annotation_query.py +9 -29
- annofabcli/annotation/change_annotation_attributes.py +6 -14
- annofabcli/annotation/change_annotation_properties.py +5 -12
- annofabcli/annotation/copy_annotation.py +9 -11
- annofabcli/annotation/delete_annotation.py +21 -26
- annofabcli/annotation/dump_annotation.py +1 -4
- annofabcli/annotation/import_annotation.py +16 -40
- annofabcli/annotation/list_annotation.py +1 -4
- annofabcli/annotation/merge_segmentation.py +10 -16
- annofabcli/annotation/remove_segmentation_overlap.py +14 -30
- annofabcli/annotation/restore_annotation.py +3 -9
- annofabcli/annotation_specs/add_attribute_restriction.py +2 -8
- annofabcli/annotation_specs/attribute_restriction.py +2 -10
- annofabcli/annotation_specs/export_annotation_specs.py +1 -3
- annofabcli/annotation_specs/get_annotation_specs_with_attribute_id_replaced.py +3 -10
- annofabcli/annotation_specs/get_annotation_specs_with_choice_id_replaced.py +4 -10
- annofabcli/annotation_specs/get_annotation_specs_with_label_id_replaced.py +1 -3
- annofabcli/annotation_specs/list_annotation_specs_attribute.py +7 -18
- annofabcli/annotation_specs/list_annotation_specs_choice.py +3 -8
- annofabcli/annotation_specs/list_annotation_specs_history.py +0 -1
- annofabcli/annotation_specs/list_annotation_specs_label.py +3 -8
- annofabcli/annotation_specs/list_annotation_specs_label_attribute.py +4 -9
- annofabcli/annotation_specs/list_attribute_restriction.py +3 -9
- annofabcli/annotation_specs/put_label_color.py +1 -6
- annofabcli/comment/delete_comment.py +3 -9
- annofabcli/comment/list_all_comment.py +2 -4
- annofabcli/comment/list_comment.py +1 -4
- annofabcli/comment/put_comment.py +4 -13
- annofabcli/comment/put_comment_simply.py +2 -6
- annofabcli/comment/put_inspection_comment.py +2 -6
- annofabcli/comment/put_inspection_comment_simply.py +3 -6
- annofabcli/comment/put_onhold_comment.py +2 -6
- annofabcli/comment/put_onhold_comment_simply.py +2 -4
- annofabcli/common/cli.py +5 -43
- annofabcli/common/download.py +8 -25
- annofabcli/common/image.py +5 -9
- annofabcli/common/utils.py +1 -3
- annofabcli/common/visualize.py +2 -4
- annofabcli/filesystem/draw_annotation.py +8 -20
- annofabcli/filesystem/filter_annotation.py +7 -24
- annofabcli/filesystem/mask_user_info.py +3 -6
- annofabcli/filesystem/merge_annotation.py +2 -6
- annofabcli/input_data/change_input_data_name.py +3 -7
- annofabcli/input_data/copy_input_data.py +6 -14
- annofabcli/input_data/delete_input_data.py +7 -24
- annofabcli/input_data/delete_metadata_key_of_input_data.py +5 -16
- annofabcli/input_data/list_all_input_data.py +5 -14
- annofabcli/input_data/list_all_input_data_merged_task.py +8 -23
- annofabcli/input_data/list_input_data.py +5 -16
- annofabcli/input_data/put_input_data.py +7 -19
- annofabcli/input_data/update_metadata_of_input_data.py +6 -14
- annofabcli/instruction/list_instruction_history.py +0 -1
- annofabcli/instruction/upload_instruction.py +1 -4
- annofabcli/job/list_job.py +1 -2
- annofabcli/job/list_last_job.py +1 -3
- annofabcli/organization/list_organization.py +0 -1
- annofabcli/organization_member/change_organization_member.py +1 -3
- annofabcli/organization_member/delete_organization_member.py +32 -16
- annofabcli/organization_member/invite_organization_member.py +25 -14
- annofabcli/organization_member/list_organization_member.py +0 -1
- annofabcli/project/change_organization_of_project.py +257 -0
- annofabcli/project/change_project_status.py +2 -2
- annofabcli/project/copy_project.py +2 -7
- annofabcli/project/diff_projects.py +4 -16
- annofabcli/project/list_project.py +0 -1
- annofabcli/project/put_project.py +2 -6
- annofabcli/project/subcommand_project.py +2 -0
- annofabcli/project_member/change_project_members.py +2 -2
- annofabcli/project_member/copy_project_members.py +2 -7
- annofabcli/project_member/drop_project_members.py +1 -3
- annofabcli/project_member/invite_project_members.py +1 -3
- annofabcli/project_member/list_users.py +0 -1
- annofabcli/project_member/put_project_members.py +4 -12
- annofabcli/stat_visualization/mask_visualization_dir.py +6 -16
- annofabcli/stat_visualization/merge_visualization_dir.py +6 -18
- annofabcli/stat_visualization/summarize_whole_performance_csv.py +3 -7
- annofabcli/stat_visualization/write_graph.py +5 -15
- annofabcli/stat_visualization/write_performance_rating_csv.py +4 -12
- annofabcli/statistics/list_annotation_area.py +3 -7
- annofabcli/statistics/list_annotation_attribute.py +6 -15
- annofabcli/statistics/list_annotation_attribute_filled_count.py +9 -23
- annofabcli/statistics/list_annotation_count.py +18 -44
- annofabcli/statistics/list_annotation_duration.py +14 -40
- annofabcli/statistics/list_video_duration.py +2 -3
- annofabcli/statistics/list_worktime.py +0 -1
- annofabcli/statistics/scatter.py +3 -9
- annofabcli/statistics/summarize_task_count.py +7 -12
- annofabcli/statistics/summarize_task_count_by_task_id_group.py +3 -11
- annofabcli/statistics/summarize_task_count_by_user.py +1 -5
- annofabcli/statistics/visualization/dataframe/annotation_count.py +1 -3
- annofabcli/statistics/visualization/dataframe/cumulative_productivity.py +3 -9
- annofabcli/statistics/visualization/dataframe/productivity_per_date.py +11 -23
- annofabcli/statistics/visualization/dataframe/project_performance.py +1 -3
- annofabcli/statistics/visualization/dataframe/task.py +2 -5
- annofabcli/statistics/visualization/dataframe/task_worktime_by_phase_user.py +6 -20
- annofabcli/statistics/visualization/dataframe/user_performance.py +29 -88
- annofabcli/statistics/visualization/dataframe/whole_performance.py +4 -10
- annofabcli/statistics/visualization/dataframe/whole_productivity_per_date.py +17 -49
- annofabcli/statistics/visualization/dataframe/worktime_per_date.py +3 -9
- annofabcli/statistics/visualization/filtering_query.py +2 -6
- annofabcli/statistics/visualization/project_dir.py +9 -26
- annofabcli/statistics/visualization/visualization_source_files.py +3 -10
- annofabcli/statistics/visualize_annotation_count.py +7 -21
- annofabcli/statistics/visualize_annotation_duration.py +7 -17
- annofabcli/statistics/visualize_statistics.py +17 -52
- annofabcli/statistics/visualize_video_duration.py +8 -19
- annofabcli/supplementary/delete_supplementary_data.py +7 -23
- annofabcli/supplementary/list_supplementary_data.py +1 -1
- annofabcli/supplementary/put_supplementary_data.py +5 -15
- annofabcli/task/cancel_acceptance.py +3 -4
- annofabcli/task/change_operator.py +3 -11
- annofabcli/task/change_status_to_break.py +1 -1
- annofabcli/task/change_status_to_on_hold.py +5 -18
- annofabcli/task/complete_tasks.py +8 -25
- annofabcli/task/copy_tasks.py +2 -3
- annofabcli/task/delete_metadata_key_of_task.py +2 -6
- annofabcli/task/delete_tasks.py +7 -25
- annofabcli/task/list_all_tasks.py +2 -4
- annofabcli/task/list_tasks.py +2 -6
- annofabcli/task/list_tasks_added_task_history.py +7 -21
- annofabcli/task/put_tasks.py +2 -3
- annofabcli/task/put_tasks_by_count.py +3 -7
- annofabcli/task/reject_tasks.py +7 -19
- annofabcli/task/update_metadata_of_task.py +1 -1
- annofabcli/task_history/list_all_task_history.py +2 -5
- annofabcli/task_history/list_task_history.py +0 -1
- annofabcli/task_history_event/list_all_task_history_event.py +4 -11
- annofabcli/task_history_event/list_worktime.py +4 -14
- {annofabcli-1.102.0.dist-info → annofabcli-1.103.0.dist-info}/METADATA +1 -1
- annofabcli-1.103.0.dist-info/RECORD +215 -0
- annofabcli-1.102.0.dist-info/RECORD +0 -214
- {annofabcli-1.102.0.dist-info → annofabcli-1.103.0.dist-info}/WHEEL +0 -0
- {annofabcli-1.102.0.dist-info → annofabcli-1.103.0.dist-info}/entry_points.txt +0 -0
- {annofabcli-1.102.0.dist-info → annofabcli-1.103.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -12,6 +12,7 @@ from typing import Any, Optional
|
|
|
12
12
|
|
|
13
13
|
import annofabapi
|
|
14
14
|
import numpy
|
|
15
|
+
from annofabapi.models import ProjectMemberRole
|
|
15
16
|
from annofabapi.pydantic_models.default_annotation_type import DefaultAnnotationType
|
|
16
17
|
from annofabapi.pydantic_models.task_status import TaskStatus
|
|
17
18
|
from annofabapi.segmentation import read_binary_image, write_binary_image
|
|
@@ -195,15 +196,10 @@ class MergeSegmentationMain(CommandLineWithConfirm):
|
|
|
195
196
|
return 0
|
|
196
197
|
|
|
197
198
|
if task["status"] in {TaskStatus.WORKING.value, TaskStatus.COMPLETE.value}:
|
|
198
|
-
logger.debug(
|
|
199
|
-
f"{log_message_prefix}task_id='{task_id}'のタスクの状態は「作業中」または「完了」であるため、"
|
|
200
|
-
f"アノテーションの更新をスキップします。 :: status='{task['status']}'"
|
|
201
|
-
)
|
|
199
|
+
logger.debug(f"{log_message_prefix}task_id='{task_id}'のタスクの状態は「作業中」または「完了」であるため、アノテーションの更新をスキップします。 :: status='{task['status']}'")
|
|
202
200
|
return 0
|
|
203
201
|
|
|
204
|
-
if not self.confirm_processing(
|
|
205
|
-
f"task_id='{task_id}'の次のラベル名に対応する複数の塗りつぶしアノテーションを1つにまとめますか? :: {self.label_names}"
|
|
206
|
-
):
|
|
202
|
+
if not self.confirm_processing(f"task_id='{task_id}'の次のラベル名に対応する複数の塗りつぶしアノテーションを1つにまとめますか? :: {self.label_names}"):
|
|
207
203
|
return 0
|
|
208
204
|
|
|
209
205
|
# 担当者割り当て変更チェック
|
|
@@ -234,16 +230,12 @@ class MergeSegmentationMain(CommandLineWithConfirm):
|
|
|
234
230
|
if result:
|
|
235
231
|
success_input_data_count += 1
|
|
236
232
|
except Exception:
|
|
237
|
-
logger.warning(
|
|
238
|
-
f"{log_message_prefix}task_id='{task_id}', input_data_id='{input_data_id}'のアノテーションの更新に失敗しました。", exc_info=True
|
|
239
|
-
)
|
|
233
|
+
logger.warning(f"{log_message_prefix}task_id='{task_id}', input_data_id='{input_data_id}'のアノテーションの更新に失敗しました。", exc_info=True)
|
|
240
234
|
continue
|
|
241
235
|
|
|
242
236
|
# 担当者を元に戻す
|
|
243
237
|
if changed_operator:
|
|
244
|
-
logger.debug(
|
|
245
|
-
f"{log_message_prefix}task_id='{task_id}' のタスクの担当者を、元の担当者(account_id='{original_operator_account_id}')に変更します。"
|
|
246
|
-
)
|
|
238
|
+
logger.debug(f"{log_message_prefix}task_id='{task_id}' のタスクの担当者を、元の担当者(account_id='{original_operator_account_id}')に変更します。")
|
|
247
239
|
self.annofab_service.wrapper.change_task_operator(
|
|
248
240
|
self.project_id,
|
|
249
241
|
task_id,
|
|
@@ -304,6 +296,8 @@ class MergeSegmentation(CommandLine):
|
|
|
304
296
|
sys.exit(COMMAND_LINE_ERROR_STATUS_CODE)
|
|
305
297
|
|
|
306
298
|
project_id = args.project_id
|
|
299
|
+
super().validate_project(project_id, [ProjectMemberRole.OWNER, ProjectMemberRole.ACCEPTER, ProjectMemberRole.WORKER])
|
|
300
|
+
|
|
307
301
|
task_id_list = annofabcli.common.cli.get_list_from_args(args.task_id)
|
|
308
302
|
label_name_list = annofabcli.common.cli.get_list_from_args(args.label_name)
|
|
309
303
|
|
|
@@ -325,8 +319,7 @@ class MergeSegmentation(CommandLine):
|
|
|
325
319
|
|
|
326
320
|
if len(invalid_label_name_list) > 0:
|
|
327
321
|
print( # noqa: T201
|
|
328
|
-
f"{self.COMMON_MESSAGE} --label_name: 次のラベル名(英語)
|
|
329
|
-
f"アノテーションの種類が「塗りつぶし」ではありません。 :: {invalid_label_name_list}",
|
|
322
|
+
f"{self.COMMON_MESSAGE} --label_name: 次のラベル名(英語)はアノテーション仕様に存在しないか、アノテーションの種類が「塗りつぶし」ではありません。 :: {invalid_label_name_list}",
|
|
330
323
|
file=sys.stderr,
|
|
331
324
|
)
|
|
332
325
|
sys.exit(COMMAND_LINE_ERROR_STATUS_CODE)
|
|
@@ -385,6 +378,7 @@ def add_parser(subparsers: Optional[argparse._SubParsersAction] = None) -> argpa
|
|
|
385
378
|
"複数の塗りつぶしアノテーションを1つにまとめます。"
|
|
386
379
|
"ラベルの種類を「塗りつぶし(インスタンスセグメンテーション)」から「塗りつぶしv2(セマンティックセグメンテーション)」に変更する場合などに有用です。"
|
|
387
380
|
)
|
|
388
|
-
|
|
381
|
+
epilog = "オーナー、チェッカーまたはアノテータロールを持つユーザで実行してください。"
|
|
382
|
+
parser = annofabcli.common.cli.add_parser(subparsers, subcommand_name, subcommand_help, description, epilog=epilog)
|
|
389
383
|
parse_args(parser)
|
|
390
384
|
return parser
|
|
@@ -12,6 +12,7 @@ from typing import Any, Optional
|
|
|
12
12
|
|
|
13
13
|
import annofabapi
|
|
14
14
|
import numpy
|
|
15
|
+
from annofabapi.models import ProjectMemberRole
|
|
15
16
|
from annofabapi.pydantic_models.task_status import TaskStatus
|
|
16
17
|
from annofabapi.segmentation import read_binary_image, write_binary_image
|
|
17
18
|
from annofabapi.utils import can_put_annotation
|
|
@@ -30,9 +31,7 @@ from annofabcli.common.facade import AnnofabApiFacade
|
|
|
30
31
|
logger = logging.getLogger(__name__)
|
|
31
32
|
|
|
32
33
|
|
|
33
|
-
def remove_overlap_of_binary_image_array(
|
|
34
|
-
binary_image_array_by_annotation: dict[str, numpy.ndarray], annotation_id_list: list[str]
|
|
35
|
-
) -> dict[str, numpy.ndarray]:
|
|
34
|
+
def remove_overlap_of_binary_image_array(binary_image_array_by_annotation: dict[str, numpy.ndarray], annotation_id_list: list[str]) -> dict[str, numpy.ndarray]:
|
|
36
35
|
"""
|
|
37
36
|
塗りつぶし画像の重なりを除去したbool配列をdictで返します。
|
|
38
37
|
|
|
@@ -98,9 +97,7 @@ class RemoveSegmentationOverlapMain(CommandLineWithConfirm):
|
|
|
98
97
|
|
|
99
98
|
# reversedを使っている理由:
|
|
100
99
|
# `details`には、前面から背面の順にアノテーションが格納されているため、
|
|
101
|
-
output_binary_image_array_by_annotation = remove_overlap_of_binary_image_array(
|
|
102
|
-
input_binary_image_array_by_annotation, list(reversed(segmentation_annotation_id_list))
|
|
103
|
-
)
|
|
100
|
+
output_binary_image_array_by_annotation = remove_overlap_of_binary_image_array(input_binary_image_array_by_annotation, list(reversed(segmentation_annotation_id_list)))
|
|
104
101
|
|
|
105
102
|
updated_annotation_id_list = []
|
|
106
103
|
for annotation_id, output_binary_image_array in output_binary_image_array_by_annotation.items():
|
|
@@ -127,10 +124,7 @@ class RemoveSegmentationOverlapMain(CommandLineWithConfirm):
|
|
|
127
124
|
temp_dir_path = Path(temp_dir)
|
|
128
125
|
updated_annotation_id_list = self.remove_segmentation_overlap_and_save(old_details, temp_dir_path)
|
|
129
126
|
if len(updated_annotation_id_list) == 0:
|
|
130
|
-
logger.debug(
|
|
131
|
-
f"{log_message_prefix}塗りつぶしアノテーションの重なりはなかったので、スキップします。 :: "
|
|
132
|
-
f"task_id='{task_id}', input_data_id='{input_data_id}'"
|
|
133
|
-
)
|
|
127
|
+
logger.debug(f"{log_message_prefix}塗りつぶしアノテーションの重なりはなかったので、スキップします。 :: task_id='{task_id}', input_data_id='{input_data_id}'")
|
|
134
128
|
return False
|
|
135
129
|
|
|
136
130
|
logger.debug(
|
|
@@ -163,10 +157,7 @@ class RemoveSegmentationOverlapMain(CommandLineWithConfirm):
|
|
|
163
157
|
"updated_datetime": old_annotation["updated_datetime"],
|
|
164
158
|
}
|
|
165
159
|
self.annofab_service.api.put_annotation(self.project_id, task_id, input_data_id, query_params={"v": "2"}, request_body=request_body)
|
|
166
|
-
logger.debug(
|
|
167
|
-
f"{log_message_prefix}{len(updated_annotation_id_list)} 件の塗りつぶしアノテーションを更新しました。 :: "
|
|
168
|
-
f"task_id='{task_id}', input_data_id='{input_data_id}'"
|
|
169
|
-
)
|
|
160
|
+
logger.debug(f"{log_message_prefix}{len(updated_annotation_id_list)} 件の塗りつぶしアノテーションを更新しました。 :: task_id='{task_id}', input_data_id='{input_data_id}'")
|
|
170
161
|
return True
|
|
171
162
|
|
|
172
163
|
def update_segmentation_annotation_for_task(self, task_id: str, *, task_index: Optional[int] = None) -> int:
|
|
@@ -184,10 +175,7 @@ class RemoveSegmentationOverlapMain(CommandLineWithConfirm):
|
|
|
184
175
|
return 0
|
|
185
176
|
|
|
186
177
|
if task["status"] in {TaskStatus.WORKING.value, TaskStatus.COMPLETE.value}:
|
|
187
|
-
logger.debug(
|
|
188
|
-
f"{log_message_prefix}task_id='{task_id}'のタスクの状態は「作業中」または「完了」であるため、"
|
|
189
|
-
f"アノテーションの更新をスキップします。 :: status='{task['status']}'"
|
|
190
|
-
)
|
|
178
|
+
logger.debug(f"{log_message_prefix}task_id='{task_id}'のタスクの状態は「作業中」または「完了」であるため、アノテーションの更新をスキップします。 :: status='{task['status']}'")
|
|
191
179
|
return 0
|
|
192
180
|
|
|
193
181
|
if not self.confirm_processing(f"task_id='{task_id}'の塗りつぶしアノテーションの重なりを除去しますか?"):
|
|
@@ -221,16 +209,12 @@ class RemoveSegmentationOverlapMain(CommandLineWithConfirm):
|
|
|
221
209
|
if result:
|
|
222
210
|
success_input_data_count += 1
|
|
223
211
|
except Exception:
|
|
224
|
-
logger.warning(
|
|
225
|
-
f"{log_message_prefix}task_id='{task_id}', input_data_id='{input_data_id}'のアノテーションの更新に失敗しました。", exc_info=True
|
|
226
|
-
)
|
|
212
|
+
logger.warning(f"{log_message_prefix}task_id='{task_id}', input_data_id='{input_data_id}'のアノテーションの更新に失敗しました。", exc_info=True)
|
|
227
213
|
continue
|
|
228
214
|
|
|
229
215
|
# 担当者を元に戻す
|
|
230
216
|
if changed_operator:
|
|
231
|
-
logger.debug(
|
|
232
|
-
f"{log_message_prefix}task_id='{task_id}' のタスクの担当者を、元の担当者(account_id='{original_operator_account_id}')に変更します。"
|
|
233
|
-
)
|
|
217
|
+
logger.debug(f"{log_message_prefix}task_id='{task_id}' のタスクの担当者を、元の担当者(account_id='{original_operator_account_id}')に変更します。")
|
|
234
218
|
self.annofab_service.wrapper.change_task_operator(
|
|
235
219
|
self.project_id,
|
|
236
220
|
task_id,
|
|
@@ -291,8 +275,11 @@ class RemoveSegmentationOverlap(CommandLine):
|
|
|
291
275
|
sys.exit(COMMAND_LINE_ERROR_STATUS_CODE)
|
|
292
276
|
|
|
293
277
|
project_id = args.project_id
|
|
278
|
+
|
|
294
279
|
task_id_list = annofabcli.common.cli.get_list_from_args(args.task_id)
|
|
295
280
|
|
|
281
|
+
super().validate_project(project_id, [ProjectMemberRole.OWNER, ProjectMemberRole.ACCEPTER, ProjectMemberRole.WORKER])
|
|
282
|
+
|
|
296
283
|
main_obj = RemoveSegmentationOverlapMain(
|
|
297
284
|
self.service,
|
|
298
285
|
project_id=project_id,
|
|
@@ -333,11 +320,8 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
333
320
|
def add_parser(subparsers: Optional[argparse._SubParsersAction] = None) -> argparse.ArgumentParser:
|
|
334
321
|
subcommand_name = "remove_segmentation_overlap"
|
|
335
322
|
subcommand_help = "塗りつぶしアノテーションの重なりを除去します。"
|
|
336
|
-
description =
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
"この重なりをなくしたいときに有用です。"
|
|
340
|
-
)
|
|
341
|
-
parser = annofabcli.common.cli.add_parser(subparsers, subcommand_name, subcommand_help, description)
|
|
323
|
+
description = "塗りつぶしアノテーションの重なりを除去します。Annofabでインスタンスセグメンテーションは重ねることができてしまいます。この重なりをなくしたいときに有用です。"
|
|
324
|
+
epilog = "オーナー、チェッカーまたはアノテータロールを持つユーザで実行してください。"
|
|
325
|
+
parser = annofabcli.common.cli.add_parser(subparsers, subcommand_name, subcommand_help, description, epilog=epilog)
|
|
342
326
|
parse_args(parser)
|
|
343
327
|
return parser
|
|
@@ -214,9 +214,7 @@ class RestoreAnnotationMain(CommandLineWithConfirm):
|
|
|
214
214
|
parallelism: 並列度。Noneなら逐次処理
|
|
215
215
|
"""
|
|
216
216
|
|
|
217
|
-
def get_iter_task_parser_from_task_ids(
|
|
218
|
-
_iter_task_parser: Iterator[SimpleAnnotationParserByTask], _target_task_ids: set[str]
|
|
219
|
-
) -> Iterator[SimpleAnnotationParserByTask]:
|
|
217
|
+
def get_iter_task_parser_from_task_ids(_iter_task_parser: Iterator[SimpleAnnotationParserByTask], _target_task_ids: set[str]) -> Iterator[SimpleAnnotationParserByTask]:
|
|
220
218
|
for task_parser in _iter_task_parser:
|
|
221
219
|
if task_parser.task_id in _target_task_ids:
|
|
222
220
|
_target_task_ids.remove(task_parser.task_id)
|
|
@@ -252,9 +250,7 @@ class RestoreAnnotationMain(CommandLineWithConfirm):
|
|
|
252
250
|
task_count += 1
|
|
253
251
|
|
|
254
252
|
if target_task_ids is not None and len(tmp_target_task_ids) > 0:
|
|
255
|
-
logger.warning(
|
|
256
|
-
f"'--task_id'で指定したタスクの内 {len(tmp_target_task_ids)} 件は、リストア対象のアノテーションデータに含まれていません。 :: {tmp_target_task_ids}" # noqa: E501
|
|
257
|
-
)
|
|
253
|
+
logger.warning(f"'--task_id'で指定したタスクの内 {len(tmp_target_task_ids)} 件は、リストア対象のアノテーションデータに含まれていません。 :: {tmp_target_task_ids}")
|
|
258
254
|
|
|
259
255
|
logger.info(f"{success_count} / {task_count} 件のタスクに対してアノテーションをリストアしました。")
|
|
260
256
|
|
|
@@ -288,9 +284,7 @@ class RestoreAnnotation(CommandLine):
|
|
|
288
284
|
|
|
289
285
|
task_id_list = set(annofabcli.common.cli.get_list_from_args(args.task_id)) if args.task_id is not None else None
|
|
290
286
|
|
|
291
|
-
RestoreAnnotationMain(self.service, project_id=project_id, is_force=args.force, all_yes=args.yes).main(
|
|
292
|
-
args.annotation, target_task_ids=task_id_list, parallelism=args.parallelism
|
|
293
|
-
)
|
|
287
|
+
RestoreAnnotationMain(self.service, project_id=project_id, is_force=args.force, all_yes=args.yes).main(args.annotation, target_task_ids=task_id_list, parallelism=args.parallelism)
|
|
294
288
|
|
|
295
289
|
|
|
296
290
|
def main(args: argparse.Namespace) -> None:
|
|
@@ -60,10 +60,7 @@ class AddAttributeRestrictionMain(CommandLineWithConfirm):
|
|
|
60
60
|
try:
|
|
61
61
|
restriction_text = msg_obj.get_restriction_text(restriction["additional_data_definition_id"], restriction["condition"])
|
|
62
62
|
except ValueError as e:
|
|
63
|
-
logger.warning(
|
|
64
|
-
f"{index + 1}件目 :: 次の属性制約は存在しないIDが含まれていたため、アノテーション仕様に追加しません。 :: "
|
|
65
|
-
f"restriction=`{restriction}`, error_message=`{e!s}`"
|
|
66
|
-
)
|
|
63
|
+
logger.warning(f"{index + 1}件目 :: 次の属性制約は存在しないIDが含まれていたため、アノテーション仕様に追加しません。 :: restriction=`{restriction}`, error_message=`{e!s}`")
|
|
67
64
|
continue
|
|
68
65
|
|
|
69
66
|
if restriction in old_restrictions:
|
|
@@ -131,10 +128,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
131
128
|
"--json",
|
|
132
129
|
type=str,
|
|
133
130
|
required=True,
|
|
134
|
-
help="追加する属性の制約情報のJSONを指定します。"
|
|
135
|
-
"JSON形式は ... を参照してください。\n"
|
|
136
|
-
f"(例) ``{json.dumps(sample_json)}``\n"
|
|
137
|
-
"``file://`` を先頭に付けるとjsonファイルを指定できます。",
|
|
131
|
+
help=f"追加する属性の制約情報のJSONを指定します。JSON形式は ... を参照してください。\n(例) ``{json.dumps(sample_json)}``\n``file://`` を先頭に付けるとjsonファイルを指定できます。",
|
|
138
132
|
)
|
|
139
133
|
|
|
140
134
|
parser.add_argument("--comment", type=str, help="アノテーション仕様の変更時に指定できるコメント。未指定の場合、自動でコメントが生成されます。")
|
|
@@ -169,11 +169,7 @@ class AttributeRestrictionMessage:
|
|
|
169
169
|
return tmp
|
|
170
170
|
|
|
171
171
|
def get_attribute_from_name(self, attribute_name: str) -> Optional[dict[str, Any]]:
|
|
172
|
-
tmp = [
|
|
173
|
-
attribute
|
|
174
|
-
for attribute in self.attribute_dict.values()
|
|
175
|
-
if AnnofabApiFacade.get_additional_data_definition_name_en(attribute) == attribute_name
|
|
176
|
-
]
|
|
172
|
+
tmp = [attribute for attribute in self.attribute_dict.values() if AnnofabApiFacade.get_additional_data_definition_name_en(attribute) == attribute_name]
|
|
177
173
|
if len(tmp) == 1:
|
|
178
174
|
return tmp[0]
|
|
179
175
|
elif len(tmp) == 0:
|
|
@@ -231,10 +227,6 @@ class AttributeRestrictionMessage:
|
|
|
231
227
|
"""
|
|
232
228
|
if target_attribute_names is not None or target_label_names is not None:
|
|
233
229
|
target_attribute_ids = self.get_target_attribute_ids(target_attribute_names=target_attribute_names, target_label_names=target_label_names)
|
|
234
|
-
return [
|
|
235
|
-
self.get_restriction_text(e["additional_data_definition_id"], e["condition"])
|
|
236
|
-
for e in restrictions
|
|
237
|
-
if e["additional_data_definition_id"] in target_attribute_ids
|
|
238
|
-
]
|
|
230
|
+
return [self.get_restriction_text(e["additional_data_definition_id"], e["condition"]) for e in restrictions if e["additional_data_definition_id"] in target_attribute_ids]
|
|
239
231
|
else:
|
|
240
232
|
return [self.get_restriction_text(e["additional_data_definition_id"], e["condition"]) for e in restrictions]
|
|
@@ -28,9 +28,7 @@ class ExportAnnotationSpecs(CommandLine):
|
|
|
28
28
|
sorted_histories = sorted(histories, key=lambda x: x["updated_datetime"], reverse=True)
|
|
29
29
|
|
|
30
30
|
if before + 1 > len(sorted_histories):
|
|
31
|
-
logger.warning(
|
|
32
|
-
f"アノテーション仕様の履歴は{len(sorted_histories)}個のため、最新より{before}個前のアノテーション仕様は見つかりませんでした。"
|
|
33
|
-
)
|
|
31
|
+
logger.warning(f"アノテーション仕様の履歴は{len(sorted_histories)}個のため、最新より{before}個前のアノテーション仕様は見つかりませんでした。")
|
|
34
32
|
return None
|
|
35
33
|
|
|
36
34
|
history = sorted_histories[before]
|
|
@@ -101,16 +101,11 @@ class ReplacingAttributeId(CommandLineWithConfirm):
|
|
|
101
101
|
continue
|
|
102
102
|
|
|
103
103
|
if not self.validate_attribute_id(attribute_name_en):
|
|
104
|
-
logger.warning(
|
|
105
|
-
f"属性英語名='{attribute_name_en}'は属性IDに利用できない文字を含むため、"
|
|
106
|
-
f"属性ID='{attribute_id}'を'{attribute_name_en}'に変更しません。"
|
|
107
|
-
)
|
|
104
|
+
logger.warning(f"属性英語名='{attribute_name_en}'は属性IDに利用できない文字を含むため、属性ID='{attribute_id}'を'{attribute_name_en}'に変更しません。")
|
|
108
105
|
continue
|
|
109
106
|
|
|
110
107
|
if self.exists_attribute_with_attribute_id(attribute_list, attribute_id=attribute_name_en):
|
|
111
|
-
logger.warning(
|
|
112
|
-
f"属性ID='{attribute_name_en}'である属性が既に存在するため、属性ID='{attribute_id}'を'{attribute_name_en}'に変更しません。"
|
|
113
|
-
)
|
|
108
|
+
logger.warning(f"属性ID='{attribute_name_en}'である属性が既に存在するため、属性ID='{attribute_id}'を'{attribute_name_en}'に変更しません。")
|
|
114
109
|
continue
|
|
115
110
|
|
|
116
111
|
if not self.confirm_processing(f"属性ID='{attribute_id}'を'{attribute_name_en}'に変更したアノテーション仕様のJSONを出力しますか?"):
|
|
@@ -118,9 +113,7 @@ class ReplacingAttributeId(CommandLineWithConfirm):
|
|
|
118
113
|
|
|
119
114
|
attribute["additional_data_definition_id"] = attribute_name_en
|
|
120
115
|
self.replace_attribute_id_of_labels(old_attribute_id=attribute_id, new_attribute_id=attribute_name_en, label_list=label_list)
|
|
121
|
-
self.replace_attribute_id_of_restrictions(
|
|
122
|
-
old_attribute_id=attribute_id, new_attribute_id=attribute_name_en, restriction_list=restriction_list
|
|
123
|
-
)
|
|
116
|
+
self.replace_attribute_id_of_restrictions(old_attribute_id=attribute_id, new_attribute_id=attribute_name_en, restriction_list=restriction_list)
|
|
124
117
|
replaced_count += 1
|
|
125
118
|
|
|
126
119
|
logger.info(f"{replaced_count} 個の属性の属性IDを変更しました。")
|
|
@@ -44,7 +44,7 @@ class ReplacingChoiceId(CommandLineWithConfirm):
|
|
|
44
44
|
annotation_specs: (IN/OUT) アノテーション仕様情報。中身が変更されます。
|
|
45
45
|
target_attribute_names: 変更対象のラジオボタン/ドロップダウン属性の英語名。Noneならすべてのラジオボタン/ドロップダウン属性の選択肢IDを変更します。
|
|
46
46
|
|
|
47
|
-
"""
|
|
47
|
+
"""
|
|
48
48
|
attribute_list = annotation_specs["additionals"]
|
|
49
49
|
|
|
50
50
|
replaced_count = 0
|
|
@@ -62,9 +62,7 @@ class ReplacingChoiceId(CommandLineWithConfirm):
|
|
|
62
62
|
|
|
63
63
|
choice_list = attribute["choices"]
|
|
64
64
|
|
|
65
|
-
if not self.confirm_processing(
|
|
66
|
-
f"属性英語名='{attribute_name_en}'の{len(choice_list)}個の選択肢IDを、選択肢英語名に変更したアノテーション仕様のJSONを出力しますか?"
|
|
67
|
-
):
|
|
65
|
+
if not self.confirm_processing(f"属性英語名='{attribute_name_en}'の{len(choice_list)}個の選択肢IDを、選択肢英語名に変更したアノテーション仕様のJSONを出力しますか?"):
|
|
68
66
|
continue
|
|
69
67
|
|
|
70
68
|
replaced_choice_id_count = 0
|
|
@@ -74,16 +72,12 @@ class ReplacingChoiceId(CommandLineWithConfirm):
|
|
|
74
72
|
|
|
75
73
|
if not self.validate_choice_id(choice_name_en):
|
|
76
74
|
logger.warning(
|
|
77
|
-
f"属性英語名='{attribute_name_en}', 選択肢英語名='{choice_name_en}'は選択肢ID
|
|
78
|
-
f"選択肢ID='{choice_id}'を'{choice_name_en}'に変更しません。"
|
|
75
|
+
f"属性英語名='{attribute_name_en}', 選択肢英語名='{choice_name_en}'は選択肢IDに利用できない文字を含むため、選択肢ID='{choice_id}'を'{choice_name_en}'に変更しません。"
|
|
79
76
|
)
|
|
80
77
|
continue
|
|
81
78
|
|
|
82
79
|
if self.exists_choice_with_choice_id(choice_list, choice_id=choice_name_en):
|
|
83
|
-
logger.warning(
|
|
84
|
-
f"属性英語名='{attribute_name_en}', 選択肢ID='{choice_name_en}'である選択肢が既に存在するため、"
|
|
85
|
-
f"選択肢ID='{choice_id}'を'{choice_name_en}'に変更しません。"
|
|
86
|
-
)
|
|
80
|
+
logger.warning(f"属性英語名='{attribute_name_en}', 選択肢ID='{choice_name_en}'である選択肢が既に存在するため、選択肢ID='{choice_id}'を'{choice_name_en}'に変更しません。")
|
|
87
81
|
continue
|
|
88
82
|
|
|
89
83
|
choice["choice_id"] = choice_name_en
|
|
@@ -86,9 +86,7 @@ class ReplacingLabelId(CommandLineWithConfirm):
|
|
|
86
86
|
continue
|
|
87
87
|
|
|
88
88
|
if not self.validate_label_id(label_name_en):
|
|
89
|
-
logger.warning(
|
|
90
|
-
f"label_name_en='{label_name_en}'はlabel_idにできない文字を含むため、label_id='{label_id}'を'{label_name_en}'に変更しません。"
|
|
91
|
-
)
|
|
89
|
+
logger.warning(f"label_name_en='{label_name_en}'はlabel_idにできない文字を含むため、label_id='{label_id}'を'{label_name_en}'に変更しません。")
|
|
92
90
|
continue
|
|
93
91
|
|
|
94
92
|
if self.exists_label_with_label_id(label_list, label_id=label_name_en):
|
|
@@ -43,7 +43,7 @@ class FlattenAttribute(DataClassJsonMixin):
|
|
|
43
43
|
Notes:
|
|
44
44
|
APIレスポンスの ``additional_data_definition_id`` に相当します。
|
|
45
45
|
``additional_data_definition_id`` という名前がアノテーションJSONの `attributes` と対応していることが分かりにくかったので、`attribute_id`という名前に変えました。
|
|
46
|
-
"""
|
|
46
|
+
"""
|
|
47
47
|
attribute_name_en: Optional[str]
|
|
48
48
|
attribute_name_ja: Optional[str]
|
|
49
49
|
attribute_name_vi: Optional[str]
|
|
@@ -81,9 +81,7 @@ def create_relationship_between_attribute_and_label(labels_v3: list[dict[str, An
|
|
|
81
81
|
return result
|
|
82
82
|
|
|
83
83
|
|
|
84
|
-
def create_flatten_attribute_list_from_additionals(
|
|
85
|
-
additionals_v3: list[dict[str, Any]], labels_v3: list[dict[str, Any]], restrictions: list[dict[str, Any]]
|
|
86
|
-
) -> list[FlattenAttribute]:
|
|
84
|
+
def create_flatten_attribute_list_from_additionals(additionals_v3: list[dict[str, Any]], labels_v3: list[dict[str, Any]], restrictions: list[dict[str, Any]]) -> list[FlattenAttribute]:
|
|
87
85
|
"""
|
|
88
86
|
APIから取得した属性情報(v3版)から、属性情報の一覧を生成します。
|
|
89
87
|
|
|
@@ -127,12 +125,8 @@ def create_flatten_attribute_list_from_additionals(
|
|
|
127
125
|
class PrintAnnotationSpecsAttribute(CommandLine):
|
|
128
126
|
COMMON_MESSAGE = "annofabcli annotation_specs list_attribute: error:"
|
|
129
127
|
|
|
130
|
-
def print_annotation_specs_attribute(
|
|
131
|
-
|
|
132
|
-
) -> None:
|
|
133
|
-
attribute_list = create_flatten_attribute_list_from_additionals(
|
|
134
|
-
annotation_specs_v3["additionals"], annotation_specs_v3["labels"], annotation_specs_v3["restrictions"]
|
|
135
|
-
)
|
|
128
|
+
def print_annotation_specs_attribute(self, annotation_specs_v3: dict[str, Any], output_format: FormatArgument, output: Optional[str] = None) -> None:
|
|
129
|
+
attribute_list = create_flatten_attribute_list_from_additionals(annotation_specs_v3["additionals"], annotation_specs_v3["labels"], annotation_specs_v3["restrictions"])
|
|
136
130
|
logger.info(f"{len(attribute_list)} 件の属性情報を出力します。")
|
|
137
131
|
if output_format == FormatArgument.CSV:
|
|
138
132
|
columns = [
|
|
@@ -161,9 +155,7 @@ class PrintAnnotationSpecsAttribute(CommandLine):
|
|
|
161
155
|
logger.warning(f"アノテーション仕様の履歴は{len(histories)}個のため、最新より{before}個前のアノテーション仕様は見つかりませんでした。")
|
|
162
156
|
return None
|
|
163
157
|
history = histories[-(before + 1)]
|
|
164
|
-
logger.info(
|
|
165
|
-
f"{history['updated_datetime']}のアノテーション仕様を出力します。 :: history_id='{history['history_id']}', comment='{history['comment']}'"
|
|
166
|
-
)
|
|
158
|
+
logger.info(f"{history['updated_datetime']}のアノテーション仕様を出力します。 :: history_id='{history['history_id']}', comment='{history['comment']}'")
|
|
167
159
|
return history["history_id"]
|
|
168
160
|
|
|
169
161
|
def main(self) -> None:
|
|
@@ -195,14 +187,11 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
195
187
|
argument_parser = ArgumentParser(parser)
|
|
196
188
|
|
|
197
189
|
required_group = parser.add_mutually_exclusive_group(required=True)
|
|
198
|
-
required_group.add_argument(
|
|
199
|
-
"-p", "--project_id", help="対象のプロジェクトのproject_idを指定します。APIで取得したアノテーション仕様情報を元に出力します。"
|
|
200
|
-
)
|
|
190
|
+
required_group.add_argument("-p", "--project_id", help="対象のプロジェクトのproject_idを指定します。APIで取得したアノテーション仕様情報を元に出力します。")
|
|
201
191
|
required_group.add_argument(
|
|
202
192
|
"--annotation_specs_json",
|
|
203
193
|
type=Path,
|
|
204
|
-
help="指定したアノテーション仕様のJSONファイルを指定します。"
|
|
205
|
-
"JSONファイルに記載された情報を元に出力します。ただしアノテーション仕様の ``format_version`` は ``3`` である必要があります。",
|
|
194
|
+
help="指定したアノテーション仕様のJSONファイルを指定します。JSONファイルに記載された情報を元に出力します。ただしアノテーション仕様の ``format_version`` は ``3`` である必要があります。",
|
|
206
195
|
)
|
|
207
196
|
|
|
208
197
|
# 過去のアノテーション仕様を参照するためのオプション
|
|
@@ -133,9 +133,7 @@ class PrintAnnotationSpecsAttribute(CommandLine):
|
|
|
133
133
|
logger.warning(f"アノテーション仕様の履歴は{len(histories)}個のため、最新より{before}個前のアノテーション仕様は見つかりませんでした。")
|
|
134
134
|
return None
|
|
135
135
|
history = histories[-(before + 1)]
|
|
136
|
-
logger.info(
|
|
137
|
-
f"{history['updated_datetime']}のアノテーション仕様を出力します。 :: history_id='{history['history_id']}', comment='{history['comment']}'"
|
|
138
|
-
)
|
|
136
|
+
logger.info(f"{history['updated_datetime']}のアノテーション仕様を出力します。 :: history_id='{history['history_id']}', comment='{history['comment']}'")
|
|
139
137
|
return history["history_id"]
|
|
140
138
|
|
|
141
139
|
def main(self) -> None:
|
|
@@ -169,14 +167,11 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
169
167
|
argument_parser = ArgumentParser(parser)
|
|
170
168
|
|
|
171
169
|
required_group = parser.add_mutually_exclusive_group(required=True)
|
|
172
|
-
required_group.add_argument(
|
|
173
|
-
"-p", "--project_id", help="対象のプロジェクトのproject_idを指定します。APIで取得したアノテーション仕様情報を元に出力します。"
|
|
174
|
-
)
|
|
170
|
+
required_group.add_argument("-p", "--project_id", help="対象のプロジェクトのproject_idを指定します。APIで取得したアノテーション仕様情報を元に出力します。")
|
|
175
171
|
required_group.add_argument(
|
|
176
172
|
"--annotation_specs_json",
|
|
177
173
|
type=Path,
|
|
178
|
-
help="指定したアノテーション仕様のJSONファイルを指定します。"
|
|
179
|
-
"JSONファイルに記載された情報を元に出力します。ただしアノテーション仕様の ``format_version`` は ``3`` である必要があります。",
|
|
174
|
+
help="指定したアノテーション仕様のJSONファイルを指定します。JSONファイルに記載された情報を元に出力します。ただしアノテーション仕様の ``format_version`` は ``3`` である必要があります。",
|
|
180
175
|
)
|
|
181
176
|
|
|
182
177
|
# 過去のアノテーション仕様を参照するためのオプション
|
|
@@ -50,7 +50,6 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
50
50
|
|
|
51
51
|
argument_parser.add_format(choices=[FormatArgument.CSV, FormatArgument.JSON, FormatArgument.PRETTY_JSON], default=FormatArgument.CSV)
|
|
52
52
|
argument_parser.add_output()
|
|
53
|
-
argument_parser.add_csv_format()
|
|
54
53
|
|
|
55
54
|
parser.set_defaults(subcommand_func=main)
|
|
56
55
|
|
|
@@ -119,9 +119,7 @@ class PrintAnnotationSpecsLabel(CommandLine):
|
|
|
119
119
|
logger.warning(f"アノテーション仕様の履歴は{len(histories)}個のため、最新より{before}個前のアノテーション仕様は見つかりませんでした。")
|
|
120
120
|
return None
|
|
121
121
|
history = histories[-(before + 1)]
|
|
122
|
-
logger.info(
|
|
123
|
-
f"{history['updated_datetime']}のアノテーション仕様を出力します。 :: history_id='{history['history_id']}', comment='{history['comment']}'"
|
|
124
|
-
)
|
|
122
|
+
logger.info(f"{history['updated_datetime']}のアノテーション仕様を出力します。 :: history_id='{history['history_id']}', comment='{history['comment']}'")
|
|
125
123
|
return history["history_id"]
|
|
126
124
|
|
|
127
125
|
def main(self) -> None:
|
|
@@ -156,14 +154,11 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
156
154
|
argument_parser = ArgumentParser(parser)
|
|
157
155
|
|
|
158
156
|
required_group = parser.add_mutually_exclusive_group(required=True)
|
|
159
|
-
required_group.add_argument(
|
|
160
|
-
"-p", "--project_id", help="対象のプロジェクトのproject_idを指定します。APIで取得したアノテーション仕様情報を元に出力します。"
|
|
161
|
-
)
|
|
157
|
+
required_group.add_argument("-p", "--project_id", help="対象のプロジェクトのproject_idを指定します。APIで取得したアノテーション仕様情報を元に出力します。")
|
|
162
158
|
required_group.add_argument(
|
|
163
159
|
"--annotation_specs_json",
|
|
164
160
|
type=Path,
|
|
165
|
-
help="指定したアノテーション仕様のJSONファイルを指定します。"
|
|
166
|
-
"JSONファイルに記載された情報を元に出力します。ただしアノテーション仕様の ``format_version`` は ``3`` である必要があります。",
|
|
161
|
+
help="指定したアノテーション仕様のJSONファイルを指定します。JSONファイルに記載された情報を元に出力します。ただしアノテーション仕様の ``format_version`` は ``3`` である必要があります。",
|
|
167
162
|
)
|
|
168
163
|
|
|
169
164
|
# 過去のアノテーション仕様を参照するためのオプション
|
|
@@ -42,7 +42,7 @@ class LabelAndAttribute(DataClassJsonMixin):
|
|
|
42
42
|
Notes:
|
|
43
43
|
APIレスポンスの ``additional_data_definition_id`` に相当します。
|
|
44
44
|
``additional_data_definition_id`` という名前がアノテーションJSONの `attributes` と対応していることが分かりにくかったので、`attribute_id`という名前に変えました。
|
|
45
|
-
"""
|
|
45
|
+
"""
|
|
46
46
|
attribute_name_en: Optional[str]
|
|
47
47
|
attribute_name_ja: Optional[str]
|
|
48
48
|
attribute_name_vi: Optional[str]
|
|
@@ -121,9 +121,7 @@ class PrintAnnotationSpecsLabelAndAttribute(CommandLine):
|
|
|
121
121
|
logger.warning(f"アノテーション仕様の履歴は{len(histories)}個のため、最新より{before}個前のアノテーション仕様は見つかりませんでした。")
|
|
122
122
|
return None
|
|
123
123
|
history = histories[-(before + 1)]
|
|
124
|
-
logger.info(
|
|
125
|
-
f"{history['updated_datetime']}のアノテーション仕様を出力します。 :: history_id='{history['history_id']}', comment='{history['comment']}'"
|
|
126
|
-
)
|
|
124
|
+
logger.info(f"{history['updated_datetime']}のアノテーション仕様を出力します。 :: history_id='{history['history_id']}', comment='{history['comment']}'")
|
|
127
125
|
return history["history_id"]
|
|
128
126
|
|
|
129
127
|
def main(self) -> None:
|
|
@@ -158,14 +156,11 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
158
156
|
argument_parser = ArgumentParser(parser)
|
|
159
157
|
|
|
160
158
|
required_group = parser.add_mutually_exclusive_group(required=True)
|
|
161
|
-
required_group.add_argument(
|
|
162
|
-
"-p", "--project_id", help="対象のプロジェクトのproject_idを指定します。APIで取得したアノテーション仕様情報を元に出力します。"
|
|
163
|
-
)
|
|
159
|
+
required_group.add_argument("-p", "--project_id", help="対象のプロジェクトのproject_idを指定します。APIで取得したアノテーション仕様情報を元に出力します。")
|
|
164
160
|
required_group.add_argument(
|
|
165
161
|
"--annotation_specs_json",
|
|
166
162
|
type=Path,
|
|
167
|
-
help="指定したアノテーション仕様のJSONファイルを指定します。"
|
|
168
|
-
"JSONファイルに記載された情報を元に出力します。ただしアノテーション仕様の ``format_version`` は ``3`` である必要があります。",
|
|
163
|
+
help="指定したアノテーション仕様のJSONファイルを指定します。JSONファイルに記載された情報を元に出力します。ただしアノテーション仕様の ``format_version`` は ``3`` である必要があります。",
|
|
169
164
|
)
|
|
170
165
|
|
|
171
166
|
# 過去のアノテーション仕様を参照するためのオプション
|
|
@@ -82,14 +82,11 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
82
82
|
argument_parser = ArgumentParser(parser)
|
|
83
83
|
|
|
84
84
|
required_group = parser.add_mutually_exclusive_group(required=True)
|
|
85
|
-
required_group.add_argument(
|
|
86
|
-
"-p", "--project_id", help="対象のプロジェクトのproject_idを指定します。APIで取得したアノテーション仕様情報を元に出力します。"
|
|
87
|
-
)
|
|
85
|
+
required_group.add_argument("-p", "--project_id", help="対象のプロジェクトのproject_idを指定します。APIで取得したアノテーション仕様情報を元に出力します。")
|
|
88
86
|
required_group.add_argument(
|
|
89
87
|
"--annotation_specs_json",
|
|
90
88
|
type=Path,
|
|
91
|
-
help="指定したアノテーション仕様のJSONファイルを指定します。"
|
|
92
|
-
"JSONファイルに記載された情報を元に出力します。ただしアノテーション仕様の ``format_version`` は ``3`` である必要があります。",
|
|
89
|
+
help="指定したアノテーション仕様のJSONファイルを指定します。JSONファイルに記載された情報を元に出力します。ただしアノテーション仕様の ``format_version`` は ``3`` である必要があります。",
|
|
93
90
|
)
|
|
94
91
|
|
|
95
92
|
# 過去のアノテーション仕様を参照するためのオプション
|
|
@@ -124,10 +121,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
124
121
|
type=str,
|
|
125
122
|
choices=[e.value for e in OutputFormat],
|
|
126
123
|
default=OutputFormat.TEXT.value,
|
|
127
|
-
help=f"出力フォーマット\n"
|
|
128
|
-
"\n"
|
|
129
|
-
f"* {OutputFormat.TEXT.value}: 英語名のみ出力する形式\n"
|
|
130
|
-
f"* {OutputFormat.DETAILED_TEXT.value}: 属性IDや属性種類などの詳細情報を出力する形式\n",
|
|
124
|
+
help=f"出力フォーマット\n\n* {OutputFormat.TEXT.value}: 英語名のみ出力する形式\n* {OutputFormat.DETAILED_TEXT.value}: 属性IDや属性種類などの詳細情報を出力する形式\n",
|
|
131
125
|
)
|
|
132
126
|
|
|
133
127
|
parser.set_defaults(subcommand_func=main)
|
|
@@ -119,12 +119,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
119
119
|
"--json",
|
|
120
120
|
type=str,
|
|
121
121
|
required=True,
|
|
122
|
-
help=(
|
|
123
|
-
"変更したいラベルの色をJSON形式で指定してください。"
|
|
124
|
-
"keyがラベル英語名, valueがRGB値の配列です。\n"
|
|
125
|
-
f"(ex) ``{JSON_SAMPLE}`` \n"
|
|
126
|
-
"``file://`` を先頭に付けるとjsonファイルを指定できます。"
|
|
127
|
-
),
|
|
122
|
+
help=(f"変更したいラベルの色をJSON形式で指定してください。keyがラベル英語名, valueがRGB値の配列です。\n(ex) ``{JSON_SAMPLE}`` \n``file://`` を先頭に付けるとjsonファイルを指定できます。"),
|
|
128
123
|
)
|
|
129
124
|
|
|
130
125
|
parser.add_argument(
|
|
@@ -98,9 +98,7 @@ class DeleteCommentMain(CommandLineWithConfirm):
|
|
|
98
98
|
) -> bool:
|
|
99
99
|
task_id = task["task_id"]
|
|
100
100
|
if task["status"] not in [TaskStatus.NOT_STARTED.value, TaskStatus.WORKING.value, TaskStatus.BREAK.value]:
|
|
101
|
-
logger.warning(
|
|
102
|
-
f"task_id='{task_id}' : タスクの状態が未着手,作業中,休憩中 以外の状態なので、コメントを削除できません。(task_status='{task['status']}')" # noqa: E501
|
|
103
|
-
)
|
|
101
|
+
logger.warning(f"task_id='{task_id}' : タスクの状態が未着手,作業中,休憩中 以外の状態なので、コメントを削除できません。(task_status='{task['status']}')")
|
|
104
102
|
return False
|
|
105
103
|
return True
|
|
106
104
|
|
|
@@ -151,13 +149,9 @@ class DeleteCommentMain(CommandLineWithConfirm):
|
|
|
151
149
|
if len(request_body) > 0:
|
|
152
150
|
self.service.api.batch_update_comments(self.project_id, task_id, input_data_id, request_body=request_body)
|
|
153
151
|
added_comments_count += 1
|
|
154
|
-
logger.debug(
|
|
155
|
-
f"{logging_prefix} :: task_id='{task_id}', input_data_id='{input_data_id}' :: {len(request_body)}件のコメントを削除しました。"
|
|
156
|
-
)
|
|
152
|
+
logger.debug(f"{logging_prefix} :: task_id='{task_id}', input_data_id='{input_data_id}' :: {len(request_body)}件のコメントを削除しました。")
|
|
157
153
|
else:
|
|
158
|
-
logger.warning(
|
|
159
|
-
f"{logging_prefix} :: task_id='{task_id}', input_data_id='{input_data_id}' :: 削除できるコメントは存在しませんでした。"
|
|
160
|
-
)
|
|
154
|
+
logger.warning(f"{logging_prefix} :: task_id='{task_id}', input_data_id='{input_data_id}' :: 削除できるコメントは存在しませんでした。")
|
|
161
155
|
|
|
162
156
|
except Exception: # pylint: disable=broad-except
|
|
163
157
|
logger.warning(
|