annofabcli 1.102.1__py3-none-any.whl → 1.104.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 (136) hide show
  1. annofabcli/__main__.py +1 -1
  2. annofabcli/annotation/annotation_query.py +9 -29
  3. annofabcli/annotation/change_annotation_attributes.py +6 -14
  4. annofabcli/annotation/change_annotation_properties.py +5 -12
  5. annofabcli/annotation/copy_annotation.py +4 -10
  6. annofabcli/annotation/delete_annotation.py +10 -26
  7. annofabcli/annotation/dump_annotation.py +1 -4
  8. annofabcli/annotation/import_annotation.py +15 -39
  9. annofabcli/annotation/list_annotation.py +1 -4
  10. annofabcli/annotation/merge_segmentation.py +5 -15
  11. annofabcli/annotation/remove_segmentation_overlap.py +8 -29
  12. annofabcli/annotation/restore_annotation.py +3 -9
  13. annofabcli/annotation_specs/add_attribute_restriction.py +2 -8
  14. annofabcli/annotation_specs/attribute_restriction.py +2 -10
  15. annofabcli/annotation_specs/export_annotation_specs.py +1 -3
  16. annofabcli/annotation_specs/get_annotation_specs_with_attribute_id_replaced.py +3 -10
  17. annofabcli/annotation_specs/get_annotation_specs_with_choice_id_replaced.py +4 -10
  18. annofabcli/annotation_specs/get_annotation_specs_with_label_id_replaced.py +1 -3
  19. annofabcli/annotation_specs/list_annotation_specs_attribute.py +7 -18
  20. annofabcli/annotation_specs/list_annotation_specs_choice.py +3 -8
  21. annofabcli/annotation_specs/list_annotation_specs_history.py +0 -1
  22. annofabcli/annotation_specs/list_annotation_specs_label.py +3 -8
  23. annofabcli/annotation_specs/list_annotation_specs_label_attribute.py +4 -9
  24. annofabcli/annotation_specs/list_attribute_restriction.py +3 -9
  25. annofabcli/annotation_specs/put_label_color.py +1 -6
  26. annofabcli/comment/delete_comment.py +3 -9
  27. annofabcli/comment/list_all_comment.py +15 -5
  28. annofabcli/comment/list_comment.py +46 -7
  29. annofabcli/comment/put_comment.py +4 -13
  30. annofabcli/comment/put_comment_simply.py +2 -6
  31. annofabcli/comment/put_inspection_comment.py +2 -6
  32. annofabcli/comment/put_inspection_comment_simply.py +3 -6
  33. annofabcli/comment/put_onhold_comment.py +2 -6
  34. annofabcli/comment/put_onhold_comment_simply.py +2 -4
  35. annofabcli/common/cli.py +5 -43
  36. annofabcli/common/download.py +8 -25
  37. annofabcli/common/image.py +3 -7
  38. annofabcli/common/utils.py +2 -4
  39. annofabcli/common/visualize.py +2 -4
  40. annofabcli/filesystem/draw_annotation.py +6 -18
  41. annofabcli/filesystem/filter_annotation.py +7 -24
  42. annofabcli/filesystem/mask_user_info.py +2 -5
  43. annofabcli/filesystem/merge_annotation.py +2 -6
  44. annofabcli/input_data/change_input_data_name.py +3 -7
  45. annofabcli/input_data/copy_input_data.py +6 -14
  46. annofabcli/input_data/delete_input_data.py +7 -24
  47. annofabcli/input_data/delete_metadata_key_of_input_data.py +5 -16
  48. annofabcli/input_data/list_all_input_data.py +5 -14
  49. annofabcli/input_data/list_all_input_data_merged_task.py +8 -23
  50. annofabcli/input_data/list_input_data.py +5 -16
  51. annofabcli/input_data/put_input_data.py +7 -19
  52. annofabcli/input_data/update_metadata_of_input_data.py +6 -14
  53. annofabcli/instruction/list_instruction_history.py +0 -1
  54. annofabcli/instruction/upload_instruction.py +4 -7
  55. annofabcli/job/list_job.py +2 -3
  56. annofabcli/job/list_last_job.py +1 -3
  57. annofabcli/organization/list_organization.py +0 -1
  58. annofabcli/organization_member/change_organization_member.py +1 -3
  59. annofabcli/organization_member/delete_organization_member.py +2 -6
  60. annofabcli/organization_member/invite_organization_member.py +1 -3
  61. annofabcli/organization_member/list_organization_member.py +0 -1
  62. annofabcli/project/change_organization_of_project.py +257 -0
  63. annofabcli/project/change_project_status.py +2 -2
  64. annofabcli/project/copy_project.py +2 -7
  65. annofabcli/project/diff_projects.py +4 -16
  66. annofabcli/project/list_project.py +0 -1
  67. annofabcli/project/put_project.py +2 -6
  68. annofabcli/project/subcommand_project.py +2 -0
  69. annofabcli/project_member/change_project_members.py +1 -1
  70. annofabcli/project_member/copy_project_members.py +2 -7
  71. annofabcli/project_member/drop_project_members.py +1 -3
  72. annofabcli/project_member/invite_project_members.py +2 -4
  73. annofabcli/project_member/list_users.py +0 -1
  74. annofabcli/project_member/put_project_members.py +4 -12
  75. annofabcli/stat_visualization/mask_visualization_dir.py +6 -16
  76. annofabcli/stat_visualization/merge_visualization_dir.py +7 -19
  77. annofabcli/stat_visualization/summarize_whole_performance_csv.py +3 -7
  78. annofabcli/stat_visualization/write_graph.py +5 -15
  79. annofabcli/stat_visualization/write_performance_rating_csv.py +4 -12
  80. annofabcli/statistics/list_annotation_area.py +3 -7
  81. annofabcli/statistics/list_annotation_attribute.py +6 -15
  82. annofabcli/statistics/list_annotation_attribute_filled_count.py +9 -23
  83. annofabcli/statistics/list_annotation_count.py +18 -44
  84. annofabcli/statistics/list_annotation_duration.py +14 -40
  85. annofabcli/statistics/list_video_duration.py +2 -3
  86. annofabcli/statistics/list_worktime.py +0 -1
  87. annofabcli/statistics/scatter.py +3 -9
  88. annofabcli/statistics/summarize_task_count.py +7 -12
  89. annofabcli/statistics/summarize_task_count_by_task_id_group.py +3 -11
  90. annofabcli/statistics/summarize_task_count_by_user.py +1 -5
  91. annofabcli/statistics/visualization/dataframe/annotation_count.py +2 -4
  92. annofabcli/statistics/visualization/dataframe/cumulative_productivity.py +6 -12
  93. annofabcli/statistics/visualization/dataframe/productivity_per_date.py +10 -22
  94. annofabcli/statistics/visualization/dataframe/project_performance.py +1 -3
  95. annofabcli/statistics/visualization/dataframe/task.py +2 -5
  96. annofabcli/statistics/visualization/dataframe/task_history.py +1 -1
  97. annofabcli/statistics/visualization/dataframe/task_worktime_by_phase_user.py +6 -20
  98. annofabcli/statistics/visualization/dataframe/user_performance.py +29 -88
  99. annofabcli/statistics/visualization/dataframe/whole_performance.py +6 -12
  100. annofabcli/statistics/visualization/dataframe/whole_productivity_per_date.py +17 -49
  101. annofabcli/statistics/visualization/dataframe/worktime_per_date.py +4 -10
  102. annofabcli/statistics/visualization/filtering_query.py +2 -6
  103. annofabcli/statistics/visualization/project_dir.py +9 -26
  104. annofabcli/statistics/visualization/visualization_source_files.py +3 -10
  105. annofabcli/statistics/visualize_annotation_count.py +9 -23
  106. annofabcli/statistics/visualize_annotation_duration.py +5 -15
  107. annofabcli/statistics/visualize_statistics.py +18 -53
  108. annofabcli/statistics/visualize_video_duration.py +8 -19
  109. annofabcli/supplementary/delete_supplementary_data.py +7 -23
  110. annofabcli/supplementary/list_supplementary_data.py +1 -1
  111. annofabcli/supplementary/put_supplementary_data.py +5 -15
  112. annofabcli/task/cancel_acceptance.py +3 -4
  113. annofabcli/task/change_operator.py +3 -11
  114. annofabcli/task/change_status_to_break.py +1 -1
  115. annofabcli/task/change_status_to_on_hold.py +5 -18
  116. annofabcli/task/complete_tasks.py +8 -25
  117. annofabcli/task/copy_tasks.py +2 -3
  118. annofabcli/task/delete_metadata_key_of_task.py +2 -6
  119. annofabcli/task/delete_tasks.py +8 -26
  120. annofabcli/task/list_all_tasks.py +2 -4
  121. annofabcli/task/list_tasks.py +3 -7
  122. annofabcli/task/list_tasks_added_task_history.py +7 -21
  123. annofabcli/task/put_tasks.py +2 -3
  124. annofabcli/task/put_tasks_by_count.py +3 -7
  125. annofabcli/task/reject_tasks.py +7 -19
  126. annofabcli/task/update_metadata_of_task.py +2 -2
  127. annofabcli/task_history/list_all_task_history.py +2 -5
  128. annofabcli/task_history/list_task_history.py +0 -1
  129. annofabcli/task_history_event/list_all_task_history_event.py +4 -11
  130. annofabcli/task_history_event/list_worktime.py +4 -14
  131. {annofabcli-1.102.1.dist-info → annofabcli-1.104.0.dist-info}/METADATA +1 -1
  132. annofabcli-1.104.0.dist-info/RECORD +215 -0
  133. annofabcli-1.102.1.dist-info/RECORD +0 -214
  134. {annofabcli-1.102.1.dist-info → annofabcli-1.104.0.dist-info}/WHEEL +0 -0
  135. {annofabcli-1.102.1.dist-info → annofabcli-1.104.0.dist-info}/entry_points.txt +0 -0
  136. {annofabcli-1.102.1.dist-info → annofabcli-1.104.0.dist-info}/licenses/LICENSE +0 -0
@@ -214,15 +214,9 @@ class WriteCsvGraph:
214
214
  acceptor_obj = AcceptorCumulativeProductivity.from_df_wrapper(task_worktime_obj)
215
215
 
216
216
  if not self.output_only_text:
217
- self.project_dir.write_cumulative_line_graph(
218
- annotator_obj, phase=TaskPhase.ANNOTATION, user_id_list=user_id_list, minimal_output=self.minimal_output
219
- )
220
- self.project_dir.write_cumulative_line_graph(
221
- inspector_obj, phase=TaskPhase.INSPECTION, user_id_list=user_id_list, minimal_output=self.minimal_output
222
- )
223
- self.project_dir.write_cumulative_line_graph(
224
- acceptor_obj, phase=TaskPhase.ACCEPTANCE, user_id_list=user_id_list, minimal_output=self.minimal_output
225
- )
217
+ self.project_dir.write_cumulative_line_graph(annotator_obj, phase=TaskPhase.ANNOTATION, user_id_list=user_id_list, minimal_output=self.minimal_output)
218
+ self.project_dir.write_cumulative_line_graph(inspector_obj, phase=TaskPhase.INSPECTION, user_id_list=user_id_list, minimal_output=self.minimal_output)
219
+ self.project_dir.write_cumulative_line_graph(acceptor_obj, phase=TaskPhase.ACCEPTANCE, user_id_list=user_id_list, minimal_output=self.minimal_output)
226
220
 
227
221
  def write_worktime_per_date(self, user_id_list: Optional[list[str]] = None) -> None:
228
222
  """日ごとの作業時間情報を出力する。"""
@@ -231,15 +225,11 @@ class WriteCsvGraph:
231
225
  self.project_dir.write_worktime_per_date_user(worktime_per_date_obj)
232
226
 
233
227
  task = self._get_task()
234
- productivity_per_completed_date_obj = WholeProductivityPerCompletedDate.from_df_wrapper(
235
- task, worktime_per_date_obj, task_completion_criteria=self.task_completion_criteria
236
- )
228
+ productivity_per_completed_date_obj = WholeProductivityPerCompletedDate.from_df_wrapper(task, worktime_per_date_obj, task_completion_criteria=self.task_completion_criteria)
237
229
 
238
230
  self.project_dir.write_whole_productivity_per_date(productivity_per_completed_date_obj)
239
231
 
240
- productivity_per_started_date_obj = WholeProductivityPerFirstAnnotationStartedDate.from_task(
241
- task, task_completion_criteria=self.task_completion_criteria
242
- )
232
+ productivity_per_started_date_obj = WholeProductivityPerFirstAnnotationStartedDate.from_task(task, task_completion_criteria=self.task_completion_criteria)
243
233
  self.project_dir.write_whole_productivity_per_first_annotation_started_date(productivity_per_started_date_obj)
244
234
 
245
235
  if not self.output_only_text:
@@ -352,7 +342,7 @@ class VisualizingStatisticsMain:
352
342
  df_annotation_count = self.annotation_count.df
353
343
  df_annotation_count = df_annotation_count[df_annotation_count["project_id"] == project_id]
354
344
  # `annotation_count = None`にする理由:後続の処理でアノテーションZIPからアノテーション数を算出するようにするため
355
- if len(df_annotation_count) == 0: # noqa: SIM108
345
+ if len(df_annotation_count) == 0:
356
346
  annotation_count = None
357
347
  else:
358
348
  annotation_count = AnnotationCount(df_annotation_count)
@@ -525,12 +515,8 @@ class VisualizeStatistics(CommandLine):
525
515
 
526
516
  if len(output_project_dir_list) > 0:
527
517
  project_dir_list = [ProjectDir(e, task_completion_criteria) for e in output_project_dir_list]
528
- custom_production_volume_list = (
529
- custom_production_volume.custom_production_volume_list if custom_production_volume is not None else None
530
- )
531
- project_performance = ProjectPerformance.from_project_dirs(
532
- project_dir_list, custom_production_volume_list=custom_production_volume_list
533
- )
518
+ custom_production_volume_list = custom_production_volume.custom_production_volume_list if custom_production_volume is not None else None
519
+ project_performance = ProjectPerformance.from_project_dirs(project_dir_list, custom_production_volume_list=custom_production_volume_list)
534
520
  project_performance.to_csv(root_output_dir / "プロジェクトごとの生産性と品質.csv")
535
521
 
536
522
  project_actual_worktime = ProjectWorktimePerMonth.from_project_dirs(project_dir_list, WorktimeColumn.ACTUAL_WORKTIME_HOUR)
@@ -571,18 +557,14 @@ class VisualizeStatistics(CommandLine):
571
557
  else:
572
558
  df_actual_worktime = pandas.read_csv(args.labor_csv)
573
559
  if not ActualWorktime.required_columns_exist(df_actual_worktime):
574
- logger.error(
575
- "引数`--labor_csv`のCSVには以下の列が存在しないので、終了します。\n`project_id`, `date`, `account_id`, `actual_worktime_hour`"
576
- )
560
+ logger.error("引数`--labor_csv`のCSVには以下の列が存在しないので、終了します。\n`project_id`, `date`, `account_id`, `actual_worktime_hour`")
577
561
  sys.exit(COMMAND_LINE_ERROR_STATUS_CODE)
578
562
  actual_worktime = ActualWorktime(df_actual_worktime)
579
563
 
580
564
  if args.annotation_count_csv is not None:
581
565
  df_annotation_count = pandas.read_csv(args.annotation_count_csv)
582
566
  if not AnnotationCount.required_columns_exist(df_annotation_count):
583
- logger.error(
584
- "引数`--annotation_count_csv`のCSVには以下の列が存在しないので、終了します。\n`project_id`, `task_id`, `annotation_count`"
585
- )
567
+ logger.error("引数`--annotation_count_csv`のCSVには以下の列が存在しないので、終了します。\n`project_id`, `task_id`, `annotation_count`")
586
568
  sys.exit(COMMAND_LINE_ERROR_STATUS_CODE)
587
569
  annotation_count = AnnotationCount(df_annotation_count)
588
570
  else:
@@ -591,22 +573,16 @@ class VisualizeStatistics(CommandLine):
591
573
  if args.input_data_count_csv is not None:
592
574
  df_input_data_count = pandas.read_csv(args.input_data_count_csv)
593
575
  if not InputDataCount.required_columns_exist(df_input_data_count):
594
- logger.error(
595
- "引数`--input_data_count_csv`のCSVには以下の列が存在しないので、終了します。\n`project_id`, `task_id`, `input_data_count`"
596
- )
576
+ logger.error("引数`--input_data_count_csv`のCSVには以下の列が存在しないので、終了します。\n`project_id`, `task_id`, `input_data_count`")
597
577
  sys.exit(COMMAND_LINE_ERROR_STATUS_CODE)
598
578
  input_data_count = InputDataCount(df_input_data_count)
599
579
  else:
600
580
  input_data_count = None
601
581
 
602
- custom_production_volume = (
603
- create_custom_production_volume(args.custom_production_volume) if args.custom_production_volume is not None else None
604
- )
582
+ custom_production_volume = create_custom_production_volume(args.custom_production_volume) if args.custom_production_volume is not None else None
605
583
 
606
584
  ignored_task_id_set = set(get_list_from_args(args.ignored_task_id)) if args.ignored_task_id is not None else None
607
- filtering_query = FilteringQuery(
608
- task_query=task_query, start_date=args.start_date, end_date=args.end_date, ignored_task_ids=ignored_task_id_set
609
- )
585
+ filtering_query = FilteringQuery(task_query=task_query, start_date=args.start_date, end_date=args.end_date, ignored_task_ids=ignored_task_id_set)
610
586
 
611
587
  if args.temp_dir is None:
612
588
  with tempfile.TemporaryDirectory() as str_temp_dir:
@@ -690,11 +666,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
690
666
  "-u",
691
667
  "--user_id",
692
668
  nargs="+",
693
- help=(
694
- "メンバごとの統計グラフに表示するユーザのuser_idを指定してください。"
695
- "指定しない場合は、上位20人が表示されます。\n"
696
- "``file://`` を先頭に付けると、一覧が記載されたファイルを指定できます。"
697
- ),
669
+ help=("メンバごとの統計グラフに表示するユーザのuser_idを指定してください。指定しない場合は、上位20人が表示されます。\n``file://`` を先頭に付けると、一覧が記載されたファイルを指定できます。"),
698
670
  )
699
671
 
700
672
  parser.add_argument(
@@ -714,7 +686,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
714
686
  "--latest",
715
687
  action="store_true",
716
688
  help="統計情報の元になるファイル(アノテーションzipなど)の最新版を参照します。このオプションを指定すると、各ファイルを更新するのに5分以上待ちます。\n"
717
- "ただしWebAPIの都合上、'タスク履歴全件ファイル'は最新版を参照できません。タスク履歴の最新版を参照する場合は ``--get_task_histories_one_of_each`` を指定してください。", # noqa: E501
689
+ "ただしWebAPIの都合上、'タスク履歴全件ファイル'は最新版を参照できません。タスク履歴の最新版を参照する場合は ``--get_task_histories_one_of_each`` を指定してください。",
718
690
  )
719
691
 
720
692
  parser.add_argument(
@@ -727,12 +699,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
727
699
  "--labor_csv",
728
700
  type=Path,
729
701
  help=(
730
- "実績作業時間情報が格納されたCSVを指定してください。指定しない場合は、実績作業時間は0とみなします。列名は以下の通りです。\n"
731
- "\n"
732
- "* date\n"
733
- "* account_id\n"
734
- "* actual_worktime_hour\n"
735
- "* project_id \n"
702
+ "実績作業時間情報が格納されたCSVを指定してください。指定しない場合は、実績作業時間は0とみなします。列名は以下の通りです。\n\n* date\n* account_id\n* actual_worktime_hour\n* project_id \n"
736
703
  ),
737
704
  )
738
705
 
@@ -773,7 +740,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
773
740
  help=(
774
741
  "プロジェクト独自の生産量をJSON形式で指定します。"
775
742
  f"(例) ``{json.dumps(custom_production_volume_sample, ensure_ascii=False)}`` \n"
776
- "詳細は https://annofab-cli.readthedocs.io/ja/latest/command_reference/statistics/visualize.html#custom-project-volume を参照してください。" # noqa: E501
743
+ "詳細は https://annofab-cli.readthedocs.io/ja/latest/command_reference/statistics/visualize.html#custom-project-volume を参照してください。"
777
744
  ),
778
745
  )
779
746
 
@@ -798,9 +765,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
798
765
  parser.add_argument(
799
766
  "--not_download",
800
767
  action="store_true",
801
- help=(
802
- "指定した場合、アノテーションZIPなどのファイルをダウンロードせずに、`--temp_dir`で指定したディレクトリ内のファイルを読み込みます。`--temp_dir`は必須です。"
803
- ),
768
+ help=("指定した場合、アノテーションZIPなどのファイルをダウンロードせずに、`--temp_dir`で指定したディレクトリ内のファイルを読み込みます。`--temp_dir`は必須です。"),
804
769
  )
805
770
 
806
771
  parser.add_argument(
@@ -164,19 +164,15 @@ def get_video_duration_list(
164
164
  if input_data_ids is not None:
165
165
  input_data_list = [input_data for input_data in input_data_list if input_data["input_data_id"] in input_data_ids]
166
166
  logger.debug(
167
- f"「入力データのinput_data_idが引数'input_data_ids'に一致する」という条件で、入力データを {len(input_data_list)} 件に絞り込みました。 :: 引数'input_data_ids'は {len(input_data_ids)} 件" # noqa: E501
167
+ f"「入力データのinput_data_idが引数'input_data_ids'に一致する」という条件で、入力データを {len(input_data_list)} 件に絞り込みました。 :: 引数'input_data_ids'は {len(input_data_ids)} 件"
168
168
  )
169
169
 
170
170
  if from_datetime is not None:
171
- input_data_list = [
172
- input_data for input_data in input_data_list if datetime.datetime.fromisoformat(input_data["updated_datetime"]) >= from_datetime
173
- ]
171
+ input_data_list = [input_data for input_data in input_data_list if datetime.datetime.fromisoformat(input_data["updated_datetime"]) >= from_datetime]
174
172
  logger.debug(f"「入力データの更新日時が'{from_datetime}'以降」という条件で、入力データを {len(input_data_list)} 件に絞り込みました。")
175
173
 
176
174
  if to_datetime is not None:
177
- input_data_list = [
178
- input_data for input_data in input_data_list if datetime.datetime.fromisoformat(input_data["updated_datetime"]) <= to_datetime
179
- ]
175
+ input_data_list = [input_data for input_data in input_data_list if datetime.datetime.fromisoformat(input_data["updated_datetime"]) <= to_datetime]
180
176
  logger.debug(f"「入力データの更新日時が'{to_datetime}'以前」という条件で、入力データを {len(input_data_list)} 件に絞り込みました。")
181
177
 
182
178
  if task_ids is not None:
@@ -185,9 +181,7 @@ def get_video_duration_list(
185
181
  input_data_id_list_list = [task["input_data_id_list"] for task in task_list if task["task_id"] in task_ids]
186
182
  input_data_ids_included_task = set(itertools.chain.from_iterable(input_data_id_list_list))
187
183
  input_data_list = [input_data for input_data in input_data_list if input_data["input_data_id"] in input_data_ids_included_task]
188
- logger.debug(
189
- f"「引数'task_ids'に対応するタスクに含まれている入力データ」という条件で、入力データを {len(input_data_list)} 件に絞り込みました。 :: 引数'task_ids'は {len(task_ids)} 件" # noqa: E501
190
- )
184
+ logger.debug(f"「引数'task_ids'に対応するタスクに含まれている入力データ」という条件で、入力データを {len(input_data_list)} 件に絞り込みました。 :: 引数'task_ids'は {len(task_ids)} 件")
191
185
 
192
186
  video_duration_list = []
193
187
  for input_data in input_data_list:
@@ -206,7 +200,7 @@ class VisualizeVideoDuration(CommandLine):
206
200
  def validate(self, args: argparse.Namespace) -> bool:
207
201
  if args.project_id is None and (args.input_data_json is None or args.task_json is None):
208
202
  print( # noqa: T201
209
- f"{self.COMMON_MESSAGE} argument --project_id: '--input_data_json'または'--task_json'が未指定のときは、'--project_id' を指定してください。", # noqa: E501
203
+ f"{self.COMMON_MESSAGE} argument --project_id: '--input_data_json'または'--task_json'が未指定のときは、'--project_id' を指定してください。",
210
204
  file=sys.stderr,
211
205
  )
212
206
  return False
@@ -326,8 +320,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
326
320
  "--input_data_json",
327
321
  type=Path,
328
322
  required=False,
329
- help="入力データ情報が記載されたJSONファイルのパスを指定します。\n"
330
- "JSONファイルは ``$ annofabcli input_data download`` コマンドで取得できます。",
323
+ help="入力データ情報が記載されたJSONファイルのパスを指定します。\nJSONファイルは ``$ annofabcli input_data download`` コマンドで取得できます。",
331
324
  )
332
325
 
333
326
  parser.add_argument(
@@ -365,18 +358,14 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
365
358
  "-t",
366
359
  "--task_id",
367
360
  nargs="+",
368
- help=(
369
- "指定したtask_idのタスクに含まれている入力データを可視化対象にします。 ``file://`` を先頭に付けると、task_idの一覧が記載されたファイルを指定できます。" # noqa: E501
370
- ),
361
+ help=("指定したtask_idのタスクに含まれている入力データを可視化対象にします。 ``file://`` を先頭に付けると、task_idの一覧が記載されたファイルを指定できます。"),
371
362
  )
372
363
 
373
364
  parser.add_argument(
374
365
  "-i",
375
366
  "--input_data_id",
376
367
  nargs="+",
377
- help=(
378
- "指定したinput_data_idである入力データを可視化対象にします。 ``file://`` を先頭に付けると、input_data_idの一覧が記載されたファイルを指定できます。" # noqa: E501
379
- ),
368
+ help=("指定したinput_data_idである入力データを可視化対象にします。 ``file://`` を先頭に付けると、input_data_idの一覧が記載されたファイルを指定できます。"),
380
369
  )
381
370
 
382
371
  parser.add_argument("--from_date", type=str, help="指定した日付( ``YYYY-MM-DD`` )以降に更新された入力データを可視化対象にします。")
@@ -84,16 +84,10 @@ class DeleteSupplementaryDataMain(CommandLineWithConfirm):
84
84
  for supplementary_data_id in supplementary_data_id_list:
85
85
  supplementary_data = _get_supplementary_data_list(supplementary_data_id)
86
86
  if supplementary_data is None:
87
- logger.warning(
88
- f"input_data_id='{input_data_id}' の入力データに、"
89
- f"supplementary_data_id='{supplementary_data_id}' の補助情報は存在しないのでスキップします。"
90
- )
87
+ logger.warning(f"input_data_id='{input_data_id}' の入力データに、supplementary_data_id='{supplementary_data_id}' の補助情報は存在しないのでスキップします。")
91
88
  continue
92
89
 
93
- message_for_confirm = (
94
- f"補助情報 supplementary_data_id='{supplementary_data_id}', "
95
- f"supplementary_data_name='{supplementary_data['supplementary_data_name']}' を削除しますか?"
96
- )
90
+ message_for_confirm = f"補助情報 supplementary_data_id='{supplementary_data_id}', supplementary_data_name='{supplementary_data['supplementary_data_name']}' を削除しますか?"
97
91
  if not self.confirm_processing(message_for_confirm):
98
92
  continue
99
93
 
@@ -108,8 +102,7 @@ class DeleteSupplementaryDataMain(CommandLineWithConfirm):
108
102
  deleted_count += 1
109
103
  except requests.HTTPError:
110
104
  logger.warning(
111
- f"補助情報 supplementary_data_id='{supplementary_data_id}', "
112
- f"supplementary_data_name='{supplementary_data['supplementary_data_name']}' の削除に失敗しました。",
105
+ f"補助情報 supplementary_data_id='{supplementary_data_id}', supplementary_data_name='{supplementary_data['supplementary_data_name']}' の削除に失敗しました。",
113
106
  exc_info=True,
114
107
  )
115
108
  continue
@@ -126,9 +119,7 @@ class DeleteSupplementaryDataMain(CommandLineWithConfirm):
126
119
 
127
120
  logger.info(f"{deleted_count} / {total_count} 件の補助情報を削除しました。")
128
121
 
129
- def delete_supplementary_data_list_for_input_data2(
130
- self, project_id: str, input_data_id: str, supplementary_data_list: list[dict[str, Any]]
131
- ) -> int:
122
+ def delete_supplementary_data_list_for_input_data2(self, project_id: str, input_data_id: str, supplementary_data_list: list[dict[str, Any]]) -> int:
132
123
  """
133
124
  入力データ配下の補助情報を削除する。
134
125
 
@@ -147,8 +138,7 @@ class DeleteSupplementaryDataMain(CommandLineWithConfirm):
147
138
  try:
148
139
  self.service.api.delete_supplementary_data(project_id, input_data_id=input_data_id, supplementary_data_id=supplementary_data_id)
149
140
  logger.debug(
150
- f"補助情報を削除しました。input_data_id='{input_data_id}', supplementary_data_id='{supplementary_data_id}', "
151
- f"supplementary_data_name={supplementary_data['supplementary_data_name']}"
141
+ f"補助情報を削除しました。input_data_id='{input_data_id}', supplementary_data_id='{supplementary_data_id}', supplementary_data_name={supplementary_data['supplementary_data_name']}"
152
142
  )
153
143
  deleted_count += 1
154
144
  except requests.HTTPError:
@@ -175,18 +165,12 @@ class DeleteSupplementaryDataMain(CommandLineWithConfirm):
175
165
  logger.debug("入力データに紐づく補助情報は存在しないので、削除をスキップします。")
176
166
  continue
177
167
 
178
- message_for_confirm = (
179
- f"入力データに紐づく補助情報 {len(supplementary_data_list)} 件を削除しますか? "
180
- f"(input_data_id='{input_data_id}', "
181
- f"input_data_name='{input_data_name}') "
182
- )
168
+ message_for_confirm = f"入力データに紐づく補助情報 {len(supplementary_data_list)} 件を削除しますか? (input_data_id='{input_data_id}', input_data_name='{input_data_name}') "
183
169
  if not self.confirm_processing(message_for_confirm):
184
170
  continue
185
171
 
186
172
  try:
187
- deleted_supplementary_data_count = self.delete_supplementary_data_list_for_input_data2(
188
- project_id, input_data_id, supplementary_data_list
189
- )
173
+ deleted_supplementary_data_count = self.delete_supplementary_data_list_for_input_data2(project_id, input_data_id, supplementary_data_list)
190
174
  dict_deleted_count[input_data_id] = deleted_supplementary_data_count
191
175
  logger.debug(
192
176
  f"入力データに紐づく補助情報を {deleted_supplementary_data_count} / {len(supplementary_data_list)} 件削除しました。"
@@ -150,7 +150,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
150
150
  nargs="+",
151
151
  help=(
152
152
  "指定したinput_data_idの入力データに紐づく補助情報を出力します。\n"
153
- "未指定の場合は、入力データ全件ファイルをダウンロードして、すべての入力データに紐づく補助情報を出力します。ただし入力データの数だけAPIを実行するため、出力に時間がかかります。 \n" # noqa: E501
153
+ "未指定の場合は、入力データ全件ファイルをダウンロードして、すべての入力データに紐づく補助情報を出力します。ただし入力データの数だけAPIを実行するため、出力に時間がかかります。 \n"
154
154
  "``file://`` を先頭に付けると、input_data_idの一覧が記載されたファイルを指定できます。"
155
155
  ),
156
156
  )
@@ -152,19 +152,11 @@ class SubPutSupplementaryData:
152
152
 
153
153
  return yes
154
154
 
155
- def confirm_put_supplementary_data(
156
- self, csv_supplementary_data: CliSupplementaryData, supplementary_data_id: str, *, already_exists: bool = False
157
- ) -> bool:
155
+ def confirm_put_supplementary_data(self, csv_supplementary_data: CliSupplementaryData, supplementary_data_id: str, *, already_exists: bool = False) -> bool:
158
156
  if already_exists:
159
- message_for_confirm = (
160
- f"supplementary_data_name='{csv_supplementary_data.supplementary_data_name}', "
161
- f"supplementary_data_id='{supplementary_data_id}'の補助情報を更新しますか?"
162
- )
157
+ message_for_confirm = f"supplementary_data_name='{csv_supplementary_data.supplementary_data_name}', supplementary_data_id='{supplementary_data_id}'の補助情報を更新しますか?"
163
158
  else:
164
- message_for_confirm = (
165
- f"supplementary_data_name='{csv_supplementary_data.supplementary_data_name}', "
166
- f"supplementary_data_id='{supplementary_data_id}'の補助情報を登録しますか?"
167
- )
159
+ message_for_confirm = f"supplementary_data_name='{csv_supplementary_data.supplementary_data_name}', supplementary_data_id='{supplementary_data_id}'の補助情報を登録しますか?"
168
160
 
169
161
  return self.confirm_processing(message_for_confirm)
170
162
 
@@ -172,9 +164,7 @@ class SubPutSupplementaryData:
172
164
  last_updated_datetime = None
173
165
  input_data_id = csv_data.input_data_id
174
166
  supplementary_data_id = (
175
- csv_data.supplementary_data_id
176
- if csv_data.supplementary_data_id is not None
177
- else convert_supplementary_data_name_to_supplementary_data_id(csv_data.supplementary_data_name)
167
+ csv_data.supplementary_data_id if csv_data.supplementary_data_id is not None else convert_supplementary_data_name_to_supplementary_data_id(csv_data.supplementary_data_name)
178
168
  )
179
169
 
180
170
  supplementary_data_list = self.service.wrapper.get_supplementary_data_list_or_none(project_id, input_data_id)
@@ -270,7 +260,7 @@ class PutSupplementaryData(CommandLine):
270
260
  overwrite: Trueならば、supplementary_data_id(省略時はsupplementary_data_number)がすでに存在していたら上書きします。Falseならばスキップします。
271
261
  parallelism: 並列度
272
262
 
273
- """ # noqa: E501
263
+ """
274
264
 
275
265
  project_title = self.facade.get_project_title(project_id)
276
266
  logger.info(f"{project_title} に、{len(supplementary_data_list)} 件の補助情報を登録します。")
@@ -101,8 +101,7 @@ class CancelAcceptanceMain(CommandLineWithConfirm):
101
101
  return False
102
102
 
103
103
  logger.debug(
104
- f"{logging_prefix}: task_id = {task_id} のタスクの受入完了状態を取り消します。"
105
- f"タスクの担当者は {actual_acceptor.username}({actual_acceptor.user_id}) です。"
104
+ f"{logging_prefix}: task_id = {task_id} のタスクの受入完了状態を取り消します。タスクの担当者は {actual_acceptor.username}({actual_acceptor.user_id}) です。"
106
105
  if actual_acceptor is not None
107
106
  else "タスクの担当者は未割り当てです。"
108
107
  )
@@ -234,7 +233,7 @@ class CancelAcceptance(CommandLine):
234
233
  member = more_itertools.first_true(project_member_list, pred=lambda e: e["user_id"] == assigned_acceptor_user_id)
235
234
  if member is None:
236
235
  print( # noqa: T201
237
- f"{self.COMMON_MESSAGE} argument --assigned_acceptor_user_id: プロジェクトメンバーに user_id='{assigned_acceptor_user_id}'メンバーは存在しません", # noqa: E501
236
+ f"{self.COMMON_MESSAGE} argument --assigned_acceptor_user_id: プロジェクトメンバーに user_id='{assigned_acceptor_user_id}'メンバーは存在しません",
238
237
  file=sys.stderr,
239
238
  )
240
239
  sys.exit(COMMAND_LINE_ERROR_STATUS_CODE)
@@ -297,7 +296,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
297
296
  "--parallelism",
298
297
  type=int,
299
298
  choices=PARALLELISM_CHOICES,
300
- help="使用するプロセス数(並列度)を指定してください。指定する場合は必ず ``--yes`` を指定してください。指定しない場合は、逐次的に処理します。", # noqa: E501
299
+ help="使用するプロセス数(並列度)を指定してください。指定する場合は必ず ``--yes`` を指定してください。指定しない場合は、逐次的に処理します。",
301
300
  )
302
301
 
303
302
  parser.add_argument("--dryrun", action="store_true", help="取り消しが行われた時の結果を表示しますが、実際は受け入れを取り消しません。")
@@ -78,13 +78,7 @@ class ChangeOperatorMain:
78
78
  if task.account_id is not None:
79
79
  now_user_id = self.facade.get_user_id_from_account_id(project_id, task.account_id)
80
80
 
81
- logger.debug(
82
- f"{logging_prefix} : task_id = {task.task_id}, "
83
- f"status = {task.status.value}, "
84
- f"phase = {task.phase.value}, "
85
- f"phase_stage = {task.phase_stage}, "
86
- f"user_id = {now_user_id}"
87
- )
81
+ logger.debug(f"{logging_prefix} : task_id = {task.task_id}, status = {task.status.value}, phase = {task.phase.value}, phase_stage = {task.phase_stage}, user_id = {now_user_id}")
88
82
 
89
83
  if task.status in [TaskStatus.COMPLETE, TaskStatus.WORKING]:
90
84
  logger.warning(f"{logging_prefix} : task_id = {task_id} : タスクのstatusがworking or complete なので、担当者を変更できません。")
@@ -174,9 +168,7 @@ class ChangeOperatorMain:
174
168
  # 逐次処理
175
169
  for task_index, task_id in enumerate(task_id_list):
176
170
  try:
177
- result = self.change_operator_for_task(
178
- project_id, task_id, task_index=task_index, task_query=task_query, new_account_id=new_account_id
179
- )
171
+ result = self.change_operator_for_task(project_id, task_id, task_index=task_index, task_query=task_query, new_account_id=new_account_id)
180
172
  if result:
181
173
  success_count += 1
182
174
  except Exception: # pylint: disable=broad-except
@@ -254,7 +246,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
254
246
  "--parallelism",
255
247
  type=int,
256
248
  choices=PARALLELISM_CHOICES,
257
- help="使用するプロセス数(並列度)を指定してください。指定する場合は必ず ``--yes`` を指定してください。指定しない場合は、逐次的に処理します。", # noqa: E501
249
+ help="使用するプロセス数(並列度)を指定してください。指定する場合は必ず ``--yes`` を指定してください。指定しない場合は、逐次的に処理します。",
258
250
  )
259
251
 
260
252
  parser.set_defaults(subcommand_func=main)
@@ -204,7 +204,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
204
204
  "--parallelism",
205
205
  type=int,
206
206
  choices=PARALLELISM_CHOICES,
207
- help="使用するプロセス数(並列度)を指定してください。指定する場合は必ず ``--yes`` を指定してください。指定しない場合は、逐次的に処理します。", # noqa: E501
207
+ help="使用するプロセス数(並列度)を指定してください。指定する場合は必ず ``--yes`` を指定してください。指定しない場合は、逐次的に処理します。",
208
208
  )
209
209
 
210
210
  parser.set_defaults(subcommand_func=main)
@@ -40,10 +40,7 @@ class ChangingStatusToOnHoldMain(CommandLineWithConfirm):
40
40
  if task.account_id is not None:
41
41
  user_id = self.facade.get_user_id_from_account_id(self.project_id, task.account_id)
42
42
 
43
- confirm_message = (
44
- f"task_id='{task.task_id}' のタスクのステータスを保留中に変更しますか?"
45
- f"(status='{task.status.value}, phase='{task.phase.value}', user_id='{user_id}')"
46
- )
43
+ confirm_message = f"task_id='{task.task_id}' のタスクのステータスを保留中に変更しますか?(status='{task.status.value}, phase='{task.phase.value}', user_id='{user_id}')"
47
44
  return self.confirm_processing(confirm_message)
48
45
 
49
46
  def add_comment(self, task: Task, comment: str) -> None:
@@ -83,16 +80,11 @@ class ChangingStatusToOnHoldMain(CommandLineWithConfirm):
83
80
 
84
81
  def preprocess() -> bool:
85
82
  if not match_task_with_query(task, task_query):
86
- logger.debug(
87
- f"{logging_prefix} : task_id = {task_id} : `--task_query` の条件にマッチしないため、スキップします。 :: task_query={task_query}"
88
- )
83
+ logger.debug(f"{logging_prefix} : task_id = {task_id} : `--task_query` の条件にマッチしないため、スキップします。 :: task_query={task_query}")
89
84
  return False
90
85
 
91
86
  if task.status not in [TaskStatus.NOT_STARTED, TaskStatus.BREAK]:
92
- logger.warning(
93
- f"{logging_prefix}: task_id = '{task_id}' のタスクのステータスが未着手または休憩中でないので、スキップします。 :: "
94
- f"status='{task.status.value}'"
95
- )
87
+ logger.warning(f"{logging_prefix}: task_id = '{task_id}' のタスクのステータスが未着手または休憩中でないので、スキップします。 :: status='{task.status.value}'")
96
88
  return False
97
89
 
98
90
  if not self.confirm_change_status_to_on_hold(task): # noqa: SIM103
@@ -115,10 +107,7 @@ class ChangingStatusToOnHoldMain(CommandLineWithConfirm):
115
107
  if task.account_id is not None:
116
108
  task_user_id = self.facade.get_user_id_from_account_id(self.project_id, task.account_id)
117
109
 
118
- logger.debug(
119
- f"{logging_prefix}: task_id='{task_id}'のステータスを保留中に変更します。 :: "
120
- f"status='{task.status.value}, phase='{task.phase.value}', user_id='{task_user_id}'"
121
- )
110
+ logger.debug(f"{logging_prefix}: task_id='{task_id}'のステータスを保留中に変更します。 :: status='{task.status.value}, phase='{task.phase.value}', user_id='{task_user_id}'")
122
111
 
123
112
  task_last_updated_datetime = None
124
113
 
@@ -130,9 +119,7 @@ class ChangingStatusToOnHoldMain(CommandLineWithConfirm):
130
119
  task_last_updated_datetime = updated_task["updated_datetime"]
131
120
  logger.debug(f"{logging_prefix}: task_id='{task_id}' のタスクの担当者を'{task_user_id}'から自分自身に変更しました。")
132
121
 
133
- updated_task = self.service.wrapper.change_task_status_to_working(
134
- self.project_id, task_id, last_updated_datetime=task_last_updated_datetime
135
- )
122
+ updated_task = self.service.wrapper.change_task_status_to_working(self.project_id, task_id, last_updated_datetime=task_last_updated_datetime)
136
123
  task_last_updated_datetime = updated_task["updated_datetime"]
137
124
  logger.debug(f"{logging_prefix}: task_id='{task_id}'のタスクのステータスを作業中に変更しました。")
138
125
 
@@ -144,15 +144,11 @@ class CompleteTasksMain(CommandLineWithConfirm):
144
144
  try:
145
145
  last_updated_datetime = None
146
146
  if task.account_id != my_account_id:
147
- _task = self.service.wrapper.change_task_operator(
148
- task.project_id, task.task_id, my_account_id, last_updated_datetime=task.updated_datetime
149
- )
147
+ _task = self.service.wrapper.change_task_operator(task.project_id, task.task_id, my_account_id, last_updated_datetime=task.updated_datetime)
150
148
  last_updated_datetime = _task["updated_datetime"]
151
149
  logger.debug(f"{task.task_id}: 担当者を自分自身に変更しました。")
152
150
 
153
- dict_task = self.service.wrapper.change_task_status_to_working(
154
- project_id=task.project_id, task_id=task.task_id, last_updated_datetime=last_updated_datetime
155
- )
151
+ dict_task = self.service.wrapper.change_task_status_to_working(project_id=task.project_id, task_id=task.task_id, last_updated_datetime=last_updated_datetime)
156
152
  return Task.from_dict(dict_task)
157
153
 
158
154
  except requests.HTTPError:
@@ -192,11 +188,7 @@ class CompleteTasksMain(CommandLineWithConfirm):
192
188
 
193
189
  comment_list, _ = self.service.api.get_comments(task.project_id, task.task_id, input_data_id, query_params={"v": "2"})
194
190
  # 未処置の検査コメント
195
- unprocessed_inspection_list = [
196
- e
197
- for e in comment_list
198
- if e["comment_type"] == "inspection" and e["comment_node"]["_type"] == "Root" and e["comment_node"]["status"] == "open"
199
- ]
191
+ unprocessed_inspection_list = [e for e in comment_list if e["comment_type"] == "inspection" and e["comment_node"]["_type"] == "Root" and e["comment_node"]["status"] == "open"]
200
192
 
201
193
  unanswered_comment_list = [e for e in unprocessed_inspection_list if not exists_answered_comment(e["comment_id"])]
202
194
  return unanswered_comment_list
@@ -228,9 +220,7 @@ class CompleteTasksMain(CommandLineWithConfirm):
228
220
  logger.debug(f"{task.task_id}: 未回答の検査コメントが {unanswered_comment_count_for_task} 件あります。")
229
221
  if unanswered_comment_count_for_task > 0: # noqa: SIM102
230
222
  if reply_comment is None:
231
- logger.warning(
232
- f"{task.task_id}: 未回答の検査コメントに対する返信コメント('--reply_comment')が指定されていないので、スキップします。"
233
- )
223
+ logger.warning(f"{task.task_id}: 未回答の検査コメントに対する返信コメント('--reply_comment')が指定されていないので、スキップします。")
234
224
  return False
235
225
 
236
226
  if not self.confirm_processing(f"タスク'{task.task_id}'の教師付フェーズを次のフェーズに進めますか?"):
@@ -269,9 +259,7 @@ class CompleteTasksMain(CommandLineWithConfirm):
269
259
  logger.debug(f"{task.task_id}: 未処置の検査コメントが {unprocessed_inspection_count} 件あります。")
270
260
  if unprocessed_inspection_count > 0: # noqa: SIM102
271
261
  if inspection_status is None:
272
- logger.warning(
273
- f"{task.task_id}: 未処置の検査コメントに対する対応方法('--inspection_status')が指定されていないので、スキップします。"
274
- )
262
+ logger.warning(f"{task.task_id}: 未処置の検査コメントに対する対応方法('--inspection_status')が指定されていないので、スキップします。")
275
263
  return False
276
264
 
277
265
  if not self.confirm_processing(f"タスク'{task.task_id}'の検査/受入フェーズを次のフェーズに進めますか?"):
@@ -331,9 +319,7 @@ class CompleteTasksMain(CommandLineWithConfirm):
331
319
  return False
332
320
 
333
321
  task: Task = Task.from_dict(dict_task)
334
- logger.info(
335
- f"{logging_prefix} : タスク情報 task_id='{task_id}', phase={task.phase.value}, phase_stage={task.phase_stage}, status={task.status.value}"
336
- )
322
+ logger.info(f"{logging_prefix} : タスク情報 task_id='{task_id}', phase={task.phase.value}, phase_stage={task.phase_stage}, status={task.status.value}")
337
323
  if not self._validate_task(task, target_phase=target_phase, target_phase_stage=target_phase_stage, task_query=task_query):
338
324
  return False
339
325
 
@@ -456,10 +442,7 @@ class CompleteTasks(CommandLine):
456
442
  logger.warning(f"'--phase'に'{TaskPhase.ANNOTATION.value}'を指定しているとき、'--inspection_status'の値は無視されます。")
457
443
  elif args.phase in [TaskPhase.INSPECTION.value, TaskPhase.ACCEPTANCE.value]: # noqa: SIM102
458
444
  if args.reply_comment is not None:
459
- logger.warning(
460
- f"'--phase'に'{TaskPhase.INSPECTION.value}'または'{TaskPhase.ACCEPTANCE.value}'を指定しているとき、"
461
- f"'--reply_comment'の値は無視されます。"
462
- )
445
+ logger.warning(f"'--phase'に'{TaskPhase.INSPECTION.value}'または'{TaskPhase.ACCEPTANCE.value}'を指定しているとき、'--reply_comment'の値は無視されます。")
463
446
 
464
447
  if args.parallelism is not None and not args.yes:
465
448
  print( # noqa: T201
@@ -547,7 +530,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
547
530
  "--parallelism",
548
531
  type=int,
549
532
  choices=PARALLELISM_CHOICES,
550
- help="使用するプロセス数(並列度)を指定してください。指定する場合は必ず ``--yes`` を指定してください。指定しない場合は、逐次的に処理します。", # noqa: E501
533
+ help="使用するプロセス数(並列度)を指定してください。指定する場合は必ず ``--yes`` を指定してください。指定しない場合は、逐次的に処理します。",
551
534
  )
552
535
 
553
536
  parser.set_defaults(subcommand_func=main)
@@ -203,8 +203,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
203
203
  type=str,
204
204
  nargs="+",
205
205
  required=True,
206
- help="コピー元のtask_idとコピー先のtask_idを ``:`` で区切って指定してください。\n"
207
- "``file://`` を先頭に付けると、コピー元とコピー先が記載されているファイルを指定できます。",
206
+ help="コピー元のtask_idとコピー先のtask_idを ``:`` で区切って指定してください。\n``file://`` を先頭に付けると、コピー元とコピー先が記載されているファイルを指定できます。",
208
207
  )
209
208
 
210
209
  parser.add_argument("--copy_metadata", action="store_true", help="指定した場合、タスクのメタデータもコピーします。")
@@ -213,7 +212,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
213
212
  "--parallelism",
214
213
  type=int,
215
214
  choices=PARALLELISM_CHOICES,
216
- help="使用するプロセス数(並列度)を指定してください。指定する場合は必ず ``--yes`` を指定してください。指定しない場合は、逐次的に処理します。", # noqa: E501
215
+ help="使用するプロセス数(並列度)を指定してください。指定する場合は必ず ``--yes`` を指定してください。指定しない場合は、逐次的に処理します。",
217
216
  )
218
217
 
219
218
  parser.set_defaults(subcommand_func=main)
@@ -82,17 +82,13 @@ class DeleteMetadataKeysOfTaskMain(CommandLineWithConfirm):
82
82
  # メタデータを更新する必要がないのでreturnします。
83
83
  return False
84
84
 
85
- if not self.all_yes and not self.confirm_processing(
86
- f"task_id='{task_id}' :: metadata='{str_old_metadata}' からキー'{deleted_keys}'を削除しますか?"
87
- ):
85
+ if not self.all_yes and not self.confirm_processing(f"task_id='{task_id}' :: metadata='{str_old_metadata}' からキー'{deleted_keys}'を削除しますか?"):
88
86
  return False
89
87
 
90
88
  request_body = {task_id: new_metadata}
91
89
  self.service.api.patch_tasks_metadata(self.project_id, request_body=request_body)
92
90
  str_new_metadata = json.dumps(new_metadata)
93
- logger.debug(
94
- f"{logging_prefix} task_id='{task_id}' :: タスクのメタデータからキー'{deleted_keys}'を削除しました。 :: metadata='{str_new_metadata}'"
95
- )
91
+ logger.debug(f"{logging_prefix} task_id='{task_id}' :: タスクのメタデータからキー'{deleted_keys}'を削除しました。 :: metadata='{str_new_metadata}'")
96
92
  return True
97
93
 
98
94
  def delete_metadata_keys_for_one_task_wrapper(self, tpl: tuple[int, str], metadata_keys: Collection[str]) -> bool: