annofabcli 1.111.2__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 +2 -3
- 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/visualize_annotation_count.py +22 -23
- annofabcli/statistics/visualize_annotation_duration.py +21 -22
- annofabcli/statistics/visualize_statistics.py +36 -33
- 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.2.dist-info → annofabcli-1.112.0.dist-info}/METADATA +9 -15
- annofabcli-1.112.0.dist-info/RECORD +229 -0
- {annofabcli-1.111.2.dist-info → annofabcli-1.112.0.dist-info}/WHEEL +1 -1
- annofabcli-1.111.2.dist-info/RECORD +0 -228
- {annofabcli-1.111.2.dist-info → annofabcli-1.112.0.dist-info}/entry_points.txt +0 -0
- {annofabcli-1.111.2.dist-info → annofabcli-1.112.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -8,7 +8,7 @@ import tempfile
|
|
|
8
8
|
import zipfile
|
|
9
9
|
from collections.abc import Collection, Iterator
|
|
10
10
|
from pathlib import Path
|
|
11
|
-
from typing import Any, Literal
|
|
11
|
+
from typing import Any, Literal
|
|
12
12
|
|
|
13
13
|
import pandas
|
|
14
14
|
import pydantic
|
|
@@ -19,7 +19,6 @@ from annofabapi.parser import (
|
|
|
19
19
|
lazy_parse_simple_annotation_zip,
|
|
20
20
|
)
|
|
21
21
|
|
|
22
|
-
import annofabcli
|
|
23
22
|
import annofabcli.common.cli
|
|
24
23
|
from annofabcli.common.cli import (
|
|
25
24
|
COMMAND_LINE_ERROR_STATUS_CODE,
|
|
@@ -65,11 +64,11 @@ class AnnotationAttribute(pydantic.BaseModel):
|
|
|
65
64
|
|
|
66
65
|
input_data_id: str
|
|
67
66
|
input_data_name: str
|
|
68
|
-
updated_datetime:
|
|
67
|
+
updated_datetime: str | None
|
|
69
68
|
"""アノテーションJSONに格納されているアノテーションの更新日時"""
|
|
70
69
|
annotation_id: str
|
|
71
70
|
label: str
|
|
72
|
-
attributes: dict[str,
|
|
71
|
+
attributes: dict[str, str | int | bool]
|
|
73
72
|
|
|
74
73
|
|
|
75
74
|
def get_annotation_attribute_list_from_annotation_json(simple_annotation: dict[str, Any], *, target_labels: Collection[str] | None = None) -> list[AnnotationAttribute]:
|
|
@@ -109,8 +108,8 @@ def get_annotation_attribute_list_from_annotation_json(simple_annotation: dict[s
|
|
|
109
108
|
def get_annotation_attribute_list_from_annotation_zipdir_path(
|
|
110
109
|
annotation_zipdir_path: Path,
|
|
111
110
|
*,
|
|
112
|
-
target_task_ids:
|
|
113
|
-
task_query:
|
|
111
|
+
target_task_ids: Collection[str] | None = None,
|
|
112
|
+
task_query: TaskQuery | None = None,
|
|
114
113
|
target_labels: Collection[str] | None = None,
|
|
115
114
|
) -> list[AnnotationAttribute]:
|
|
116
115
|
"""
|
|
@@ -142,7 +141,7 @@ def get_annotation_attribute_list_from_annotation_zipdir_path(
|
|
|
142
141
|
return result
|
|
143
142
|
|
|
144
143
|
|
|
145
|
-
def print_annotation_attribute_list_as_csv(annotation_attribute_list: list, output_file:
|
|
144
|
+
def print_annotation_attribute_list_as_csv(annotation_attribute_list: list, output_file: Path | None) -> None:
|
|
146
145
|
df = pandas.json_normalize(annotation_attribute_list)
|
|
147
146
|
|
|
148
147
|
base_columns = [
|
|
@@ -197,7 +196,7 @@ class ListAnnotationAttribute(CommandLine):
|
|
|
197
196
|
if not self.validate(args):
|
|
198
197
|
sys.exit(COMMAND_LINE_ERROR_STATUS_CODE)
|
|
199
198
|
|
|
200
|
-
project_id:
|
|
199
|
+
project_id: str | None = args.project_id
|
|
201
200
|
if project_id is not None:
|
|
202
201
|
super().validate_project(project_id, project_member_roles=[ProjectMemberRole.OWNER, ProjectMemberRole.TRAINING_DATA_USER])
|
|
203
202
|
|
|
@@ -212,7 +211,7 @@ class ListAnnotationAttribute(CommandLine):
|
|
|
212
211
|
|
|
213
212
|
downloading_obj = DownloadingFile(self.service)
|
|
214
213
|
|
|
215
|
-
def download_and_print_annotation_attribute_list(project_id: str, temp_dir: Path, *, is_latest: bool, annotation_path:
|
|
214
|
+
def download_and_print_annotation_attribute_list(project_id: str, temp_dir: Path, *, is_latest: bool, annotation_path: Path | None) -> None:
|
|
216
215
|
if annotation_path is None:
|
|
217
216
|
annotation_path = temp_dir / f"{project_id}__annotation.zip"
|
|
218
217
|
downloading_obj.download_annotation_zip(
|
|
@@ -299,7 +298,7 @@ def main(args: argparse.Namespace) -> None:
|
|
|
299
298
|
ListAnnotationAttribute(service, facade, args).main()
|
|
300
299
|
|
|
301
300
|
|
|
302
|
-
def add_parser(subparsers:
|
|
301
|
+
def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
|
|
303
302
|
subcommand_name = "list_annotation_attribute"
|
|
304
303
|
subcommand_help = "アノテーションZIPを読み込み、アノテーションの属性値の一覧を出力します。"
|
|
305
304
|
epilog = "オーナロールまたはアノテーションユーザロールを持つユーザで実行してください。"
|
|
@@ -13,7 +13,7 @@ from dataclasses import dataclass, field
|
|
|
13
13
|
from enum import Enum
|
|
14
14
|
from functools import partial
|
|
15
15
|
from pathlib import Path
|
|
16
|
-
from typing import Any, Literal,
|
|
16
|
+
from typing import Any, Literal, Protocol
|
|
17
17
|
|
|
18
18
|
import annofabapi
|
|
19
19
|
import pandas
|
|
@@ -28,7 +28,6 @@ from annofabapi.pydantic_models.task_phase import TaskPhase
|
|
|
28
28
|
from annofabapi.pydantic_models.task_status import TaskStatus
|
|
29
29
|
from dataclasses_json import DataClassJsonMixin, config
|
|
30
30
|
|
|
31
|
-
import annofabcli
|
|
32
31
|
import annofabcli.common.cli
|
|
33
32
|
from annofabcli.common.cli import (
|
|
34
33
|
COMMAND_LINE_ERROR_STATUS_CODE,
|
|
@@ -108,7 +107,7 @@ class AnnotationCountByInputData(DataClassJsonMixin, HasAnnotationAttributeCount
|
|
|
108
107
|
|
|
109
108
|
input_data_id: str
|
|
110
109
|
input_data_name: str
|
|
111
|
-
updated_datetime:
|
|
110
|
+
updated_datetime: str | None
|
|
112
111
|
"""アノテーションJSONに格納されているアノテーションの更新日時"""
|
|
113
112
|
|
|
114
113
|
annotation_attribute_counts: dict[AttributeValueKey, int] = field(
|
|
@@ -119,7 +118,7 @@ class AnnotationCountByInputData(DataClassJsonMixin, HasAnnotationAttributeCount
|
|
|
119
118
|
"""属性値ごとのアノテーションの個数
|
|
120
119
|
key: tuple[ラベル名(英語),属性名(英語),属性値の種類], value: アノテーション数
|
|
121
120
|
"""
|
|
122
|
-
frame_no:
|
|
121
|
+
frame_no: int | None = None
|
|
123
122
|
"""フレーム番号(1始まり)。アノテーションJSONには含まれていない情報なので、Optionalにする"""
|
|
124
123
|
|
|
125
124
|
|
|
@@ -204,11 +203,11 @@ class ListAnnotationCounterByInputData:
|
|
|
204
203
|
def __init__(
|
|
205
204
|
self,
|
|
206
205
|
*,
|
|
207
|
-
target_labels:
|
|
208
|
-
non_target_labels:
|
|
209
|
-
target_attribute_names:
|
|
210
|
-
non_target_attribute_names:
|
|
211
|
-
frame_no_map:
|
|
206
|
+
target_labels: Collection[str] | None = None,
|
|
207
|
+
non_target_labels: Collection[str] | None = None,
|
|
208
|
+
target_attribute_names: Collection[AttributeNameKey] | None = None,
|
|
209
|
+
non_target_attribute_names: Collection[AttributeNameKey] | None = None,
|
|
210
|
+
frame_no_map: dict[tuple[str, str], int] | None = None,
|
|
212
211
|
) -> None:
|
|
213
212
|
self.target_labels = set(target_labels) if target_labels is not None else None
|
|
214
213
|
self.target_attribute_names = set(target_attribute_names) if target_attribute_names is not None else None
|
|
@@ -225,7 +224,7 @@ class ListAnnotationCounterByInputData:
|
|
|
225
224
|
|
|
226
225
|
"""
|
|
227
226
|
|
|
228
|
-
def convert_attribute_value_to_type(value:
|
|
227
|
+
def convert_attribute_value_to_type(value: bool | str | float | None) -> AttributeValueType: # noqa: FBT001
|
|
229
228
|
"""
|
|
230
229
|
アノテーションJSONに格納されている属性値を、dict用のkeyに変換する。
|
|
231
230
|
|
|
@@ -263,7 +262,7 @@ class ListAnnotationCounterByInputData:
|
|
|
263
262
|
attribute_key = (label, attribute_name, convert_attribute_value_to_type(attribute_value))
|
|
264
263
|
annotation_count_by_attribute[attribute_key] += 1
|
|
265
264
|
|
|
266
|
-
frame_no:
|
|
265
|
+
frame_no: int | None = None
|
|
267
266
|
if self.frame_no_map is not None:
|
|
268
267
|
frame_no = self.frame_no_map.get((simple_annotation["task_id"], simple_annotation["input_data_id"]))
|
|
269
268
|
|
|
@@ -284,8 +283,8 @@ class ListAnnotationCounterByInputData:
|
|
|
284
283
|
self,
|
|
285
284
|
annotation_path: Path,
|
|
286
285
|
*,
|
|
287
|
-
target_task_ids:
|
|
288
|
-
task_query:
|
|
286
|
+
target_task_ids: Collection[str] | None = None,
|
|
287
|
+
task_query: TaskQuery | None = None,
|
|
289
288
|
) -> list[AnnotationCountByInputData]:
|
|
290
289
|
"""
|
|
291
290
|
アノテーションzipまたはそれを展開したディレクトリから、属性値ごとのアノテーション数を取得する。
|
|
@@ -328,7 +327,7 @@ class AnnotationCountCsvByAttribute:
|
|
|
328
327
|
def __init__(self, selective_attribute_value_max_count: int = 20) -> None:
|
|
329
328
|
self.selective_attribute_value_max_count = selective_attribute_value_max_count
|
|
330
329
|
|
|
331
|
-
def _value_columns(self, annotation_count_list: Collection[HasAnnotationAttributeCounts], *, prior_attribute_columns:
|
|
330
|
+
def _value_columns(self, annotation_count_list: Collection[HasAnnotationAttributeCounts], *, prior_attribute_columns: list[tuple[str, str, str]] | None) -> list[tuple[str, str, str]]:
|
|
332
331
|
"""
|
|
333
332
|
CSVの数値列を取得します。
|
|
334
333
|
"""
|
|
@@ -347,7 +346,7 @@ class AnnotationCountCsvByAttribute:
|
|
|
347
346
|
def get_columns_by_input_data(
|
|
348
347
|
self,
|
|
349
348
|
annotation_count_list: list[AnnotationCountByInputData],
|
|
350
|
-
prior_attribute_columns:
|
|
349
|
+
prior_attribute_columns: list[tuple[str, str, str]] | None = None,
|
|
351
350
|
) -> list[tuple[str, str, str]]:
|
|
352
351
|
basic_columns = [
|
|
353
352
|
("project_id", "", ""),
|
|
@@ -366,7 +365,7 @@ class AnnotationCountCsvByAttribute:
|
|
|
366
365
|
def get_columns_by_task(
|
|
367
366
|
self,
|
|
368
367
|
annotation_count_list: list[AnnotationCountByTask],
|
|
369
|
-
prior_attribute_columns:
|
|
368
|
+
prior_attribute_columns: list[tuple[str, str, str]] | None = None,
|
|
370
369
|
) -> list[tuple[str, str, str]]:
|
|
371
370
|
basic_columns = [
|
|
372
371
|
("project_id", "", ""),
|
|
@@ -383,7 +382,7 @@ class AnnotationCountCsvByAttribute:
|
|
|
383
382
|
self,
|
|
384
383
|
annotation_count_list: list[AnnotationCountByInputData],
|
|
385
384
|
*,
|
|
386
|
-
prior_attribute_columns:
|
|
385
|
+
prior_attribute_columns: list[tuple[str, str, str]] | None = None,
|
|
387
386
|
) -> pandas.DataFrame:
|
|
388
387
|
def to_cell(c: AnnotationCountByInputData) -> dict[tuple[str, str, str], Any]:
|
|
389
388
|
cell: dict[tuple[str, str, str], Any] = {
|
|
@@ -413,7 +412,7 @@ class AnnotationCountCsvByAttribute:
|
|
|
413
412
|
self,
|
|
414
413
|
annotation_count_list: list[AnnotationCountByTask],
|
|
415
414
|
*,
|
|
416
|
-
prior_attribute_columns:
|
|
415
|
+
prior_attribute_columns: list[tuple[str, str, str]] | None = None,
|
|
417
416
|
) -> pandas.DataFrame:
|
|
418
417
|
def to_cell(c: AnnotationCountByTask) -> dict[tuple[str, str, str], Any]:
|
|
419
418
|
cell: dict[tuple[str, str, str], Any] = {
|
|
@@ -460,16 +459,16 @@ class ListAnnotationAttributeFilledCountMain:
|
|
|
460
459
|
def __init__(self, service: annofabapi.Resource) -> None:
|
|
461
460
|
self.service = service
|
|
462
461
|
|
|
463
|
-
def print_annotation_count_csv_by_input_data(self, annotation_count_list: list[AnnotationCountByInputData], output_file: Path, *, attribute_names:
|
|
464
|
-
attribute_columns:
|
|
462
|
+
def print_annotation_count_csv_by_input_data(self, annotation_count_list: list[AnnotationCountByInputData], output_file: Path, *, attribute_names: list[tuple[str, str]] | None) -> None:
|
|
463
|
+
attribute_columns: list[tuple[str, str, str]] | None = None
|
|
465
464
|
if attribute_names is not None:
|
|
466
465
|
attribute_columns = get_attribute_columns(attribute_names)
|
|
467
466
|
|
|
468
467
|
df = AnnotationCountCsvByAttribute().create_df_by_input_data(annotation_count_list, prior_attribute_columns=attribute_columns)
|
|
469
468
|
print_csv(df, output_file)
|
|
470
469
|
|
|
471
|
-
def print_annotation_count_csv_by_task(self, annotation_count_list: list[AnnotationCountByTask], output_file: Path, *, attribute_names:
|
|
472
|
-
attribute_columns:
|
|
470
|
+
def print_annotation_count_csv_by_task(self, annotation_count_list: list[AnnotationCountByTask], output_file: Path, *, attribute_names: list[tuple[str, str]] | None) -> None:
|
|
471
|
+
attribute_columns: list[tuple[str, str, str]] | None = None
|
|
473
472
|
if attribute_names is not None:
|
|
474
473
|
attribute_columns = get_attribute_columns(attribute_names)
|
|
475
474
|
|
|
@@ -483,14 +482,14 @@ class ListAnnotationAttributeFilledCountMain:
|
|
|
483
482
|
group_by: GroupBy,
|
|
484
483
|
output_format: FormatArgument,
|
|
485
484
|
*,
|
|
486
|
-
project_id:
|
|
485
|
+
project_id: str | None = None,
|
|
487
486
|
include_flag_attribute: bool = False,
|
|
488
|
-
task_json_path:
|
|
489
|
-
target_task_ids:
|
|
490
|
-
task_query:
|
|
487
|
+
task_json_path: Path | None = None,
|
|
488
|
+
target_task_ids: Collection[str] | None = None,
|
|
489
|
+
task_query: TaskQuery | None = None,
|
|
491
490
|
) -> None:
|
|
492
|
-
annotation_specs:
|
|
493
|
-
target_attribute_names:
|
|
491
|
+
annotation_specs: AnnotationSpecs | None = None
|
|
492
|
+
target_attribute_names: list[AttributeNameKey] | None = None
|
|
494
493
|
if project_id is not None:
|
|
495
494
|
annotation_specs = AnnotationSpecs(self.service, project_id)
|
|
496
495
|
if not include_flag_attribute:
|
|
@@ -555,7 +554,7 @@ class ListAnnotationAttributeFilledCount(CommandLine):
|
|
|
555
554
|
if not self.validate(args):
|
|
556
555
|
sys.exit(COMMAND_LINE_ERROR_STATUS_CODE)
|
|
557
556
|
|
|
558
|
-
project_id:
|
|
557
|
+
project_id: str | None = args.project_id
|
|
559
558
|
if project_id is not None:
|
|
560
559
|
super().validate_project(project_id, project_member_roles=[ProjectMemberRole.OWNER, ProjectMemberRole.TRAINING_DATA_USER])
|
|
561
560
|
|
|
@@ -571,7 +570,7 @@ class ListAnnotationAttributeFilledCount(CommandLine):
|
|
|
571
570
|
|
|
572
571
|
downloading_obj = DownloadingFile(self.service)
|
|
573
572
|
|
|
574
|
-
def download_and_process_annotation(temp_dir: Path, *, is_latest: bool, annotation_path:
|
|
573
|
+
def download_and_process_annotation(temp_dir: Path, *, is_latest: bool, annotation_path: Path | None) -> None:
|
|
575
574
|
# タスク全件ファイルは、フレーム番号を参照するのに利用する
|
|
576
575
|
if project_id is not None and group_by == GroupBy.INPUT_DATA_ID:
|
|
577
576
|
# group_byで条件を絞り込んでいる理由:
|
|
@@ -699,7 +698,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
|
|
|
699
698
|
parser.set_defaults(subcommand_func=main)
|
|
700
699
|
|
|
701
700
|
|
|
702
|
-
def add_parser(subparsers:
|
|
701
|
+
def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
|
|
703
702
|
subcommand_name = "list_annotation_attribute_filled_count"
|
|
704
703
|
subcommand_help = "値が入力されている属性の個数を、タスクごとまたは入力データごとに集計します。"
|
|
705
704
|
|
|
@@ -16,7 +16,7 @@ from dataclasses import dataclass, field
|
|
|
16
16
|
from enum import Enum
|
|
17
17
|
from functools import partial
|
|
18
18
|
from pathlib import Path
|
|
19
|
-
from typing import Any
|
|
19
|
+
from typing import Any
|
|
20
20
|
|
|
21
21
|
import annofabapi
|
|
22
22
|
import pandas
|
|
@@ -32,7 +32,6 @@ from annofabapi.parser import (
|
|
|
32
32
|
from annofabapi.pydantic_models.additional_data_definition_type import AdditionalDataDefinitionType
|
|
33
33
|
from dataclasses_json import DataClassJsonMixin, config
|
|
34
34
|
|
|
35
|
-
import annofabcli
|
|
36
35
|
import annofabcli.common.cli
|
|
37
36
|
from annofabcli.common.cli import (
|
|
38
37
|
COMMAND_LINE_ERROR_STATUS_CODE,
|
|
@@ -133,9 +132,9 @@ class AnnotationCounterByInputData(AnnotationCounter, DataClassJsonMixin):
|
|
|
133
132
|
|
|
134
133
|
input_data_id: str
|
|
135
134
|
input_data_name: str
|
|
136
|
-
updated_datetime:
|
|
135
|
+
updated_datetime: str | None
|
|
137
136
|
"""アノテーションJSONに格納されているアノテーションの更新日時"""
|
|
138
|
-
frame_no:
|
|
137
|
+
frame_no: int | None = None
|
|
139
138
|
"""アノテーションJSONには含まれていない情報なので、Optionalにする"""
|
|
140
139
|
|
|
141
140
|
|
|
@@ -178,11 +177,11 @@ class ListAnnotationCounterByInputData:
|
|
|
178
177
|
def __init__(
|
|
179
178
|
self,
|
|
180
179
|
*,
|
|
181
|
-
target_labels:
|
|
182
|
-
non_target_labels:
|
|
183
|
-
target_attribute_names:
|
|
184
|
-
non_target_attribute_names:
|
|
185
|
-
frame_no_map:
|
|
180
|
+
target_labels: Collection[str] | None = None,
|
|
181
|
+
non_target_labels: Collection[str] | None = None,
|
|
182
|
+
target_attribute_names: Collection[AttributeNameKey] | None = None,
|
|
183
|
+
non_target_attribute_names: Collection[AttributeNameKey] | None = None,
|
|
184
|
+
frame_no_map: dict[tuple[str, str], int] | None = None,
|
|
186
185
|
) -> None:
|
|
187
186
|
self.target_labels = set(target_labels) if target_labels is not None else None
|
|
188
187
|
self.target_attribute_names = set(target_attribute_names) if target_attribute_names is not None else None
|
|
@@ -201,7 +200,7 @@ class ListAnnotationCounterByInputData:
|
|
|
201
200
|
simple_annotation: JSONファイルの内容
|
|
202
201
|
"""
|
|
203
202
|
|
|
204
|
-
def convert_attribute_value_to_key(value:
|
|
203
|
+
def convert_attribute_value_to_key(value: bool | str | float) -> str: # noqa: FBT001
|
|
205
204
|
"""
|
|
206
205
|
アノテーションJSONに格納されている属性値を、dict用のkeyに変換する。
|
|
207
206
|
|
|
@@ -253,7 +252,7 @@ class ListAnnotationCounterByInputData:
|
|
|
253
252
|
|
|
254
253
|
task_id = simple_annotation["task_id"]
|
|
255
254
|
input_data_id = simple_annotation["input_data_id"]
|
|
256
|
-
frame_no:
|
|
255
|
+
frame_no: int | None = None
|
|
257
256
|
if self.frame_no_map is not None:
|
|
258
257
|
frame_no = self.frame_no_map.get((task_id, input_data_id))
|
|
259
258
|
|
|
@@ -276,8 +275,8 @@ class ListAnnotationCounterByInputData:
|
|
|
276
275
|
self,
|
|
277
276
|
annotation_path: Path,
|
|
278
277
|
*,
|
|
279
|
-
target_task_ids:
|
|
280
|
-
task_query:
|
|
278
|
+
target_task_ids: Collection[str] | None = None,
|
|
279
|
+
task_query: TaskQuery | None = None,
|
|
281
280
|
) -> list[AnnotationCounterByInputData]:
|
|
282
281
|
"""
|
|
283
282
|
アノテーションzipまたはそれを展開したディレクトリから、ラベルごと/属性ごとのアノテーション数を集計情報を取得する。
|
|
@@ -315,10 +314,10 @@ class ListAnnotationCounterByTask:
|
|
|
315
314
|
def __init__(
|
|
316
315
|
self,
|
|
317
316
|
*,
|
|
318
|
-
target_labels:
|
|
319
|
-
non_target_labels:
|
|
320
|
-
target_attribute_names:
|
|
321
|
-
non_target_attribute_names:
|
|
317
|
+
target_labels: Collection[str] | None = None,
|
|
318
|
+
non_target_labels: Collection[str] | None = None,
|
|
319
|
+
target_attribute_names: Collection[AttributeNameKey] | None = None,
|
|
320
|
+
non_target_attribute_names: Collection[AttributeNameKey] | None = None,
|
|
322
321
|
) -> None:
|
|
323
322
|
self.counter_by_input_data = ListAnnotationCounterByInputData(
|
|
324
323
|
target_labels=target_labels,
|
|
@@ -372,8 +371,8 @@ class ListAnnotationCounterByTask:
|
|
|
372
371
|
self,
|
|
373
372
|
annotation_path: Path,
|
|
374
373
|
*,
|
|
375
|
-
target_task_ids:
|
|
376
|
-
task_query:
|
|
374
|
+
target_task_ids: Collection[str] | None = None,
|
|
375
|
+
task_query: TaskQuery | None = None,
|
|
377
376
|
) -> list[AnnotationCounterByTask]:
|
|
378
377
|
"""
|
|
379
378
|
アノテーションzipまたはそれを展開したディレクトリから、ラベルごと/属性ごとのアノテーション数を集計情報を取得する。
|
|
@@ -437,7 +436,7 @@ class AttributeCountCsv:
|
|
|
437
436
|
|
|
438
437
|
return [(label, attribute_name, attribute_value) for (label, attribute_name, attribute_value) in columns if (label, attribute_name) not in non_selective_attribute_names]
|
|
439
438
|
|
|
440
|
-
def _value_columns(self, counter_list: Collection[AnnotationCounter], prior_attribute_columns:
|
|
439
|
+
def _value_columns(self, counter_list: Collection[AnnotationCounter], prior_attribute_columns: list[AttributeValueKey] | None) -> list[AttributeValueKey]:
|
|
441
440
|
all_attr_key_set = {attr_key for c in counter_list for attr_key in c.annotation_count_by_attribute}
|
|
442
441
|
if prior_attribute_columns is not None:
|
|
443
442
|
remaining_columns = sorted(all_attr_key_set - set(prior_attribute_columns))
|
|
@@ -471,7 +470,7 @@ class AttributeCountCsv:
|
|
|
471
470
|
self,
|
|
472
471
|
counter_list: list[AnnotationCounterByTask],
|
|
473
472
|
output_file: Path,
|
|
474
|
-
prior_attribute_columns:
|
|
473
|
+
prior_attribute_columns: list[AttributeValueKey] | None = None,
|
|
475
474
|
) -> None:
|
|
476
475
|
def get_columns() -> list[AttributeValueKey]:
|
|
477
476
|
basic_columns = [
|
|
@@ -511,7 +510,7 @@ class AttributeCountCsv:
|
|
|
511
510
|
self,
|
|
512
511
|
counter_list: list[AnnotationCounterByInputData],
|
|
513
512
|
output_file: Path,
|
|
514
|
-
prior_attribute_columns:
|
|
513
|
+
prior_attribute_columns: list[AttributeValueKey] | None = None,
|
|
515
514
|
) -> None:
|
|
516
515
|
def get_columns() -> list[AttributeValueKey]:
|
|
517
516
|
basic_columns = [
|
|
@@ -563,7 +562,7 @@ class LabelCountCsv:
|
|
|
563
562
|
|
|
564
563
|
"""
|
|
565
564
|
|
|
566
|
-
def _value_columns(self, counter_list: Collection[AnnotationCounter], prior_label_columns:
|
|
565
|
+
def _value_columns(self, counter_list: Collection[AnnotationCounter], prior_label_columns: list[str] | None) -> list[str]:
|
|
567
566
|
all_attr_key_set = {attr_key for c in counter_list for attr_key in c.annotation_count_by_label}
|
|
568
567
|
if prior_label_columns is not None:
|
|
569
568
|
remaining_columns = sorted(all_attr_key_set - set(prior_label_columns))
|
|
@@ -578,7 +577,7 @@ class LabelCountCsv:
|
|
|
578
577
|
self,
|
|
579
578
|
counter_list: list[AnnotationCounterByTask],
|
|
580
579
|
output_file: Path,
|
|
581
|
-
prior_label_columns:
|
|
580
|
+
prior_label_columns: list[str] | None = None,
|
|
582
581
|
) -> None:
|
|
583
582
|
def get_columns() -> list[str]:
|
|
584
583
|
basic_columns = [
|
|
@@ -618,7 +617,7 @@ class LabelCountCsv:
|
|
|
618
617
|
self,
|
|
619
618
|
counter_list: list[AnnotationCounterByInputData],
|
|
620
619
|
output_file: Path,
|
|
621
|
-
prior_label_columns:
|
|
620
|
+
prior_label_columns: list[str] | None = None,
|
|
622
621
|
) -> None:
|
|
623
622
|
def get_columns() -> list[str]:
|
|
624
623
|
basic_columns = [
|
|
@@ -670,7 +669,7 @@ class AnnotationSpecs:
|
|
|
670
669
|
|
|
671
670
|
"""
|
|
672
671
|
|
|
673
|
-
def __init__(self, service: annofabapi.Resource, project_id: str, *, annotation_type:
|
|
672
|
+
def __init__(self, service: annofabapi.Resource, project_id: str, *, annotation_type: str | None = None) -> None:
|
|
674
673
|
self.service = service
|
|
675
674
|
self.project_id = project_id
|
|
676
675
|
|
|
@@ -699,8 +698,8 @@ class AnnotationSpecs:
|
|
|
699
698
|
|
|
700
699
|
def attribute_name_keys(
|
|
701
700
|
self,
|
|
702
|
-
excluded_attribute_types:
|
|
703
|
-
include_attribute_types:
|
|
701
|
+
excluded_attribute_types: Collection[AdditionalDataDefinitionType] | None = None,
|
|
702
|
+
include_attribute_types: Collection[AdditionalDataDefinitionType] | None = None,
|
|
704
703
|
) -> list[tuple[str, str]]:
|
|
705
704
|
"""
|
|
706
705
|
属性名の一覧を取得します。
|
|
@@ -858,14 +857,14 @@ class ListAnnotationCountMain:
|
|
|
858
857
|
csv_type: CsvType,
|
|
859
858
|
output_file: Path,
|
|
860
859
|
*,
|
|
861
|
-
project_id:
|
|
862
|
-
task_json_path:
|
|
863
|
-
target_task_ids:
|
|
864
|
-
task_query:
|
|
860
|
+
project_id: str | None = None,
|
|
861
|
+
task_json_path: Path | None = None,
|
|
862
|
+
target_task_ids: Collection[str] | None = None,
|
|
863
|
+
task_query: TaskQuery | None = None,
|
|
865
864
|
) -> None:
|
|
866
865
|
# アノテーション仕様の非選択系の属性は、集計しないようにする。集計しても意味がないため。
|
|
867
|
-
annotation_specs:
|
|
868
|
-
non_selective_attribute_name_keys:
|
|
866
|
+
annotation_specs: AnnotationSpecs | None = None
|
|
867
|
+
non_selective_attribute_name_keys: list[AttributeNameKey] | None = None
|
|
869
868
|
if project_id is not None:
|
|
870
869
|
annotation_specs = AnnotationSpecs(self.service, project_id)
|
|
871
870
|
non_selective_attribute_name_keys = annotation_specs.non_selective_attribute_name_keys()
|
|
@@ -880,13 +879,13 @@ class ListAnnotationCountMain:
|
|
|
880
879
|
|
|
881
880
|
if csv_type == CsvType.LABEL:
|
|
882
881
|
# ラベル名の列順が、アノテーション仕様にあるラベル名の順番に対応するようにする。
|
|
883
|
-
label_columns:
|
|
882
|
+
label_columns: list[str] | None = None
|
|
884
883
|
if annotation_specs is not None:
|
|
885
884
|
label_columns = annotation_specs.label_keys()
|
|
886
885
|
|
|
887
886
|
LabelCountCsv().print_csv_by_input_data(counter_list_by_input_data, output_file, prior_label_columns=label_columns)
|
|
888
887
|
elif csv_type == CsvType.ATTRIBUTE:
|
|
889
|
-
attribute_columns:
|
|
888
|
+
attribute_columns: list[AttributeValueKey] | None = None
|
|
890
889
|
if annotation_specs is not None:
|
|
891
890
|
attribute_columns = annotation_specs.selective_attribute_value_keys()
|
|
892
891
|
|
|
@@ -898,13 +897,13 @@ class ListAnnotationCountMain:
|
|
|
898
897
|
csv_type: CsvType,
|
|
899
898
|
output_file: Path,
|
|
900
899
|
*,
|
|
901
|
-
project_id:
|
|
902
|
-
target_task_ids:
|
|
903
|
-
task_query:
|
|
900
|
+
project_id: str | None = None,
|
|
901
|
+
target_task_ids: Collection[str] | None = None,
|
|
902
|
+
task_query: TaskQuery | None = None,
|
|
904
903
|
) -> None:
|
|
905
904
|
# アノテーション仕様の非選択系の属性は、集計しないようにする。集計しても意味がないため。
|
|
906
|
-
annotation_specs:
|
|
907
|
-
non_selective_attribute_name_keys:
|
|
905
|
+
annotation_specs: AnnotationSpecs | None = None
|
|
906
|
+
non_selective_attribute_name_keys: list[AttributeNameKey] | None = None
|
|
908
907
|
if project_id is not None:
|
|
909
908
|
annotation_specs = AnnotationSpecs(self.service, project_id)
|
|
910
909
|
non_selective_attribute_name_keys = annotation_specs.non_selective_attribute_name_keys()
|
|
@@ -917,7 +916,7 @@ class ListAnnotationCountMain:
|
|
|
917
916
|
|
|
918
917
|
if csv_type == CsvType.LABEL:
|
|
919
918
|
# 列順が、アノテーション仕様にあるラベル名の順番に対応するようにする。
|
|
920
|
-
label_columns:
|
|
919
|
+
label_columns: list[str] | None = None
|
|
921
920
|
if annotation_specs is not None:
|
|
922
921
|
label_columns = annotation_specs.label_keys()
|
|
923
922
|
|
|
@@ -925,7 +924,7 @@ class ListAnnotationCountMain:
|
|
|
925
924
|
|
|
926
925
|
elif csv_type == CsvType.ATTRIBUTE:
|
|
927
926
|
# 列順が、アノテーション仕様にある属性名と属性値の順番に対応するようにする。
|
|
928
|
-
attribute_columns:
|
|
927
|
+
attribute_columns: list[AttributeValueKey] | None = None
|
|
929
928
|
if annotation_specs is not None:
|
|
930
929
|
attribute_columns = annotation_specs.selective_attribute_value_keys()
|
|
931
930
|
|
|
@@ -936,10 +935,10 @@ class ListAnnotationCountMain:
|
|
|
936
935
|
annotation_path: Path,
|
|
937
936
|
output_file: Path,
|
|
938
937
|
*,
|
|
939
|
-
project_id:
|
|
940
|
-
task_json_path:
|
|
941
|
-
target_task_ids:
|
|
942
|
-
task_query:
|
|
938
|
+
project_id: str | None = None,
|
|
939
|
+
task_json_path: Path | None = None,
|
|
940
|
+
target_task_ids: Collection[str] | None = None,
|
|
941
|
+
task_query: TaskQuery | None = None,
|
|
943
942
|
json_is_pretty: bool = False,
|
|
944
943
|
) -> None:
|
|
945
944
|
"""ラベルごと/属性ごとのアノテーション数を入力データ単位でJSONファイルに出力します。"""
|
|
@@ -969,9 +968,9 @@ class ListAnnotationCountMain:
|
|
|
969
968
|
annotation_path: Path,
|
|
970
969
|
output_file: Path,
|
|
971
970
|
*,
|
|
972
|
-
project_id:
|
|
973
|
-
target_task_ids:
|
|
974
|
-
task_query:
|
|
971
|
+
project_id: str | None = None,
|
|
972
|
+
target_task_ids: Collection[str] | None = None,
|
|
973
|
+
task_query: TaskQuery | None = None,
|
|
975
974
|
json_is_pretty: bool = False,
|
|
976
975
|
) -> None:
|
|
977
976
|
"""ラベルごと/属性ごとのアノテーション数をタスク単位でJSONファイルに出力します。"""
|
|
@@ -1004,11 +1003,11 @@ class ListAnnotationCountMain:
|
|
|
1004
1003
|
output_file: Path,
|
|
1005
1004
|
arg_format: FormatArgument,
|
|
1006
1005
|
*,
|
|
1007
|
-
project_id:
|
|
1008
|
-
task_json_path:
|
|
1009
|
-
target_task_ids:
|
|
1010
|
-
task_query:
|
|
1011
|
-
csv_type:
|
|
1006
|
+
project_id: str | None = None,
|
|
1007
|
+
task_json_path: Path | None = None,
|
|
1008
|
+
target_task_ids: Collection[str] | None = None,
|
|
1009
|
+
task_query: TaskQuery | None = None,
|
|
1010
|
+
csv_type: CsvType | None = None,
|
|
1012
1011
|
) -> None:
|
|
1013
1012
|
"""ラベルごと/属性ごとのアノテーション数を出力します。"""
|
|
1014
1013
|
if arg_format == FormatArgument.CSV:
|
|
@@ -1082,7 +1081,7 @@ class ListAnnotationCount(CommandLine):
|
|
|
1082
1081
|
if not self.validate(args):
|
|
1083
1082
|
sys.exit(COMMAND_LINE_ERROR_STATUS_CODE)
|
|
1084
1083
|
|
|
1085
|
-
project_id:
|
|
1084
|
+
project_id: str | None = args.project_id
|
|
1086
1085
|
if project_id is not None:
|
|
1087
1086
|
super().validate_project(project_id, project_member_roles=[ProjectMemberRole.OWNER, ProjectMemberRole.TRAINING_DATA_USER])
|
|
1088
1087
|
|
|
@@ -1099,7 +1098,7 @@ class ListAnnotationCount(CommandLine):
|
|
|
1099
1098
|
|
|
1100
1099
|
downloading_obj = DownloadingFile(self.service)
|
|
1101
1100
|
|
|
1102
|
-
def download_and_process_annotation(temp_dir: Path, *, is_latest: bool, annotation_path:
|
|
1101
|
+
def download_and_process_annotation(temp_dir: Path, *, is_latest: bool, annotation_path: Path | None) -> None:
|
|
1103
1102
|
# タスク全件ファイルは、フレーム番号を参照するのに利用する
|
|
1104
1103
|
if project_id is not None:
|
|
1105
1104
|
task_json_path = downloading_obj.download_task_json_to_dir(
|
|
@@ -1228,7 +1227,7 @@ def main(args: argparse.Namespace) -> None:
|
|
|
1228
1227
|
ListAnnotationCount(service, facade, args).main()
|
|
1229
1228
|
|
|
1230
1229
|
|
|
1231
|
-
def add_parser(subparsers:
|
|
1230
|
+
def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
|
|
1232
1231
|
subcommand_name = "list_annotation_count"
|
|
1233
1232
|
subcommand_help = "ラベルごとまたは属性値ごとにアノテーション数を出力します。"
|
|
1234
1233
|
epilog = "オーナロールまたはアノテーションユーザロールを持つユーザで実行してください。"
|