annofabcli 1.111.1__py3-none-any.whl → 1.112.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/__main__.py +1 -2
- annofabcli/annotation/annotation_query.py +10 -10
- annofabcli/annotation/change_annotation_attributes.py +9 -9
- annofabcli/annotation/change_annotation_attributes_per_annotation.py +3 -4
- annofabcli/annotation/change_annotation_properties.py +13 -13
- annofabcli/annotation/copy_annotation.py +5 -5
- annofabcli/annotation/create_classification_annotation.py +6 -6
- annofabcli/annotation/delete_annotation.py +8 -8
- annofabcli/annotation/download_annotation_zip.py +1 -3
- annofabcli/annotation/dump_annotation.py +7 -7
- annofabcli/annotation/import_annotation.py +12 -12
- annofabcli/annotation/list_annotation.py +8 -8
- annofabcli/annotation/list_annotation_count.py +1 -2
- annofabcli/annotation/merge_segmentation.py +5 -5
- annofabcli/annotation/remove_segmentation_overlap.py +4 -4
- annofabcli/annotation/restore_annotation.py +6 -6
- annofabcli/annotation/subcommand_annotation.py +1 -2
- annofabcli/annotation_specs/add_attribute_restriction.py +4 -5
- annofabcli/annotation_specs/attribute_restriction.py +8 -8
- annofabcli/annotation_specs/export_annotation_specs.py +4 -5
- annofabcli/annotation_specs/get_annotation_specs_with_attribute_id_replaced.py +3 -4
- annofabcli/annotation_specs/get_annotation_specs_with_choice_id_replaced.py +3 -4
- annofabcli/annotation_specs/get_annotation_specs_with_label_id_replaced.py +3 -4
- annofabcli/annotation_specs/list_annotation_specs_attribute.py +9 -10
- annofabcli/annotation_specs/list_annotation_specs_choice.py +9 -10
- annofabcli/annotation_specs/list_annotation_specs_history.py +2 -2
- annofabcli/annotation_specs/list_annotation_specs_label.py +8 -9
- annofabcli/annotation_specs/list_annotation_specs_label_attribute.py +10 -11
- annofabcli/annotation_specs/list_attribute_restriction.py +2 -4
- annofabcli/annotation_specs/list_label_color.py +2 -3
- annofabcli/annotation_specs/put_label_color.py +3 -4
- annofabcli/annotation_specs/subcommand_annotation_specs.py +1 -3
- annofabcli/annotation_zip/list_annotation_3d_bounding_box.py +365 -0
- annofabcli/annotation_zip/list_annotation_bounding_box_2d.py +11 -12
- annofabcli/annotation_zip/list_range_annotation.py +24 -14
- annofabcli/annotation_zip/list_single_point_annotation.py +11 -12
- annofabcli/annotation_zip/subcommand_annotation_zip.py +3 -2
- annofabcli/annotation_zip/validate_annotation.py +8 -7
- annofabcli/comment/delete_comment.py +4 -6
- annofabcli/comment/download_comment_json.py +4 -6
- annofabcli/comment/list_all_comment.py +5 -6
- annofabcli/comment/list_comment.py +3 -4
- annofabcli/comment/put_comment.py +9 -10
- annofabcli/comment/put_comment_simply.py +5 -6
- annofabcli/comment/put_inspection_comment.py +1 -3
- annofabcli/comment/put_inspection_comment_simply.py +1 -3
- annofabcli/comment/put_onhold_comment.py +1 -3
- annofabcli/comment/put_onhold_comment_simply.py +1 -3
- annofabcli/comment/subcommand_comment.py +1 -3
- annofabcli/common/bokeh.py +4 -4
- annofabcli/common/cli.py +17 -17
- annofabcli/common/download.py +28 -29
- annofabcli/common/facade.py +37 -38
- annofabcli/common/image.py +14 -14
- annofabcli/common/utils.py +8 -8
- annofabcli/common/visualize.py +13 -13
- annofabcli/experimental/list_out_of_range_annotation_for_movie.py +3 -4
- annofabcli/experimental/subcommand_experimental.py +1 -3
- annofabcli/filesystem/draw_annotation.py +26 -26
- annofabcli/filesystem/filter_annotation.py +9 -10
- annofabcli/filesystem/mask_user_info.py +14 -14
- annofabcli/filesystem/merge_annotation.py +8 -8
- annofabcli/filesystem/subcommand_filesystem.py +1 -3
- annofabcli/input_data/copy_input_data.py +8 -9
- annofabcli/input_data/delete_input_data.py +2 -2
- annofabcli/input_data/delete_metadata_key_of_input_data.py +3 -5
- annofabcli/input_data/download_input_data_json.py +4 -6
- annofabcli/input_data/list_all_input_data.py +8 -8
- annofabcli/input_data/list_all_input_data_merged_task.py +4 -4
- annofabcli/input_data/list_input_data.py +4 -4
- annofabcli/input_data/put_input_data.py +5 -5
- annofabcli/input_data/put_input_data_with_zip.py +2 -3
- annofabcli/input_data/subcommand_input_data.py +1 -3
- annofabcli/input_data/update_input_data.py +6 -8
- annofabcli/input_data/update_metadata_of_input_data.py +3 -5
- annofabcli/instruction/copy_instruction.py +4 -5
- annofabcli/instruction/download_instruction.py +4 -5
- annofabcli/instruction/list_instruction_history.py +2 -2
- annofabcli/instruction/subcommand_instruction.py +1 -3
- annofabcli/instruction/upload_instruction.py +2 -3
- annofabcli/job/delete_job.py +1 -2
- annofabcli/job/list_job.py +4 -4
- annofabcli/job/list_last_job.py +3 -3
- annofabcli/job/subcommand_job.py +1 -3
- annofabcli/job/wait_job.py +4 -5
- annofabcli/my_account/get_my_account.py +1 -2
- annofabcli/my_account/subcommand_my_account.py +1 -3
- annofabcli/organization/list_organization.py +1 -2
- annofabcli/organization/subcommand_organization.py +1 -3
- annofabcli/organization_member/change_organization_member.py +3 -4
- annofabcli/organization_member/delete_organization_member.py +3 -4
- annofabcli/organization_member/invite_organization_member.py +1 -3
- annofabcli/organization_member/list_organization_member.py +2 -2
- annofabcli/organization_member/subcommand_organization_member.py +1 -3
- annofabcli/project/change_organization_of_project.py +3 -3
- annofabcli/project/change_project_status.py +3 -3
- annofabcli/project/copy_project.py +4 -4
- annofabcli/project/create_project.py +7 -7
- annofabcli/project/diff_projects.py +4 -5
- annofabcli/project/list_project.py +4 -4
- annofabcli/project/put_project.py +1 -2
- annofabcli/project/subcommand_project.py +1 -2
- annofabcli/project/update_configuration.py +3 -3
- annofabcli/project/update_project.py +6 -8
- annofabcli/project_member/change_project_members.py +7 -7
- annofabcli/project_member/copy_project_members.py +3 -3
- annofabcli/project_member/drop_project_members.py +1 -2
- annofabcli/project_member/invite_project_members.py +1 -3
- annofabcli/project_member/list_users.py +1 -2
- annofabcli/project_member/put_project_members.py +5 -5
- annofabcli/project_member/subcommand_project_member.py +1 -3
- annofabcli/stat_visualization/mask_visualization_dir.py +8 -9
- annofabcli/stat_visualization/merge_visualization_dir.py +6 -7
- annofabcli/stat_visualization/subcommand_stat_visualization.py +1 -2
- annofabcli/stat_visualization/summarize_whole_performance_csv.py +1 -2
- annofabcli/stat_visualization/write_graph.py +2 -3
- annofabcli/stat_visualization/write_performance_rating_csv.py +20 -27
- annofabcli/statistics/histogram.py +5 -6
- annofabcli/statistics/linegraph.py +13 -14
- annofabcli/statistics/list_annotation_area.py +38 -13
- annofabcli/statistics/list_annotation_attribute.py +9 -10
- annofabcli/statistics/list_annotation_attribute_filled_count.py +30 -31
- annofabcli/statistics/list_annotation_count.py +57 -58
- annofabcli/statistics/list_annotation_duration.py +33 -34
- annofabcli/statistics/list_video_duration.py +4 -5
- annofabcli/statistics/list_worktime.py +3 -3
- annofabcli/statistics/scatter.py +9 -8
- annofabcli/statistics/subcommand_statistics.py +1 -4
- annofabcli/statistics/summarize_task_count.py +4 -6
- annofabcli/statistics/summarize_task_count_by_task_id_group.py +2 -4
- annofabcli/statistics/summarize_task_count_by_user.py +1 -3
- annofabcli/statistics/visualization/dataframe/annotation_count.py +5 -4
- annofabcli/statistics/visualization/dataframe/annotation_duration.py +6 -7
- annofabcli/statistics/visualization/dataframe/cumulative_productivity.py +15 -17
- annofabcli/statistics/visualization/dataframe/productivity_per_date.py +17 -19
- annofabcli/statistics/visualization/dataframe/project_performance.py +3 -12
- annofabcli/statistics/visualization/dataframe/task.py +11 -12
- annofabcli/statistics/visualization/dataframe/task_worktime_by_phase_user.py +9 -10
- annofabcli/statistics/visualization/dataframe/user_performance.py +21 -19
- annofabcli/statistics/visualization/dataframe/whole_performance.py +3 -4
- annofabcli/statistics/visualization/dataframe/whole_productivity_per_date.py +12 -14
- annofabcli/statistics/visualization/dataframe/worktime_per_date.py +11 -13
- annofabcli/statistics/visualization/filtering_query.py +7 -7
- annofabcli/statistics/visualization/project_dir.py +27 -14
- annofabcli/statistics/visualization/visualization_source_files.py +49 -0
- annofabcli/statistics/visualize_annotation_count.py +22 -23
- annofabcli/statistics/visualize_annotation_duration.py +21 -22
- annofabcli/statistics/visualize_statistics.py +126 -69
- annofabcli/statistics/visualize_video_duration.py +18 -20
- annofabcli/supplementary/delete_supplementary_data.py +4 -4
- annofabcli/supplementary/list_supplementary_data.py +3 -3
- annofabcli/supplementary/put_supplementary_data.py +8 -8
- annofabcli/supplementary/subcommand_supplementary.py +1 -3
- annofabcli/task/cancel_acceptance.py +16 -17
- annofabcli/task/change_operator.py +10 -12
- annofabcli/task/change_status_to_break.py +7 -9
- annofabcli/task/change_status_to_on_hold.py +10 -12
- annofabcli/task/complete_tasks.py +17 -18
- annofabcli/task/copy_tasks.py +3 -5
- annofabcli/task/delete_metadata_key_of_task.py +4 -6
- annofabcli/task/delete_tasks.py +6 -6
- annofabcli/task/download_task_json.py +4 -6
- annofabcli/task/list_all_tasks.py +7 -7
- annofabcli/task/list_all_tasks_added_task_history.py +12 -12
- annofabcli/task/list_tasks.py +6 -6
- annofabcli/task/list_tasks_added_task_history.py +9 -9
- annofabcli/task/put_tasks.py +4 -5
- annofabcli/task/put_tasks_by_count.py +1 -2
- annofabcli/task/reject_tasks.py +18 -20
- annofabcli/task/subcommand_task.py +1 -3
- annofabcli/task/update_metadata_of_task.py +5 -6
- annofabcli/task_history/download_task_history_json.py +4 -6
- annofabcli/task_history/list_all_task_history.py +5 -6
- annofabcli/task_history/list_task_history.py +3 -4
- annofabcli/task_history/subcommand_task_history.py +1 -3
- annofabcli/task_history_event/download_task_history_event_json.py +4 -6
- annofabcli/task_history_event/list_all_task_history_event.py +6 -6
- annofabcli/task_history_event/list_worktime.py +15 -15
- annofabcli/task_history_event/subcommand_task_history_event.py +1 -2
- {annofabcli-1.111.1.dist-info → annofabcli-1.112.0.dist-info}/METADATA +9 -15
- annofabcli-1.112.0.dist-info/RECORD +229 -0
- {annofabcli-1.111.1.dist-info → annofabcli-1.112.0.dist-info}/WHEEL +1 -1
- annofabcli-1.111.1.dist-info/RECORD +0 -228
- {annofabcli-1.111.1.dist-info → annofabcli-1.112.0.dist-info}/entry_points.txt +0 -0
- {annofabcli-1.111.1.dist-info → annofabcli-1.112.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -7,13 +7,12 @@ import tempfile
|
|
|
7
7
|
from collections.abc import Collection
|
|
8
8
|
from dataclasses import dataclass
|
|
9
9
|
from pathlib import Path
|
|
10
|
-
from typing import Any
|
|
10
|
+
from typing import Any
|
|
11
11
|
|
|
12
12
|
import pandas
|
|
13
13
|
from annofabapi.models import InputDataType, ProjectMemberRole
|
|
14
14
|
from dataclasses_json import DataClassJsonMixin
|
|
15
15
|
|
|
16
|
-
import annofabcli
|
|
17
16
|
import annofabcli.common.cli
|
|
18
17
|
from annofabcli.common.annofab.annotation_zip import lazy_parse_simple_annotation_by_input_data
|
|
19
18
|
from annofabcli.common.cli import COMMAND_LINE_ERROR_STATUS_CODE, ArgumentParser, CommandLine, build_annofabapi_resource_and_login, get_list_from_args
|
|
@@ -40,7 +39,7 @@ class RangeAnnotationInfo(DataClassJsonMixin):
|
|
|
40
39
|
input_data_id: str
|
|
41
40
|
input_data_name: str
|
|
42
41
|
|
|
43
|
-
updated_datetime:
|
|
42
|
+
updated_datetime: str | None
|
|
44
43
|
"""アノテーションJSONに格納されているアノテーションの更新日時"""
|
|
45
44
|
|
|
46
45
|
label: str
|
|
@@ -48,9 +47,10 @@ class RangeAnnotationInfo(DataClassJsonMixin):
|
|
|
48
47
|
begin_second: float
|
|
49
48
|
end_second: float
|
|
50
49
|
duration_second: float
|
|
50
|
+
attributes: dict[str, str | int | bool]
|
|
51
51
|
|
|
52
52
|
|
|
53
|
-
def get_range_annotation_info_list(simple_annotation: dict[str, Any], *, target_label_names:
|
|
53
|
+
def get_range_annotation_info_list(simple_annotation: dict[str, Any], *, target_label_names: Collection[str] | None = None) -> list[RangeAnnotationInfo]:
|
|
54
54
|
result = []
|
|
55
55
|
target_label_names_set = set(target_label_names) if target_label_names is not None else None
|
|
56
56
|
for detail in simple_annotation["details"]:
|
|
@@ -81,6 +81,7 @@ def get_range_annotation_info_list(simple_annotation: dict[str, Any], *, target_
|
|
|
81
81
|
end_second=end_second,
|
|
82
82
|
duration_second=duration_second,
|
|
83
83
|
updated_datetime=simple_annotation["updated_datetime"],
|
|
84
|
+
attributes=detail["attributes"],
|
|
84
85
|
)
|
|
85
86
|
)
|
|
86
87
|
|
|
@@ -90,9 +91,9 @@ def get_range_annotation_info_list(simple_annotation: dict[str, Any], *, target_
|
|
|
90
91
|
def get_range_annotation_info_list_from_annotation_path(
|
|
91
92
|
annotation_path: Path,
|
|
92
93
|
*,
|
|
93
|
-
target_task_ids:
|
|
94
|
-
task_query:
|
|
95
|
-
target_label_names:
|
|
94
|
+
target_task_ids: Collection[str] | None = None,
|
|
95
|
+
task_query: TaskQuery | None = None,
|
|
96
|
+
target_label_names: Collection[str] | None = None,
|
|
96
97
|
) -> list[RangeAnnotationInfo]:
|
|
97
98
|
range_annotation_list = []
|
|
98
99
|
target_task_ids = set(target_task_ids) if target_task_ids is not None else None
|
|
@@ -114,7 +115,7 @@ def get_range_annotation_info_list_from_annotation_path(
|
|
|
114
115
|
def create_df(
|
|
115
116
|
range_annotation_list: list[RangeAnnotationInfo],
|
|
116
117
|
) -> pandas.DataFrame:
|
|
117
|
-
|
|
118
|
+
base_columns = [
|
|
118
119
|
"project_id",
|
|
119
120
|
"task_id",
|
|
120
121
|
"task_status",
|
|
@@ -129,7 +130,16 @@ def create_df(
|
|
|
129
130
|
"end_second",
|
|
130
131
|
"duration_second",
|
|
131
132
|
]
|
|
132
|
-
|
|
133
|
+
|
|
134
|
+
if not range_annotation_list:
|
|
135
|
+
# 空のリストの場合は、base_columnsのみで空のDataFrameを返す
|
|
136
|
+
return pandas.DataFrame(columns=base_columns)
|
|
137
|
+
|
|
138
|
+
tmp_range_annotation_list = [e.to_dict(encode_json=True) for e in range_annotation_list]
|
|
139
|
+
df = pandas.json_normalize(tmp_range_annotation_list)
|
|
140
|
+
|
|
141
|
+
attribute_columns = sorted(col for col in df.columns if col.startswith("attributes."))
|
|
142
|
+
columns = base_columns + attribute_columns
|
|
133
143
|
|
|
134
144
|
return df[columns]
|
|
135
145
|
|
|
@@ -139,9 +149,9 @@ def print_range_annotation(
|
|
|
139
149
|
output_file: Path,
|
|
140
150
|
output_format: FormatArgument,
|
|
141
151
|
*,
|
|
142
|
-
target_task_ids:
|
|
143
|
-
task_query:
|
|
144
|
-
target_label_names:
|
|
152
|
+
target_task_ids: Collection[str] | None = None,
|
|
153
|
+
task_query: TaskQuery | None = None,
|
|
154
|
+
target_label_names: Collection[str] | None = None,
|
|
145
155
|
) -> None:
|
|
146
156
|
range_annotation_list = get_range_annotation_info_list_from_annotation_path(
|
|
147
157
|
annotation_path,
|
|
@@ -187,7 +197,7 @@ class ListRangeAnnotation(CommandLine):
|
|
|
187
197
|
if not self.validate(args):
|
|
188
198
|
sys.exit(COMMAND_LINE_ERROR_STATUS_CODE)
|
|
189
199
|
|
|
190
|
-
project_id:
|
|
200
|
+
project_id: str | None = args.project_id
|
|
191
201
|
if project_id is not None:
|
|
192
202
|
super().validate_project(project_id, project_member_roles=[ProjectMemberRole.OWNER, ProjectMemberRole.TRAINING_DATA_USER])
|
|
193
203
|
project, _ = self.service.api.get_project(project_id)
|
|
@@ -299,7 +309,7 @@ def main(args: argparse.Namespace) -> None:
|
|
|
299
309
|
ListRangeAnnotation(service, facade, args).main()
|
|
300
310
|
|
|
301
311
|
|
|
302
|
-
def add_parser(subparsers:
|
|
312
|
+
def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
|
|
303
313
|
subcommand_name = "list_range_annotation"
|
|
304
314
|
subcommand_help = "アノテーションZIPから動画プロジェクトの区間アノテーションの情報を出力します。"
|
|
305
315
|
epilog = "アノテーションZIPをダウンロードする場合は、オーナロールまたはアノテーションユーザロールを持つユーザで実行してください。"
|
|
@@ -5,13 +5,12 @@ import tempfile
|
|
|
5
5
|
from collections.abc import Collection
|
|
6
6
|
from dataclasses import dataclass
|
|
7
7
|
from pathlib import Path
|
|
8
|
-
from typing import Any
|
|
8
|
+
from typing import Any
|
|
9
9
|
|
|
10
10
|
import pandas
|
|
11
11
|
from annofabapi.models import InputDataType, ProjectMemberRole
|
|
12
12
|
from dataclasses_json import DataClassJsonMixin
|
|
13
13
|
|
|
14
|
-
import annofabcli
|
|
15
14
|
import annofabcli.common.cli
|
|
16
15
|
from annofabcli.common.annofab.annotation_zip import lazy_parse_simple_annotation_by_input_data
|
|
17
16
|
from annofabcli.common.cli import COMMAND_LINE_ERROR_STATUS_CODE, ArgumentParser, CommandLine, build_annofabapi_resource_and_login, get_list_from_args
|
|
@@ -38,7 +37,7 @@ class AnnotationSinglePointInfo(DataClassJsonMixin):
|
|
|
38
37
|
input_data_id: str
|
|
39
38
|
input_data_name: str
|
|
40
39
|
|
|
41
|
-
updated_datetime:
|
|
40
|
+
updated_datetime: str | None
|
|
42
41
|
"""アノテーションJSONに格納されているアノテーションの更新日時"""
|
|
43
42
|
|
|
44
43
|
label: str
|
|
@@ -46,7 +45,7 @@ class AnnotationSinglePointInfo(DataClassJsonMixin):
|
|
|
46
45
|
point: dict[str, int]
|
|
47
46
|
|
|
48
47
|
|
|
49
|
-
def get_annotation_single_point_info_list(simple_annotation: dict[str, Any], *, target_label_names:
|
|
48
|
+
def get_annotation_single_point_info_list(simple_annotation: dict[str, Any], *, target_label_names: Collection[str] | None = None) -> list[AnnotationSinglePointInfo]:
|
|
50
49
|
result = []
|
|
51
50
|
target_label_names_set = set(target_label_names) if target_label_names is not None else None
|
|
52
51
|
for detail in simple_annotation["details"]:
|
|
@@ -80,9 +79,9 @@ def get_annotation_single_point_info_list(simple_annotation: dict[str, Any], *,
|
|
|
80
79
|
def get_annotation_single_point_info_list_from_annotation_path(
|
|
81
80
|
annotation_path: Path,
|
|
82
81
|
*,
|
|
83
|
-
target_task_ids:
|
|
84
|
-
task_query:
|
|
85
|
-
target_label_names:
|
|
82
|
+
target_task_ids: Collection[str] | None = None,
|
|
83
|
+
task_query: TaskQuery | None = None,
|
|
84
|
+
target_label_names: Collection[str] | None = None,
|
|
86
85
|
) -> list[AnnotationSinglePointInfo]:
|
|
87
86
|
annotation_point_list = []
|
|
88
87
|
target_task_ids = set(target_task_ids) if target_task_ids is not None else None
|
|
@@ -147,9 +146,9 @@ def print_annotation_single_point(
|
|
|
147
146
|
output_file: Path,
|
|
148
147
|
output_format: FormatArgument,
|
|
149
148
|
*,
|
|
150
|
-
target_task_ids:
|
|
151
|
-
task_query:
|
|
152
|
-
target_label_names:
|
|
149
|
+
target_task_ids: Collection[str] | None = None,
|
|
150
|
+
task_query: TaskQuery | None = None,
|
|
151
|
+
target_label_names: Collection[str] | None = None,
|
|
153
152
|
) -> None:
|
|
154
153
|
annotation_point_list = get_annotation_single_point_info_list_from_annotation_path(
|
|
155
154
|
annotation_path,
|
|
@@ -195,7 +194,7 @@ class ListAnnotationSinglePoint(CommandLine):
|
|
|
195
194
|
if not self.validate(args):
|
|
196
195
|
sys.exit(COMMAND_LINE_ERROR_STATUS_CODE)
|
|
197
196
|
|
|
198
|
-
project_id:
|
|
197
|
+
project_id: str | None = args.project_id
|
|
199
198
|
if project_id is not None:
|
|
200
199
|
super().validate_project(project_id, project_member_roles=[ProjectMemberRole.OWNER, ProjectMemberRole.TRAINING_DATA_USER])
|
|
201
200
|
project, _ = self.service.api.get_project(project_id)
|
|
@@ -308,7 +307,7 @@ def main(args: argparse.Namespace) -> None:
|
|
|
308
307
|
ListAnnotationSinglePoint(service, facade, args).main()
|
|
309
308
|
|
|
310
309
|
|
|
311
|
-
def add_parser(subparsers:
|
|
310
|
+
def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
|
|
312
311
|
subcommand_name = "list_single_point_annotation"
|
|
313
312
|
subcommand_help = "アノテーションZIPから点アノテーションの座標情報を出力します。"
|
|
314
313
|
epilog = "アノテーションZIPをダウンロードする場合は、オーナロールまたはアノテーションユーザロールを持つユーザで実行してください。"
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"""サブコマンド annotation_zip"""
|
|
2
2
|
|
|
3
3
|
import argparse
|
|
4
|
-
from typing import Optional
|
|
5
4
|
|
|
6
5
|
import annofabcli
|
|
6
|
+
from annofabcli.annotation_zip.list_annotation_3d_bounding_box import add_parser as add_parser_list_annotation_3d_bounding_box
|
|
7
7
|
from annofabcli.annotation_zip.list_annotation_bounding_box_2d import add_parser as add_parser_list_annotation_bounding_box_2d
|
|
8
8
|
from annofabcli.annotation_zip.list_range_annotation import add_parser as add_parser_list_range_annotation
|
|
9
9
|
from annofabcli.annotation_zip.list_single_point_annotation import add_parser as add_parser_list_single_point_annotation
|
|
@@ -18,6 +18,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
18
18
|
subparsers = parser.add_subparsers(dest="subcommand_name")
|
|
19
19
|
|
|
20
20
|
# サブコマンドの定義
|
|
21
|
+
add_parser_list_annotation_3d_bounding_box(subparsers)
|
|
21
22
|
add_parser_list_annotation_bounding_box_2d(subparsers)
|
|
22
23
|
add_parser_list_range_annotation(subparsers)
|
|
23
24
|
add_parser_list_single_point_annotation(subparsers)
|
|
@@ -25,7 +26,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
25
26
|
# add_parser_validate_annotation(subparsers)
|
|
26
27
|
|
|
27
28
|
|
|
28
|
-
def add_parser(subparsers:
|
|
29
|
+
def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
|
|
29
30
|
"""
|
|
30
31
|
annotation_zipサブコマンドを追加する。
|
|
31
32
|
Args:
|
|
@@ -6,9 +6,10 @@ import json
|
|
|
6
6
|
import logging
|
|
7
7
|
import sys
|
|
8
8
|
import tempfile
|
|
9
|
+
from collections.abc import Callable
|
|
9
10
|
from dataclasses import dataclass
|
|
10
11
|
from pathlib import Path
|
|
11
|
-
from typing import Any
|
|
12
|
+
from typing import Any
|
|
12
13
|
|
|
13
14
|
import annofabapi
|
|
14
15
|
import pandas
|
|
@@ -37,8 +38,8 @@ class ValidationResult:
|
|
|
37
38
|
label_name: str
|
|
38
39
|
function_name: str
|
|
39
40
|
is_valid: bool
|
|
40
|
-
error_message:
|
|
41
|
-
detail_data:
|
|
41
|
+
error_message: str | None = None
|
|
42
|
+
detail_data: dict[str, Any] | None = None
|
|
42
43
|
|
|
43
44
|
|
|
44
45
|
class ValidationFunctionLoader:
|
|
@@ -101,7 +102,7 @@ class AnnotationValidator:
|
|
|
101
102
|
service: annofabapi.Resource,
|
|
102
103
|
project_id: str,
|
|
103
104
|
validation_functions: dict[str, Callable[[dict[str, Any]], bool]],
|
|
104
|
-
task_query:
|
|
105
|
+
task_query: TaskQuery | None = None,
|
|
105
106
|
) -> None:
|
|
106
107
|
self.service = service
|
|
107
108
|
self.project_id = project_id
|
|
@@ -233,7 +234,7 @@ class ValidateAnnotation(CommandLine):
|
|
|
233
234
|
logger.info(f"読み込んだバリデーション関数: {list(validation_functions.keys())}")
|
|
234
235
|
|
|
235
236
|
# タスク検索クエリ
|
|
236
|
-
task_query:
|
|
237
|
+
task_query: TaskQuery | None = None
|
|
237
238
|
if args.task_query is not None:
|
|
238
239
|
dict_task_query = annofabcli.common.cli.get_json_from_args(args.task_query)
|
|
239
240
|
task_query = TaskQuery.from_dict(dict_task_query)
|
|
@@ -277,7 +278,7 @@ class ValidateAnnotation(CommandLine):
|
|
|
277
278
|
# サマリー表示
|
|
278
279
|
self._print_summary(results)
|
|
279
280
|
|
|
280
|
-
def _output_results(self, results: list[ValidationResult], format_type: str, output_file:
|
|
281
|
+
def _output_results(self, results: list[ValidationResult], format_type: str, output_file: Path | None) -> None:
|
|
281
282
|
"""バリデーション結果を出力する"""
|
|
282
283
|
if not results:
|
|
283
284
|
logger.info("バリデーション結果はありません。")
|
|
@@ -382,7 +383,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
382
383
|
parser.set_defaults(subcommand_func=main)
|
|
383
384
|
|
|
384
385
|
|
|
385
|
-
def add_parser(subparsers:
|
|
386
|
+
def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
|
|
386
387
|
subcommand_name = "validate"
|
|
387
388
|
subcommand_help = "ユーザー定義のバリデーション関数でアノテーションZIPを検証します。"
|
|
388
389
|
description = "ユーザー定義のバリデーション関数でアノテーションZIPを検証します。\nバリデーション関数は 'validate_' から始まる関数名で定義してください。"
|
|
@@ -3,14 +3,12 @@ import json
|
|
|
3
3
|
import logging
|
|
4
4
|
import multiprocessing
|
|
5
5
|
import sys
|
|
6
|
-
from typing import Any
|
|
6
|
+
from typing import Any
|
|
7
7
|
|
|
8
8
|
import annofabapi
|
|
9
|
-
import annofabapi.utils
|
|
10
9
|
import requests
|
|
11
10
|
from annofabapi.models import ProjectMemberRole, TaskStatus
|
|
12
11
|
|
|
13
|
-
import annofabcli
|
|
14
12
|
import annofabcli.common.cli
|
|
15
13
|
from annofabcli.common.cli import (
|
|
16
14
|
COMMAND_LINE_ERROR_STATUS_CODE,
|
|
@@ -106,7 +104,7 @@ class DeleteCommentMain(CommandLineWithConfirm):
|
|
|
106
104
|
self,
|
|
107
105
|
task_id: str,
|
|
108
106
|
comment_ids_for_task: DeletedCommentsForTask,
|
|
109
|
-
task_index:
|
|
107
|
+
task_index: int | None = None,
|
|
110
108
|
) -> int:
|
|
111
109
|
"""
|
|
112
110
|
タスクに対してコメントを削除します。
|
|
@@ -172,7 +170,7 @@ class DeleteCommentMain(CommandLineWithConfirm):
|
|
|
172
170
|
def delete_comments_for_task_list(
|
|
173
171
|
self,
|
|
174
172
|
comment_ids_for_task_list: DeletedComments,
|
|
175
|
-
parallelism:
|
|
173
|
+
parallelism: int | None = None,
|
|
176
174
|
) -> None:
|
|
177
175
|
comments_count = sum(len(e) for e in comment_ids_for_task_list.values())
|
|
178
176
|
logger.info(f"削除対象のコメントを含むタスクの個数: {len(comment_ids_for_task_list)}, 削除対象のコメントを含む入力データ数: {comments_count}")
|
|
@@ -260,7 +258,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
260
258
|
parser.set_defaults(subcommand_func=main)
|
|
261
259
|
|
|
262
260
|
|
|
263
|
-
def add_parser(subparsers:
|
|
261
|
+
def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
|
|
264
262
|
subcommand_name = "delete"
|
|
265
263
|
subcommand_help = "コメントを削除します。"
|
|
266
264
|
description = "コメントを削除します。\n【注意】他人の付けたコメントも削除できてしまいます。"
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import argparse
|
|
2
2
|
import logging
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
from typing import Optional
|
|
5
4
|
|
|
6
5
|
from annofabapi.models import ProjectMemberRole
|
|
7
6
|
|
|
8
|
-
import annofabcli
|
|
9
7
|
import annofabcli.common.cli
|
|
10
8
|
from annofabcli.common.cli import CommandLine, build_annofabapi_resource_and_login
|
|
11
9
|
from annofabcli.common.download import DownloadingFile
|
|
@@ -15,17 +13,17 @@ logger = logging.getLogger(__name__)
|
|
|
15
13
|
|
|
16
14
|
|
|
17
15
|
class DownloadingComment(CommandLine):
|
|
18
|
-
def download_comment_json(self, project_id: str, output_file: Path)
|
|
16
|
+
def download_comment_json(self, project_id: str, output_file: Path) -> None:
|
|
19
17
|
super().validate_project(project_id, [ProjectMemberRole.OWNER, ProjectMemberRole.TRAINING_DATA_USER])
|
|
20
18
|
project_title = self.facade.get_project_title(project_id)
|
|
21
|
-
logger.info(f"{project_title}
|
|
19
|
+
logger.info(f"project_id='{project_id}'のコメント全件ファイルをダウンロードします。 :: project_title='{project_title}'")
|
|
22
20
|
|
|
23
21
|
obj = DownloadingFile(self.service)
|
|
24
22
|
obj.download_comment_json(
|
|
25
23
|
project_id,
|
|
26
24
|
str(output_file),
|
|
27
25
|
)
|
|
28
|
-
logger.info(f"
|
|
26
|
+
logger.info(f"project_id='{project_id}'のコメント全件ファイルをダウンロードしました。 :: output='{output_file}', project_title='{project_title}'")
|
|
29
27
|
|
|
30
28
|
def main(self) -> None:
|
|
31
29
|
args = self.args
|
|
@@ -50,7 +48,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
50
48
|
parser.set_defaults(subcommand_func=main)
|
|
51
49
|
|
|
52
50
|
|
|
53
|
-
def add_parser(subparsers:
|
|
51
|
+
def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
|
|
54
52
|
subcommand_name = "download"
|
|
55
53
|
subcommand_help = "コメント全件ファイルをダウンロードします。"
|
|
56
54
|
epilog = "オーナロールまたはアノテーションユーザロールを持つユーザで実行してください。"
|
|
@@ -10,13 +10,12 @@ import logging
|
|
|
10
10
|
import tempfile
|
|
11
11
|
from collections.abc import Collection
|
|
12
12
|
from pathlib import Path
|
|
13
|
-
from typing import Any
|
|
13
|
+
from typing import Any
|
|
14
14
|
|
|
15
15
|
import annofabapi
|
|
16
16
|
import pandas
|
|
17
17
|
from annofabapi.models import CommentType
|
|
18
18
|
|
|
19
|
-
import annofabcli
|
|
20
19
|
import annofabcli.common.cli
|
|
21
20
|
from annofabcli.comment.list_comment import create_empty_df_comment, create_reply_counter
|
|
22
21
|
from annofabcli.common.cli import ArgumentParser, CommandLine, build_annofabapi_resource_and_login
|
|
@@ -36,9 +35,9 @@ class ListAllCommentMain:
|
|
|
36
35
|
def get_all_comment(
|
|
37
36
|
self,
|
|
38
37
|
project_id: str,
|
|
39
|
-
comment_json:
|
|
40
|
-
task_ids:
|
|
41
|
-
comment_type:
|
|
38
|
+
comment_json: Path | None,
|
|
39
|
+
task_ids: Collection[str] | None,
|
|
40
|
+
comment_type: CommentType | None,
|
|
42
41
|
exclude_reply: bool, # noqa: FBT001
|
|
43
42
|
) -> list[dict[str, Any]]:
|
|
44
43
|
if comment_json is None:
|
|
@@ -154,7 +153,7 @@ def main(args: argparse.Namespace) -> None:
|
|
|
154
153
|
ListAllComment(service, facade, args).main()
|
|
155
154
|
|
|
156
155
|
|
|
157
|
-
def add_parser(subparsers:
|
|
156
|
+
def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
|
|
158
157
|
subcommand_name = "list_all"
|
|
159
158
|
subcommand_help = "すべてのコメントの一覧を出力します。"
|
|
160
159
|
description = (
|
|
@@ -3,13 +3,12 @@ from __future__ import annotations
|
|
|
3
3
|
import argparse
|
|
4
4
|
import logging
|
|
5
5
|
from collections import Counter
|
|
6
|
-
from typing import Any
|
|
6
|
+
from typing import Any
|
|
7
7
|
|
|
8
8
|
import pandas
|
|
9
9
|
import requests
|
|
10
10
|
from annofabapi.models import Comment, CommentType
|
|
11
11
|
|
|
12
|
-
import annofabcli
|
|
13
12
|
import annofabcli.common.cli
|
|
14
13
|
from annofabcli.common.cli import ArgumentParser, CommandLine, build_annofabapi_resource_and_login
|
|
15
14
|
from annofabcli.common.enums import FormatArgument
|
|
@@ -61,7 +60,7 @@ class ListingComments(CommandLine):
|
|
|
61
60
|
c["reply_count"] = reply_counter.get(key, 0)
|
|
62
61
|
return comments
|
|
63
62
|
|
|
64
|
-
def get_comment_list(self, project_id: str, task_id_list: list[str], *, comment_type:
|
|
63
|
+
def get_comment_list(self, project_id: str, task_id_list: list[str], *, comment_type: CommentType | None, exclude_reply: bool) -> list[dict[str, Any]]:
|
|
65
64
|
all_comments: list[Comment] = []
|
|
66
65
|
|
|
67
66
|
for task_id in task_id_list:
|
|
@@ -151,7 +150,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
151
150
|
parser.set_defaults(subcommand_func=main)
|
|
152
151
|
|
|
153
152
|
|
|
154
|
-
def add_parser(subparsers:
|
|
153
|
+
def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
|
|
155
154
|
subcommand_name = "list"
|
|
156
155
|
subcommand_help = "コメント一覧を出力します。"
|
|
157
156
|
|
|
@@ -4,10 +4,9 @@ import logging
|
|
|
4
4
|
import multiprocessing
|
|
5
5
|
import uuid
|
|
6
6
|
from dataclasses import dataclass
|
|
7
|
-
from typing import Any
|
|
7
|
+
from typing import Any
|
|
8
8
|
|
|
9
9
|
import annofabapi
|
|
10
|
-
import annofabapi.utils
|
|
11
10
|
import requests
|
|
12
11
|
from annofabapi.models import CommentType, TaskPhase, TaskStatus
|
|
13
12
|
from dataclasses_json import DataClassJsonMixin
|
|
@@ -29,13 +28,13 @@ class AddedComment(DataClassJsonMixin):
|
|
|
29
28
|
comment: str
|
|
30
29
|
"""コメントの中身"""
|
|
31
30
|
|
|
32
|
-
data:
|
|
31
|
+
data: dict[str, Any] | None
|
|
33
32
|
"""コメントを付与する位置や区間"""
|
|
34
33
|
|
|
35
|
-
annotation_id:
|
|
34
|
+
annotation_id: str | None
|
|
36
35
|
"""コメントに紐付けるアノテーションID"""
|
|
37
36
|
|
|
38
|
-
phrases:
|
|
37
|
+
phrases: list[str] | None
|
|
39
38
|
"""参照している定型指摘ID"""
|
|
40
39
|
|
|
41
40
|
|
|
@@ -139,7 +138,7 @@ class PutCommentMain(CommandLineWithConfirm):
|
|
|
139
138
|
self,
|
|
140
139
|
task_id: str,
|
|
141
140
|
comments_for_task: AddedCommentsForTask,
|
|
142
|
-
task_index:
|
|
141
|
+
task_index: int | None = None,
|
|
143
142
|
) -> int:
|
|
144
143
|
"""
|
|
145
144
|
タスクにコメントを付与します。
|
|
@@ -207,7 +206,7 @@ class PutCommentMain(CommandLineWithConfirm):
|
|
|
207
206
|
def add_comments_for_task_list(
|
|
208
207
|
self,
|
|
209
208
|
comments_for_task_list: AddedComments,
|
|
210
|
-
parallelism:
|
|
209
|
+
parallelism: int | None = None,
|
|
211
210
|
) -> None:
|
|
212
211
|
comments_count = sum(len(e) for e in comments_for_task_list.values())
|
|
213
212
|
logger.info(f"{self.comment_type_name}を付与するタスク数: {len(comments_for_task_list)}, {self.comment_type_name}を付与する入力データ数: {comments_count}")
|
|
@@ -252,10 +251,10 @@ def convert_cli_comments(dict_comments: dict[str, Any], *, comment_type: Comment
|
|
|
252
251
|
data: dict[str, Any]
|
|
253
252
|
"""コメントを付与する位置や区間"""
|
|
254
253
|
|
|
255
|
-
annotation_id:
|
|
254
|
+
annotation_id: str | None = None
|
|
256
255
|
"""コメントに紐付けるアノテーションID"""
|
|
257
256
|
|
|
258
|
-
phrases:
|
|
257
|
+
phrases: list[str] | None = None
|
|
259
258
|
"""参照している定型指摘ID"""
|
|
260
259
|
|
|
261
260
|
@dataclass
|
|
@@ -267,7 +266,7 @@ def convert_cli_comments(dict_comments: dict[str, Any], *, comment_type: Comment
|
|
|
267
266
|
comment: str
|
|
268
267
|
"""コメントの中身"""
|
|
269
268
|
|
|
270
|
-
annotation_id:
|
|
269
|
+
annotation_id: str | None = None
|
|
271
270
|
"""コメントに紐付けるアノテーションID"""
|
|
272
271
|
|
|
273
272
|
def convert_inspection_comment(comment: dict[str, Any]) -> AddedComment:
|
|
@@ -4,10 +4,9 @@ import uuid
|
|
|
4
4
|
from collections.abc import Collection
|
|
5
5
|
from dataclasses import dataclass
|
|
6
6
|
from functools import partial
|
|
7
|
-
from typing import Any
|
|
7
|
+
from typing import Any
|
|
8
8
|
|
|
9
9
|
import annofabapi
|
|
10
|
-
import annofabapi.utils
|
|
11
10
|
from annofabapi.models import CommentType, TaskPhase, TaskStatus
|
|
12
11
|
|
|
13
12
|
from annofabcli.comment.utils import get_comment_type_name
|
|
@@ -26,10 +25,10 @@ class AddedSimpleComment:
|
|
|
26
25
|
comment: str
|
|
27
26
|
"""コメントの中身"""
|
|
28
27
|
|
|
29
|
-
data:
|
|
28
|
+
data: dict[str, Any] | None
|
|
30
29
|
"""コメントを付与する位置や区間"""
|
|
31
30
|
|
|
32
|
-
phrases:
|
|
31
|
+
phrases: list[str] | None = None
|
|
33
32
|
"""参照している定型指摘ID"""
|
|
34
33
|
|
|
35
34
|
|
|
@@ -103,7 +102,7 @@ class PutCommentSimplyMain(CommandLineWithConfirm):
|
|
|
103
102
|
self,
|
|
104
103
|
task_id: str,
|
|
105
104
|
comment_info: AddedSimpleComment,
|
|
106
|
-
task_index:
|
|
105
|
+
task_index: int | None = None,
|
|
107
106
|
) -> bool:
|
|
108
107
|
"""
|
|
109
108
|
タスクにコメントを付与します。
|
|
@@ -166,7 +165,7 @@ class PutCommentSimplyMain(CommandLineWithConfirm):
|
|
|
166
165
|
self,
|
|
167
166
|
task_ids: Collection[str],
|
|
168
167
|
comment_info: AddedSimpleComment,
|
|
169
|
-
parallelism:
|
|
168
|
+
parallelism: int | None = None,
|
|
170
169
|
) -> None:
|
|
171
170
|
logger.info(f"{len(task_ids)} 件のタスクに{self.comment_type_name}を付与します。")
|
|
172
171
|
|
|
@@ -4,11 +4,9 @@ import argparse
|
|
|
4
4
|
import json
|
|
5
5
|
import logging
|
|
6
6
|
import sys
|
|
7
|
-
from typing import Optional
|
|
8
7
|
|
|
9
8
|
from annofabapi.models import CommentType, ProjectMemberRole
|
|
10
9
|
|
|
11
|
-
import annofabcli
|
|
12
10
|
import annofabcli.common.cli
|
|
13
11
|
from annofabcli.comment.put_comment import PutCommentMain, convert_cli_comments
|
|
14
12
|
from annofabcli.common.cli import (
|
|
@@ -83,7 +81,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
83
81
|
parser.set_defaults(subcommand_func=main)
|
|
84
82
|
|
|
85
83
|
|
|
86
|
-
def add_parser(subparsers:
|
|
84
|
+
def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
|
|
87
85
|
subcommand_name = "put_inspection"
|
|
88
86
|
subcommand_help = "検査コメントを付与します"
|
|
89
87
|
description = "検査コメントを付与します。"
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import argparse
|
|
2
2
|
import logging
|
|
3
3
|
import sys
|
|
4
|
-
from typing import Optional
|
|
5
4
|
|
|
6
5
|
from annofabapi.models import CommentType, InputDataType, ProjectMemberRole
|
|
7
6
|
from annofabapi.plugin import EditorPluginId
|
|
8
7
|
|
|
9
|
-
import annofabcli
|
|
10
8
|
import annofabcli.common.cli
|
|
11
9
|
from annofabcli.comment.put_comment_simply import AddedSimpleComment, PutCommentSimplyMain
|
|
12
10
|
from annofabcli.common.cli import (
|
|
@@ -135,7 +133,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
135
133
|
parser.set_defaults(subcommand_func=main)
|
|
136
134
|
|
|
137
135
|
|
|
138
|
-
def add_parser(subparsers:
|
|
136
|
+
def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
|
|
139
137
|
subcommand_name = "put_inspection_simply"
|
|
140
138
|
subcommand_help = "``comment put_inspection`` コマンドよりも、簡単に検査コメントを付与します。"
|
|
141
139
|
epilog = "チェッカーロールまたはオーナロールを持つユーザで実行してください。"
|
|
@@ -2,11 +2,9 @@ import argparse
|
|
|
2
2
|
import json
|
|
3
3
|
import logging
|
|
4
4
|
import sys
|
|
5
|
-
from typing import Optional
|
|
6
5
|
|
|
7
6
|
from annofabapi.models import CommentType
|
|
8
7
|
|
|
9
|
-
import annofabcli
|
|
10
8
|
import annofabcli.common.cli
|
|
11
9
|
from annofabcli.comment.put_comment import PutCommentMain, convert_cli_comments
|
|
12
10
|
from annofabcli.common.cli import (
|
|
@@ -84,7 +82,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
84
82
|
parser.set_defaults(subcommand_func=main)
|
|
85
83
|
|
|
86
84
|
|
|
87
|
-
def add_parser(subparsers:
|
|
85
|
+
def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
|
|
88
86
|
subcommand_name = "put_onhold"
|
|
89
87
|
subcommand_help = "保留コメントを付与します"
|
|
90
88
|
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import argparse
|
|
2
2
|
import logging
|
|
3
3
|
import sys
|
|
4
|
-
from typing import Optional
|
|
5
4
|
|
|
6
5
|
from annofabapi.models import CommentType
|
|
7
6
|
|
|
8
|
-
import annofabcli
|
|
9
7
|
import annofabcli.common.cli
|
|
10
8
|
from annofabcli.comment.put_comment_simply import AddedSimpleComment, PutCommentSimplyMain
|
|
11
9
|
from annofabcli.common.cli import (
|
|
@@ -87,7 +85,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
87
85
|
parser.set_defaults(subcommand_func=main)
|
|
88
86
|
|
|
89
87
|
|
|
90
|
-
def add_parser(subparsers:
|
|
88
|
+
def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
|
|
91
89
|
subcommand_name = "put_onhold_simply"
|
|
92
90
|
subcommand_help = "``comment put_onhold`` コマンドよりも、簡単に保留コメントを付与します。"
|
|
93
91
|
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import argparse
|
|
2
|
-
from typing import Optional
|
|
3
2
|
|
|
4
|
-
import annofabcli
|
|
5
3
|
import annofabcli.comment.delete_comment
|
|
6
4
|
import annofabcli.comment.download_comment_json
|
|
7
5
|
import annofabcli.comment.list_all_comment
|
|
@@ -27,7 +25,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
27
25
|
annofabcli.comment.put_onhold_comment_simply.add_parser(subparsers)
|
|
28
26
|
|
|
29
27
|
|
|
30
|
-
def add_parser(subparsers:
|
|
28
|
+
def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
|
|
31
29
|
subcommand_name = "comment"
|
|
32
30
|
subcommand_help = "コメント関係のサブコマンド"
|
|
33
31
|
|