annofabcli 1.102.1__py3-none-any.whl → 1.103.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 (134) hide show
  1. annofabcli/annotation/annotation_query.py +9 -29
  2. annofabcli/annotation/change_annotation_attributes.py +6 -14
  3. annofabcli/annotation/change_annotation_properties.py +5 -12
  4. annofabcli/annotation/copy_annotation.py +4 -10
  5. annofabcli/annotation/delete_annotation.py +10 -26
  6. annofabcli/annotation/dump_annotation.py +1 -4
  7. annofabcli/annotation/import_annotation.py +16 -40
  8. annofabcli/annotation/list_annotation.py +1 -4
  9. annofabcli/annotation/merge_segmentation.py +5 -15
  10. annofabcli/annotation/remove_segmentation_overlap.py +8 -29
  11. annofabcli/annotation/restore_annotation.py +3 -9
  12. annofabcli/annotation_specs/add_attribute_restriction.py +2 -8
  13. annofabcli/annotation_specs/attribute_restriction.py +2 -10
  14. annofabcli/annotation_specs/export_annotation_specs.py +1 -3
  15. annofabcli/annotation_specs/get_annotation_specs_with_attribute_id_replaced.py +3 -10
  16. annofabcli/annotation_specs/get_annotation_specs_with_choice_id_replaced.py +4 -10
  17. annofabcli/annotation_specs/get_annotation_specs_with_label_id_replaced.py +1 -3
  18. annofabcli/annotation_specs/list_annotation_specs_attribute.py +7 -18
  19. annofabcli/annotation_specs/list_annotation_specs_choice.py +3 -8
  20. annofabcli/annotation_specs/list_annotation_specs_history.py +0 -1
  21. annofabcli/annotation_specs/list_annotation_specs_label.py +3 -8
  22. annofabcli/annotation_specs/list_annotation_specs_label_attribute.py +4 -9
  23. annofabcli/annotation_specs/list_attribute_restriction.py +3 -9
  24. annofabcli/annotation_specs/put_label_color.py +1 -6
  25. annofabcli/comment/delete_comment.py +3 -9
  26. annofabcli/comment/list_all_comment.py +2 -4
  27. annofabcli/comment/list_comment.py +1 -4
  28. annofabcli/comment/put_comment.py +4 -13
  29. annofabcli/comment/put_comment_simply.py +2 -6
  30. annofabcli/comment/put_inspection_comment.py +2 -6
  31. annofabcli/comment/put_inspection_comment_simply.py +3 -6
  32. annofabcli/comment/put_onhold_comment.py +2 -6
  33. annofabcli/comment/put_onhold_comment_simply.py +2 -4
  34. annofabcli/common/cli.py +5 -43
  35. annofabcli/common/download.py +8 -25
  36. annofabcli/common/image.py +5 -9
  37. annofabcli/common/utils.py +1 -3
  38. annofabcli/common/visualize.py +2 -4
  39. annofabcli/filesystem/draw_annotation.py +8 -20
  40. annofabcli/filesystem/filter_annotation.py +7 -24
  41. annofabcli/filesystem/mask_user_info.py +3 -6
  42. annofabcli/filesystem/merge_annotation.py +2 -6
  43. annofabcli/input_data/change_input_data_name.py +3 -7
  44. annofabcli/input_data/copy_input_data.py +6 -14
  45. annofabcli/input_data/delete_input_data.py +7 -24
  46. annofabcli/input_data/delete_metadata_key_of_input_data.py +5 -16
  47. annofabcli/input_data/list_all_input_data.py +5 -14
  48. annofabcli/input_data/list_all_input_data_merged_task.py +8 -23
  49. annofabcli/input_data/list_input_data.py +5 -16
  50. annofabcli/input_data/put_input_data.py +7 -19
  51. annofabcli/input_data/update_metadata_of_input_data.py +6 -14
  52. annofabcli/instruction/list_instruction_history.py +0 -1
  53. annofabcli/instruction/upload_instruction.py +1 -4
  54. annofabcli/job/list_job.py +1 -2
  55. annofabcli/job/list_last_job.py +1 -3
  56. annofabcli/organization/list_organization.py +0 -1
  57. annofabcli/organization_member/change_organization_member.py +1 -3
  58. annofabcli/organization_member/delete_organization_member.py +2 -6
  59. annofabcli/organization_member/invite_organization_member.py +1 -3
  60. annofabcli/organization_member/list_organization_member.py +0 -1
  61. annofabcli/project/change_organization_of_project.py +257 -0
  62. annofabcli/project/change_project_status.py +2 -2
  63. annofabcli/project/copy_project.py +2 -7
  64. annofabcli/project/diff_projects.py +4 -16
  65. annofabcli/project/list_project.py +0 -1
  66. annofabcli/project/put_project.py +2 -6
  67. annofabcli/project/subcommand_project.py +2 -0
  68. annofabcli/project_member/change_project_members.py +2 -2
  69. annofabcli/project_member/copy_project_members.py +2 -7
  70. annofabcli/project_member/drop_project_members.py +1 -3
  71. annofabcli/project_member/invite_project_members.py +1 -3
  72. annofabcli/project_member/list_users.py +0 -1
  73. annofabcli/project_member/put_project_members.py +4 -12
  74. annofabcli/stat_visualization/mask_visualization_dir.py +6 -16
  75. annofabcli/stat_visualization/merge_visualization_dir.py +6 -18
  76. annofabcli/stat_visualization/summarize_whole_performance_csv.py +3 -7
  77. annofabcli/stat_visualization/write_graph.py +5 -15
  78. annofabcli/stat_visualization/write_performance_rating_csv.py +4 -12
  79. annofabcli/statistics/list_annotation_area.py +3 -7
  80. annofabcli/statistics/list_annotation_attribute.py +6 -15
  81. annofabcli/statistics/list_annotation_attribute_filled_count.py +9 -23
  82. annofabcli/statistics/list_annotation_count.py +18 -44
  83. annofabcli/statistics/list_annotation_duration.py +14 -40
  84. annofabcli/statistics/list_video_duration.py +2 -3
  85. annofabcli/statistics/list_worktime.py +0 -1
  86. annofabcli/statistics/scatter.py +3 -9
  87. annofabcli/statistics/summarize_task_count.py +7 -12
  88. annofabcli/statistics/summarize_task_count_by_task_id_group.py +3 -11
  89. annofabcli/statistics/summarize_task_count_by_user.py +1 -5
  90. annofabcli/statistics/visualization/dataframe/annotation_count.py +1 -3
  91. annofabcli/statistics/visualization/dataframe/cumulative_productivity.py +3 -9
  92. annofabcli/statistics/visualization/dataframe/productivity_per_date.py +11 -23
  93. annofabcli/statistics/visualization/dataframe/project_performance.py +1 -3
  94. annofabcli/statistics/visualization/dataframe/task.py +2 -5
  95. annofabcli/statistics/visualization/dataframe/task_worktime_by_phase_user.py +6 -20
  96. annofabcli/statistics/visualization/dataframe/user_performance.py +29 -88
  97. annofabcli/statistics/visualization/dataframe/whole_performance.py +4 -10
  98. annofabcli/statistics/visualization/dataframe/whole_productivity_per_date.py +17 -49
  99. annofabcli/statistics/visualization/dataframe/worktime_per_date.py +3 -9
  100. annofabcli/statistics/visualization/filtering_query.py +2 -6
  101. annofabcli/statistics/visualization/project_dir.py +9 -26
  102. annofabcli/statistics/visualization/visualization_source_files.py +3 -10
  103. annofabcli/statistics/visualize_annotation_count.py +7 -21
  104. annofabcli/statistics/visualize_annotation_duration.py +7 -17
  105. annofabcli/statistics/visualize_statistics.py +17 -52
  106. annofabcli/statistics/visualize_video_duration.py +8 -19
  107. annofabcli/supplementary/delete_supplementary_data.py +7 -23
  108. annofabcli/supplementary/list_supplementary_data.py +1 -1
  109. annofabcli/supplementary/put_supplementary_data.py +5 -15
  110. annofabcli/task/cancel_acceptance.py +3 -4
  111. annofabcli/task/change_operator.py +3 -11
  112. annofabcli/task/change_status_to_break.py +1 -1
  113. annofabcli/task/change_status_to_on_hold.py +5 -18
  114. annofabcli/task/complete_tasks.py +8 -25
  115. annofabcli/task/copy_tasks.py +2 -3
  116. annofabcli/task/delete_metadata_key_of_task.py +2 -6
  117. annofabcli/task/delete_tasks.py +7 -25
  118. annofabcli/task/list_all_tasks.py +2 -4
  119. annofabcli/task/list_tasks.py +2 -6
  120. annofabcli/task/list_tasks_added_task_history.py +7 -21
  121. annofabcli/task/put_tasks.py +2 -3
  122. annofabcli/task/put_tasks_by_count.py +3 -7
  123. annofabcli/task/reject_tasks.py +7 -19
  124. annofabcli/task/update_metadata_of_task.py +1 -1
  125. annofabcli/task_history/list_all_task_history.py +2 -5
  126. annofabcli/task_history/list_task_history.py +0 -1
  127. annofabcli/task_history_event/list_all_task_history_event.py +4 -11
  128. annofabcli/task_history_event/list_worktime.py +4 -14
  129. {annofabcli-1.102.1.dist-info → annofabcli-1.103.0.dist-info}/METADATA +1 -1
  130. annofabcli-1.103.0.dist-info/RECORD +215 -0
  131. annofabcli-1.102.1.dist-info/RECORD +0 -214
  132. {annofabcli-1.102.1.dist-info → annofabcli-1.103.0.dist-info}/WHEEL +0 -0
  133. {annofabcli-1.102.1.dist-info → annofabcli-1.103.0.dist-info}/entry_points.txt +0 -0
  134. {annofabcli-1.102.1.dist-info → annofabcli-1.103.0.dist-info}/licenses/LICENSE +0 -0
@@ -70,18 +70,14 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
70
70
  parser.add_argument(
71
71
  "--json",
72
72
  type=str,
73
- help=(
74
- "付与する検査コメントの内容をJSON形式で指定してください。"
75
- "``file://`` を先頭に付けると、JSON形式のファイルを指定できます。\n\n"
76
- f"(ex) ``{json.dumps(SAMPLE_JSON, ensure_ascii=False)}``"
77
- ),
73
+ help=(f"付与する検査コメントの内容をJSON形式で指定してください。``file://`` を先頭に付けると、JSON形式のファイルを指定できます。\n\n(ex) ``{json.dumps(SAMPLE_JSON, ensure_ascii=False)}``"),
78
74
  )
79
75
 
80
76
  parser.add_argument(
81
77
  "--parallelism",
82
78
  type=int,
83
79
  choices=PARALLELISM_CHOICES,
84
- help="使用するプロセス数(並列度)を指定してください。指定する場合は必ず ``--yes`` を指定してください。指定しない場合は、逐次的に処理します。", # noqa: E501
80
+ help="使用するプロセス数(並列度)を指定してください。指定する場合は必ず ``--yes`` を指定してください。指定しない場合は、逐次的に処理します。",
85
81
  )
86
82
 
87
83
  parser.set_defaults(subcommand_func=main)
@@ -94,10 +94,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
94
94
  type=str,
95
95
  nargs="+",
96
96
  required=True,
97
- help=(
98
- "検査コメントを付与するタスクのtask_idを指定してください。\n"
99
- "``file://`` を先頭に付けると、task_idの一覧が記載されたファイルを指定できます。"
100
- ),
97
+ help=("検査コメントを付与するタスクのtask_idを指定してください。\n``file://`` を先頭に付けると、task_idの一覧が記載されたファイルを指定できます。"),
101
98
  )
102
99
 
103
100
  parser.add_argument(
@@ -125,14 +122,14 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
125
122
  "--custom_project_type",
126
123
  type=str,
127
124
  choices=[e.value for e in CustomProjectType],
128
- help="[BETA] ビルトインのエディタプラグインを使用していないカスタムプロジェクトの種類を指定します。カスタムプロジェクトに対して、検査コメントの位置を指定しない場合は必須です。\n", # noqa: E501
125
+ help="[BETA] ビルトインのエディタプラグインを使用していないカスタムプロジェクトの種類を指定します。カスタムプロジェクトに対して、検査コメントの位置を指定しない場合は必須です。\n",
129
126
  )
130
127
 
131
128
  parser.add_argument(
132
129
  "--parallelism",
133
130
  type=int,
134
131
  choices=PARALLELISM_CHOICES,
135
- help="使用するプロセス数(並列度)を指定してください。指定する場合は必ず ``--yes`` を指定してください。指定しない場合は、逐次的に処理します。", # noqa: E501
132
+ help="使用するプロセス数(並列度)を指定してください。指定する場合は必ず ``--yes`` を指定してください。指定しない場合は、逐次的に処理します。",
136
133
  )
137
134
 
138
135
  parser.set_defaults(subcommand_func=main)
@@ -71,18 +71,14 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
71
71
  parser.add_argument(
72
72
  "--json",
73
73
  type=str,
74
- help=(
75
- "付与する保留コメントの情報をJSON形式で指定してください。"
76
- "``file://`` を先頭に付けると、JSON形式のファイルを指定できます。\n\n"
77
- f"(ex) ``{json.dumps(SAMPLE_JSON, ensure_ascii=False)}``"
78
- ),
74
+ help=(f"付与する保留コメントの情報をJSON形式で指定してください。``file://`` を先頭に付けると、JSON形式のファイルを指定できます。\n\n(ex) ``{json.dumps(SAMPLE_JSON, ensure_ascii=False)}``"),
79
75
  )
80
76
 
81
77
  parser.add_argument(
82
78
  "--parallelism",
83
79
  type=int,
84
80
  choices=PARALLELISM_CHOICES,
85
- help="使用するプロセス数(並列度)を指定してください。指定する場合は必ず ``--yes`` を指定してください。指定しない場合は、逐次的に処理します。", # noqa: E501
81
+ help="使用するプロセス数(並列度)を指定してください。指定する場合は必ず ``--yes`` を指定してください。指定しない場合は、逐次的に処理します。",
86
82
  )
87
83
 
88
84
  parser.set_defaults(subcommand_func=main)
@@ -67,9 +67,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
67
67
  type=str,
68
68
  nargs="+",
69
69
  required=True,
70
- help=(
71
- "コメントを付与するタスクのtask_idを指定してください。\n``file://`` を先頭に付けると、task_idの一覧が記載されたファイルを指定できます。"
72
- ),
70
+ help=("コメントを付与するタスクのtask_idを指定してください。\n``file://`` を先頭に付けると、task_idの一覧が記載されたファイルを指定できます。"),
73
71
  )
74
72
 
75
73
  parser.add_argument(
@@ -83,7 +81,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
83
81
  "--parallelism",
84
82
  type=int,
85
83
  choices=PARALLELISM_CHOICES,
86
- help="使用するプロセス数(並列度)を指定してください。指定する場合は必ず ``--yes`` を指定してください。指定しない場合は、逐次的に処理します。", # noqa: E501
84
+ help="使用するプロセス数(並列度)を指定してください。指定する場合は必ず ``--yes`` を指定してください。指定しない場合は、逐次的に処理します。",
87
85
  )
88
86
 
89
87
  parser.set_defaults(subcommand_func=main)
annofabcli/common/cli.py CHANGED
@@ -25,7 +25,6 @@ from annofabcli.common.exceptions import AnnofabCliException, AuthenticationErro
25
25
  from annofabcli.common.facade import AnnofabApiFacade
26
26
  from annofabcli.common.typing import InputDataSize
27
27
  from annofabcli.common.utils import (
28
- DEFAULT_CSV_FORMAT,
29
28
  get_file_scheme_path,
30
29
  print_according_to_format,
31
30
  print_csv,
@@ -130,9 +129,7 @@ def add_parser(
130
129
 
131
130
  group.add_argument("--disable_log", action="store_true", help="ログを無効にします。")
132
131
 
133
- group.add_argument(
134
- "--debug", action="store_true", help="HTTPリクエストの内容やレスポンスのステータスコードなど、デバッグ用のログが出力されます。"
135
- )
132
+ group.add_argument("--debug", action="store_true", help="HTTPリクエストの内容やレスポンスのステータスコードなど、デバッグ用のログが出力されます。")
136
133
 
137
134
  return parent_parser
138
135
 
@@ -150,7 +147,7 @@ def add_parser(
150
147
  )
151
148
  parser.set_defaults(command_help=parser.print_help)
152
149
 
153
- # 引数グループに"global optional group"がある場合は、"--help"オプションをデフォルトの"optional"グループから、"global optional arguments"グループに移動する # noqa: E501
150
+ # 引数グループに"global optional group"がある場合は、"--help"オプションをデフォルトの"optional"グループから、"global optional arguments"グループに移動する
154
151
  # https://ja.stackoverflow.com/a/57313/19524
155
152
  global_optional_argument_group = first_true(parser._action_groups, pred=lambda e: e.title == GLOBAL_OPTIONAL_ARGUMENTS_TITLE) # noqa: SLF001
156
153
  if global_optional_argument_group is not None:
@@ -188,20 +185,6 @@ def get_list_from_args(str_list: Optional[list[str]] = None) -> list[str]:
188
185
  return str_list
189
186
 
190
187
 
191
- def get_csv_format_from_args(target: Optional[str] = None) -> dict[str, Any]:
192
- """
193
- コマンドライン引数の値から csv_format を取得する。
194
- Default: {"encoding": "utf_8_sig", "index": False}
195
-
196
- """
197
- csv_format = DEFAULT_CSV_FORMAT.copy()
198
- if target is not None:
199
- arg_csv_format = get_json_from_args(target)
200
- csv_format.update(arg_csv_format)
201
-
202
- return csv_format
203
-
204
-
205
188
  def get_json_from_args(target: Optional[str] = None) -> Any: # noqa: ANN401
206
189
  """
207
190
  JSON形式をPythonオブジェクトに変換する。
@@ -420,9 +403,7 @@ class ArgumentParser:
420
403
  '--input_data_id` 引数を追加
421
404
  """
422
405
  if help_message is None:
423
- help_message = (
424
- "対象の入力データのinput_data_idを指定します。 ``file://`` を先頭に付けると、input_data_idの一覧が記載されたファイルを指定できます。"
425
- )
406
+ help_message = "対象の入力データのinput_data_idを指定します。 ``file://`` を先頭に付けると、input_data_idの一覧が記載されたファイルを指定できます。"
426
407
 
427
408
  self.parser.add_argument("-i", "--input_data_id", type=str, required=required, nargs="+", help=help_message)
428
409
 
@@ -435,19 +416,6 @@ class ArgumentParser:
435
416
 
436
417
  self.parser.add_argument("-f", "--format", type=str, choices=[e.value for e in choices], default=default.value, help=help_message)
437
418
 
438
- def add_csv_format(self, help_message: Optional[str] = None) -> None:
439
- """
440
- '--csv_format` 引数を追加
441
- """
442
- if help_message is None:
443
- help_message = (
444
- "CSVのフォーマットをJSON形式で指定します。 ``--format`` が ``csv`` でないときは、このオプションは無視されます。\n"
445
- "``file://`` を先頭に付けると、JSON形式のファイルを指定できます。\n"
446
- "指定した値は ``pandas.DataFrame.to_csv`` の引数として渡されます。"
447
- )
448
-
449
- self.parser.add_argument("--csv_format", type=str, help=help_message)
450
-
451
419
  def add_output(self, *, required: bool = False, help_message: Optional[str] = None) -> None:
452
420
  """
453
421
  '--output` 引数を追加
@@ -510,9 +478,6 @@ class CommandLineWithoutWebapi:
510
478
  #: 出力先
511
479
  output: Optional[str] = None
512
480
 
513
- #: CSVのフォーマット
514
- csv_format: Optional[dict[str, Any]] = None
515
-
516
481
  #: 出力フォーマット
517
482
  str_format: Optional[str] = None
518
483
 
@@ -530,9 +495,6 @@ class CommandLineWithoutWebapi:
530
495
  if hasattr(args, "query"):
531
496
  self.query = args.query
532
497
 
533
- if hasattr(args, "csv_format"):
534
- self.csv_format = get_csv_format_from_args(args.csv_format)
535
-
536
498
  if hasattr(args, "output"):
537
499
  self.output = args.output
538
500
 
@@ -590,10 +552,10 @@ class CommandLineWithoutWebapi:
590
552
  return True
591
553
 
592
554
  def print_csv(self, df: pandas.DataFrame) -> None:
593
- print_csv(df, output=self.output, to_csv_kwargs=self.csv_format)
555
+ print_csv(df, output=self.output)
594
556
 
595
557
  def print_according_to_format(self, target: Any) -> None: # noqa: ANN401
596
- print_according_to_format(target, format=FormatArgument(self.str_format), output=self.output, csv_format=self.csv_format)
558
+ print_according_to_format(target, format=FormatArgument(self.str_format), output=self.output)
597
559
 
598
560
 
599
561
  class PrettyHelpFormatter(argparse.RawTextHelpFormatter, argparse.ArgumentDefaultsHelpFormatter):
@@ -110,10 +110,7 @@ class DownloadingFile:
110
110
  except requests.HTTPError as e:
111
111
  # すでにジョブが進行中の場合は、無視する
112
112
  if e.response.status_code == requests.codes.conflict:
113
- logger.warning(
114
- f"別のバックグラウンドジョブが既に実行されているので、アノテーションZIPの更新処理を実行できません。"
115
- f" :: error_message: {_get_annofab_error_message(e)}"
116
- )
113
+ logger.warning(f"別のバックグラウンドジョブが既に実行されているので、アノテーションZIPの更新処理を実行できません。 :: error_message: {_get_annofab_error_message(e)}")
117
114
  else:
118
115
  raise e # noqa: TRY201
119
116
 
@@ -160,9 +157,7 @@ class DownloadingFile:
160
157
  except requests.HTTPError as e:
161
158
  # すでにジョブが進行中の場合は、無視する
162
159
  if e.response.status_code == requests.codes.conflict:
163
- logger.warning(
164
- f"別のバックグラウンドジョブが既に実行されているので、更新処理を無視します。 :: error_message: {_get_annofab_error_message(e)}"
165
- )
160
+ logger.warning(f"別のバックグラウンドジョブが既に実行されているので、更新処理を無視します。 :: error_message: {_get_annofab_error_message(e)}")
166
161
  else:
167
162
  raise e # noqa: TRY201
168
163
 
@@ -179,9 +174,7 @@ class DownloadingFile:
179
174
  partial_func = partial(self.download_task_json, project_id, dest_path, is_latest=is_latest, wait_options=wait_options)
180
175
  await loop.run_in_executor(None, partial_func)
181
176
 
182
- def download_task_json(
183
- self, project_id: str, dest_path: Union[str, Path], *, is_latest: bool = False, wait_options: Optional[WaitOptions] = None
184
- ) -> None:
177
+ def download_task_json(self, project_id: str, dest_path: Union[str, Path], *, is_latest: bool = False, wait_options: Optional[WaitOptions] = None) -> None:
185
178
  if is_latest:
186
179
  self.wait_until_updated_task_json(project_id, wait_options)
187
180
  self.service.wrapper.download_project_tasks_url(project_id, dest_path)
@@ -205,9 +198,7 @@ class DownloadingFile:
205
198
  except requests.HTTPError as e:
206
199
  # すでにジョブが進行中の場合は、無視する
207
200
  if e.response.status_code == requests.codes.conflict:
208
- logger.warning(
209
- f"別のバックグラウンドジョブが既に実行されているので、更新処理を無視します。 :: error_message={_get_annofab_error_message(e)}"
210
- )
201
+ logger.warning(f"別のバックグラウンドジョブが既に実行されているので、更新処理を無視します。 :: error_message={_get_annofab_error_message(e)}")
211
202
  else:
212
203
  raise e # noqa: TRY201
213
204
 
@@ -237,9 +228,7 @@ class DownloadingFile:
237
228
  self.service.wrapper.download_project_task_histories_url(project_id, dest_path)
238
229
  except requests.HTTPError as e:
239
230
  if e.response.status_code == requests.codes.not_found:
240
- raise DownloadingFileNotFoundError(
241
- f"project_id='{project_id}'のプロジェクトに、タスク履歴全件ファイルが存在しないため、ダウンロードできませんでした。"
242
- ) from e
231
+ raise DownloadingFileNotFoundError(f"project_id='{project_id}'のプロジェクトに、タスク履歴全件ファイルが存在しないため、ダウンロードできませんでした。") from e
243
232
  raise e # noqa: TRY201
244
233
 
245
234
  def download_task_history_event_json(self, project_id: str, dest_path: Union[str, Path]) -> None:
@@ -257,9 +246,7 @@ class DownloadingFile:
257
246
  self.service.wrapper.download_project_task_history_events_url(project_id, dest_path)
258
247
  except requests.HTTPError as e:
259
248
  if e.response.status_code == requests.codes.not_found:
260
- raise DownloadingFileNotFoundError(
261
- f"project_id='{project_id}'のプロジェクトに、タスク履歴イベント全件ファイルが存在しないため、ダウンロードできませんでした。"
262
- ) from e
249
+ raise DownloadingFileNotFoundError(f"project_id='{project_id}'のプロジェクトに、タスク履歴イベント全件ファイルが存在しないため、ダウンロードできませんでした。") from e
263
250
  raise e # noqa: TRY201
264
251
 
265
252
  async def download_task_history_event_json_with_async(self, project_id: str, dest_path: Union[str, Path]) -> None:
@@ -294,9 +281,7 @@ class DownloadingFile:
294
281
  self.service.wrapper.download_project_inspections_url(project_id, dest_path)
295
282
  except requests.HTTPError as e:
296
283
  if e.response.status_code == requests.codes.not_found:
297
- raise DownloadingFileNotFoundError(
298
- f"project_id='{project_id}'のプロジェクトに、検査コメント全件ファイルが存在しないため、ダウンロードできませんでした。"
299
- ) from e
284
+ raise DownloadingFileNotFoundError(f"project_id='{project_id}'のプロジェクトに、検査コメント全件ファイルが存在しないため、ダウンロードできませんでした。") from e
300
285
  raise e # noqa: TRY201
301
286
 
302
287
  async def download_comment_json_with_async(self, project_id: str, dest_path: Union[str, Path]) -> None:
@@ -321,7 +306,5 @@ class DownloadingFile:
321
306
  self.service.wrapper.download_project_comments_url(project_id, dest_path)
322
307
  except requests.HTTPError as e:
323
308
  if e.response.status_code == requests.codes.not_found:
324
- raise DownloadingFileNotFoundError(
325
- f"project_id='{project_id}'のプロジェクトに、コメント全件ファイルが存在しないため、ダウンロードできませんでした。"
326
- ) from e
309
+ raise DownloadingFileNotFoundError(f"project_id='{project_id}'のプロジェクトに、コメント全件ファイルが存在しないため、ダウンロードできませんでした。") from e
327
310
  raise e # noqa: TRY201
@@ -112,7 +112,7 @@ def fill_annotation_list(
112
112
 
113
113
  # 下層レイヤにあるアノテーションから順に画像化する
114
114
  # reversed関数を使う理由:`simple_annotation.details`は上層レイヤのアノテーションから順に格納されているため
115
- if label_name_list is not None:
115
+ if label_name_list is not None: # noqa: SIM108
116
116
  annotation_list = [elm for elm in reversed(simple_annotation.details) if elm.label in label_name_list]
117
117
  else:
118
118
  annotation_list = list(reversed(simple_annotation.details))
@@ -219,15 +219,13 @@ def write_annotation_grayscale_image(
219
219
 
220
220
  # 下層レイヤにあるアノテーションから順に画像化する
221
221
  # reversed関数を使う理由:`simple_annotation.details`は上層レイヤのアノテーションから順に格納されているため
222
- if label_name_list is not None:
222
+ if label_name_list is not None: # noqa: SIM108
223
223
  annotation_list = [elm for elm in reversed(simple_annotation["details"]) if elm["label"] in set(label_name_list)]
224
224
  else:
225
225
  annotation_list = list(reversed(simple_annotation["details"]))
226
226
 
227
227
  # 描画対象のアノテーションを絞り込む
228
- annotation_list = [
229
- e for e in annotation_list if e["data"] is not None and e["data"]["_type"] in ["BoundingBox", "Points", "SegmentationV2", "Segmentation"]
230
- ]
228
+ annotation_list = [e for e in annotation_list if e["data"] is not None and e["data"]["_type"] in ["BoundingBox", "Points", "SegmentationV2", "Segmentation"]]
231
229
 
232
230
  if len(annotation_list) > 255:
233
231
  # channel depthは8bitなので、255個のアノテーションまでしか描画できない
@@ -297,7 +295,7 @@ def write_annotation_images_from_path(
297
295
  Returns:
298
296
  True: アノテーション情報の画像化に成功した。False: アノテーション情報の画像化に失敗した。
299
297
 
300
- """ # noqa: E501
298
+ """
301
299
 
302
300
  def _get_image_size(input_data_id: str) -> Optional[InputDataSize]:
303
301
  def _get_image_size_from_system_metadata(arg_input_data: dict[str, Any]): # noqa: ANN202
@@ -306,9 +304,7 @@ def write_annotation_images_from_path(
306
304
  if original_resolution is not None and (original_resolution.get("width") is not None and original_resolution.get("height") is not None):
307
305
  return original_resolution.get("width"), original_resolution.get("height")
308
306
  else:
309
- logger.warning(
310
- f"input_data_id='{input_data_id}'のプロパティ`system_metadata.original_resolution`には画像サイズが設定されていません。"
311
- )
307
+ logger.warning(f"input_data_id='{input_data_id}'のプロパティ`system_metadata.original_resolution`には画像サイズが設定されていません。")
312
308
  return None
313
309
 
314
310
  if image_size is not None:
@@ -110,7 +110,6 @@ def print_according_to_format(
110
110
  target: Any, # noqa: ANN401
111
111
  format: FormatArgument, # noqa: A002
112
112
  output: Optional[Union[str, Path]] = None,
113
- csv_format: Optional[dict[str, Any]] = None,
114
113
  ) -> None:
115
114
  """
116
115
  コマンドライン引数 ``--format`` の値にしたがって、内容を出力する。
@@ -119,7 +118,6 @@ def print_according_to_format(
119
118
  target: 出力する内容
120
119
  format: 出力フォーマット
121
120
  output: 出力先(オプション)
122
- csv_format: CSVのフォーマット(オプション)
123
121
 
124
122
 
125
123
  """
@@ -132,7 +130,7 @@ def print_according_to_format(
132
130
 
133
131
  elif format == FormatArgument.CSV:
134
132
  df = pandas.DataFrame(target)
135
- print_csv(df, output=output, to_csv_kwargs=csv_format)
133
+ print_csv(df, output=output)
136
134
 
137
135
  elif format == FormatArgument.TASK_ID_LIST:
138
136
  task_id_list = [e["task_id"] for e in target]
@@ -47,9 +47,7 @@ class AddProps:
47
47
  アノテーション仕様に関する情報をインスタンス変数に格納します。
48
48
  """
49
49
  annotation_specs, _ = self.service.api.get_annotation_specs(self.project_id, query_params={"v": "2"})
50
- self._specs_labels = convert_annotation_specs_labels_v2_to_v1(
51
- labels_v2=annotation_specs["labels"], additionals_v2=annotation_specs["additionals"]
52
- )
50
+ self._specs_labels = convert_annotation_specs_labels_v2_to_v1(labels_v2=annotation_specs["labels"], additionals_v2=annotation_specs["additionals"])
53
51
  self._specs_inspection_phrases = annotation_specs["inspection_phrases"]
54
52
 
55
53
  @property
@@ -345,7 +343,7 @@ class AddProps:
345
343
  task["number_of_rejections_by_inspection"] = get_number_of_rejections(histories, TaskPhase.INSPECTION)
346
344
  task["number_of_rejections_by_acceptance"] = get_number_of_rejections(histories, TaskPhase.ACCEPTANCE)
347
345
 
348
- # number_of_rejectionsは非推奨なプロパティで、number_of_rejections_by_inspection/number_of_rejections_by_acceptanceと矛盾する場合があるので、削除する # noqa: E501
346
+ # number_of_rejectionsは非推奨なプロパティで、number_of_rejections_by_inspection/number_of_rejections_by_acceptanceと矛盾する場合があるので、削除する
349
347
  task.pop("number_of_rejections", None)
350
348
 
351
349
  task["input_data_count"] = len(task["input_data_id_list"])
@@ -259,25 +259,21 @@ def draw_annotation_all( # noqa: ANN201, PLR0913
259
259
  continue
260
260
 
261
261
  json_file = Path(parser.json_file_path)
262
- if image_file is not None:
262
+ if image_file is not None: # noqa: SIM108
263
263
  output_file = output_dir / f"{json_file.parent.name}/{json_file.stem}{image_file.suffix}"
264
264
  else:
265
265
  output_file = output_dir / f"{json_file.parent.name}/{json_file.stem}.png"
266
266
 
267
267
  try:
268
268
  drawing.main(parser, image_file=image_file, output_file=output_file, image_size=default_image_size)
269
- logger.debug(
270
- f"{success_count + 1}件目: {output_file!s} を出力しました。image_file={image_file}, アノテーションJSON={parser.json_file_path}"
271
- )
269
+ logger.debug(f"{success_count + 1}件目: {output_file!s} を出力しました。image_file={image_file}, アノテーションJSON={parser.json_file_path}")
272
270
  success_count += 1
273
271
  except Exception: # pylint: disable=broad-except
274
272
  logger.warning(f"{parser.json_file_path} のアノテーションの描画に失敗しました。", exc_info=True)
275
273
 
276
274
  logger.info(f"{success_count} / {total_count} 件、アノテーションを描画しました。")
277
275
 
278
- new_label_color_dict = {
279
- label_name: ImageColor.getrgb(color) if isinstance(color, str) else color for label_name, color in drawing.label_color_dict.items()
280
- }
276
+ new_label_color_dict = {label_name: ImageColor.getrgb(color) if isinstance(color, str) else color for label_name, color in drawing.label_color_dict.items()}
281
277
  logger.info(f"label_color={json.dumps(new_label_color_dict, ensure_ascii=False)}")
282
278
 
283
279
 
@@ -321,7 +317,7 @@ class DrawAnnotation(CommandLineWithoutWebapi):
321
317
 
322
318
  annotation_path: Path = args.annotation
323
319
  # Simpleアノテーションの読み込み
324
- if annotation_path.is_file():
320
+ if annotation_path.is_file(): # noqa: SIM108
325
321
  iter_parser = lazy_parse_simple_annotation_zip(annotation_path)
326
322
  else:
327
323
  iter_parser = lazy_parse_simple_annotation_dir(annotation_path)
@@ -367,9 +363,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
367
363
  help="Annofabからダウンロードしたアノテーションzip、またはzipを展開したディレクトリを指定してください。",
368
364
  )
369
365
 
370
- parser.add_argument(
371
- "--image_dir", type=Path, help="画像が存在するディレクトリを指定してください。\n'--input_data_id_csv'を指定したときは必須です。"
372
- )
366
+ parser.add_argument("--image_dir", type=Path, help="画像が存在するディレクトリを指定してください。\n'--input_data_id_csv'を指定したときは必須です。")
373
367
 
374
368
  parser.add_argument(
375
369
  "--input_data_id_csv",
@@ -380,17 +374,13 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
380
374
  "詳細は https://annofab-cli.readthedocs.io/ja/latest/command_reference/filesystem/draw_annotation.html を参照してください。",
381
375
  )
382
376
 
383
- parser.add_argument(
384
- "--default_image_size", type=str, help="デフォルトの画像サイズ。 ``--input_data_id_csv`` を指定しないときは必須です。\n(例) 1280x720"
385
- )
377
+ parser.add_argument("--default_image_size", type=str, help="デフォルトの画像サイズ。 ``--input_data_id_csv`` を指定しないときは必須です。\n(例) 1280x720")
386
378
 
387
379
  LABEL_COLOR_SAMPLE = {"dog": [255, 128, 64], "cat": "blue"} # noqa: N806
388
380
  parser.add_argument(
389
381
  "--label_color",
390
382
  type=str,
391
- help="label_nameとRGBの関係をJSON形式で指定します。\n"
392
- f"(例) ``{json.dumps(LABEL_COLOR_SAMPLE)}``\n"
393
- "``file://`` を先頭に付けると、JSON形式のファイルを指定できます。",
383
+ help=f"label_nameとRGBの関係をJSON形式で指定します。\n(例) ``{json.dumps(LABEL_COLOR_SAMPLE)}``\n``file://`` を先頭に付けると、JSON形式のファイルを指定できます。",
394
384
  )
395
385
 
396
386
  parser.add_argument(
@@ -425,9 +415,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
425
415
  parser.add_argument(
426
416
  "--drawing_options",
427
417
  type=str,
428
- help="描画オプションをJSON形式で指定します。\n"
429
- f"(例) ``{json.dumps(DRAWING_OPTIONS_SAMPLE)}``\n\n"
430
- "``file://`` を先頭に付けると、JSON形式のファイルを指定できます。",
418
+ help=f"描画オプションをJSON形式で指定します。\n(例) ``{json.dumps(DRAWING_OPTIONS_SAMPLE)}``\n\n``file://`` を先頭に付けると、JSON形式のファイルを指定できます。",
431
419
  )
432
420
 
433
421
  argument_parser.add_task_id(
@@ -126,13 +126,9 @@ class FilterAnnotation:
126
126
  task_id_set = set(annofabcli.common.cli.get_list_from_args(args.task_id)) if args.task_id is not None else None
127
127
  exclude_task_id_set = set(annofabcli.common.cli.get_list_from_args(args.exclude_task_id)) if args.exclude_task_id is not None else None
128
128
  input_data_id_set = set(annofabcli.common.cli.get_list_from_args(args.input_data_id)) if args.input_data_id is not None else None
129
- exclude_input_data_id_set = (
130
- set(annofabcli.common.cli.get_list_from_args(args.exclude_input_data_id)) if args.exclude_input_data_id is not None else None
131
- )
129
+ exclude_input_data_id_set = set(annofabcli.common.cli.get_list_from_args(args.exclude_input_data_id)) if args.exclude_input_data_id is not None else None
132
130
  input_data_name_set = set(annofabcli.common.cli.get_list_from_args(args.input_data_name)) if args.input_data_name is not None else None
133
- exclude_input_data_name_set = (
134
- set(annofabcli.common.cli.get_list_from_args(args.exclude_input_data_name)) if args.exclude_input_data_name is not None else None
135
- )
131
+ exclude_input_data_name_set = set(annofabcli.common.cli.get_list_from_args(args.exclude_input_data_name)) if args.exclude_input_data_name is not None else None
136
132
 
137
133
  return FilterQuery(
138
134
  task_query=task_query,
@@ -173,8 +169,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
173
169
  "-tq",
174
170
  "--task_query",
175
171
  type=str,
176
- help="タスクを絞り込むためのクエリ条件をJSON形式で指定します。使用できるキーは task_id, status, phase, phase_stage です。"
177
- " ``file://`` を先頭に付けると、JSON形式のファイルを指定できます。",
172
+ help="タスクを絞り込むためのクエリ条件をJSON形式で指定します。使用できるキーは task_id, status, phase, phase_stage です。 ``file://`` を先頭に付けると、JSON形式のファイルを指定できます。",
178
173
  )
179
174
 
180
175
  id_name_list_group = parser.add_mutually_exclusive_group()
@@ -198,38 +193,26 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
198
193
  "--input_data_id",
199
194
  type=str,
200
195
  nargs="+",
201
- help=(
202
- "抽出する入力データのinput_data_idを指定してください。"
203
- " ``file://`` を先頭に付けると、input_data_id の一覧が記載されたファイルを指定できます。"
204
- ),
196
+ help=("抽出する入力データのinput_data_idを指定してください。 ``file://`` を先頭に付けると、input_data_id の一覧が記載されたファイルを指定できます。"),
205
197
  )
206
198
  id_name_list_group.add_argument(
207
199
  "--exclude_input_data_id",
208
200
  type=str,
209
201
  nargs="+",
210
- help=(
211
- "除外する入力データのinput_data_idを指定してください。"
212
- " ``file://`` を先頭に付けると、input_data_id の一覧が記載されたファイルを指定できます。"
213
- ),
202
+ help=("除外する入力データのinput_data_idを指定してください。 ``file://`` を先頭に付けると、input_data_id の一覧が記載されたファイルを指定できます。"),
214
203
  )
215
204
 
216
205
  id_name_list_group.add_argument(
217
206
  "--input_data_name",
218
207
  type=str,
219
208
  nargs="+",
220
- help=(
221
- "抽出する入力データのinput_data_nameを指定してください。"
222
- " ``file://`` を先頭に付けると、input_data_name の一覧が記載されたファイルを指定できます。"
223
- ),
209
+ help=("抽出する入力データのinput_data_nameを指定してください。 ``file://`` を先頭に付けると、input_data_name の一覧が記載されたファイルを指定できます。"),
224
210
  )
225
211
  id_name_list_group.add_argument(
226
212
  "--exclude_input_data_name",
227
213
  type=str,
228
214
  nargs="+",
229
- help=(
230
- "除外する入力データのinput_data_nameを指定してください。"
231
- " ``file://`` を先頭に付けると、input_data_name の一覧が記載されたファイルを指定できます。"
232
- ),
215
+ help=("除外する入力データのinput_data_nameを指定してください。 ``file://`` を先頭に付けると、input_data_name の一覧が記載されたファイルを指定できます。"),
233
216
  )
234
217
 
235
218
  parser.add_argument("-o", "--output_dir", type=Path, required=True, help="出力先ディレクトリのパス")
@@ -215,7 +215,7 @@ def create_replacement_dict_by_user_id(
215
215
  """
216
216
  keyが置換対象のuser_id、valueが置換後のマスクされたuser_idであるdictを作成する。
217
217
  """
218
- if "biography" in df:
218
+ if "biography" in df: # noqa: SIM108
219
219
  replaced_user_id_set = get_replaced_user_id_set_from_biography(df, not_masked_location_set=not_masked_biography_set)
220
220
  else:
221
221
  replaced_user_id_set = set()
@@ -296,9 +296,7 @@ def create_masked_user_info_df(
296
296
  return df
297
297
 
298
298
  df_output = df.copy()
299
- replacement_dict_by_user_id = create_replacement_dict_by_user_id(
300
- df, not_masked_biography_set=not_masked_biography_set, not_masked_user_id_set=not_masked_user_id_set
301
- )
299
+ replacement_dict_by_user_id = create_replacement_dict_by_user_id(df, not_masked_biography_set=not_masked_biography_set, not_masked_user_id_set=not_masked_user_id_set)
302
300
 
303
301
  if "biography" in df_output:
304
302
  replacement_dict_by_biography = create_replacement_dict_by_biography(df_output, not_masked_biography_set=not_masked_biography_set)
@@ -322,7 +320,7 @@ class MaskUserInfo(CommandLineWithoutWebapi):
322
320
 
323
321
  csv_header_row_count: int = args.csv_header_row_count
324
322
  csv_path: Path = args.csv
325
- if csv_header_row_count == 1:
323
+ if csv_header_row_count == 1: # noqa: SIM108
326
324
  original_df = pandas.read_csv(str(csv_path))
327
325
  else:
328
326
  original_df = read_multiheader_csv(str(csv_path), header_row_count=csv_header_row_count)
@@ -358,7 +356,6 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
358
356
  parser.add_argument("--csv_header_row_count", type=int, help="CSVのヘッダ行数", default=1)
359
357
 
360
358
  argument_parser.add_output()
361
- argument_parser.add_csv_format()
362
359
 
363
360
  parser.set_defaults(subcommand_func=main)
364
361
 
@@ -238,11 +238,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
238
238
 
239
239
  argument_parser.add_task_id(
240
240
  required=False,
241
- help_message=(
242
- "マージ対象であるタスクのtask_idを指定します。"
243
- "指定しない場合、すべてのタスクがマージ対象です。"
244
- " ``file://`` を先頭に付けると、task_idの一覧が記載されたファイルを指定できます。"
245
- ),
241
+ help_message=("マージ対象であるタスクのtask_idを指定します。指定しない場合、すべてのタスクがマージ対象です。 ``file://`` を先頭に付けると、task_idの一覧が記載されたファイルを指定できます。"),
246
242
  )
247
243
 
248
244
  parser.set_defaults(subcommand_func=main)
@@ -253,7 +249,7 @@ def add_parser(subparsers: Optional[argparse._SubParsersAction] = None) -> argpa
253
249
 
254
250
  subcommand_help = "2つのアノテーションzip(またはzipを展開したディレクトリ)をマージします。"
255
251
 
256
- description = "2つのアノテーションzip(またはzipを展開したディレクトリ)をマージします。具体的にはアノテーションjsonの'details'キー配下の情報をマージします。" # noqa: E501
252
+ description = "2つのアノテーションzip(またはzipを展開したディレクトリ)をマージします。具体的にはアノテーションjsonの'details'キー配下の情報をマージします。"
257
253
 
258
254
  parser = annofabcli.common.cli.add_parser(subparsers, subcommand_name, subcommand_help, description)
259
255
  parse_args(parser)
@@ -55,9 +55,7 @@ class ChangeInputDataNameMain(CommandLineWithConfirm):
55
55
  logger.warning(f"input_data_id='{input_data_id}'である入力データは存在しません。")
56
56
  return False
57
57
 
58
- if not self.confirm_processing(
59
- f"input_data_id='{input_data_id}' :: input_data_name='{old_input_data['input_data_name']}'を'{new_input_data_name}'に変更しますか?"
60
- ):
58
+ if not self.confirm_processing(f"input_data_id='{input_data_id}' :: input_data_name='{old_input_data['input_data_name']}'を'{new_input_data_name}'に変更しますか?"):
61
59
  return False
62
60
 
63
61
  request_body = old_input_data
@@ -187,9 +185,7 @@ class ChangeInputDataName(CommandLine):
187
185
 
188
186
  project_id: str = args.project_id
189
187
  if args.parallelism is not None:
190
- main_obj.change_input_data_name_list_in_parallel(
191
- project_id, changed_input_data_list=changed_input_data_list, parallelism=args.parallelism
192
- )
188
+ main_obj.change_input_data_name_list_in_parallel(project_id, changed_input_data_list=changed_input_data_list, parallelism=args.parallelism)
193
189
  else:
194
190
  main_obj.change_input_data_name_list_sequentially(project_id, changed_input_data_list=changed_input_data_list)
195
191
 
@@ -234,7 +230,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
234
230
  "--parallelism",
235
231
  type=int,
236
232
  choices=PARALLELISM_CHOICES,
237
- help="使用するプロセス数(並列度)を指定してください。指定する場合は必ず ``--yes`` を指定してください。指定しない場合は、逐次的に処理します。", # noqa: E501
233
+ help="使用するプロセス数(並列度)を指定してください。指定する場合は必ず ``--yes`` を指定してください。指定しない場合は、逐次的に処理します。",
238
234
  )
239
235
 
240
236
  parser.set_defaults(subcommand_func=main)