annofabcli 1.111.2__py3-none-any.whl → 1.113.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.
Files changed (186) hide show
  1. annofabcli/__main__.py +1 -2
  2. annofabcli/annotation/annotation_query.py +10 -10
  3. annofabcli/annotation/change_annotation_attributes.py +10 -10
  4. annofabcli/annotation/change_annotation_attributes_per_annotation.py +4 -5
  5. annofabcli/annotation/change_annotation_properties.py +14 -14
  6. annofabcli/annotation/copy_annotation.py +6 -6
  7. annofabcli/annotation/create_classification_annotation.py +7 -7
  8. annofabcli/annotation/delete_annotation.py +9 -9
  9. annofabcli/annotation/download_annotation_zip.py +1 -3
  10. annofabcli/annotation/dump_annotation.py +8 -8
  11. annofabcli/annotation/import_annotation.py +13 -13
  12. annofabcli/annotation/list_annotation.py +9 -9
  13. annofabcli/annotation/list_annotation_count.py +2 -3
  14. annofabcli/annotation/merge_segmentation.py +6 -6
  15. annofabcli/annotation/remove_segmentation_overlap.py +5 -5
  16. annofabcli/annotation/restore_annotation.py +7 -7
  17. annofabcli/annotation/subcommand_annotation.py +1 -2
  18. annofabcli/annotation_specs/add_attribute_restriction.py +4 -5
  19. annofabcli/annotation_specs/attribute_restriction.py +8 -8
  20. annofabcli/annotation_specs/export_annotation_specs.py +4 -5
  21. annofabcli/annotation_specs/get_annotation_specs_with_attribute_id_replaced.py +3 -4
  22. annofabcli/annotation_specs/get_annotation_specs_with_choice_id_replaced.py +3 -4
  23. annofabcli/annotation_specs/get_annotation_specs_with_label_id_replaced.py +3 -4
  24. annofabcli/annotation_specs/list_annotation_specs_attribute.py +9 -10
  25. annofabcli/annotation_specs/list_annotation_specs_choice.py +9 -10
  26. annofabcli/annotation_specs/list_annotation_specs_history.py +3 -3
  27. annofabcli/annotation_specs/list_annotation_specs_label.py +8 -9
  28. annofabcli/annotation_specs/list_annotation_specs_label_attribute.py +10 -11
  29. annofabcli/annotation_specs/list_attribute_restriction.py +2 -4
  30. annofabcli/annotation_specs/list_label_color.py +2 -3
  31. annofabcli/annotation_specs/put_label_color.py +3 -4
  32. annofabcli/annotation_specs/subcommand_annotation_specs.py +1 -3
  33. annofabcli/annotation_zip/list_annotation_3d_bounding_box.py +365 -0
  34. annofabcli/annotation_zip/list_annotation_bounding_box_2d.py +37 -38
  35. annofabcli/annotation_zip/list_polygon_annotation.py +390 -0
  36. annofabcli/annotation_zip/list_polyline_annotation.py +402 -0
  37. annofabcli/annotation_zip/list_range_annotation.py +25 -15
  38. annofabcli/annotation_zip/list_single_point_annotation.py +25 -34
  39. annofabcli/annotation_zip/subcommand_annotation_zip.py +7 -2
  40. annofabcli/annotation_zip/validate_annotation.py +8 -7
  41. annofabcli/comment/delete_comment.py +4 -6
  42. annofabcli/comment/download_comment_json.py +4 -6
  43. annofabcli/comment/list_all_comment.py +5 -6
  44. annofabcli/comment/list_comment.py +3 -4
  45. annofabcli/comment/put_comment.py +9 -10
  46. annofabcli/comment/put_comment_simply.py +5 -6
  47. annofabcli/comment/put_inspection_comment.py +1 -3
  48. annofabcli/comment/put_inspection_comment_simply.py +1 -3
  49. annofabcli/comment/put_onhold_comment.py +1 -3
  50. annofabcli/comment/put_onhold_comment_simply.py +1 -3
  51. annofabcli/comment/subcommand_comment.py +1 -3
  52. annofabcli/common/bokeh.py +4 -4
  53. annofabcli/common/cli.py +18 -17
  54. annofabcli/common/download.py +28 -29
  55. annofabcli/common/facade.py +37 -38
  56. annofabcli/common/image.py +14 -14
  57. annofabcli/common/utils.py +8 -8
  58. annofabcli/common/visualize.py +13 -13
  59. annofabcli/experimental/list_out_of_range_annotation_for_movie.py +3 -4
  60. annofabcli/experimental/subcommand_experimental.py +1 -3
  61. annofabcli/filesystem/draw_annotation.py +27 -27
  62. annofabcli/filesystem/filter_annotation.py +9 -10
  63. annofabcli/filesystem/mask_user_info.py +15 -15
  64. annofabcli/filesystem/merge_annotation.py +9 -9
  65. annofabcli/filesystem/subcommand_filesystem.py +1 -3
  66. annofabcli/input_data/copy_input_data.py +8 -9
  67. annofabcli/input_data/delete_input_data.py +3 -3
  68. annofabcli/input_data/delete_metadata_key_of_input_data.py +3 -5
  69. annofabcli/input_data/download_input_data_json.py +4 -6
  70. annofabcli/input_data/list_all_input_data.py +9 -9
  71. annofabcli/input_data/list_all_input_data_merged_task.py +5 -5
  72. annofabcli/input_data/list_input_data.py +5 -5
  73. annofabcli/input_data/put_input_data.py +6 -6
  74. annofabcli/input_data/put_input_data_with_zip.py +3 -4
  75. annofabcli/input_data/subcommand_input_data.py +1 -3
  76. annofabcli/input_data/update_input_data.py +6 -8
  77. annofabcli/input_data/update_metadata_of_input_data.py +3 -5
  78. annofabcli/instruction/copy_instruction.py +5 -6
  79. annofabcli/instruction/download_instruction.py +5 -6
  80. annofabcli/instruction/list_instruction_history.py +3 -3
  81. annofabcli/instruction/subcommand_instruction.py +1 -3
  82. annofabcli/instruction/upload_instruction.py +3 -4
  83. annofabcli/job/delete_job.py +2 -3
  84. annofabcli/job/list_job.py +5 -5
  85. annofabcli/job/list_last_job.py +4 -4
  86. annofabcli/job/subcommand_job.py +1 -3
  87. annofabcli/job/wait_job.py +4 -5
  88. annofabcli/my_account/get_my_account.py +2 -3
  89. annofabcli/my_account/subcommand_my_account.py +1 -3
  90. annofabcli/organization/list_organization.py +2 -3
  91. annofabcli/organization/subcommand_organization.py +1 -3
  92. annofabcli/organization_member/change_organization_member.py +3 -4
  93. annofabcli/organization_member/delete_organization_member.py +3 -4
  94. annofabcli/organization_member/invite_organization_member.py +1 -3
  95. annofabcli/organization_member/list_organization_member.py +3 -3
  96. annofabcli/organization_member/subcommand_organization_member.py +1 -3
  97. annofabcli/project/change_organization_of_project.py +4 -4
  98. annofabcli/project/change_project_status.py +4 -4
  99. annofabcli/project/copy_project.py +5 -5
  100. annofabcli/project/create_project.py +8 -8
  101. annofabcli/project/diff_projects.py +4 -5
  102. annofabcli/project/list_project.py +5 -5
  103. annofabcli/project/put_project.py +2 -3
  104. annofabcli/project/subcommand_project.py +1 -2
  105. annofabcli/project/update_configuration.py +4 -4
  106. annofabcli/project/update_project.py +6 -8
  107. annofabcli/project_member/change_project_members.py +8 -8
  108. annofabcli/project_member/copy_project_members.py +4 -4
  109. annofabcli/project_member/drop_project_members.py +2 -3
  110. annofabcli/project_member/invite_project_members.py +1 -3
  111. annofabcli/project_member/list_users.py +2 -3
  112. annofabcli/project_member/put_project_members.py +6 -6
  113. annofabcli/project_member/subcommand_project_member.py +1 -3
  114. annofabcli/stat_visualization/mask_visualization_dir.py +8 -9
  115. annofabcli/stat_visualization/merge_visualization_dir.py +6 -7
  116. annofabcli/stat_visualization/subcommand_stat_visualization.py +1 -2
  117. annofabcli/stat_visualization/summarize_whole_performance_csv.py +1 -2
  118. annofabcli/stat_visualization/write_graph.py +2 -3
  119. annofabcli/stat_visualization/write_performance_rating_csv.py +20 -27
  120. annofabcli/statistics/histogram.py +5 -6
  121. annofabcli/statistics/linegraph.py +13 -14
  122. annofabcli/statistics/list_annotation_area.py +38 -13
  123. annofabcli/statistics/list_annotation_attribute.py +9 -10
  124. annofabcli/statistics/list_annotation_attribute_filled_count.py +30 -31
  125. annofabcli/statistics/list_annotation_count.py +57 -58
  126. annofabcli/statistics/list_annotation_duration.py +33 -34
  127. annofabcli/statistics/list_video_duration.py +4 -5
  128. annofabcli/statistics/list_worktime.py +4 -4
  129. annofabcli/statistics/scatter.py +9 -8
  130. annofabcli/statistics/subcommand_statistics.py +1 -4
  131. annofabcli/statistics/summarize_task_count.py +4 -6
  132. annofabcli/statistics/summarize_task_count_by_task_id_group.py +2 -4
  133. annofabcli/statistics/summarize_task_count_by_user.py +1 -3
  134. annofabcli/statistics/visualization/dataframe/annotation_count.py +5 -4
  135. annofabcli/statistics/visualization/dataframe/annotation_duration.py +2 -3
  136. annofabcli/statistics/visualization/dataframe/cumulative_productivity.py +15 -17
  137. annofabcli/statistics/visualization/dataframe/productivity_per_date.py +17 -19
  138. annofabcli/statistics/visualization/dataframe/project_performance.py +3 -12
  139. annofabcli/statistics/visualization/dataframe/task.py +11 -12
  140. annofabcli/statistics/visualization/dataframe/task_worktime_by_phase_user.py +9 -10
  141. annofabcli/statistics/visualization/dataframe/user_performance.py +21 -19
  142. annofabcli/statistics/visualization/dataframe/whole_performance.py +3 -4
  143. annofabcli/statistics/visualization/dataframe/whole_productivity_per_date.py +12 -14
  144. annofabcli/statistics/visualization/dataframe/worktime_per_date.py +11 -13
  145. annofabcli/statistics/visualization/filtering_query.py +7 -7
  146. annofabcli/statistics/visualization/project_dir.py +27 -14
  147. annofabcli/statistics/visualize_annotation_count.py +22 -23
  148. annofabcli/statistics/visualize_annotation_duration.py +21 -22
  149. annofabcli/statistics/visualize_statistics.py +36 -33
  150. annofabcli/statistics/visualize_video_duration.py +18 -20
  151. annofabcli/supplementary/delete_supplementary_data.py +5 -5
  152. annofabcli/supplementary/list_supplementary_data.py +4 -4
  153. annofabcli/supplementary/put_supplementary_data.py +9 -9
  154. annofabcli/supplementary/subcommand_supplementary.py +1 -3
  155. annofabcli/task/cancel_acceptance.py +16 -17
  156. annofabcli/task/change_operator.py +10 -12
  157. annofabcli/task/change_status_to_break.py +7 -9
  158. annofabcli/task/change_status_to_on_hold.py +10 -12
  159. annofabcli/task/complete_tasks.py +17 -18
  160. annofabcli/task/copy_tasks.py +3 -5
  161. annofabcli/task/delete_metadata_key_of_task.py +4 -6
  162. annofabcli/task/delete_tasks.py +7 -7
  163. annofabcli/task/download_task_json.py +4 -6
  164. annofabcli/task/list_all_tasks.py +8 -8
  165. annofabcli/task/list_all_tasks_added_task_history.py +14 -13
  166. annofabcli/task/list_tasks.py +7 -7
  167. annofabcli/task/list_tasks_added_task_history.py +10 -10
  168. annofabcli/task/put_tasks.py +5 -6
  169. annofabcli/task/put_tasks_by_count.py +2 -3
  170. annofabcli/task/reject_tasks.py +18 -20
  171. annofabcli/task/subcommand_task.py +1 -3
  172. annofabcli/task/update_metadata_of_task.py +5 -6
  173. annofabcli/task_history/download_task_history_json.py +4 -6
  174. annofabcli/task_history/list_all_task_history.py +6 -7
  175. annofabcli/task_history/list_task_history.py +4 -5
  176. annofabcli/task_history/subcommand_task_history.py +1 -3
  177. annofabcli/task_history_event/download_task_history_event_json.py +4 -6
  178. annofabcli/task_history_event/list_all_task_history_event.py +7 -7
  179. annofabcli/task_history_event/list_worktime.py +17 -16
  180. annofabcli/task_history_event/subcommand_task_history_event.py +1 -2
  181. {annofabcli-1.111.2.dist-info → annofabcli-1.113.0.dist-info}/METADATA +9 -15
  182. annofabcli-1.113.0.dist-info/RECORD +231 -0
  183. {annofabcli-1.111.2.dist-info → annofabcli-1.113.0.dist-info}/WHEEL +1 -1
  184. annofabcli-1.111.2.dist-info/RECORD +0 -228
  185. {annofabcli-1.111.2.dist-info → annofabcli-1.113.0.dist-info}/entry_points.txt +0 -0
  186. {annofabcli-1.111.2.dist-info → annofabcli-1.113.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, Optional, Union
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: Optional[str]
67
+ updated_datetime: str | None
69
68
  """アノテーションJSONに格納されているアノテーションの更新日時"""
70
69
  annotation_id: str
71
70
  label: str
72
- attributes: dict[str, Union[str, int, bool]]
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: Optional[Collection[str]] = None,
113
- task_query: Optional[TaskQuery] = None,
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: Optional[Path]) -> None:
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: Optional[str] = args.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: Optional[Path]) -> None:
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: Optional[argparse._SubParsersAction] = None) -> argparse.ArgumentParser:
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, Optional, Protocol, Union
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: Optional[str]
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: Optional[int] = None
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: Optional[Collection[str]] = None,
208
- non_target_labels: Optional[Collection[str]] = None,
209
- target_attribute_names: Optional[Collection[AttributeNameKey]] = None,
210
- non_target_attribute_names: Optional[Collection[AttributeNameKey]] = None,
211
- frame_no_map: Optional[dict[tuple[str, str], int]] = None,
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: Optional[Union[bool, str, float]]) -> AttributeValueType: # noqa: FBT001
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: Optional[int] = None
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: Optional[Collection[str]] = None,
288
- task_query: Optional[TaskQuery] = None,
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: Optional[list[tuple[str, str, str]]]) -> list[tuple[str, str, str]]:
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: Optional[list[tuple[str, str, str]]] = None,
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: Optional[list[tuple[str, str, str]]] = None,
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: Optional[list[tuple[str, str, str]]] = None,
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: Optional[list[tuple[str, str, str]]] = None,
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: Optional[list[tuple[str, str]]]) -> None:
464
- attribute_columns: Optional[list[tuple[str, str, str]]] = None
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: Optional[list[tuple[str, str]]]) -> None:
472
- attribute_columns: Optional[list[tuple[str, str, str]]] = None
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: Optional[str] = None,
485
+ project_id: str | None = None,
487
486
  include_flag_attribute: bool = False,
488
- task_json_path: Optional[Path] = None,
489
- target_task_ids: Optional[Collection[str]] = None,
490
- task_query: Optional[TaskQuery] = None,
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: Optional[AnnotationSpecs] = None
493
- target_attribute_names: Optional[list[AttributeNameKey]] = None
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: Optional[str] = args.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: Optional[Path]) -> None:
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: Optional[argparse._SubParsersAction] = None) -> argparse.ArgumentParser:
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, Optional, Union
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: Optional[str]
135
+ updated_datetime: str | None
137
136
  """アノテーションJSONに格納されているアノテーションの更新日時"""
138
- frame_no: Optional[int] = None
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: Optional[Collection[str]] = None,
182
- non_target_labels: Optional[Collection[str]] = None,
183
- target_attribute_names: Optional[Collection[AttributeNameKey]] = None,
184
- non_target_attribute_names: Optional[Collection[AttributeNameKey]] = None,
185
- frame_no_map: Optional[dict[tuple[str, str], int]] = None,
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: Union[bool, str, float]) -> str: # noqa: FBT001
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: Optional[int] = None
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: Optional[Collection[str]] = None,
280
- task_query: Optional[TaskQuery] = None,
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: Optional[Collection[str]] = None,
319
- non_target_labels: Optional[Collection[str]] = None,
320
- target_attribute_names: Optional[Collection[AttributeNameKey]] = None,
321
- non_target_attribute_names: Optional[Collection[AttributeNameKey]] = None,
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: Optional[Collection[str]] = None,
376
- task_query: Optional[TaskQuery] = None,
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: Optional[list[AttributeValueKey]]) -> list[AttributeValueKey]:
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: Optional[list[AttributeValueKey]] = None,
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: Optional[list[AttributeValueKey]] = None,
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: Optional[list[str]]) -> list[str]:
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: Optional[list[str]] = None,
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: Optional[list[str]] = None,
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: Optional[str] = None) -> None:
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: Optional[Collection[AdditionalDataDefinitionType]] = None,
703
- include_attribute_types: Optional[Collection[AdditionalDataDefinitionType]] = None,
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: Optional[str] = None,
862
- task_json_path: Optional[Path] = None,
863
- target_task_ids: Optional[Collection[str]] = None,
864
- task_query: Optional[TaskQuery] = None,
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: Optional[AnnotationSpecs] = None
868
- non_selective_attribute_name_keys: Optional[list[AttributeNameKey]] = None
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: Optional[list[str]] = None
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: Optional[list[AttributeValueKey]] = None
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: Optional[str] = None,
902
- target_task_ids: Optional[Collection[str]] = None,
903
- task_query: Optional[TaskQuery] = None,
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: Optional[AnnotationSpecs] = None
907
- non_selective_attribute_name_keys: Optional[list[AttributeNameKey]] = None
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: Optional[list[str]] = None
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: Optional[list[AttributeValueKey]] = None
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: Optional[str] = None,
940
- task_json_path: Optional[Path] = None,
941
- target_task_ids: Optional[Collection[str]] = None,
942
- task_query: Optional[TaskQuery] = None,
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: Optional[str] = None,
973
- target_task_ids: Optional[Collection[str]] = None,
974
- task_query: Optional[TaskQuery] = None,
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: Optional[str] = None,
1008
- task_json_path: Optional[Path] = None,
1009
- target_task_ids: Optional[Collection[str]] = None,
1010
- task_query: Optional[TaskQuery] = None,
1011
- csv_type: Optional[CsvType] = None,
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: Optional[str] = args.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: Optional[Path]) -> None:
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: Optional[argparse._SubParsersAction] = None) -> argparse.ArgumentParser:
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 = "オーナロールまたはアノテーションユーザロールを持つユーザで実行してください。"