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
@@ -3,7 +3,6 @@ import datetime
3
3
  import logging.config
4
4
  from functools import partial
5
5
  from pathlib import Path
6
- from typing import Optional, Union
7
6
 
8
7
  import annofabapi
9
8
  import requests
@@ -23,7 +22,7 @@ DOWNLOADING_FILETYPE_DICT = {
23
22
  DEFAULT_WAIT_OPTIONS = WaitOptions(interval=60, max_tries=360)
24
23
 
25
24
 
26
- def _get_annofab_error_message(http_error: requests.HTTPError) -> Optional[str]:
25
+ def _get_annofab_error_message(http_error: requests.HTTPError) -> str | None:
27
26
  obj = http_error.response.json()
28
27
  errors = obj.get("errors")
29
28
  if errors is None:
@@ -48,8 +47,8 @@ class DownloadingFile:
48
47
  self,
49
48
  project_id: str,
50
49
  job_type: ProjectJobType,
51
- wait_options: Optional[WaitOptions] = None,
52
- job_id: Optional[str] = None,
50
+ wait_options: WaitOptions | None = None,
51
+ job_id: str | None = None,
53
52
  ):
54
53
  if wait_options is None:
55
54
  wait_options = DEFAULT_WAIT_OPTIONS
@@ -69,9 +68,9 @@ class DownloadingFile:
69
68
  async def download_annotation_zip_with_async(
70
69
  self,
71
70
  project_id: str,
72
- dest_path: Union[str, Path],
71
+ dest_path: str | Path,
73
72
  is_latest: bool = False, # noqa: FBT001, FBT002
74
- wait_options: Optional[WaitOptions] = None,
73
+ wait_options: WaitOptions | None = None,
75
74
  ) -> None:
76
75
  loop = asyncio.get_event_loop()
77
76
  partial_func = partial(self.download_annotation_zip, project_id, dest_path, is_latest, wait_options)
@@ -80,9 +79,9 @@ class DownloadingFile:
80
79
  def download_annotation_zip(
81
80
  self,
82
81
  project_id: str,
83
- dest_path: Union[str, Path],
82
+ dest_path: str | Path,
84
83
  is_latest: bool = False, # noqa: FBT001, FBT002
85
- wait_options: Optional[WaitOptions] = None,
84
+ wait_options: WaitOptions | None = None,
86
85
  should_download_full_annotation: bool = False, # noqa: FBT001, FBT002
87
86
  ) -> None:
88
87
  """アノテーションZIPをダウンロードします。"""
@@ -108,7 +107,7 @@ class DownloadingFile:
108
107
  else:
109
108
  raise e # noqa: TRY201
110
109
 
111
- def wait_until_updated_annotation_zip(self, project_id: str, wait_options: Optional[WaitOptions] = None) -> None:
110
+ def wait_until_updated_annotation_zip(self, project_id: str, wait_options: WaitOptions | None = None) -> None:
112
111
  job_id = None
113
112
  try:
114
113
  job = self.service.api.post_annotation_archive_update(project_id)[0]["job"]
@@ -125,9 +124,9 @@ class DownloadingFile:
125
124
  async def download_input_data_json_with_async(
126
125
  self,
127
126
  project_id: str,
128
- dest_path: Union[str, Path],
127
+ dest_path: str | Path,
129
128
  is_latest: bool = False, # noqa: FBT001, FBT002
130
- wait_options: Optional[WaitOptions] = None,
129
+ wait_options: WaitOptions | None = None,
131
130
  ) -> None:
132
131
  loop = asyncio.get_event_loop()
133
132
  partial_func = partial(self.download_input_data_json, project_id, dest_path, is_latest, wait_options)
@@ -136,9 +135,9 @@ class DownloadingFile:
136
135
  def download_input_data_json(
137
136
  self,
138
137
  project_id: str,
139
- dest_path: Union[str, Path],
138
+ dest_path: str | Path,
140
139
  is_latest: bool = False, # noqa: FBT001, FBT002
141
- wait_options: Optional[WaitOptions] = None,
140
+ wait_options: WaitOptions | None = None,
142
141
  ) -> None:
143
142
  if is_latest:
144
143
  self.wait_until_updated_input_data_json(project_id, wait_options)
@@ -155,7 +154,7 @@ class DownloadingFile:
155
154
  else:
156
155
  raise e # noqa: TRY201
157
156
 
158
- def wait_until_updated_input_data_json(self, project_id: str, wait_options: Optional[WaitOptions] = None) -> None:
157
+ def wait_until_updated_input_data_json(self, project_id: str, wait_options: WaitOptions | None = None) -> None:
159
158
  job_id = None
160
159
  try:
161
160
  job = self.service.api.post_project_inputs_update(project_id)[0]["job"]
@@ -172,15 +171,15 @@ class DownloadingFile:
172
171
  async def download_task_json_with_async(
173
172
  self,
174
173
  project_id: str,
175
- dest_path: Union[str, Path],
174
+ dest_path: str | Path,
176
175
  is_latest: bool = False, # noqa: FBT001, FBT002
177
- wait_options: Optional[WaitOptions] = None,
176
+ wait_options: WaitOptions | None = None,
178
177
  ) -> None:
179
178
  loop = asyncio.get_event_loop()
180
179
  partial_func = partial(self.download_task_json, project_id, dest_path, is_latest=is_latest, wait_options=wait_options)
181
180
  await loop.run_in_executor(None, partial_func)
182
181
 
183
- def download_task_json(self, project_id: str, dest_path: Union[str, Path], *, is_latest: bool = False, wait_options: Optional[WaitOptions] = None) -> None:
182
+ def download_task_json(self, project_id: str, dest_path: str | Path, *, is_latest: bool = False, wait_options: WaitOptions | None = None) -> None:
184
183
  if is_latest:
185
184
  self.wait_until_updated_task_json(project_id, wait_options)
186
185
  self.service.wrapper.download_project_tasks_url(project_id, dest_path)
@@ -196,7 +195,7 @@ class DownloadingFile:
196
195
  else:
197
196
  raise e # noqa: TRY201
198
197
 
199
- def wait_until_updated_task_json(self, project_id: str, wait_options: Optional[WaitOptions] = None) -> None:
198
+ def wait_until_updated_task_json(self, project_id: str, wait_options: WaitOptions | None = None) -> None:
200
199
  job_id = None
201
200
  try:
202
201
  job = self.service.api.post_project_tasks_update(project_id)[0]["job"]
@@ -210,7 +209,7 @@ class DownloadingFile:
210
209
 
211
210
  self._wait_for_completion(project_id, job_type=ProjectJobType.GEN_TASKS_LIST, wait_options=wait_options, job_id=job_id)
212
211
 
213
- async def download_task_history_json_with_async(self, project_id: str, dest_path: Union[str, Path]) -> None:
212
+ async def download_task_history_json_with_async(self, project_id: str, dest_path: str | Path) -> None:
214
213
  """
215
214
  非同期でタスク履歴全件ファイルをダウンロードする。
216
215
 
@@ -219,7 +218,7 @@ class DownloadingFile:
219
218
  """
220
219
  return self.download_task_history_json(project_id, dest_path=dest_path)
221
220
 
222
- def download_task_history_json(self, project_id: str, dest_path: Union[str, Path]) -> None:
221
+ def download_task_history_json(self, project_id: str, dest_path: str | Path) -> None:
223
222
  """
224
223
  タスク履歴全件ファイルをダウンロードする。
225
224
 
@@ -237,7 +236,7 @@ class DownloadingFile:
237
236
  raise DownloadingFileNotFoundError(f"project_id='{project_id}'のプロジェクトに、タスク履歴全件ファイルが存在しないため、ダウンロードできませんでした。") from e
238
237
  raise e # noqa: TRY201
239
238
 
240
- def download_task_history_event_json(self, project_id: str, dest_path: Union[str, Path]) -> None:
239
+ def download_task_history_event_json(self, project_id: str, dest_path: str | Path) -> None:
241
240
  """
242
241
  タスク履歴イベント全件ファイルをダウンロードする。
243
242
 
@@ -255,7 +254,7 @@ class DownloadingFile:
255
254
  raise DownloadingFileNotFoundError(f"project_id='{project_id}'のプロジェクトに、タスク履歴イベント全件ファイルが存在しないため、ダウンロードできませんでした。") from e
256
255
  raise e # noqa: TRY201
257
256
 
258
- async def download_task_history_event_json_with_async(self, project_id: str, dest_path: Union[str, Path]) -> None:
257
+ async def download_task_history_event_json_with_async(self, project_id: str, dest_path: str | Path) -> None:
259
258
  """
260
259
  非同期でタスク履歴全件ファイルをダウンロードする。
261
260
 
@@ -265,7 +264,7 @@ class DownloadingFile:
265
264
  """
266
265
  return self.download_task_history_event_json(project_id, dest_path=dest_path)
267
266
 
268
- async def download_inspection_json_with_async(self, project_id: str, dest_path: Union[str, Path]) -> None:
267
+ async def download_inspection_json_with_async(self, project_id: str, dest_path: str | Path) -> None:
269
268
  """
270
269
  非同期で検査コメント全件ファイルをダウンロードする。
271
270
 
@@ -275,7 +274,7 @@ class DownloadingFile:
275
274
 
276
275
  return self.download_inspection_comment_json(project_id, dest_path=dest_path)
277
276
 
278
- def download_inspection_comment_json(self, project_id: str, dest_path: Union[str, Path]) -> None:
277
+ def download_inspection_comment_json(self, project_id: str, dest_path: str | Path) -> None:
279
278
  """
280
279
  検査コメント全件ファイルをダウンロードする。
281
280
 
@@ -290,7 +289,7 @@ class DownloadingFile:
290
289
  raise DownloadingFileNotFoundError(f"project_id='{project_id}'のプロジェクトに、検査コメント全件ファイルが存在しないため、ダウンロードできませんでした。") from e
291
290
  raise e # noqa: TRY201
292
291
 
293
- async def download_comment_json_with_async(self, project_id: str, dest_path: Union[str, Path]) -> None:
292
+ async def download_comment_json_with_async(self, project_id: str, dest_path: str | Path) -> None:
294
293
  """
295
294
  非同期でコメント全件ファイルをダウンロードする。
296
295
 
@@ -300,7 +299,7 @@ class DownloadingFile:
300
299
 
301
300
  return self.download_comment_json(project_id, dest_path=dest_path)
302
301
 
303
- def download_comment_json(self, project_id: str, dest_path: Union[str, Path]) -> None:
302
+ def download_comment_json(self, project_id: str, dest_path: str | Path) -> None:
304
303
  """
305
304
  コメント全件ファイルをダウンロードする。
306
305
 
@@ -322,7 +321,7 @@ class DownloadingFile:
322
321
  output_dir: Path,
323
322
  *,
324
323
  is_latest: bool = False,
325
- wait_options: Optional[WaitOptions] = None,
324
+ wait_options: WaitOptions | None = None,
326
325
  ) -> Path:
327
326
  """
328
327
  アノテーションZIPをoutput_dirに統一された命名規則でダウンロードする。
@@ -352,7 +351,7 @@ class DownloadingFile:
352
351
  output_dir: Path,
353
352
  *,
354
353
  is_latest: bool = False,
355
- wait_options: Optional[WaitOptions] = None,
354
+ wait_options: WaitOptions | None = None,
356
355
  ) -> Path:
357
356
  """
358
357
  タスクJSONをoutput_dirに統一された命名規則でダウンロードする。
@@ -382,7 +381,7 @@ class DownloadingFile:
382
381
  output_dir: Path,
383
382
  *,
384
383
  is_latest: bool = False,
385
- wait_options: Optional[WaitOptions] = None,
384
+ wait_options: WaitOptions | None = None,
386
385
  ) -> Path:
387
386
  """
388
387
  入力データJSONをoutput_dirに統一された命名規則でダウンロードする。
@@ -1,12 +1,11 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import logging
4
- from collections.abc import Collection
4
+ from collections.abc import Callable, Collection
5
5
  from dataclasses import dataclass
6
- from typing import Any, Callable, Optional
6
+ from typing import Any
7
7
 
8
8
  import annofabapi
9
- import annofabapi.utils
10
9
  import more_itertools
11
10
  from annofabapi.dataclass.annotation import AdditionalDataV1
12
11
  from annofabapi.dataclass.input import InputData
@@ -33,27 +32,27 @@ class AnnotationQuery(DataClassJsonMixin):
33
32
  """
34
33
 
35
34
  label_id: str
36
- attributes: Optional[list[AdditionalDataV1]] = None
35
+ attributes: list[AdditionalDataV1] | None = None
37
36
 
38
37
 
39
38
  @dataclass
40
39
  class AdditionalDataForCli(DataClassJsonMixin):
41
- additional_data_definition_id: Optional[str] = None
40
+ additional_data_definition_id: str | None = None
42
41
  """属性ID"""
43
42
 
44
- additional_data_definition_name_en: Optional[str] = None
43
+ additional_data_definition_name_en: str | None = None
45
44
  """属性の英語名"""
46
45
 
47
- flag: Optional[bool] = None
46
+ flag: bool | None = None
48
47
 
49
- integer: Optional[int] = None
48
+ integer: int | None = None
50
49
 
51
- comment: Optional[str] = None
50
+ comment: str | None = None
52
51
 
53
- choice: Optional[str] = None
52
+ choice: str | None = None
54
53
  """選択肢ID"""
55
54
 
56
- choice_name_en: Optional[str] = None
55
+ choice_name_en: str | None = None
57
56
  """選択肢の英語名"""
58
57
 
59
58
 
@@ -63,10 +62,10 @@ class AnnotationQueryForCli(DataClassJsonMixin):
63
62
  コマンドライン上で指定するアノテーション検索条件
64
63
  """
65
64
 
66
- label_name_en: Optional[str] = None
65
+ label_name_en: str | None = None
67
66
  """ラベルの英語名"""
68
- label_id: Optional[str] = None
69
- attributes: Optional[list[AdditionalDataForCli]] = None
67
+ label_id: str | None = None
68
+ attributes: list[AdditionalDataForCli] | None = None
70
69
 
71
70
 
72
71
  @dataclass
@@ -75,12 +74,12 @@ class TaskQuery(DataClassJsonMixin):
75
74
  コマンドライン上で指定するタスクの検索条件
76
75
  """
77
76
 
78
- task_id: Optional[str] = None
79
- phase: Optional[TaskPhase] = None
80
- status: Optional[TaskStatus] = None
81
- phase_stage: Optional[int] = None
82
- user_id: Optional[str] = None
83
- account_id: Optional[str] = None
77
+ task_id: str | None = None
78
+ phase: TaskPhase | None = None
79
+ status: TaskStatus | None = None
80
+ phase_stage: int | None = None
81
+ user_id: str | None = None
82
+ account_id: str | None = None
84
83
  no_user: bool = False
85
84
  """Trueなら未割り当てのタスクで絞り込む"""
86
85
 
@@ -91,12 +90,12 @@ class InputDataQuery(DataClassJsonMixin):
91
90
  コマンドライン上で指定する入力データの検索条件
92
91
  """
93
92
 
94
- input_data_id: Optional[str] = None
95
- input_data_name: Optional[str] = None
96
- input_data_path: Optional[str] = None
93
+ input_data_id: str | None = None
94
+ input_data_name: str | None = None
95
+ input_data_path: str | None = None
97
96
 
98
97
 
99
- def match_annotation_with_task_query(annotation: dict[str, Any], task_query: Optional[TaskQuery]) -> bool:
98
+ def match_annotation_with_task_query(annotation: dict[str, Any], task_query: TaskQuery | None) -> bool:
100
99
  """
101
100
  Simple Annotationが、タスククエリ条件に合致するか
102
101
 
@@ -130,7 +129,7 @@ def match_annotation_with_task_query(annotation: dict[str, Any], task_query: Opt
130
129
 
131
130
 
132
131
  def match_task_with_query( # pylint: disable=too-many-return-statements # noqa: PLR0911
133
- task: Task, task_query: Optional[TaskQuery]
132
+ task: Task, task_query: TaskQuery | None
134
133
  ) -> bool:
135
134
  """
136
135
  タスク情報が、タスククエリ条件に合致するかどうか。
@@ -175,7 +174,7 @@ def match_task_with_query( # pylint: disable=too-many-return-statements # noqa
175
174
 
176
175
 
177
176
  def match_input_data_with_query( # pylint: disable=too-many-return-statements
178
- input_data: InputData, input_data_query: Optional[InputDataQuery]
177
+ input_data: InputData, input_data_query: InputDataQuery | None
179
178
  ) -> bool:
180
179
  """
181
180
  入力データが、クエリ条件に合致するかどうか。
@@ -222,7 +221,7 @@ def convert_annotation_specs_labels_v2_to_v1(labels_v2: list[dict[str, Any]], ad
222
221
  List[LabelV1]: V1版のラベル情報
223
222
  """
224
223
 
225
- def get_additional(additional_data_definition_id: str) -> Optional[dict[str, Any]]:
224
+ def get_additional(additional_data_definition_id: str) -> dict[str, Any] | None:
226
225
  return more_itertools.first_true(additionals_v2, pred=lambda e: e["additional_data_definition_id"] == additional_data_definition_id)
227
226
 
228
227
  def to_label_v1(label_v2: dict[str, Any]) -> dict[str, Any]:
@@ -249,7 +248,7 @@ class AnnofabApiFacade:
249
248
  """
250
249
 
251
250
  #: 組織メンバ一覧のキャッシュ
252
- _organization_members: Optional[tuple[str, list[OrganizationMember]]] = None
251
+ _organization_members: tuple[str, list[OrganizationMember]] | None = None
253
252
 
254
253
  _project_members_dict: dict[str, list[ProjectMember]] = {} # noqa: RUF012
255
254
  """プロジェクトメンバ一覧の情報。key:project_id, value:プロジェクトメンバ一覧"""
@@ -258,7 +257,7 @@ class AnnofabApiFacade:
258
257
  self.service = service
259
258
 
260
259
  @staticmethod
261
- def get_account_id_last_annotation_phase(task_histories: list[dict[str, Any]]) -> Optional[str]:
260
+ def get_account_id_last_annotation_phase(task_histories: list[dict[str, Any]]) -> str | None:
262
261
  """
263
262
  タスク履歴の最後のannotation phaseを担当したaccount_idを取得する. なければNoneを返す
264
263
  Args:
@@ -303,7 +302,7 @@ class AnnofabApiFacade:
303
302
  project, _ = self.service.api.get_project(project_id)
304
303
  return project["title"]
305
304
 
306
- def _get_organization_member_with_predicate(self, project_id: str, predicate: Callable[[Any], bool]) -> Optional[OrganizationMember]:
305
+ def _get_organization_member_with_predicate(self, project_id: str, predicate: Callable[[Any], bool]) -> OrganizationMember | None:
307
306
  """
308
307
  account_idから組織メンバを取得する。
309
308
  インスタンス変数に組織メンバがあれば、WebAPIは実行しない。
@@ -335,7 +334,7 @@ class AnnofabApiFacade:
335
334
  update_organization_members()
336
335
  return self._get_organization_member_with_predicate(project_id, predicate)
337
336
 
338
- def _get_project_member_with_predicate(self, project_id: str, predicate: Callable[[Any], bool]) -> Optional[ProjectMember]:
337
+ def _get_project_member_with_predicate(self, project_id: str, predicate: Callable[[Any], bool]) -> ProjectMember | None:
339
338
  """
340
339
  project_memberを取得する
341
340
 
@@ -352,7 +351,7 @@ class AnnofabApiFacade:
352
351
  self._project_members_dict[project_id] = project_member_list
353
352
  return more_itertools.first_true(project_member_list, pred=predicate)
354
353
 
355
- def get_project_member_from_account_id(self, project_id: str, account_id: str) -> Optional[ProjectMember]:
354
+ def get_project_member_from_account_id(self, project_id: str, account_id: str) -> ProjectMember | None:
356
355
  """
357
356
  account_idからプロジェクトメンバを取得する。
358
357
 
@@ -365,7 +364,7 @@ class AnnofabApiFacade:
365
364
  """
366
365
  return self._get_project_member_with_predicate(project_id, predicate=lambda e: e["account_id"] == account_id)
367
366
 
368
- def get_project_member_from_user_id(self, project_id: str, user_id: str) -> Optional[ProjectMember]:
367
+ def get_project_member_from_user_id(self, project_id: str, user_id: str) -> ProjectMember | None:
369
368
  """
370
369
  user_idからプロジェクトメンバを取得する。
371
370
 
@@ -378,7 +377,7 @@ class AnnofabApiFacade:
378
377
  """
379
378
  return self._get_project_member_with_predicate(project_id, predicate=lambda e: e["user_id"] == user_id)
380
379
 
381
- def get_organization_member_from_user_id(self, project_id: str, user_id: str) -> Optional[OrganizationMember]:
380
+ def get_organization_member_from_user_id(self, project_id: str, user_id: str) -> OrganizationMember | None:
382
381
  """
383
382
  user_idから組織メンバを取得する。
384
383
  インスタンス変数に組織メンバがあれば、WebAPIは実行しない。
@@ -392,7 +391,7 @@ class AnnofabApiFacade:
392
391
  """
393
392
  return self._get_organization_member_with_predicate(project_id, lambda e: e["user_id"] == user_id)
394
393
 
395
- def get_user_id_from_account_id(self, project_id: str, account_id: str) -> Optional[str]:
394
+ def get_user_id_from_account_id(self, project_id: str, account_id: str) -> str | None:
396
395
  """
397
396
  account_idからuser_idを取得する.
398
397
  インスタンス変数に組織メンバがあれば、WebAPIは実行しない。
@@ -411,7 +410,7 @@ class AnnofabApiFacade:
411
410
  else:
412
411
  return member.get("user_id")
413
412
 
414
- def get_account_id_from_user_id(self, project_id: str, user_id: str) -> Optional[str]:
413
+ def get_account_id_from_user_id(self, project_id: str, user_id: str) -> str | None:
415
414
  """
416
415
  user_idからaccount_idを取得する。
417
416
  インスタンス変数に組織メンバがあれば、WebAPIは実行しない。
@@ -502,8 +501,8 @@ class AnnofabApiFacade:
502
501
  def validate_project(
503
502
  self,
504
503
  project_id: str,
505
- project_member_roles: Optional[list[ProjectMemberRole]] = None,
506
- organization_member_roles: Optional[list[OrganizationMemberRole]] = None,
504
+ project_member_roles: list[ProjectMemberRole] | None = None,
505
+ organization_member_roles: list[OrganizationMemberRole] | None = None,
507
506
  ) -> None:
508
507
  """
509
508
  プロジェクト or 組織に対して、必要な権限が付与されているかを確認する。
@@ -5,10 +5,10 @@
5
5
 
6
6
  import logging
7
7
  import zipfile
8
+ from collections.abc import Callable
8
9
  from pathlib import Path
9
- from typing import Any, Callable, Optional
10
+ from typing import Any
10
11
 
11
- import PIL
12
12
  import PIL.Image
13
13
  import PIL.ImageDraw
14
14
  from annofabapi.dataclass.annotation import SimpleAnnotationDetail
@@ -24,7 +24,7 @@ IsParserFunc = Callable[[SimpleAnnotationParser], bool]
24
24
  """アノテーションparserに対してboolを返す関数"""
25
25
 
26
26
 
27
- def get_data_uri_of_outer_file(annotation: SimpleAnnotationDetail) -> Optional[str]:
27
+ def get_data_uri_of_outer_file(annotation: SimpleAnnotationDetail) -> str | None:
28
28
  """
29
29
  外部ファイルの data_uri を取得する
30
30
  Args:
@@ -45,7 +45,7 @@ def fill_annotation(
45
45
  draw: PIL.ImageDraw.ImageDraw,
46
46
  annotation: SimpleAnnotationDetail,
47
47
  label_color_dict: dict[str, RGB],
48
- outer_image: Optional[Any] = None, # noqa: ANN401
48
+ outer_image: Any | None = None, # noqa: ANN401
49
49
  ) -> PIL.ImageDraw.ImageDraw:
50
50
  """
51
51
  1個のアノテーションを、塗りつぶしで描画する。(矩形、ポリゴン、塗りつぶし、塗りつぶしv2)
@@ -94,7 +94,7 @@ def fill_annotation_list(
94
94
  draw: PIL.ImageDraw.ImageDraw,
95
95
  parser: SimpleAnnotationParser,
96
96
  label_color_dict: dict[str, RGB],
97
- label_name_list: Optional[list[str]] = None,
97
+ label_name_list: list[str] | None = None,
98
98
  ) -> PIL.ImageDraw.ImageDraw:
99
99
  """
100
100
  1個の入力データに属するアノテーションlistを描画する
@@ -142,8 +142,8 @@ def write_annotation_image( # noqa: ANN201
142
142
  image_size: InputDataSize,
143
143
  label_color_dict: dict[str, RGB],
144
144
  output_image_file: Path,
145
- background_color: Optional[Any] = None, # noqa: ANN401
146
- label_name_list: Optional[list[str]] = None,
145
+ background_color: Any | None = None, # noqa: ANN401
146
+ label_name_list: list[str] | None = None,
147
147
  ):
148
148
  """
149
149
  JSONファイルに記載されているアノテーション情報を、画像化する。
@@ -191,7 +191,7 @@ def write_annotation_grayscale_image(
191
191
  parser: SimpleAnnotationParser,
192
192
  image_size: InputDataSize,
193
193
  output_image_file: Path,
194
- label_name_list: Optional[list[str]] = None,
194
+ label_name_list: list[str] | None = None,
195
195
  ) -> None:
196
196
  """
197
197
  JSONファイルに記載されているアノテーション情報を、グレースケール(8bit 1channel)で画像化します。
@@ -267,12 +267,12 @@ def write_annotation_images_from_path(
267
267
  annotation_path: Path,
268
268
  label_color_dict: dict[str, RGB],
269
269
  output_dir_path: Path,
270
- image_size: Optional[InputDataSize] = None,
271
- input_data_dict: Optional[dict[str, InputData]] = None,
270
+ image_size: InputDataSize | None = None,
271
+ input_data_dict: dict[str, InputData] | None = None,
272
272
  output_image_extension: str = "png",
273
- background_color: Optional[Any] = None, # noqa: ANN401
274
- label_name_list: Optional[list[str]] = None,
275
- is_target_parser_func: Optional[IsParserFunc] = None,
273
+ background_color: Any | None = None, # noqa: ANN401
274
+ label_name_list: list[str] | None = None,
275
+ is_target_parser_func: IsParserFunc | None = None,
276
276
  ) -> bool:
277
277
  """
278
278
  Annofabからダウンロードしたアノテーションzipファイル、またはそのzipを展開したディレクトリから、アノテーション情報を画像化します。
@@ -297,7 +297,7 @@ def write_annotation_images_from_path(
297
297
 
298
298
  """
299
299
 
300
- def _get_image_size(input_data_id: str) -> Optional[InputDataSize]:
300
+ def _get_image_size(input_data_id: str) -> InputDataSize | None:
301
301
  def _get_image_size_from_system_metadata(arg_input_data: dict[str, Any]): # noqa: ANN202
302
302
  # 入力データの`input_data.system_metadata.original_resolution`を参照して、画像サイズを決める。
303
303
  original_resolution = arg_input_data["system_metadata"]["original_resolution"]
@@ -1,11 +1,11 @@
1
1
  import json
2
2
  import logging
3
- import logging.config
4
3
  import os
5
4
  import re
6
5
  import sys
6
+ from collections.abc import Callable
7
7
  from pathlib import Path
8
- from typing import Any, Callable, Optional, TypeVar, Union
8
+ from typing import Any, TypeVar
9
9
 
10
10
  import dateutil.parser
11
11
  import isodate
@@ -46,7 +46,7 @@ def duplicated_set(target_list: list[T]) -> set[T]:
46
46
  return {x for x in set(target_list) if target_list.count(x) > 1}
47
47
 
48
48
 
49
- def output_string(target: str, output: Optional[Union[str, Path]] = None) -> None:
49
+ def output_string(target: str, output: str | Path | None = None) -> None:
50
50
  """
51
51
  文字列を出力する。
52
52
 
@@ -64,7 +64,7 @@ def output_string(target: str, output: Optional[Union[str, Path]] = None) -> Non
64
64
  logger.info(f"'{output}'を出力しました。")
65
65
 
66
66
 
67
- def print_json(target: Any, is_pretty: bool = False, output: Optional[Union[str, Path]] = None) -> None: # noqa: ANN401, FBT001, FBT002
67
+ def print_json(target: Any, is_pretty: bool = False, output: str | Path | None = None) -> None: # noqa: ANN401, FBT001, FBT002
68
68
  """
69
69
  JSONを出力する。
70
70
 
@@ -80,7 +80,7 @@ def print_json(target: Any, is_pretty: bool = False, output: Optional[Union[str,
80
80
  output_string(json.dumps(target, ensure_ascii=False), output)
81
81
 
82
82
 
83
- def print_csv(df: pandas.DataFrame, output: Optional[Union[str, Path]] = None, to_csv_kwargs: Optional[dict[str, Any]] = None) -> None:
83
+ def print_csv(df: pandas.DataFrame, output: str | Path | None = None, to_csv_kwargs: dict[str, Any] | None = None) -> None:
84
84
  if output is not None:
85
85
  Path(output).parent.mkdir(parents=True, exist_ok=True)
86
86
 
@@ -98,7 +98,7 @@ def print_csv(df: pandas.DataFrame, output: Optional[Union[str, Path]] = None, t
98
98
  logger.info(f"'{output}'を出力しました。")
99
99
 
100
100
 
101
- def print_id_list(id_list: list[Any], output: Optional[Union[str, Path]]) -> None:
101
+ def print_id_list(id_list: list[Any], output: str | Path | None) -> None:
102
102
  s = "\n".join(id_list)
103
103
  output_string(s, output)
104
104
 
@@ -106,7 +106,7 @@ def print_id_list(id_list: list[Any], output: Optional[Union[str, Path]]) -> Non
106
106
  def print_according_to_format(
107
107
  target: Any, # noqa: ANN401
108
108
  format: FormatArgument, # noqa: A002
109
- output: Optional[Union[str, Path]] = None,
109
+ output: str | Path | None = None,
110
110
  ) -> None:
111
111
  """
112
112
  コマンドライン引数 ``--format`` の値にしたがって、内容を出力する。
@@ -171,7 +171,7 @@ def is_file_scheme(str_value: str) -> bool:
171
171
  return str_value.startswith("file://")
172
172
 
173
173
 
174
- def get_file_scheme_path(str_value: str) -> Optional[str]:
174
+ def get_file_scheme_path(str_value: str) -> str | None:
175
175
  """
176
176
  file schemaのパスを取得する。file schemeでない場合は、Noneを返す
177
177
 
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import enum
4
- from typing import Any, Optional
4
+ from typing import Any
5
5
 
6
6
  import annofabapi
7
7
  import more_itertools
@@ -32,15 +32,15 @@ class AddProps:
32
32
  """
33
33
 
34
34
  #: 組織メンバ一覧のキャッシュ
35
- _organization_members: Optional[list[OrganizationMember]] = None
36
- _project_member_list: Optional[list[ProjectMember]] = None
35
+ _organization_members: list[OrganizationMember] | None = None
36
+ _project_member_list: list[ProjectMember] | None = None
37
37
 
38
38
  def __init__(self, service: annofabapi.Resource, project_id: str) -> None:
39
39
  self.service = service
40
40
  self.project_id = project_id
41
41
 
42
- self._specs_labels: Optional[list[dict[str, Any]]] = None
43
- self._specs_inspection_phrases: Optional[list[dict[str, Any]]] = None
42
+ self._specs_labels: list[dict[str, Any]] | None = None
43
+ self._specs_inspection_phrases: list[dict[str, Any]] | None = None
44
44
 
45
45
  def _set_annotation_specs(self): # noqa: ANN202
46
46
  """
@@ -84,7 +84,7 @@ class AddProps:
84
84
  return millisecond / 1000 / 3600
85
85
 
86
86
  @staticmethod
87
- def get_message(i18n_messages: dict[str, Any], locale: MessageLocale) -> Optional[str]:
87
+ def get_message(i18n_messages: dict[str, Any], locale: MessageLocale) -> str | None:
88
88
  messages: list[dict[str, Any]] = i18n_messages["messages"]
89
89
  dict_message = more_itertools.first_true(messages, pred=lambda e: e["lang"] == locale.value)
90
90
  if dict_message is not None:
@@ -112,7 +112,7 @@ class AddProps:
112
112
  target["username"] = username
113
113
  return target
114
114
 
115
- def get_project_member_from_account_id(self, account_id: str) -> Optional[ProjectMember]:
115
+ def get_project_member_from_account_id(self, account_id: str) -> ProjectMember | None:
116
116
  if self._project_member_list is None:
117
117
  project_member_list = self.service.wrapper.get_all_project_members(self.project_id, query_params={"include_inactive_member": True})
118
118
  self._project_member_list = project_member_list
@@ -128,22 +128,22 @@ class AddProps:
128
128
  organization, _ = self.service.api.get_organization_of_project(project_id)
129
129
  return organization["organization_name"]
130
130
 
131
- def get_phrase_name(self, phrase_id: str, locale: MessageLocale) -> Optional[str]:
132
- phrase: Optional[dict[str, Any]] = more_itertools.first_true(self.specs_inspection_phrases, pred=lambda e: e["id"] == phrase_id)
131
+ def get_phrase_name(self, phrase_id: str, locale: MessageLocale) -> str | None:
132
+ phrase: dict[str, Any] | None = more_itertools.first_true(self.specs_inspection_phrases, pred=lambda e: e["id"] == phrase_id)
133
133
  if phrase is None:
134
134
  return None
135
135
 
136
136
  return self.get_message(phrase["text"], locale)
137
137
 
138
- def get_label_name(self, label_id: str, locale: MessageLocale) -> Optional[str]:
138
+ def get_label_name(self, label_id: str, locale: MessageLocale) -> str | None:
139
139
  label = more_itertools.first_true(self.specs_labels, pred=lambda e: e["label_id"] == label_id)
140
140
  if label is None:
141
141
  return None
142
142
 
143
143
  return self.get_message(label["label_name"], locale)
144
144
 
145
- def get_additional_data_name(self, additional_data_definition_id: str, locale: MessageLocale, label_id: Optional[str] = None) -> Optional[str]:
146
- def _get_additional_data_name(arg_additional_data_definitions: list[dict[str, Any]]) -> Optional[str]:
145
+ def get_additional_data_name(self, additional_data_definition_id: str, locale: MessageLocale, label_id: str | None = None) -> str | None:
146
+ def _get_additional_data_name(arg_additional_data_definitions: list[dict[str, Any]]) -> str | None:
147
147
  additional_data = more_itertools.first_true(
148
148
  arg_additional_data_definitions,
149
149
  pred=lambda e: e["additional_data_definition_id"] == additional_data_definition_id,
@@ -194,7 +194,7 @@ class AddProps:
194
194
  """
195
195
  return self._add_user_info(instruction_history)
196
196
 
197
- def add_properties_to_inspection(self, inspection: Inspection, detail: Optional[dict[str, Any]] = None) -> Inspection:
197
+ def add_properties_to_inspection(self, inspection: Inspection, detail: dict[str, Any] | None = None) -> Inspection:
198
198
  """
199
199
  検査コメントに、以下のキーを追加する.
200
200
  commenter_user_id