annofabcli 1.102.0__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 +9 -11
  5. annofabcli/annotation/delete_annotation.py +21 -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 +10 -16
  10. annofabcli/annotation/remove_segmentation_overlap.py +14 -30
  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 +32 -16
  59. annofabcli/organization_member/invite_organization_member.py +25 -14
  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.0.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.0.dist-info/RECORD +0 -214
  132. {annofabcli-1.102.0.dist-info → annofabcli-1.103.0.dist-info}/WHEEL +0 -0
  133. {annofabcli-1.102.0.dist-info → annofabcli-1.103.0.dist-info}/entry_points.txt +0 -0
  134. {annofabcli-1.102.0.dist-info → annofabcli-1.103.0.dist-info}/licenses/LICENSE +0 -0
@@ -173,9 +173,7 @@ class ProjectDir(DataClassJsonMixin):
173
173
  phase_name = self.get_phase_name_for_filename(phase)
174
174
  obj.to_csv(self.project_dir / Path(f"{phase_name}者_{phase_name}開始日list.csv"))
175
175
 
176
- def write_performance_line_graph_per_date(
177
- self, obj: AbstractPhaseProductivityPerDate, phase: TaskPhase, *, user_id_list: Optional[list[str]] = None
178
- ) -> None:
176
+ def write_performance_line_graph_per_date(self, obj: AbstractPhaseProductivityPerDate, phase: TaskPhase, *, user_id_list: Optional[list[str]] = None) -> None:
179
177
  """
180
178
  指定したフェーズの開始日ごとの作業時間や生産性情報を、折れ線グラフとして出力します。
181
179
  """
@@ -199,8 +197,7 @@ class ProjectDir(DataClassJsonMixin):
199
197
  obj.plot_production_volume_metrics(
200
198
  production_volume_column=custom_production_volume.value,
201
199
  production_volume_name=custom_production_volume.name,
202
- output_file=output_dir
203
- / Path(f"{phase_name}者用/折れ線-横軸_{phase_name}開始日-縦軸_{custom_production_volume.name}単位の指標-{phase_name}者用.html"),
200
+ output_file=output_dir / Path(f"{phase_name}者用/折れ線-横軸_{phase_name}開始日-縦軸_{custom_production_volume.name}単位の指標-{phase_name}者用.html"),
204
201
  target_user_id_list=user_id_list,
205
202
  metadata=self.metadata,
206
203
  )
@@ -209,14 +206,10 @@ class ProjectDir(DataClassJsonMixin):
209
206
  """`全体の生産性と品質.csv`を読み込む。"""
210
207
  file = self.project_dir / self.FILENAME_WHOLE_PERFORMANCE
211
208
  if file.exists():
212
- return WholePerformance.from_csv(
213
- file, custom_production_volume_list=self.custom_production_volume_list, task_completion_criteria=self.task_completion_criteria
214
- )
209
+ return WholePerformance.from_csv(file, custom_production_volume_list=self.custom_production_volume_list, task_completion_criteria=self.task_completion_criteria)
215
210
  else:
216
211
  logger.warning(f"'{file!s}'を読み込もうとしましたが、ファイルは存在しません。")
217
- return WholePerformance.empty(
218
- custom_production_volume_list=self.custom_production_volume_list, task_completion_criteria=self.task_completion_criteria
219
- )
212
+ return WholePerformance.empty(custom_production_volume_list=self.custom_production_volume_list, task_completion_criteria=self.task_completion_criteria)
220
213
 
221
214
  def write_whole_performance(self, whole_performance: WholePerformance) -> None:
222
215
  """`全体の生産性と品質.csv`を出力します。"""
@@ -234,9 +227,7 @@ class ProjectDir(DataClassJsonMixin):
234
227
  custom_production_volume_list=self.custom_production_volume_list,
235
228
  )
236
229
  else:
237
- return WholeProductivityPerCompletedDate.empty(
238
- task_completion_criteria=self.task_completion_criteria, custom_production_volume_list=self.custom_production_volume_list
239
- )
230
+ return WholeProductivityPerCompletedDate.empty(task_completion_criteria=self.task_completion_criteria, custom_production_volume_list=self.custom_production_volume_list)
240
231
 
241
232
  def write_whole_productivity_per_date(self, obj: WholeProductivityPerCompletedDate) -> None:
242
233
  """
@@ -263,9 +254,7 @@ class ProjectDir(DataClassJsonMixin):
263
254
  custom_production_volume_list=self.custom_production_volume_list,
264
255
  )
265
256
  else:
266
- return WholeProductivityPerFirstAnnotationStartedDate.empty(
267
- self.task_completion_criteria, custom_production_volume_list=self.custom_production_volume_list
268
- )
257
+ return WholeProductivityPerFirstAnnotationStartedDate.empty(self.task_completion_criteria, custom_production_volume_list=self.custom_production_volume_list)
269
258
 
270
259
  def write_whole_productivity_per_first_annotation_started_date(self, obj: WholeProductivityPerFirstAnnotationStartedDate) -> None:
271
260
  """
@@ -285,14 +274,10 @@ class ProjectDir(DataClassJsonMixin):
285
274
  """
286
275
  file = self.project_dir / self.FILENAME_USER_PERFORMANCE
287
276
  if file.exists():
288
- return UserPerformance.from_csv(
289
- file, custom_production_volume_list=self.custom_production_volume_list, task_completion_criteria=self.task_completion_criteria
290
- )
277
+ return UserPerformance.from_csv(file, custom_production_volume_list=self.custom_production_volume_list, task_completion_criteria=self.task_completion_criteria)
291
278
  else:
292
279
  logger.warning(f"'{file!s}'を読み込もうとしましたが、ファイルは存在しません。")
293
- return UserPerformance.empty(
294
- custom_production_volume_list=self.custom_production_volume_list, task_completion_criteria=self.task_completion_criteria
295
- )
280
+ return UserPerformance.empty(custom_production_volume_list=self.custom_production_volume_list, task_completion_criteria=self.task_completion_criteria)
296
281
 
297
282
  def write_user_performance(self, user_performance: UserPerformance) -> None:
298
283
  """
@@ -407,9 +392,7 @@ class ProjectDir(DataClassJsonMixin):
407
392
 
408
393
  def write_worktime_line_graph(self, obj: WorktimePerDate, user_id_list: Optional[list[str]] = None) -> None:
409
394
  """横軸が日付、縦軸がユーザごとの作業時間である折れ線グラフを出力します。"""
410
- obj.plot_cumulatively(
411
- self.project_dir / "line-graph/累積折れ線-横軸_日-縦軸_作業時間.html", target_user_id_list=user_id_list, metadata=self.metadata
412
- )
395
+ obj.plot_cumulatively(self.project_dir / "line-graph/累積折れ線-横軸_日-縦軸_作業時間.html", target_user_id_list=user_id_list, metadata=self.metadata)
413
396
 
414
397
  def read_project_info(self) -> ProjectInfo:
415
398
  """
@@ -70,9 +70,7 @@ class VisualizationSourceFiles:
70
70
  with open(str(self.task_history_json_path), encoding="utf-8") as f: # noqa: PTH123
71
71
  task_histories_dict = json.load(f)
72
72
 
73
- logger.debug(
74
- f"{self.logging_prefix}: '{self.task_history_json_path}'を読み込みました。{len(task_histories_dict)}件のタスクの履歴が含まれています。"
75
- )
73
+ logger.debug(f"{self.logging_prefix}: '{self.task_history_json_path}'を読み込みました。{len(task_histories_dict)}件のタスクの履歴が含まれています。")
76
74
  return task_histories_dict
77
75
 
78
76
  def read_task_history_events_json(self) -> list[dict[str, Any]]:
@@ -85,10 +83,7 @@ class VisualizationSourceFiles:
85
83
  with self.task_history_event_json_path.open(encoding="utf-8") as f:
86
84
  task_history_event_list = json.load(f)
87
85
 
88
- logger.debug(
89
- f"{self.logging_prefix}: '{self.task_history_event_json_path}'を読み込みました。"
90
- f"{len(task_history_event_list)}件のタスク履歴イベントが含まれています。"
91
- )
86
+ logger.debug(f"{self.logging_prefix}: '{self.task_history_event_json_path}'を読み込みました。{len(task_history_event_list)}件のタスク履歴イベントが含まれています。")
92
87
  return task_history_event_list
93
88
 
94
89
  def read_comments_json(self) -> list[dict[str, Any]]:
@@ -104,9 +99,7 @@ class VisualizationSourceFiles:
104
99
  logger.debug(f"{self.logging_prefix}: '{self.comment_json_path}'を読み込みました。{len(comment_list)}件のコメントが含まれています。")
105
100
  return comment_list
106
101
 
107
- def write_files(
108
- self, *, is_latest: bool = False, should_get_task_histories_one_of_each: bool = False, should_download_annotation_zip: bool = True
109
- ) -> None:
102
+ def write_files(self, *, is_latest: bool = False, should_get_task_histories_one_of_each: bool = False, should_download_annotation_zip: bool = True) -> None:
110
103
  """
111
104
  可視化に必要なファイルを作成します。
112
105
  原則、全件ファイルをダウンロードしてファイルを作成します。必要に応じて個別にAPIを実行してファイルを作成します。
@@ -88,20 +88,12 @@ def get_only_selective_attribute(columns: list[AttributeValueKey]) -> list[Attri
88
88
  for label, attribute_name, _ in columns:
89
89
  attribute_name_list.append((label, attribute_name))
90
90
 
91
- non_selective_attribute_names = {
92
- key for key, value in collections.Counter(attribute_name_list).items() if value > SELECTIVE_ATTRIBUTE_VALUE_MAX_COUNT
93
- }
91
+ non_selective_attribute_names = {key for key, value in collections.Counter(attribute_name_list).items() if value > SELECTIVE_ATTRIBUTE_VALUE_MAX_COUNT}
94
92
 
95
93
  if len(non_selective_attribute_names) > 0:
96
- logger.debug(
97
- f"以下の属性は値の個数が{SELECTIVE_ATTRIBUTE_VALUE_MAX_COUNT}を超えていたため、集計しません。 :: {non_selective_attribute_names}"
98
- )
94
+ logger.debug(f"以下の属性は値の個数が{SELECTIVE_ATTRIBUTE_VALUE_MAX_COUNT}を超えていたため、集計しません。 :: {non_selective_attribute_names}")
99
95
 
100
- return [
101
- (label, attribute_name, attribute_value)
102
- for (label, attribute_name, attribute_value) in columns
103
- if (label, attribute_name) not in non_selective_attribute_names
104
- ]
96
+ return [(label, attribute_name, attribute_value) for (label, attribute_name, attribute_value) in columns if (label, attribute_name) not in non_selective_attribute_names]
105
97
 
106
98
 
107
99
  def plot_label_histogram(
@@ -154,9 +146,7 @@ def plot_label_histogram(
154
146
  # すべての値が0である列を除外する
155
147
  columns = [col for col in df.columns if df[col].sum() > 0]
156
148
  if len(columns) < len(df.columns):
157
- logger.debug(
158
- f"以下のラベルは、すべてのタスクでアノテーション数が0であるためヒストグラムを描画しません。 :: {set(df.columns) - set(columns)}"
159
- )
149
+ logger.debug(f"以下のラベルは、すべてのタスクでアノテーション数が0であるためヒストグラムを描画しません。 :: {set(df.columns) - set(columns)}")
160
150
  else:
161
151
  columns = df.columns
162
152
 
@@ -260,9 +250,7 @@ def plot_attribute_histogram( # noqa: PLR0915
260
250
  # すべての値が0である列を除外する
261
251
  columns = [col for col in df.columns if df[col].sum() > 0]
262
252
  if len(columns) < len(df.columns):
263
- logger.debug(
264
- f"以下の属性値は、すべてのタスクでアノテーション数が0であるためヒストグラムを描画しません。 :: {set(df.columns) - set(columns)}"
265
- )
253
+ logger.debug(f"以下の属性値は、すべてのタスクでアノテーション数が0であるためヒストグラムを描画しません。 :: {set(df.columns) - set(columns)}")
266
254
  else:
267
255
  columns = df.columns
268
256
 
@@ -387,9 +375,7 @@ class VisualizeAnnotationCount(CommandLine):
387
375
  metadata = {
388
376
  "project_id": project_id,
389
377
  "project_title": project_title,
390
- "task_query": {k: v for k, v in task_query.to_dict(encode_json=True).items() if v is not None and v is not False}
391
- if task_query is not None
392
- else None,
378
+ "task_query": {k: v for k, v in task_query.to_dict(encode_json=True).items() if v is not None and v is not False} if task_query is not None else None,
393
379
  "target_task_ids": target_task_ids,
394
380
  }
395
381
 
@@ -530,7 +516,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
530
516
  parser.add_argument(
531
517
  "--latest",
532
518
  action="store_true",
533
- help="``--annotation`` を指定しないとき、最新のアノテーションzipを参照します。このオプションを指定すると、アノテーションzipを更新するのに数分待ちます。", # noqa: E501
519
+ help="``--annotation`` を指定しないとき、最新のアノテーションzipを参照します。このオプションを指定すると、アノテーションzipを更新するのに数分待ちます。",
534
520
  )
535
521
 
536
522
  parser.add_argument(
@@ -114,10 +114,7 @@ def plot_annotation_duration_histogram_by_label( # noqa: PLR0915
114
114
  # すべての値が0である列を除外する
115
115
  columns = [col for col in df.columns if df[col].sum() > 0]
116
116
  if len(columns) < len(df.columns):
117
- logger.debug(
118
- f"以下の属性値は、すべてのタスクで区間アノテーションの長さが0であるためヒストグラムを描画しません。 :: "
119
- f"{set(df.columns) - set(columns)}"
120
- )
117
+ logger.debug(f"以下の属性値は、すべてのタスクで区間アノテーションの長さが0であるためヒストグラムを描画しません。 :: {set(df.columns) - set(columns)}")
121
118
  df = df[columns]
122
119
 
123
120
  if bin_width is not None: # noqa: SIM102
@@ -130,7 +127,7 @@ def plot_annotation_duration_histogram_by_label( # noqa: PLR0915
130
127
  logger.debug(f"{len(df.columns)}個のラベルごとのヒストグラムを出力します。")
131
128
  for col in df.columns:
132
129
  if bin_width is not None:
133
- if arrange_bin_edge:
130
+ if arrange_bin_edge: # noqa: SIM108
134
131
  bin_edges = get_bin_edges(min_value=0, max_value=max_duration, bin_width=bin_width)
135
132
  else:
136
133
  bin_edges = get_bin_edges(min_value=0, max_value=df[col].max(), bin_width=bin_width)
@@ -220,10 +217,7 @@ def plot_annotation_duration_histogram_by_attribute( # noqa: PLR0915
220
217
  # すべての値が0である列を除外する
221
218
  columns = [col for col in df.columns if df[col].sum() > 0]
222
219
  if len(columns) < len(df.columns):
223
- logger.debug(
224
- f"以下のラベルは、すべてのタスクで区間アノテーションの長さが0であるためヒストグラムを描画しません。 :: "
225
- f"{set(df.columns) - set(columns)}"
226
- )
220
+ logger.debug(f"以下のラベルは、すべてのタスクで区間アノテーションの長さが0であるためヒストグラムを描画しません。 :: {set(df.columns) - set(columns)}")
227
221
  df = df[columns]
228
222
 
229
223
  histogram_range = get_histogram_range(df)
@@ -244,7 +238,7 @@ def plot_annotation_duration_histogram_by_attribute( # noqa: PLR0915
244
238
  header = (str(col[0]), str(col[1])) # ラベル名, 属性名
245
239
 
246
240
  if bin_width is not None:
247
- if arrange_bin_edge:
241
+ if arrange_bin_edge: # noqa: SIM108
248
242
  bin_edges = get_bin_edges(min_value=0, max_value=max_duration, bin_width=bin_width)
249
243
  else:
250
244
  bin_edges = get_bin_edges(min_value=0, max_value=df[col].max(), bin_width=bin_width)
@@ -335,9 +329,7 @@ class VisualizeAnnotationDuration(CommandLine):
335
329
  metadata = {
336
330
  "project_id": project_id,
337
331
  "project_title": project_title,
338
- "task_query": {k: v for k, v in task_query.to_dict(encode_json=True).items() if v is not None and v is not False}
339
- if task_query is not None
340
- else None,
332
+ "task_query": {k: v for k, v in task_query.to_dict(encode_json=True).items() if v is not None and v is not False} if task_query is not None else None,
341
333
  "target_task_ids": target_task_ids,
342
334
  }
343
335
  plot_annotation_duration_histogram_by_label(
@@ -372,9 +364,7 @@ class VisualizeAnnotationDuration(CommandLine):
372
364
  super().validate_project(project_id, project_member_roles=[ProjectMemberRole.OWNER, ProjectMemberRole.TRAINING_DATA_USER])
373
365
  project, _ = self.service.api.get_project(project_id)
374
366
  if project["input_data_type"] != InputDataType.MOVIE.value:
375
- logger.warning(
376
- f"project_id='{project_id}'であるプロジェクトは、動画プロジェクトでないので、出力される区間アノテーションの長さはすべて0秒になります。"
377
- )
367
+ logger.warning(f"project_id='{project_id}'であるプロジェクトは、動画プロジェクトでないので、出力される区間アノテーションの長さはすべて0秒になります。")
378
368
 
379
369
  output_dir: Path = args.output_dir
380
370
  annotation_path = Path(args.annotation) if args.annotation is not None else None
@@ -479,7 +469,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
479
469
  parser.add_argument(
480
470
  "--latest",
481
471
  action="store_true",
482
- help="``--annotation`` を指定しないとき、最新のアノテーションzipを参照します。このオプションを指定すると、アノテーションzipを更新するのに数分待ちます。", # noqa: E501
472
+ help="``--annotation`` を指定しないとき、最新のアノテーションzipを参照します。このオプションを指定すると、アノテーションzipを更新するのに数分待ちます。",
483
473
  )
484
474
 
485
475
  parser.add_argument(
@@ -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:
@@ -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)} 件の補助情報を登録します。")