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
@@ -1,10 +1,12 @@
1
1
  """サブコマンド annotation_zip"""
2
2
 
3
3
  import argparse
4
- from typing import Optional
5
4
 
6
5
  import annofabcli
6
+ from annofabcli.annotation_zip.list_annotation_3d_bounding_box import add_parser as add_parser_list_annotation_3d_bounding_box
7
7
  from annofabcli.annotation_zip.list_annotation_bounding_box_2d import add_parser as add_parser_list_annotation_bounding_box_2d
8
+ from annofabcli.annotation_zip.list_polygon_annotation import add_parser as add_parser_list_polygon_annotation
9
+ from annofabcli.annotation_zip.list_polyline_annotation import add_parser as add_parser_list_polyline_annotation
8
10
  from annofabcli.annotation_zip.list_range_annotation import add_parser as add_parser_list_range_annotation
9
11
  from annofabcli.annotation_zip.list_single_point_annotation import add_parser as add_parser_list_single_point_annotation
10
12
 
@@ -18,14 +20,17 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
18
20
  subparsers = parser.add_subparsers(dest="subcommand_name")
19
21
 
20
22
  # サブコマンドの定義
23
+ add_parser_list_annotation_3d_bounding_box(subparsers)
21
24
  add_parser_list_annotation_bounding_box_2d(subparsers)
25
+ add_parser_list_polygon_annotation(subparsers)
26
+ add_parser_list_polyline_annotation(subparsers)
22
27
  add_parser_list_range_annotation(subparsers)
23
28
  add_parser_list_single_point_annotation(subparsers)
24
29
  # 作成中のためコメントアウト
25
30
  # add_parser_validate_annotation(subparsers)
26
31
 
27
32
 
28
- def add_parser(subparsers: Optional[argparse._SubParsersAction] = None) -> argparse.ArgumentParser:
33
+ def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
29
34
  """
30
35
  annotation_zipサブコマンドを追加する。
31
36
  Args:
@@ -6,9 +6,10 @@ import json
6
6
  import logging
7
7
  import sys
8
8
  import tempfile
9
+ from collections.abc import Callable
9
10
  from dataclasses import dataclass
10
11
  from pathlib import Path
11
- from typing import Any, Callable, Optional
12
+ from typing import Any
12
13
 
13
14
  import annofabapi
14
15
  import pandas
@@ -37,8 +38,8 @@ class ValidationResult:
37
38
  label_name: str
38
39
  function_name: str
39
40
  is_valid: bool
40
- error_message: Optional[str] = None
41
- detail_data: Optional[dict[str, Any]] = None
41
+ error_message: str | None = None
42
+ detail_data: dict[str, Any] | None = None
42
43
 
43
44
 
44
45
  class ValidationFunctionLoader:
@@ -101,7 +102,7 @@ class AnnotationValidator:
101
102
  service: annofabapi.Resource,
102
103
  project_id: str,
103
104
  validation_functions: dict[str, Callable[[dict[str, Any]], bool]],
104
- task_query: Optional[TaskQuery] = None,
105
+ task_query: TaskQuery | None = None,
105
106
  ) -> None:
106
107
  self.service = service
107
108
  self.project_id = project_id
@@ -233,7 +234,7 @@ class ValidateAnnotation(CommandLine):
233
234
  logger.info(f"読み込んだバリデーション関数: {list(validation_functions.keys())}")
234
235
 
235
236
  # タスク検索クエリ
236
- task_query: Optional[TaskQuery] = None
237
+ task_query: TaskQuery | None = None
237
238
  if args.task_query is not None:
238
239
  dict_task_query = annofabcli.common.cli.get_json_from_args(args.task_query)
239
240
  task_query = TaskQuery.from_dict(dict_task_query)
@@ -277,7 +278,7 @@ class ValidateAnnotation(CommandLine):
277
278
  # サマリー表示
278
279
  self._print_summary(results)
279
280
 
280
- def _output_results(self, results: list[ValidationResult], format_type: str, output_file: Optional[Path]) -> None:
281
+ def _output_results(self, results: list[ValidationResult], format_type: str, output_file: Path | None) -> None:
281
282
  """バリデーション結果を出力する"""
282
283
  if not results:
283
284
  logger.info("バリデーション結果はありません。")
@@ -382,7 +383,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
382
383
  parser.set_defaults(subcommand_func=main)
383
384
 
384
385
 
385
- def add_parser(subparsers: Optional[argparse._SubParsersAction] = None) -> argparse.ArgumentParser:
386
+ def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
386
387
  subcommand_name = "validate"
387
388
  subcommand_help = "ユーザー定義のバリデーション関数でアノテーションZIPを検証します。"
388
389
  description = "ユーザー定義のバリデーション関数でアノテーションZIPを検証します。\nバリデーション関数は 'validate_' から始まる関数名で定義してください。"
@@ -3,14 +3,12 @@ import json
3
3
  import logging
4
4
  import multiprocessing
5
5
  import sys
6
- from typing import Any, Optional
6
+ from typing import Any
7
7
 
8
8
  import annofabapi
9
- import annofabapi.utils
10
9
  import requests
11
10
  from annofabapi.models import ProjectMemberRole, TaskStatus
12
11
 
13
- import annofabcli
14
12
  import annofabcli.common.cli
15
13
  from annofabcli.common.cli import (
16
14
  COMMAND_LINE_ERROR_STATUS_CODE,
@@ -106,7 +104,7 @@ class DeleteCommentMain(CommandLineWithConfirm):
106
104
  self,
107
105
  task_id: str,
108
106
  comment_ids_for_task: DeletedCommentsForTask,
109
- task_index: Optional[int] = None,
107
+ task_index: int | None = None,
110
108
  ) -> int:
111
109
  """
112
110
  タスクに対してコメントを削除します。
@@ -172,7 +170,7 @@ class DeleteCommentMain(CommandLineWithConfirm):
172
170
  def delete_comments_for_task_list(
173
171
  self,
174
172
  comment_ids_for_task_list: DeletedComments,
175
- parallelism: Optional[int] = None,
173
+ parallelism: int | None = None,
176
174
  ) -> None:
177
175
  comments_count = sum(len(e) for e in comment_ids_for_task_list.values())
178
176
  logger.info(f"削除対象のコメントを含むタスクの個数: {len(comment_ids_for_task_list)}, 削除対象のコメントを含む入力データ数: {comments_count}")
@@ -260,7 +258,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
260
258
  parser.set_defaults(subcommand_func=main)
261
259
 
262
260
 
263
- def add_parser(subparsers: Optional[argparse._SubParsersAction] = None) -> argparse.ArgumentParser:
261
+ def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
264
262
  subcommand_name = "delete"
265
263
  subcommand_help = "コメントを削除します。"
266
264
  description = "コメントを削除します。\n【注意】他人の付けたコメントも削除できてしまいます。"
@@ -1,11 +1,9 @@
1
1
  import argparse
2
2
  import logging
3
3
  from pathlib import Path
4
- from typing import Optional
5
4
 
6
5
  from annofabapi.models import ProjectMemberRole
7
6
 
8
- import annofabcli
9
7
  import annofabcli.common.cli
10
8
  from annofabcli.common.cli import CommandLine, build_annofabapi_resource_and_login
11
9
  from annofabcli.common.download import DownloadingFile
@@ -15,17 +13,17 @@ logger = logging.getLogger(__name__)
15
13
 
16
14
 
17
15
  class DownloadingComment(CommandLine):
18
- def download_comment_json(self, project_id: str, output_file: Path): # noqa: ANN201
16
+ def download_comment_json(self, project_id: str, output_file: Path) -> None:
19
17
  super().validate_project(project_id, [ProjectMemberRole.OWNER, ProjectMemberRole.TRAINING_DATA_USER])
20
18
  project_title = self.facade.get_project_title(project_id)
21
- logger.info(f"{project_title} のコメント全件ファイルをダウンロードします。")
19
+ logger.info(f"project_id='{project_id}'のコメント全件ファイルをダウンロードします。 :: project_title='{project_title}'")
22
20
 
23
21
  obj = DownloadingFile(self.service)
24
22
  obj.download_comment_json(
25
23
  project_id,
26
24
  str(output_file),
27
25
  )
28
- logger.info(f"コメント全件ファイルをダウンロードしました。output={output_file}")
26
+ logger.info(f"project_id='{project_id}'のコメント全件ファイルをダウンロードしました。 :: output='{output_file}', project_title='{project_title}'")
29
27
 
30
28
  def main(self) -> None:
31
29
  args = self.args
@@ -50,7 +48,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
50
48
  parser.set_defaults(subcommand_func=main)
51
49
 
52
50
 
53
- def add_parser(subparsers: Optional[argparse._SubParsersAction] = None) -> argparse.ArgumentParser:
51
+ def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
54
52
  subcommand_name = "download"
55
53
  subcommand_help = "コメント全件ファイルをダウンロードします。"
56
54
  epilog = "オーナロールまたはアノテーションユーザロールを持つユーザで実行してください。"
@@ -10,13 +10,12 @@ import logging
10
10
  import tempfile
11
11
  from collections.abc import Collection
12
12
  from pathlib import Path
13
- from typing import Any, Optional
13
+ from typing import Any
14
14
 
15
15
  import annofabapi
16
16
  import pandas
17
17
  from annofabapi.models import CommentType
18
18
 
19
- import annofabcli
20
19
  import annofabcli.common.cli
21
20
  from annofabcli.comment.list_comment import create_empty_df_comment, create_reply_counter
22
21
  from annofabcli.common.cli import ArgumentParser, CommandLine, build_annofabapi_resource_and_login
@@ -36,9 +35,9 @@ class ListAllCommentMain:
36
35
  def get_all_comment(
37
36
  self,
38
37
  project_id: str,
39
- comment_json: Optional[Path],
40
- task_ids: Optional[Collection[str]],
41
- comment_type: Optional[CommentType],
38
+ comment_json: Path | None,
39
+ task_ids: Collection[str] | None,
40
+ comment_type: CommentType | None,
42
41
  exclude_reply: bool, # noqa: FBT001
43
42
  ) -> list[dict[str, Any]]:
44
43
  if comment_json is None:
@@ -154,7 +153,7 @@ def main(args: argparse.Namespace) -> None:
154
153
  ListAllComment(service, facade, args).main()
155
154
 
156
155
 
157
- def add_parser(subparsers: Optional[argparse._SubParsersAction] = None) -> argparse.ArgumentParser:
156
+ def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
158
157
  subcommand_name = "list_all"
159
158
  subcommand_help = "すべてのコメントの一覧を出力します。"
160
159
  description = (
@@ -3,13 +3,12 @@ from __future__ import annotations
3
3
  import argparse
4
4
  import logging
5
5
  from collections import Counter
6
- from typing import Any, Optional
6
+ from typing import Any
7
7
 
8
8
  import pandas
9
9
  import requests
10
10
  from annofabapi.models import Comment, CommentType
11
11
 
12
- import annofabcli
13
12
  import annofabcli.common.cli
14
13
  from annofabcli.common.cli import ArgumentParser, CommandLine, build_annofabapi_resource_and_login
15
14
  from annofabcli.common.enums import FormatArgument
@@ -61,7 +60,7 @@ class ListingComments(CommandLine):
61
60
  c["reply_count"] = reply_counter.get(key, 0)
62
61
  return comments
63
62
 
64
- def get_comment_list(self, project_id: str, task_id_list: list[str], *, comment_type: Optional[CommentType], exclude_reply: bool) -> list[dict[str, Any]]:
63
+ def get_comment_list(self, project_id: str, task_id_list: list[str], *, comment_type: CommentType | None, exclude_reply: bool) -> list[dict[str, Any]]:
65
64
  all_comments: list[Comment] = []
66
65
 
67
66
  for task_id in task_id_list:
@@ -151,7 +150,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
151
150
  parser.set_defaults(subcommand_func=main)
152
151
 
153
152
 
154
- def add_parser(subparsers: Optional[argparse._SubParsersAction] = None) -> argparse.ArgumentParser:
153
+ def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
155
154
  subcommand_name = "list"
156
155
  subcommand_help = "コメント一覧を出力します。"
157
156
 
@@ -4,10 +4,9 @@ import logging
4
4
  import multiprocessing
5
5
  import uuid
6
6
  from dataclasses import dataclass
7
- from typing import Any, Optional
7
+ from typing import Any
8
8
 
9
9
  import annofabapi
10
- import annofabapi.utils
11
10
  import requests
12
11
  from annofabapi.models import CommentType, TaskPhase, TaskStatus
13
12
  from dataclasses_json import DataClassJsonMixin
@@ -29,13 +28,13 @@ class AddedComment(DataClassJsonMixin):
29
28
  comment: str
30
29
  """コメントの中身"""
31
30
 
32
- data: Optional[dict[str, Any]]
31
+ data: dict[str, Any] | None
33
32
  """コメントを付与する位置や区間"""
34
33
 
35
- annotation_id: Optional[str]
34
+ annotation_id: str | None
36
35
  """コメントに紐付けるアノテーションID"""
37
36
 
38
- phrases: Optional[list[str]]
37
+ phrases: list[str] | None
39
38
  """参照している定型指摘ID"""
40
39
 
41
40
 
@@ -139,7 +138,7 @@ class PutCommentMain(CommandLineWithConfirm):
139
138
  self,
140
139
  task_id: str,
141
140
  comments_for_task: AddedCommentsForTask,
142
- task_index: Optional[int] = None,
141
+ task_index: int | None = None,
143
142
  ) -> int:
144
143
  """
145
144
  タスクにコメントを付与します。
@@ -207,7 +206,7 @@ class PutCommentMain(CommandLineWithConfirm):
207
206
  def add_comments_for_task_list(
208
207
  self,
209
208
  comments_for_task_list: AddedComments,
210
- parallelism: Optional[int] = None,
209
+ parallelism: int | None = None,
211
210
  ) -> None:
212
211
  comments_count = sum(len(e) for e in comments_for_task_list.values())
213
212
  logger.info(f"{self.comment_type_name}を付与するタスク数: {len(comments_for_task_list)}, {self.comment_type_name}を付与する入力データ数: {comments_count}")
@@ -252,10 +251,10 @@ def convert_cli_comments(dict_comments: dict[str, Any], *, comment_type: Comment
252
251
  data: dict[str, Any]
253
252
  """コメントを付与する位置や区間"""
254
253
 
255
- annotation_id: Optional[str] = None
254
+ annotation_id: str | None = None
256
255
  """コメントに紐付けるアノテーションID"""
257
256
 
258
- phrases: Optional[list[str]] = None
257
+ phrases: list[str] | None = None
259
258
  """参照している定型指摘ID"""
260
259
 
261
260
  @dataclass
@@ -267,7 +266,7 @@ def convert_cli_comments(dict_comments: dict[str, Any], *, comment_type: Comment
267
266
  comment: str
268
267
  """コメントの中身"""
269
268
 
270
- annotation_id: Optional[str] = None
269
+ annotation_id: str | None = None
271
270
  """コメントに紐付けるアノテーションID"""
272
271
 
273
272
  def convert_inspection_comment(comment: dict[str, Any]) -> AddedComment:
@@ -4,10 +4,9 @@ import uuid
4
4
  from collections.abc import Collection
5
5
  from dataclasses import dataclass
6
6
  from functools import partial
7
- from typing import Any, Optional
7
+ from typing import Any
8
8
 
9
9
  import annofabapi
10
- import annofabapi.utils
11
10
  from annofabapi.models import CommentType, TaskPhase, TaskStatus
12
11
 
13
12
  from annofabcli.comment.utils import get_comment_type_name
@@ -26,10 +25,10 @@ class AddedSimpleComment:
26
25
  comment: str
27
26
  """コメントの中身"""
28
27
 
29
- data: Optional[dict[str, Any]]
28
+ data: dict[str, Any] | None
30
29
  """コメントを付与する位置や区間"""
31
30
 
32
- phrases: Optional[list[str]] = None
31
+ phrases: list[str] | None = None
33
32
  """参照している定型指摘ID"""
34
33
 
35
34
 
@@ -103,7 +102,7 @@ class PutCommentSimplyMain(CommandLineWithConfirm):
103
102
  self,
104
103
  task_id: str,
105
104
  comment_info: AddedSimpleComment,
106
- task_index: Optional[int] = None,
105
+ task_index: int | None = None,
107
106
  ) -> bool:
108
107
  """
109
108
  タスクにコメントを付与します。
@@ -166,7 +165,7 @@ class PutCommentSimplyMain(CommandLineWithConfirm):
166
165
  self,
167
166
  task_ids: Collection[str],
168
167
  comment_info: AddedSimpleComment,
169
- parallelism: Optional[int] = None,
168
+ parallelism: int | None = None,
170
169
  ) -> None:
171
170
  logger.info(f"{len(task_ids)} 件のタスクに{self.comment_type_name}を付与します。")
172
171
 
@@ -4,11 +4,9 @@ import argparse
4
4
  import json
5
5
  import logging
6
6
  import sys
7
- from typing import Optional
8
7
 
9
8
  from annofabapi.models import CommentType, ProjectMemberRole
10
9
 
11
- import annofabcli
12
10
  import annofabcli.common.cli
13
11
  from annofabcli.comment.put_comment import PutCommentMain, convert_cli_comments
14
12
  from annofabcli.common.cli import (
@@ -83,7 +81,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
83
81
  parser.set_defaults(subcommand_func=main)
84
82
 
85
83
 
86
- def add_parser(subparsers: Optional[argparse._SubParsersAction] = None) -> argparse.ArgumentParser:
84
+ def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
87
85
  subcommand_name = "put_inspection"
88
86
  subcommand_help = "検査コメントを付与します"
89
87
  description = "検査コメントを付与します。"
@@ -1,12 +1,10 @@
1
1
  import argparse
2
2
  import logging
3
3
  import sys
4
- from typing import Optional
5
4
 
6
5
  from annofabapi.models import CommentType, InputDataType, ProjectMemberRole
7
6
  from annofabapi.plugin import EditorPluginId
8
7
 
9
- import annofabcli
10
8
  import annofabcli.common.cli
11
9
  from annofabcli.comment.put_comment_simply import AddedSimpleComment, PutCommentSimplyMain
12
10
  from annofabcli.common.cli import (
@@ -135,7 +133,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
135
133
  parser.set_defaults(subcommand_func=main)
136
134
 
137
135
 
138
- def add_parser(subparsers: Optional[argparse._SubParsersAction] = None) -> argparse.ArgumentParser:
136
+ def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
139
137
  subcommand_name = "put_inspection_simply"
140
138
  subcommand_help = "``comment put_inspection`` コマンドよりも、簡単に検査コメントを付与します。"
141
139
  epilog = "チェッカーロールまたはオーナロールを持つユーザで実行してください。"
@@ -2,11 +2,9 @@ import argparse
2
2
  import json
3
3
  import logging
4
4
  import sys
5
- from typing import Optional
6
5
 
7
6
  from annofabapi.models import CommentType
8
7
 
9
- import annofabcli
10
8
  import annofabcli.common.cli
11
9
  from annofabcli.comment.put_comment import PutCommentMain, convert_cli_comments
12
10
  from annofabcli.common.cli import (
@@ -84,7 +82,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
84
82
  parser.set_defaults(subcommand_func=main)
85
83
 
86
84
 
87
- def add_parser(subparsers: Optional[argparse._SubParsersAction] = None) -> argparse.ArgumentParser:
85
+ def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
88
86
  subcommand_name = "put_onhold"
89
87
  subcommand_help = "保留コメントを付与します"
90
88
 
@@ -1,11 +1,9 @@
1
1
  import argparse
2
2
  import logging
3
3
  import sys
4
- from typing import Optional
5
4
 
6
5
  from annofabapi.models import CommentType
7
6
 
8
- import annofabcli
9
7
  import annofabcli.common.cli
10
8
  from annofabcli.comment.put_comment_simply import AddedSimpleComment, PutCommentSimplyMain
11
9
  from annofabcli.common.cli import (
@@ -87,7 +85,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
87
85
  parser.set_defaults(subcommand_func=main)
88
86
 
89
87
 
90
- def add_parser(subparsers: Optional[argparse._SubParsersAction] = None) -> argparse.ArgumentParser:
88
+ def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
91
89
  subcommand_name = "put_onhold_simply"
92
90
  subcommand_help = "``comment put_onhold`` コマンドよりも、簡単に保留コメントを付与します。"
93
91
 
@@ -1,7 +1,5 @@
1
1
  import argparse
2
- from typing import Optional
3
2
 
4
- import annofabcli
5
3
  import annofabcli.comment.delete_comment
6
4
  import annofabcli.comment.download_comment_json
7
5
  import annofabcli.comment.list_all_comment
@@ -27,7 +25,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
27
25
  annofabcli.comment.put_onhold_comment_simply.add_parser(subparsers)
28
26
 
29
27
 
30
- def add_parser(subparsers: Optional[argparse._SubParsersAction] = None) -> argparse.ArgumentParser:
28
+ def add_parser(subparsers: argparse._SubParsersAction | None = None) -> argparse.ArgumentParser:
31
29
  subcommand_name = "comment"
32
30
  subcommand_help = "コメント関係のサブコマンド"
33
31
 
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import json
4
4
  import math
5
- from typing import Any, Optional
5
+ from typing import Any
6
6
 
7
7
  from bokeh.models import LayoutDOM
8
8
  from bokeh.models.widgets.markups import PreText
@@ -15,16 +15,16 @@ def create_pretext_from_metadata(metadata: dict[str, Any]) -> PreText:
15
15
  return PreText(text=text)
16
16
 
17
17
 
18
- def convert_1d_figure_list_to_2d(figure_list: list[figure], *, ncols: int = 4) -> list[list[Optional[LayoutDOM]]]:
18
+ def convert_1d_figure_list_to_2d(figure_list: list[figure], *, ncols: int = 4) -> list[list[LayoutDOM | None]]:
19
19
  """
20
20
  1次元のfigure_listを、grid layout用に2次元のfigureリストに変換する。
21
21
  """
22
- row_list: list[list[Optional[LayoutDOM]]] = []
22
+ row_list: list[list[LayoutDOM | None]] = []
23
23
 
24
24
  for i in range(math.ceil(len(figure_list) / ncols)):
25
25
  start = i * ncols
26
26
  end = (i + 1) * ncols
27
- row: list[Optional[LayoutDOM]] = []
27
+ row: list[LayoutDOM | None] = []
28
28
  row.extend(figure_list[start:end])
29
29
  if len(row) < ncols:
30
30
  row.extend([None] * (ncols - len(row)))
annofabcli/common/cli.py CHANGED
@@ -6,10 +6,11 @@ import argparse
6
6
  import getpass
7
7
  import json
8
8
  import logging
9
+ import logging.config
9
10
  import os
10
11
  import pkgutil
11
12
  from pathlib import Path
12
- from typing import Any, Optional
13
+ from typing import Any
13
14
 
14
15
  import annofabapi
15
16
  import pandas
@@ -81,12 +82,12 @@ def build_annofabapi_resource_and_login(args: argparse.Namespace) -> annofabapi.
81
82
 
82
83
 
83
84
  def add_parser(
84
- subparsers: Optional[argparse._SubParsersAction],
85
+ subparsers: argparse._SubParsersAction | None,
85
86
  command_name: str,
86
87
  command_help: str,
87
- description: Optional[str] = None,
88
+ description: str | None = None,
88
89
  is_subcommand: bool = True, # noqa: FBT001, FBT002
89
- epilog: Optional[str] = None,
90
+ epilog: str | None = None,
90
91
  ) -> argparse.ArgumentParser:
91
92
  """
92
93
  サブコマンド用にparserを追加する
@@ -159,7 +160,7 @@ def add_parser(
159
160
  return parser
160
161
 
161
162
 
162
- def get_list_from_args(str_list: Optional[list[str]] = None) -> list[str]:
163
+ def get_list_from_args(str_list: list[str] | None = None) -> list[str]:
163
164
  """
164
165
  文字列のListのサイズが1で、プレフィックスが`file://`ならば、ファイルパスとしてファイルを読み込み、行をListとして返す。
165
166
  そうでなければ、引数の値をそのまま返す。
@@ -185,7 +186,7 @@ def get_list_from_args(str_list: Optional[list[str]] = None) -> list[str]:
185
186
  return str_list
186
187
 
187
188
 
188
- def get_json_from_args(target: Optional[str] = None) -> Any: # noqa: ANN401
189
+ def get_json_from_args(target: str | None = None) -> Any: # noqa: ANN401
189
190
  """
190
191
  JSON形式をPythonオブジェクトに変換する。
191
192
  プレフィックスが`file://`ならば、ファイルパスとしてファイルを読み込み、Pythonオブジェクトを返す。
@@ -202,7 +203,7 @@ def get_json_from_args(target: Optional[str] = None) -> Any: # noqa: ANN401
202
203
  return json.loads(target)
203
204
 
204
205
 
205
- def get_input_data_size(str_input_data_size: str) -> Optional[InputDataSize]:
206
+ def get_input_data_size(str_input_data_size: str) -> InputDataSize | None:
206
207
  """400x300を(400,300)に変換する"""
207
208
  splitted_list = str_input_data_size.split("x")
208
209
  if len(splitted_list) < 2:
@@ -380,7 +381,7 @@ class ArgumentParser:
380
381
  def __init__(self, parser: argparse.ArgumentParser) -> None:
381
382
  self.parser = parser
382
383
 
383
- def add_project_id(self, help_message: Optional[str] = None) -> None:
384
+ def add_project_id(self, help_message: str | None = None) -> None:
384
385
  """
385
386
  '--project_id` 引数を追加
386
387
  """
@@ -389,7 +390,7 @@ class ArgumentParser:
389
390
 
390
391
  self.parser.add_argument("-p", "--project_id", type=str, required=True, help=help_message)
391
392
 
392
- def add_task_id(self, *, required: bool = True, help_message: Optional[str] = None) -> None:
393
+ def add_task_id(self, *, required: bool = True, help_message: str | None = None) -> None:
393
394
  """
394
395
  '--task_id` 引数を追加
395
396
  """
@@ -398,7 +399,7 @@ class ArgumentParser:
398
399
 
399
400
  self.parser.add_argument("-t", "--task_id", type=str, required=required, nargs="+", help=help_message)
400
401
 
401
- def add_input_data_id(self, *, required: bool = True, help_message: Optional[str] = None) -> None:
402
+ def add_input_data_id(self, *, required: bool = True, help_message: str | None = None) -> None:
402
403
  """
403
404
  '--input_data_id` 引数を追加
404
405
  """
@@ -407,7 +408,7 @@ class ArgumentParser:
407
408
 
408
409
  self.parser.add_argument("-i", "--input_data_id", type=str, required=required, nargs="+", help=help_message)
409
410
 
410
- def add_format(self, choices: list[FormatArgument], default: FormatArgument, help_message: Optional[str] = None) -> None:
411
+ def add_format(self, choices: list[FormatArgument], default: FormatArgument, help_message: str | None = None) -> None:
411
412
  """
412
413
  '--format` 引数を追加
413
414
  """
@@ -416,7 +417,7 @@ class ArgumentParser:
416
417
 
417
418
  self.parser.add_argument("-f", "--format", type=str, choices=[e.value for e in choices], default=default.value, help=help_message)
418
419
 
419
- def add_output(self, *, required: bool = False, help_message: Optional[str] = None) -> None:
420
+ def add_output(self, *, required: bool = False, help_message: str | None = None) -> None:
420
421
  """
421
422
  '--output` 引数を追加
422
423
  """
@@ -425,7 +426,7 @@ class ArgumentParser:
425
426
 
426
427
  self.parser.add_argument("-o", "--output", type=str, required=required, help=help_message)
427
428
 
428
- def add_task_query(self, *, required: bool = False, help_message: Optional[str] = None) -> None:
429
+ def add_task_query(self, *, required: bool = False, help_message: str | None = None) -> None:
429
430
  if help_message is None:
430
431
  help_message = (
431
432
  "タスクを絞り込むためのクエリ条件をJSON形式で指定します。"
@@ -476,10 +477,10 @@ class CommandLineWithoutWebapi:
476
477
  all_yes: bool = False
477
478
 
478
479
  #: 出力先
479
- output: Optional[str] = None
480
+ output: str | None = None
480
481
 
481
482
  #: 出力フォーマット
482
- str_format: Optional[str] = None
483
+ str_format: str | None = None
483
484
 
484
485
  def __init__(self, args: argparse.Namespace) -> None:
485
486
  self.args = args
@@ -575,8 +576,8 @@ class CommandLine(CommandLineWithoutWebapi):
575
576
  def validate_project(
576
577
  self,
577
578
  project_id: str,
578
- project_member_roles: Optional[list[ProjectMemberRole]] = None,
579
- organization_member_roles: Optional[list[OrganizationMemberRole]] = None,
579
+ project_member_roles: list[ProjectMemberRole] | None = None,
580
+ organization_member_roles: list[OrganizationMemberRole] | None = None,
580
581
  ) -> None:
581
582
  """
582
583
  プロジェクト or 組織に対して、必要な権限が付与されているかを確認する。