annofabcli 1.103.0__py3-none-any.whl → 1.104.1__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 (37) hide show
  1. annofabcli/__main__.py +1 -1
  2. annofabcli/annotation/import_annotation.py +1 -1
  3. annofabcli/comment/list_all_comment.py +13 -1
  4. annofabcli/comment/list_comment.py +45 -3
  5. annofabcli/common/image.py +2 -2
  6. annofabcli/common/utils.py +1 -1
  7. annofabcli/filesystem/draw_annotation.py +2 -2
  8. annofabcli/filesystem/mask_user_info.py +3 -3
  9. annofabcli/instruction/upload_instruction.py +3 -3
  10. annofabcli/job/list_job.py +1 -1
  11. annofabcli/project_member/change_project_members.py +1 -1
  12. annofabcli/project_member/invite_project_members.py +1 -1
  13. annofabcli/stat_visualization/merge_visualization_dir.py +1 -1
  14. annofabcli/statistics/list_annotation_area.py +3 -0
  15. annofabcli/statistics/list_annotation_attribute.py +3 -0
  16. annofabcli/statistics/list_annotation_attribute_filled_count.py +8 -0
  17. annofabcli/statistics/list_annotation_count.py +12 -0
  18. annofabcli/statistics/list_annotation_duration.py +6 -0
  19. annofabcli/statistics/list_video_duration.py +2 -1
  20. annofabcli/statistics/summarize_task_count.py +2 -2
  21. annofabcli/statistics/visualization/dataframe/annotation_count.py +1 -1
  22. annofabcli/statistics/visualization/dataframe/cumulative_productivity.py +3 -3
  23. annofabcli/statistics/visualization/dataframe/productivity_per_date.py +3 -3
  24. annofabcli/statistics/visualization/dataframe/task_history.py +1 -1
  25. annofabcli/statistics/visualization/dataframe/whole_performance.py +2 -2
  26. annofabcli/statistics/visualization/dataframe/worktime_per_date.py +1 -1
  27. annofabcli/statistics/visualize_annotation_count.py +2 -2
  28. annofabcli/statistics/visualize_annotation_duration.py +2 -2
  29. annofabcli/statistics/visualize_statistics.py +1 -1
  30. annofabcli/task/delete_tasks.py +1 -1
  31. annofabcli/task/list_tasks.py +1 -1
  32. annofabcli/task/update_metadata_of_task.py +1 -1
  33. {annofabcli-1.103.0.dist-info → annofabcli-1.104.1.dist-info}/METADATA +1 -1
  34. {annofabcli-1.103.0.dist-info → annofabcli-1.104.1.dist-info}/RECORD +37 -37
  35. {annofabcli-1.103.0.dist-info → annofabcli-1.104.1.dist-info}/WHEEL +0 -0
  36. {annofabcli-1.103.0.dist-info → annofabcli-1.104.1.dist-info}/entry_points.txt +0 -0
  37. {annofabcli-1.103.0.dist-info → annofabcli-1.104.1.dist-info}/licenses/LICENSE +0 -0
annofabcli/__main__.py CHANGED
@@ -74,7 +74,7 @@ def main(arguments: Optional[list[str]] = None) -> None:
74
74
  warn_pandas_copy_on_write()
75
75
  parser = create_parser()
76
76
 
77
- if arguments is None: # noqa: SIM108
77
+ if arguments is None:
78
78
  args = parser.parse_args()
79
79
  else:
80
80
  args = parser.parse_args(arguments)
@@ -293,7 +293,7 @@ class AnnotationConverter:
293
293
  logger.warning(f"アノテーション仕様にラベル名(英語)が'{detail.label}'であるラベル情報が存在しないか、または複数存在します。 :: {log_message_suffix}")
294
294
  raise
295
295
 
296
- if detail.attributes is not None: # noqa: SIM108
296
+ if detail.attributes is not None:
297
297
  additional_data_list = self.convert_attributes(detail.attributes, label_name=detail.label, log_message_suffix=log_message_suffix)
298
298
  else:
299
299
  additional_data_list = []
@@ -18,6 +18,7 @@ from annofabapi.models import CommentType
18
18
 
19
19
  import annofabcli
20
20
  import annofabcli.common.cli
21
+ from annofabcli.comment.list_comment import create_empty_df_comment, create_reply_counter
21
22
  from annofabcli.common.cli import ArgumentParser, CommandLine, build_annofabapi_resource_and_login
22
23
  from annofabcli.common.download import DownloadingFile
23
24
  from annofabcli.common.enums import FormatArgument
@@ -62,12 +63,19 @@ class ListAllCommentMain:
62
63
  if comment_type is not None:
63
64
  comment_list = [e for e in comment_list if e["comment_type"] == comment_type.value]
64
65
 
66
+ # 返信回数を算出する
67
+ reply_counter = create_reply_counter(comment_list)
68
+ for c in comment_list:
69
+ key = (c["task_id"], c["input_data_id"], c["comment_id"])
70
+ c["reply_count"] = reply_counter.get(key, 0)
71
+
65
72
  if exclude_reply:
66
73
  # 返信コメントを除外する
67
74
  comment_list = [e for e in comment_list if e["comment_node"]["_type"] != "Reply"]
68
75
 
69
76
  visualize = AddProps(self.service, project_id)
70
77
  comment_list = [visualize.add_properties_to_comment(e) for e in comment_list]
78
+
71
79
  return comment_list
72
80
 
73
81
 
@@ -93,7 +101,11 @@ class ListAllComment(CommandLine):
93
101
 
94
102
  output_format = FormatArgument(args.format)
95
103
  if output_format == FormatArgument.CSV:
96
- df = pandas.json_normalize(comment_list)
104
+ if len(comment_list) > 0:
105
+ df = pandas.json_normalize(comment_list)
106
+ else:
107
+ df = create_empty_df_comment()
108
+
97
109
  print_csv(df, output=args.output)
98
110
  else:
99
111
  print_according_to_format(comment_list, output_format, output=args.output)
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import argparse
4
4
  import logging
5
+ from collections import Counter
5
6
  from typing import Any, Optional
6
7
 
7
8
  import pandas
@@ -19,9 +20,45 @@ from annofabcli.common.visualize import AddProps
19
20
  logger = logging.getLogger(__name__)
20
21
 
21
22
 
23
+ def create_reply_counter(comments: list[dict[str, Any]]) -> Counter[tuple[str, str, str]]:
24
+ """
25
+ 返信コメントの回数を取得するcounterを生成します。
26
+
27
+ """
28
+ root_comment_id_counter = Counter((c["task_id"], c["input_data_id"], c["comment_node"]["root_comment_id"]) for c in comments if c["comment_node"]["_type"] == "Reply")
29
+ return root_comment_id_counter
30
+
31
+
32
+ def create_empty_df_comment() -> pandas.DataFrame:
33
+ return pandas.DataFrame(
34
+ columns=[
35
+ "project_id",
36
+ "task_id",
37
+ "input_data_id",
38
+ "comment_id",
39
+ "phase",
40
+ "phase_stage",
41
+ "comment_type",
42
+ "account_id",
43
+ "user_id",
44
+ "username",
45
+ "phrases",
46
+ "comment",
47
+ "created_datetime",
48
+ "updated_datetime",
49
+ "reply_count",
50
+ ]
51
+ )
52
+
53
+
22
54
  class ListingComments(CommandLine):
23
- def get_comments(self, project_id: str, task_id: str, input_data_id: str): # noqa: ANN201
55
+ def get_comments(self, project_id: str, task_id: str, input_data_id: str) -> list[dict[str, Any]]:
24
56
  comments, _ = self.service.api.get_comments(project_id, task_id, input_data_id, query_params={"v": "2"})
57
+ # 返信回数を算出する
58
+ reply_counter = create_reply_counter(comments)
59
+ for c in comments:
60
+ key = (c["task_id"], c["input_data_id"], c["comment_id"])
61
+ c["reply_count"] = reply_counter.get(key, 0)
25
62
  return comments
26
63
 
27
64
  def get_comment_list(self, project_id: str, task_id_list: list[str], *, comment_type: Optional[CommentType], exclude_reply: bool) -> list[dict[str, Any]]:
@@ -49,10 +86,11 @@ class ListingComments(CommandLine):
49
86
  all_comments.extend(comments)
50
87
 
51
88
  except requests.HTTPError:
52
- logger.warning(f"タスク task_id = {task_id} のコメントを取得できませんでした。", exc_info=True)
89
+ logger.warning(f"task_id='{task_id}'のタスクのコメントの取得に失敗しました。", exc_info=True)
53
90
 
54
91
  visualize = AddProps(self.service, project_id)
55
92
  all_comments = [visualize.add_properties_to_comment(e) for e in all_comments]
93
+
56
94
  return all_comments
57
95
 
58
96
  def main(self) -> None:
@@ -66,7 +104,11 @@ class ListingComments(CommandLine):
66
104
 
67
105
  output_format = FormatArgument(args.format)
68
106
  if output_format == FormatArgument.CSV:
69
- df = pandas.json_normalize(comment_list)
107
+ if len(comment_list) > 0:
108
+ df = pandas.json_normalize(comment_list)
109
+ else:
110
+ df = create_empty_df_comment()
111
+
70
112
  print_csv(df, output=args.output)
71
113
  else:
72
114
  print_according_to_format(comment_list, output_format, output=args.output)
@@ -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: # noqa: SIM108
115
+ if label_name_list is not None:
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,7 +219,7 @@ def write_annotation_grayscale_image(
219
219
 
220
220
  # 下層レイヤにあるアノテーションから順に画像化する
221
221
  # reversed関数を使う理由:`simple_annotation.details`は上層レイヤのアノテーションから順に格納されているため
222
- if label_name_list is not None: # noqa: SIM108
222
+ if label_name_list is not None:
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"]))
@@ -221,7 +221,7 @@ def get_cache_dir() -> Path:
221
221
 
222
222
  """
223
223
  cache_home_dir = os.environ.get("XDG_CACHE_HOME")
224
- if cache_home_dir is None: # noqa: SIM108
224
+ if cache_home_dir is None:
225
225
  cache_home_dir_path = Path.home() / ".cache"
226
226
  else:
227
227
  cache_home_dir_path = Path(cache_home_dir)
@@ -259,7 +259,7 @@ 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: # noqa: SIM108
262
+ if image_file is not None:
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"
@@ -317,7 +317,7 @@ class DrawAnnotation(CommandLineWithoutWebapi):
317
317
 
318
318
  annotation_path: Path = args.annotation
319
319
  # Simpleアノテーションの読み込み
320
- if annotation_path.is_file(): # noqa: SIM108
320
+ if annotation_path.is_file():
321
321
  iter_parser = lazy_parse_simple_annotation_zip(annotation_path)
322
322
  else:
323
323
  iter_parser = lazy_parse_simple_annotation_dir(annotation_path)
@@ -99,7 +99,7 @@ def create_masked_name(name: str) -> str:
99
99
 
100
100
 
101
101
  def get_replaced_user_id_set_from_biography(df: pandas.DataFrame, not_masked_location_set: Optional[set[str]] = None) -> set[str]:
102
- if not_masked_location_set is None: # noqa: SIM108
102
+ if not_masked_location_set is None:
103
103
  filtered_df = df
104
104
  else:
105
105
  filtered_df = df[df["biography"].map(lambda e: e not in not_masked_location_set)]
@@ -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: # noqa: SIM108
218
+ if "biography" in df:
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()
@@ -320,7 +320,7 @@ class MaskUserInfo(CommandLineWithoutWebapi):
320
320
 
321
321
  csv_header_row_count: int = args.csv_header_row_count
322
322
  csv_path: Path = args.csv
323
- if csv_header_row_count == 1: # noqa: SIM108
323
+ if csv_header_row_count == 1:
324
324
  original_df = pandas.read_csv(str(csv_path))
325
325
  else:
326
326
  original_df = read_multiheader_csv(str(csv_path), header_row_count=csv_header_row_count)
@@ -70,7 +70,7 @@ class UploadInstruction(CommandLine):
70
70
  if src_value.startswith("data:"):
71
71
  img_path = save_image_from_data_uri_scheme(src_value, temp_dir=temp_dir)
72
72
  else: # noqa: PLR5501
73
- if src_value[0] == "/": # noqa: SIM108
73
+ if src_value[0] == "/":
74
74
  img_path = Path(src_value)
75
75
  else:
76
76
  img_path = html_path.parent / src_value
@@ -98,7 +98,7 @@ class UploadInstruction(CommandLine):
98
98
  continue
99
99
 
100
100
  # body要素があればその中身、なければhtmlファイルの中身をアップロードする
101
- if len(pq_html("body")) > 0: # noqa: SIM108
101
+ if len(pq_html("body")) > 0:
102
102
  html_data = pq_html("body").html()
103
103
  else:
104
104
  html_data = pq_html.html()
@@ -108,7 +108,7 @@ class UploadInstruction(CommandLine):
108
108
 
109
109
  def update_instruction(self, project_id: str, html_data: str) -> None:
110
110
  histories, _ = self.service.api.get_instruction_history(project_id)
111
- if len(histories) > 0: # noqa: SIM108
111
+ if len(histories) > 0:
112
112
  last_updated_datetime = histories[0]["updated_datetime"]
113
113
  else:
114
114
  last_updated_datetime = None
@@ -23,7 +23,7 @@ class ListJob(CommandLine):
23
23
  ジョブ一覧を取得する。
24
24
  """
25
25
 
26
- if job_query is not None: # noqa: SIM108
26
+ if job_query is not None:
27
27
  query_params = copy.deepcopy(job_query)
28
28
  else:
29
29
  query_params = {}
@@ -147,7 +147,7 @@ class ChangeProjectMembers(CommandLine):
147
147
  def main(self) -> None:
148
148
  args = self.args
149
149
  project_id = args.project_id
150
- if args.all_user: # noqa: SIM108
150
+ if args.all_user:
151
151
  user_id_list = self.get_all_user_id_list_except_myself(project_id)
152
152
  else:
153
153
  user_id_list = annofabcli.common.cli.get_list_from_args(args.user_id)
@@ -42,7 +42,7 @@ class InviteProjectMemberMain:
42
42
  # プロジェクトメンバを追加/更新する
43
43
  for user_id in user_id_list:
44
44
  dest_member = get_project_member(user_id)
45
- if dest_member is not None: # noqa: SIM108
45
+ if dest_member is not None:
46
46
  last_updated_datetime = dest_member["updated_datetime"]
47
47
  else:
48
48
  last_updated_datetime = None
@@ -147,7 +147,7 @@ class MergingVisualizationFile:
147
147
  for project_dir in self.project_dir_list:
148
148
  tmp_obj = project_dir.read_worktime_per_date_user()
149
149
 
150
- if merged_obj is None: # noqa: SIM108
150
+ if merged_obj is None:
151
151
  merged_obj = tmp_obj
152
152
  else:
153
153
  merged_obj = WorktimePerDate.merge(merged_obj, tmp_obj)
@@ -55,6 +55,7 @@ def lazy_parse_simple_annotation_by_input_data(annotation_path: Path) -> Iterato
55
55
 
56
56
  @dataclass(frozen=True)
57
57
  class AnnotationAreaInfo(DataClassJsonMixin):
58
+ project_id: str
58
59
  task_id: str
59
60
  task_status: str
60
61
  task_phase: str
@@ -92,6 +93,7 @@ def get_annotation_area_info_list(parser: SimpleAnnotationParser, simple_annotat
92
93
 
93
94
  result.append(
94
95
  AnnotationAreaInfo(
96
+ project_id=simple_annotation["project_id"],
95
97
  task_id=simple_annotation["task_id"],
96
98
  task_phase=simple_annotation["task_phase"],
97
99
  task_phase_stage=simple_annotation["task_phase_stage"],
@@ -135,6 +137,7 @@ def create_df(
135
137
  annotation_area_list: list[AnnotationAreaInfo],
136
138
  ) -> pandas.DataFrame:
137
139
  columns = [
140
+ "project_id",
138
141
  "task_id",
139
142
  "task_status",
140
143
  "task_phase",
@@ -57,6 +57,7 @@ class AnnotationAttribute(pydantic.BaseModel):
57
57
  入力データまたはタスク単位の区間アノテーションの長さ情報。
58
58
  """
59
59
 
60
+ project_id: str
60
61
  task_id: str
61
62
  task_status: str
62
63
  task_phase: str
@@ -87,6 +88,7 @@ def get_annotation_attribute_list_from_annotation_json(simple_annotation: dict[s
87
88
 
88
89
  result.append(
89
90
  AnnotationAttribute(
91
+ project_id=simple_annotation["project_id"],
90
92
  task_id=simple_annotation["task_id"],
91
93
  task_status=simple_annotation["task_status"],
92
94
  task_phase=simple_annotation["task_phase"],
@@ -141,6 +143,7 @@ def print_annotation_attribute_list_as_csv(annotation_attribute_list: list, outp
141
143
  df = pandas.json_normalize(annotation_attribute_list)
142
144
 
143
145
  base_columns = [
146
+ "project_id",
144
147
  "task_id",
145
148
  "task_status",
146
149
  "task_phase",
@@ -100,6 +100,7 @@ class AnnotationCountByInputData(DataClassJsonMixin, HasAnnotationAttributeCount
100
100
  入力データ単位のアノテーション数の情報。
101
101
  """
102
102
 
103
+ project_id: str
103
104
  task_id: str
104
105
  task_status: TaskStatus
105
106
  task_phase: TaskPhase
@@ -126,6 +127,7 @@ class AnnotationCountByTask(DataClassJsonMixin, HasAnnotationAttributeCounts):
126
127
  タスク単位のアノテーション数の情報。
127
128
  """
128
129
 
130
+ project_id: str
129
131
  task_id: str
130
132
  task_status: TaskStatus
131
133
  task_phase: TaskPhase
@@ -174,6 +176,7 @@ def convert_annotation_count_list_by_input_data_to_by_task(annotation_count_list
174
176
 
175
177
  result.append(
176
178
  AnnotationCountByTask(
179
+ project_id=first_elm.project_id,
177
180
  task_id=task_id,
178
181
  task_status=first_elm.task_status,
179
182
  task_phase=first_elm.task_phase,
@@ -263,6 +266,7 @@ class ListAnnotationCounterByInputData:
263
266
  frame_no = self.frame_no_map.get((simple_annotation["task_id"], simple_annotation["input_data_id"]))
264
267
 
265
268
  return AnnotationCountByInputData(
269
+ project_id=simple_annotation["project_id"],
266
270
  task_id=simple_annotation["task_id"],
267
271
  task_phase=TaskPhase(simple_annotation["task_phase"]),
268
272
  task_phase_stage=simple_annotation["task_phase_stage"],
@@ -343,6 +347,7 @@ class AnnotationCountCsvByAttribute:
343
347
  prior_attribute_columns: Optional[list[tuple[str, str, str]]] = None,
344
348
  ) -> list[tuple[str, str, str]]:
345
349
  basic_columns = [
350
+ ("project_id", "", ""),
346
351
  ("task_id", "", ""),
347
352
  ("task_status", "", ""),
348
353
  ("task_phase", "", ""),
@@ -360,6 +365,7 @@ class AnnotationCountCsvByAttribute:
360
365
  prior_attribute_columns: Optional[list[tuple[str, str, str]]] = None,
361
366
  ) -> list[tuple[str, str, str]]:
362
367
  basic_columns = [
368
+ ("project_id", "", ""),
363
369
  ("task_id", "", ""),
364
370
  ("task_status", "", ""),
365
371
  ("task_phase", "", ""),
@@ -377,6 +383,7 @@ class AnnotationCountCsvByAttribute:
377
383
  ) -> pandas.DataFrame:
378
384
  def to_cell(c: AnnotationCountByInputData) -> dict[tuple[str, str, str], Any]:
379
385
  cell: dict[tuple[str, str, str], Any] = {
386
+ ("project_id", "", ""): c.project_id,
380
387
  ("task_id", "", ""): c.task_id,
381
388
  ("task_status", "", ""): c.task_status.value,
382
389
  ("task_phase", "", ""): c.task_phase.value,
@@ -405,6 +412,7 @@ class AnnotationCountCsvByAttribute:
405
412
  ) -> pandas.DataFrame:
406
413
  def to_cell(c: AnnotationCountByTask) -> dict[tuple[str, str, str], Any]:
407
414
  cell: dict[tuple[str, str, str], Any] = {
415
+ ("project_id", "", ""): c.project_id,
408
416
  ("task_id", "", ""): c.task_id,
409
417
  ("task_status", "", ""): c.task_status.value,
410
418
  ("task_phase", "", ""): c.task_phase.value,
@@ -115,6 +115,7 @@ class AnnotationCounter(abc.ABC):
115
115
 
116
116
  @dataclass(frozen=True)
117
117
  class AnnotationCounterByTask(AnnotationCounter, DataClassJsonMixin):
118
+ project_id: str
118
119
  task_id: str
119
120
  task_status: TaskStatus
120
121
  task_phase: TaskPhase
@@ -124,6 +125,7 @@ class AnnotationCounterByTask(AnnotationCounter, DataClassJsonMixin):
124
125
 
125
126
  @dataclass(frozen=True)
126
127
  class AnnotationCounterByInputData(AnnotationCounter, DataClassJsonMixin):
128
+ project_id: str
127
129
  task_id: str
128
130
  task_status: TaskStatus
129
131
  task_phase: TaskPhase
@@ -254,6 +256,7 @@ class ListAnnotationCounterByInputData:
254
256
  frame_no = self.frame_no_map.get((task_id, input_data_id))
255
257
 
256
258
  return AnnotationCounterByInputData(
259
+ project_id=simple_annotation["project_id"],
257
260
  task_id=simple_annotation["task_id"],
258
261
  task_phase=TaskPhase(simple_annotation["task_phase"]),
259
262
  task_phase_stage=simple_annotation["task_phase_stage"],
@@ -351,6 +354,7 @@ class ListAnnotationCounterByTask:
351
354
  raise RuntimeError(f"{task_parser.task_id} ディレクトリにはjsonファイルが1つも含まれていません。")
352
355
 
353
356
  return AnnotationCounterByTask(
357
+ project_id=last_simple_annotation["project_id"],
354
358
  task_id=last_simple_annotation["task_id"],
355
359
  task_status=TaskStatus(last_simple_annotation["task_status"]),
356
360
  task_phase=TaskPhase(last_simple_annotation["task_phase"]),
@@ -468,6 +472,7 @@ class AttributeCountCsv:
468
472
  ) -> None:
469
473
  def get_columns() -> list[AttributeValueKey]:
470
474
  basic_columns = [
475
+ ("project_id", "", ""),
471
476
  ("task_id", "", ""),
472
477
  ("task_status", "", ""),
473
478
  ("task_phase", "", ""),
@@ -480,6 +485,7 @@ class AttributeCountCsv:
480
485
 
481
486
  def to_cell(c: AnnotationCounterByTask) -> dict[AttributeValueKey, Any]:
482
487
  cell = {
488
+ ("project_id", "", ""): c.project_id,
483
489
  ("task_id", "", ""): c.task_id,
484
490
  ("task_status", "", ""): c.task_status.value,
485
491
  ("task_phase", "", ""): c.task_phase.value,
@@ -506,6 +512,7 @@ class AttributeCountCsv:
506
512
  ) -> None:
507
513
  def get_columns() -> list[AttributeValueKey]:
508
514
  basic_columns = [
515
+ ("project_id", "", ""),
509
516
  ("task_id", "", ""),
510
517
  ("task_status", "", ""),
511
518
  ("task_phase", "", ""),
@@ -520,6 +527,7 @@ class AttributeCountCsv:
520
527
 
521
528
  def to_cell(c: AnnotationCounterByInputData) -> dict[tuple[str, str, str], Any]:
522
529
  cell = {
530
+ ("project_id", "", ""): c.project_id,
523
531
  ("input_data_id", "", ""): c.input_data_id,
524
532
  ("input_data_name", "", ""): c.input_data_name,
525
533
  ("frame_no", "", ""): c.frame_no,
@@ -569,6 +577,7 @@ class LabelCountCsv:
569
577
  ) -> None:
570
578
  def get_columns() -> list[str]:
571
579
  basic_columns = [
580
+ "project_id",
572
581
  "task_id",
573
582
  "task_status",
574
583
  "task_phase",
@@ -581,6 +590,7 @@ class LabelCountCsv:
581
590
 
582
591
  def to_dict(c: AnnotationCounterByTask) -> dict[str, Any]:
583
592
  d = {
593
+ "project_id": c.project_id,
584
594
  "task_id": c.task_id,
585
595
  "task_status": c.task_status.value,
586
596
  "task_phase": c.task_phase.value,
@@ -607,6 +617,7 @@ class LabelCountCsv:
607
617
  ) -> None:
608
618
  def get_columns() -> list[str]:
609
619
  basic_columns = [
620
+ "project_id",
610
621
  "task_id",
611
622
  "task_status",
612
623
  "task_phase",
@@ -621,6 +632,7 @@ class LabelCountCsv:
621
632
 
622
633
  def to_dict(c: AnnotationCounterByInputData) -> dict[str, Any]:
623
634
  d = {
635
+ "project_id": c.project_id,
624
636
  "input_data_id": c.input_data_id,
625
637
  "input_data_name": c.input_data_name,
626
638
  "frame_no": c.frame_no,
@@ -108,6 +108,7 @@ class AnnotationDuration(DataClassJsonMixin):
108
108
  入力データまたはタスク単位の区間アノテーションの長さ情報。
109
109
  """
110
110
 
111
+ project_id: str
111
112
  task_id: str
112
113
  task_status: TaskStatus
113
114
  task_phase: TaskPhase
@@ -234,6 +235,7 @@ class ListAnnotationDurationByInputData:
234
235
  }
235
236
 
236
237
  return AnnotationDuration(
238
+ project_id=simple_annotation["project_id"],
237
239
  task_id=simple_annotation["task_id"],
238
240
  task_phase=TaskPhase(simple_annotation["task_phase"]),
239
241
  task_phase_stage=simple_annotation["task_phase_stage"],
@@ -360,6 +362,7 @@ class AnnotationDurationCsvByAttribute:
360
362
  prior_attribute_columns: Optional[list[AttributeValueKey]] = None,
361
363
  ) -> list[AttributeValueKey]:
362
364
  basic_columns = [
365
+ ("project_id", "", ""),
363
366
  ("task_id", "", ""),
364
367
  ("task_status", "", ""),
365
368
  ("task_phase", "", ""),
@@ -379,6 +382,7 @@ class AnnotationDurationCsvByAttribute:
379
382
  ) -> pandas.DataFrame:
380
383
  def to_cell(c: AnnotationDuration) -> dict[tuple[str, str, str], Any]:
381
384
  cell: dict[AttributeValueKey, Any] = {
385
+ ("project_id", "", ""): c.project_id,
382
386
  ("input_data_id", "", ""): c.input_data_id,
383
387
  ("input_data_name", "", ""): c.input_data_name,
384
388
  ("task_id", "", ""): c.task_id,
@@ -423,6 +427,7 @@ class AnnotationDurationCsvByLabel:
423
427
  prior_label_columns: Optional[list[str]] = None,
424
428
  ) -> list[str]:
425
429
  basic_columns = [
430
+ "project_id",
426
431
  "task_id",
427
432
  "task_status",
428
433
  "task_phase",
@@ -442,6 +447,7 @@ class AnnotationDurationCsvByLabel:
442
447
  ) -> pandas.DataFrame:
443
448
  def to_dict(c: AnnotationDuration) -> dict[str, Any]:
444
449
  d: dict[str, Any] = {
450
+ "project_id": c.project_id,
445
451
  "input_data_id": c.input_data_id,
446
452
  "input_data_name": c.input_data_name,
447
453
  "task_id": c.task_id,
@@ -38,7 +38,7 @@ def get_video_duration_list(task_list: list[dict[str, Any]], input_data_list: li
38
38
  result = []
39
39
  for task in task_list:
40
40
  task_id = task["task_id"]
41
- elm = {"task_id": task_id, "task_status": task["status"], "task_phase": task["phase"], "task_phase_stage": task["phase_stage"]}
41
+ elm = {"project_id": task["project_id"], "task_id": task_id, "task_status": task["status"], "task_phase": task["phase"], "task_phase_stage": task["phase_stage"]}
42
42
  input_data_id_list = task["input_data_id_list"]
43
43
  assert len(input_data_id_list) == 1, f"task_id='{task_id}'には複数の入力データが含まれています。"
44
44
  input_data_id = input_data_id_list[0]
@@ -94,6 +94,7 @@ class ListVideoDuration(CommandLine):
94
94
  logger.info(f"{len(video_duration_list)} 件のタスクの動画長さを出力します。")
95
95
  if output_format == FormatArgument.CSV:
96
96
  columns = [
97
+ "project_id",
97
98
  "task_id",
98
99
  "task_status",
99
100
  "task_phase",
@@ -96,7 +96,7 @@ def create_task_count_summary(task_list: list[Task], number_of_inspections: int)
96
96
  """
97
97
  for task in task_list:
98
98
  status = TaskStatus(task["status"])
99
- if status == TaskStatus.COMPLETE: # noqa: SIM108
99
+ if status == TaskStatus.COMPLETE:
100
100
  step_for_current_phase = sys.maxsize
101
101
  else:
102
102
  step_for_current_phase = get_step_for_current_phase(task, number_of_inspections)
@@ -142,7 +142,7 @@ class SummarizeTaskCount(CommandLine):
142
142
  # タスク全件ファイルをダウンロードするので、オーナロールかアノテーションユーザロールであることを確認する。
143
143
  super().validate_project(project_id, project_member_roles=[ProjectMemberRole.OWNER, ProjectMemberRole.TRAINING_DATA_USER])
144
144
 
145
- if is_execute_get_tasks_api: # noqa: SIM108
145
+ if is_execute_get_tasks_api:
146
146
  task_list = self.service.wrapper.get_all_tasks(project_id)
147
147
  else:
148
148
  task_list = self.get_task_list_with_downloading_file(project_id, task_json_path, is_latest=is_latest)
@@ -59,7 +59,7 @@ class AnnotationCount:
59
59
  def get_annotation_count_default(simple_annotation: dict[str, Any]) -> int:
60
60
  return len(simple_annotation["details"])
61
61
 
62
- if get_annotation_count_func is not None: # noqa: SIM108
62
+ if get_annotation_count_func is not None:
63
63
  get_annotation_count = get_annotation_count_func
64
64
  else:
65
65
  get_annotation_count = get_annotation_count_default
@@ -222,7 +222,7 @@ class AnnotatorCumulativeProductivity(AbstractPhaseCumulativeProductivity):
222
222
 
223
223
  logger.debug(f"{output_file} を出力します。")
224
224
 
225
- if target_user_id_list is not None: # noqa: SIM108
225
+ if target_user_id_list is not None:
226
226
  user_id_list = target_user_id_list
227
227
  else:
228
228
  user_id_list = self.default_user_id_list
@@ -298,7 +298,7 @@ class InspectorCumulativeProductivity(AbstractPhaseCumulativeProductivity):
298
298
 
299
299
  logger.debug(f"{output_file} を出力します。")
300
300
 
301
- if target_user_id_list is not None: # noqa: SIM108
301
+ if target_user_id_list is not None:
302
302
  user_id_list = target_user_id_list
303
303
  else:
304
304
  user_id_list = self.default_user_id_list
@@ -360,7 +360,7 @@ class AcceptorCumulativeProductivity(AbstractPhaseCumulativeProductivity):
360
360
 
361
361
  logger.debug(f"{output_file} を出力します。")
362
362
 
363
- if target_user_id_list is not None: # noqa: SIM108
363
+ if target_user_id_list is not None:
364
364
  user_id_list = target_user_id_list
365
365
  else:
366
366
  user_id_list = self.default_user_id_list
@@ -253,7 +253,7 @@ class AnnotatorProductivityPerDate(AbstractPhaseProductivityPerDate):
253
253
 
254
254
  df = self.df.copy()
255
255
 
256
- if target_user_id_list is not None: # noqa: SIM108
256
+ if target_user_id_list is not None:
257
257
  user_id_list = target_user_id_list
258
258
  else:
259
259
  user_id_list = df.sort_values(by="user_id")["user_id"].dropna().unique().tolist()
@@ -406,7 +406,7 @@ class InspectorProductivityPerDate(AbstractPhaseProductivityPerDate):
406
406
 
407
407
  df = self.df.copy()
408
408
 
409
- if target_user_id_list is not None: # noqa: SIM108
409
+ if target_user_id_list is not None:
410
410
  user_id_list = target_user_id_list
411
411
  else:
412
412
  user_id_list = df.sort_values(by="user_id", ascending=False)["user_id"].dropna().unique().tolist()
@@ -544,7 +544,7 @@ class AcceptorProductivityPerDate(AbstractPhaseProductivityPerDate):
544
544
 
545
545
  df = self.df.copy()
546
546
 
547
- if target_user_id_list is not None: # noqa: SIM108
547
+ if target_user_id_list is not None:
548
548
  user_id_list = target_user_id_list
549
549
  else:
550
550
  user_id_list = df.sort_values(by="user_id", ascending=False)["user_id"].dropna().unique().tolist()
@@ -67,7 +67,7 @@ class TaskHistory:
67
67
  new_task_history["worktime_hour"] = isoduration_to_hour(task_history["accumulated_labor_time_milliseconds"])
68
68
  all_task_history_list.append(new_task_history)
69
69
 
70
- if len(all_task_history_list) > 0: # noqa: SIM108
70
+ if len(all_task_history_list) > 0:
71
71
  df = pandas.DataFrame(all_task_history_list)
72
72
  else:
73
73
  df = cls.empty()
@@ -213,12 +213,12 @@ class WholePerformance:
213
213
  # CSVファイル読み込み直後では、数値も文字列として格納されているので、文字列情報以外は数値に変換する
214
214
  for key, value in series.items():
215
215
  # `first_working_date`など2列目が空欄の場合は、key[1]がnumpy.nanになるため、keyを変換する
216
- if isinstance(key[1], float) and numpy.isnan(key[1]): # noqa: SIM108
216
+ if isinstance(key[1], float) and numpy.isnan(key[1]):
217
217
  key2 = (key[0], "")
218
218
  else:
219
219
  key2 = key
220
220
 
221
- if key2 in cls.STRING_KEYS: # noqa: SIM108
221
+ if key2 in cls.STRING_KEYS:
222
222
  value2 = value
223
223
  else:
224
224
  value2 = float(value)
@@ -370,7 +370,7 @@ class WorktimePerDate:
370
370
 
371
371
  logger.debug(f"{output_file} を出力します。")
372
372
 
373
- if target_user_id_list is not None: # noqa: SIM108
373
+ if target_user_id_list is not None:
374
374
  user_id_list = target_user_id_list
375
375
  else:
376
376
  user_id_list = self._get_default_user_id_list()
@@ -132,7 +132,7 @@ def plot_label_histogram(
132
132
 
133
133
  df = create_df()
134
134
 
135
- if arrange_bin_edge: # noqa: SIM108
135
+ if arrange_bin_edge:
136
136
  histogram_range = (
137
137
  df.min(numeric_only=True).min(),
138
138
  df.max(numeric_only=True).max(),
@@ -238,7 +238,7 @@ def plot_attribute_histogram( # noqa: PLR0915
238
238
  df = create_df()
239
239
  y_axis_label = _get_y_axis_label(group_by)
240
240
 
241
- if arrange_bin_edge: # noqa: SIM108
241
+ if arrange_bin_edge:
242
242
  histogram_range = (
243
243
  df.min(numeric_only=True).min(),
244
244
  df.max(numeric_only=True).max(),
@@ -127,7 +127,7 @@ def plot_annotation_duration_histogram_by_label( # noqa: PLR0915
127
127
  logger.debug(f"{len(df.columns)}個のラベルごとのヒストグラムを出力します。")
128
128
  for col in df.columns:
129
129
  if bin_width is not None:
130
- if arrange_bin_edge: # noqa: SIM108
130
+ if arrange_bin_edge:
131
131
  bin_edges = get_bin_edges(min_value=0, max_value=max_duration, bin_width=bin_width)
132
132
  else:
133
133
  bin_edges = get_bin_edges(min_value=0, max_value=df[col].max(), bin_width=bin_width)
@@ -238,7 +238,7 @@ def plot_annotation_duration_histogram_by_attribute( # noqa: PLR0915
238
238
  header = (str(col[0]), str(col[1])) # ラベル名, 属性名
239
239
 
240
240
  if bin_width is not None:
241
- if arrange_bin_edge: # noqa: SIM108
241
+ if arrange_bin_edge:
242
242
  bin_edges = get_bin_edges(min_value=0, max_value=max_duration, bin_width=bin_width)
243
243
  else:
244
244
  bin_edges = get_bin_edges(min_value=0, max_value=df[col].max(), bin_width=bin_width)
@@ -342,7 +342,7 @@ class VisualizingStatisticsMain:
342
342
  df_annotation_count = self.annotation_count.df
343
343
  df_annotation_count = df_annotation_count[df_annotation_count["project_id"] == project_id]
344
344
  # `annotation_count = None`にする理由:後続の処理でアノテーションZIPからアノテーション数を算出するようにするため
345
- if len(df_annotation_count) == 0: # noqa: SIM108
345
+ if len(df_annotation_count) == 0:
346
346
  annotation_count = None
347
347
  else:
348
348
  annotation_count = AnnotationCount(df_annotation_count)
@@ -154,7 +154,7 @@ class DeleteTaskMain(CommandLineWithConfirm):
154
154
  True: タスクを削除した。False: タスクを削除しなかった。
155
155
 
156
156
  """
157
- if task_index is not None: # noqa: SIM108
157
+ if task_index is not None:
158
158
  log_prefix = f"{task_index + 1} 件目, task_id='{task_id}'"
159
159
  else:
160
160
  log_prefix = f"task_id='{task_id}'"
@@ -90,7 +90,7 @@ class ListTasksMain:
90
90
  Returns:
91
91
  対象の検査コメント一覧
92
92
  """
93
- if task_query is not None: # noqa: SIM108
93
+ if task_query is not None:
94
94
  task_query = self._modify_task_query(project_id, task_query)
95
95
  else:
96
96
  task_query = {}
@@ -74,7 +74,7 @@ class UpdateMetadataOfTaskMain(CommandLineWithConfirm):
74
74
  if not self.confirm_processing(self.get_confirm_message(task_id, metadata)):
75
75
  return False
76
76
 
77
- if self.is_overwrite_metadata: # noqa: SIM108
77
+ if self.is_overwrite_metadata:
78
78
  new_metadata = metadata
79
79
  else:
80
80
  new_metadata = {**task["metadata"], **metadata}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: annofabcli
3
- Version: 1.103.0
3
+ Version: 1.104.1
4
4
  Summary: Utility Command Line Interface for AnnoFab
5
5
  Author: Kurusugawa Computer Inc.
6
6
  License: MIT
@@ -1,5 +1,5 @@
1
1
  annofabcli/__init__.py,sha256=fdBtxy5rOI8zi26jf0hmXS5KTBjQIsm2b9ZUSAIR558,319
2
- annofabcli/__main__.py,sha256=JzfycqVG9ENhWOCxTouZwpHwWTSrI-grLsaMudxjyBM,5283
2
+ annofabcli/__main__.py,sha256=83jLGTlNGoXaYU3fz9akYXoL3kgfIuaVXo_TkpK72IU,5267
3
3
  annofabcli/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  annofabcli/annotation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  annofabcli/annotation/annotation_query.py,sha256=loXcmHhwp0gh_4u5NhvA1x2VAbIT6UJpdIzeFHT5HlY,15566
@@ -9,7 +9,7 @@ annofabcli/annotation/copy_annotation.py,sha256=Pih2k3vvpgfT3Ovb3gZw2L_8fK_ws_wK
9
9
  annofabcli/annotation/delete_annotation.py,sha256=Yo73sl96ETMnf6uscJX4h3NU3-cT-OH-rqqXMoLlhbM,23105
10
10
  annofabcli/annotation/download_annotation_zip.py,sha256=P_ZpdqIaSFEmB8jjpdykcRhh2tVlHxSlXFrYreJjShE,3282
11
11
  annofabcli/annotation/dump_annotation.py,sha256=iiTYjbUYEJrgoSfr4oQOepVkba9O4sjvpSKYfuER318,7466
12
- annofabcli/annotation/import_annotation.py,sha256=t5BiHMAUvSJFkMz3uz_2mAhlrDvR6mYd6RrY9eICA0k,33385
12
+ annofabcli/annotation/import_annotation.py,sha256=39w-LwhNrT4-20NR5Hy-cn_cUFVVWVnMp9x1d8aITn0,33369
13
13
  annofabcli/annotation/list_annotation.py,sha256=uKcOuGC7lzd6vVbzizkiZtYdXJ7EzY0iifuiqKl2wQM,10707
14
14
  annofabcli/annotation/list_annotation_count.py,sha256=T9fbaoxWeDJIVgW_YgHRldbwrVZWiE-57lfJrDQrj80,6474
15
15
  annofabcli/annotation/merge_segmentation.py,sha256=kIsCeXtJxzd6nobQPpi0fscaRDlTx3tg1qpy5PDfSJI,18107
@@ -35,8 +35,8 @@ annofabcli/annotation_specs/subcommand_annotation_specs.py,sha256=yqSjV1S3CSB0sF
35
35
  annofabcli/comment/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
36
  annofabcli/comment/delete_comment.py,sha256=NpQVrXrIPI3vjAyOZ-5Mm-Pae_uCHu8BXVEA06QzKTU,11399
37
37
  annofabcli/comment/download_comment_json.py,sha256=YfqUnMgvLgVFV7FJPIXwirREkQ2E63fXeCaF4hfwk8c,2338
38
- annofabcli/comment/list_all_comment.py,sha256=jAvOuLP5PUgEKzrDYiMaMHddWSsPeH4RIO9NYb3yHAo,6028
39
- annofabcli/comment/list_comment.py,sha256=m_Z98n_FdQZ_NGdlSHiwzY8GT_H0gfjS45bykUR7bt8,4896
38
+ annofabcli/comment/list_all_comment.py,sha256=zMZSmVe8P89WDBZE5PZn5SIv5j2OTbnP1kS-HnCxPCI,6483
39
+ annofabcli/comment/list_comment.py,sha256=ikXOtfI9W88w7YC1GQQ1ryq2BatHelIRb8Pa5-fKbSs,6187
40
40
  annofabcli/comment/put_comment.py,sha256=aP1VhjwzKLY8zjHOO1ZkHc6ulwpKtAt-10fWpDn3RUo,12000
41
41
  annofabcli/comment/put_comment_simply.py,sha256=OwanjmQy5nqqIw-i0Gt9APdEdftM-EuZW4pRLYbIwQM,8171
42
42
  annofabcli/comment/put_inspection_comment.py,sha256=TL8o_K9LCLxqMEVPs9wNK_X4jzEiJwjr327lziQbeAM,3803
@@ -53,11 +53,11 @@ annofabcli/common/download.py,sha256=b3e5tVn1dmM1BMti67WwGzDCRH7hYJQEgk0xxkkuMIw
53
53
  annofabcli/common/enums.py,sha256=pnMZEk8ADK2qO2Hmujx6NxeCwvSAEDNhmgK4ajPSC9Q,1233
54
54
  annofabcli/common/exceptions.py,sha256=trgC5eqvy7jgqOQ41pbAOC__uxy19GgrM9NAgkH_lBw,2051
55
55
  annofabcli/common/facade.py,sha256=1d5DxC4O5yHr0gisqaqgkacY5Omn1X-L1syPnYPyiwQ,19401
56
- annofabcli/common/image.py,sha256=vJM6CIoYVfxGuQRf_hsxQTRHIgrFpvOB42IwpayhNcE,16738
56
+ annofabcli/common/image.py,sha256=qUsQXEYmttT443BOiaxLthccE7hLji5toLjgSdneNWA,16706
57
57
  annofabcli/common/pandas.py,sha256=IW9xqHkdRF1I6YZc7CP_9tkGxJuu1MKEXFILjhaNUU0,449
58
58
  annofabcli/common/type_util.py,sha256=i3r5pFtRYQwJrYkl1-lVQi8XOePQxTUX_cAHgBTsagM,224
59
59
  annofabcli/common/typing.py,sha256=_AcEogoaMbib0esfN2RvHshAZH0oyRb2Ro9-rbn7NJ8,330
60
- annofabcli/common/utils.py,sha256=oB4OSnC-qbmP4w-T5tivllBtFg0I13qt8a3udzHfbbA,9561
60
+ annofabcli/common/utils.py,sha256=Eb4DS5j_EVdZW_YnsvIgjTbgWcjHd560plck2_WgrCI,9545
61
61
  annofabcli/common/visualize.py,sha256=94lPfp6jc9zhCntScuzTv_UvYiokb-l_sCwB9pjW9tA,13612
62
62
  annofabcli/common/annofab/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
63
63
  annofabcli/common/annofab/annotation_specs.py,sha256=h-YSnuK0riCLoJMmV-KDP3JS-_JMqx0feSvPAB3xCSI,765
@@ -67,9 +67,9 @@ annofabcli/experimental/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
67
67
  annofabcli/experimental/list_out_of_range_annotation_for_movie.py,sha256=klusUf9EqeGIiWcPK4DwyPbVuKRfEXXv9zYk1vDpF0g,8519
68
68
  annofabcli/experimental/subcommand_experimental.py,sha256=DcXTbeba1Qcgr7izGgwNwbo5AlKbwHa4ROhQpvFd4k4,911
69
69
  annofabcli/filesystem/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
70
- annofabcli/filesystem/draw_annotation.py,sha256=CVvN7knGAyjpXseYx0XinshYERdFnUI79Ww0YMEzUX4,19293
70
+ annofabcli/filesystem/draw_annotation.py,sha256=dcwK5czgjbWQ3qO_HOJlZQfxVHoUFjyKLJWqS2q-1z0,19261
71
71
  annofabcli/filesystem/filter_annotation.py,sha256=W9UL1GZiV-aus6P_tyGqB2XQtIxb_nO4tIwrDfjR-o8,11147
72
- annofabcli/filesystem/mask_user_info.py,sha256=8U1xbCN-uddd3BgAc0_cILNs9VmkXqdGGXPTXQnZdkA,13553
72
+ annofabcli/filesystem/mask_user_info.py,sha256=j-6gZTMGARGy3wQNGGo4xORsl2HOlC64q-F9-y7JyZ0,13505
73
73
  annofabcli/filesystem/merge_annotation.py,sha256=D6rzbHwI675p5iKeN9HVa7792fDf6z9ap4Jg0RjFuBI,10522
74
74
  annofabcli/filesystem/subcommand_filesystem.py,sha256=ZM2td5iZYIQ3TCI-9xAue8LugFlIc3WMRXrJqnjJ8-s,1186
75
75
  annofabcli/input_data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -91,10 +91,10 @@ annofabcli/instruction/copy_instruction.py,sha256=24zBMkelSI2mpJq7Esgzo3uB_f1Z3h
91
91
  annofabcli/instruction/download_instruction.py,sha256=mxlAp3Yr4HZrtNHpNc_VOiNLHyKQc7HCqF6X9kHKEKU,8317
92
92
  annofabcli/instruction/list_instruction_history.py,sha256=GccDW2h5h8x-E0v8M3bWyWICCN_uLQPP0PEEwXhaEPg,2085
93
93
  annofabcli/instruction/subcommand_instruction.py,sha256=hSj7iYX-ad23X3wi5iMb9AZJCd1bUxFvynLJ6r3ZFGE,1169
94
- annofabcli/instruction/upload_instruction.py,sha256=pJmlG2SJc57K8ZWbN8if0HoT3NaIXXQ1zaN3XMqvipQ,6081
94
+ annofabcli/instruction/upload_instruction.py,sha256=rEgLvhQ9KGOpvt09stCnJMP03llRPgyodNIkaHc6rvc,6033
95
95
  annofabcli/job/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
96
96
  annofabcli/job/delete_job.py,sha256=vWC81MgwzAG5SYMZE9fcr1XOiAoS_AryGFuFnABRbcc,3402
97
- annofabcli/job/list_job.py,sha256=hE4JYfq5TtOr2WeuCFwmTUr18Rizsu_8DWC2BH6pnw8,3162
97
+ annofabcli/job/list_job.py,sha256=id_-WomjwCDmymMGkPJb_3JdvhRVWFFa8kSpqf1iuus,3146
98
98
  annofabcli/job/list_last_job.py,sha256=RFddmjnph-cUajm4BPCQV6X9yCWuotKUTHbAvChea60,6740
99
99
  annofabcli/job/subcommand_job.py,sha256=kzKAT067Q_zODm6H2bbwOGHMDg8q6juqWzutGQpp2As,1008
100
100
  annofabcli/job/wait_job.py,sha256=n7GwRv8XQHYDC4Q6GVjmGImvhWGu_QQpEwj9g6jkWvw,4212
@@ -119,16 +119,16 @@ annofabcli/project/list_project.py,sha256=OWnbCyShI4ceugxML8kSAD2nkyld5MlpXfbvQu
119
119
  annofabcli/project/put_project.py,sha256=dsRJfx2ga4mmYci40q91UzXeQN6m_3fMU9mrcFRpY9Q,6033
120
120
  annofabcli/project/subcommand_project.py,sha256=Tpr-WOw1uCYNYKd-zpSL91j4RqXqjClJrjRVf23X4p4,1333
121
121
  annofabcli/project_member/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
122
- annofabcli/project_member/change_project_members.py,sha256=5aoCFp8Xkomt7iOcsD5ngtgxHmF_iudQQzPQnvz1QvQ,9353
122
+ annofabcli/project_member/change_project_members.py,sha256=T7l7--T2Mb8zLKKfGq3qB-wiAie6rkt2V-iq9e2LDp4,9337
123
123
  annofabcli/project_member/copy_project_members.py,sha256=Rm98Ks0PE4zdoXqpu_itNLvBkh1d5x_J7CKjdTkhKLk,8839
124
124
  annofabcli/project_member/drop_project_members.py,sha256=dv3hvHN-M9xTd33G00yVKzx07ROpclVsJUH3wD70IOE,5853
125
- annofabcli/project_member/invite_project_members.py,sha256=lCl0WIOUKx9G4t03jz9d3K9OermgZbYyeGFOpE8BhVI,6323
125
+ annofabcli/project_member/invite_project_members.py,sha256=SchaFbBRBYjxBYops--aH6mMvqWx0YVIKKNcgC5gdCM,6307
126
126
  annofabcli/project_member/list_users.py,sha256=x1hFbolBGockF3vj3eYSGIp2h4mWKDpru8T8dN56L1U,4693
127
127
  annofabcli/project_member/put_project_members.py,sha256=DNRcsQk3ad4d6cpMbI0wD2_dXD-D_lULcDgUYmpHzZc,9069
128
128
  annofabcli/project_member/subcommand_project_member.py,sha256=6cOoMiZJ82j94rSSp1GzmYggGSm1egk3S9e_YYgzhe8,1466
129
129
  annofabcli/stat_visualization/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
130
130
  annofabcli/stat_visualization/mask_visualization_dir.py,sha256=x1kP85eoRv2XsWQumLyqztDIcYDJI7feoBZWADtWapc,13166
131
- annofabcli/stat_visualization/merge_visualization_dir.py,sha256=q41bE8jBdu8nbHGM4drsS4PDhK6w7iNVMvom13vbhhM,15587
131
+ annofabcli/stat_visualization/merge_visualization_dir.py,sha256=7rOluAY7X5rcukWs2dKnwXSM6JpRpULHEYM5QomyM6o,15571
132
132
  annofabcli/stat_visualization/subcommand_stat_visualization.py,sha256=vk-LPAjhfkTaGHC-pDLhwLCc0opF3hMz-0af3yichuA,1484
133
133
  annofabcli/stat_visualization/summarize_whole_performance_csv.py,sha256=gPldqPECBqC61IdTw7JPAscUVRz76YluDiF3QOVnSEk,3099
134
134
  annofabcli/stat_visualization/write_graph.py,sha256=gRO0LcZ6x7Jgln9ALUUM3BHTMaAt1H15PB4_0bRo8TI,9101
@@ -136,21 +136,21 @@ annofabcli/stat_visualization/write_performance_rating_csv.py,sha256=0j78z5uRULo
136
136
  annofabcli/statistics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
137
137
  annofabcli/statistics/histogram.py,sha256=CvzDxT2cKLSnBGSqkZE6p92PayGxYYja1YyB24M4ALU,3245
138
138
  annofabcli/statistics/linegraph.py,sha256=0kr7jVBNMiM2ECYhv3Ry5RitElKerSl9ZKxbKzfiplI,12494
139
- annofabcli/statistics/list_annotation_area.py,sha256=K1V1w7eNXv-6P_7v3SXqO6VQx8FF6Yjl7OL0IeWiDO4,12227
140
- annofabcli/statistics/list_annotation_attribute.py,sha256=aq3wU2edygRygd3uydhh7dPBUQlyX5zQK3H4b3RiARI,12420
141
- annofabcli/statistics/list_annotation_attribute_filled_count.py,sha256=ryDLtFIdW2G5YDqYZWU2-p7L8oGAXSE6_OknSVoZLy0,28708
142
- annofabcli/statistics/list_annotation_count.py,sha256=sYepVd6UDqy2O3jUO4f6QqSRCUzTi_HorydKJcL4g5Q,52254
143
- annofabcli/statistics/list_annotation_duration.py,sha256=ZW_sSQQdUAyv14wAIKghGzUe_g1vxusWK_P2e9oGa8s,31639
144
- annofabcli/statistics/list_video_duration.py,sha256=WGM4Onucw4Z8az8how5FvpN5u-YQaxAEnIJblKY7gl8,9099
139
+ annofabcli/statistics/list_annotation_area.py,sha256=nGqhqPEHLPUccnLCmA9nmwvmYbZYlh5ZxiHNszZ1ei8,12329
140
+ annofabcli/statistics/list_annotation_attribute.py,sha256=L_wmcUGS0Lu3tnRmidDjYK3bCNdvwDjAH64r5__MQ_w,12522
141
+ annofabcli/statistics/list_annotation_attribute_filled_count.py,sha256=g-MihJwEoA1ZnLTJOGX-dn6hI5aUdqQvh2KWbREbQ9s,29033
142
+ annofabcli/statistics/list_annotation_count.py,sha256=cBmUTYifB7UESEFets7DMDn8_GKDBBDJ2vt1q_56fcc,52747
143
+ annofabcli/statistics/list_annotation_duration.py,sha256=ps0UT50W_6ZL5_cZNsSo7Dp-cSx77m1IF4QMBkwRt98,31875
144
+ annofabcli/statistics/list_video_duration.py,sha256=OCDXPOP2z7flE8NBaQD1lDkU9JG5mn3PfACijoR-5s0,9163
145
145
  annofabcli/statistics/list_worktime.py,sha256=nr--GtFY-oyFuu8M0EsUqcVxX26gjeP09LYUcdeptyk,6456
146
146
  annofabcli/statistics/scatter.py,sha256=C3hTlm_QfGBiY4KjZ-8D_u_Rk53a9f4jszx4iNZgp9w,10945
147
147
  annofabcli/statistics/subcommand_statistics.py,sha256=Pvd7s0vvDU9tSpAphPrv94IDhhR1p8iFH2tjdt7I7ZU,2536
148
- annofabcli/statistics/summarize_task_count.py,sha256=EjzdQ47EkZiL8_GPuH_kt5eLRTrgV38oBvGgnHIq1PI,9589
148
+ annofabcli/statistics/summarize_task_count.py,sha256=fMVNxUDs1KdgRXsg0yaEKw5iJzn3_U39rUN6BbkP720,9557
149
149
  annofabcli/statistics/summarize_task_count_by_task_id_group.py,sha256=eRPl89Oh7_ViDW5FA1nt56TdcCMWMjrd9LhE6lLSbeA,8533
150
150
  annofabcli/statistics/summarize_task_count_by_user.py,sha256=rwhQwO6g2No9AqLEAbAfnlg_6CkgB3CRkZiaNnXCL0I,6857
151
- annofabcli/statistics/visualize_annotation_count.py,sha256=o5B5cc1gFduO0L-9DWgKxLgWu1S5Q0b2f-V1NFGTFYo,22170
152
- annofabcli/statistics/visualize_annotation_duration.py,sha256=5kpkLmUssUd9uZTNlVa81wqI_ylJIi8q-2ytU24d-yU,21054
153
- annofabcli/statistics/visualize_statistics.py,sha256=F7tRSag1su4dl9tZreB62pcYjxrAD6epa0Db0p-adRA,38780
151
+ annofabcli/statistics/visualize_annotation_count.py,sha256=7OATuGa2okq80unuTe-X30CBVkrlMLDN5Y-Q_5mB6eI,22138
152
+ annofabcli/statistics/visualize_annotation_duration.py,sha256=9JH9MirhOyCmjcChFJMtfnFIV2k4sucP9PAwNKMcbtE,21022
153
+ annofabcli/statistics/visualize_statistics.py,sha256=Hey3LqTFoXT0zKP_KMgszaVC8xIZPpep5sxpuefWKG4,38764
154
154
  annofabcli/statistics/visualize_video_duration.py,sha256=PYiVT7CDm3g5WLNRF20s7xGluJctO1mtC6y3wNu-eK4,16651
155
155
  annofabcli/statistics/visualization/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
156
156
  annofabcli/statistics/visualization/filtering_query.py,sha256=6QH0hfyg2VPeSjiJrd3ECMLbZCTZfQMH-K2fdn4rlaE,4152
@@ -159,21 +159,21 @@ annofabcli/statistics/visualization/project_dir.py,sha256=khcSS0R6X1sm1Oq8Tr7HpH
159
159
  annofabcli/statistics/visualization/visualization_source_files.py,sha256=SFY7WXUtjECB8l7zP-exawocrTiZ0UI7Z5sjgq4J_g4,8641
160
160
  annofabcli/statistics/visualization/dataframe/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
161
161
  annofabcli/statistics/visualization/dataframe/actual_worktime.py,sha256=7nsHlvN5cDzXIw-u_MSAZf4nlSSY56IlunSmnODXTbY,1916
162
- annofabcli/statistics/visualization/dataframe/annotation_count.py,sha256=cEmymjak6v0-4jeZOyvYuWcXm5ASDF2fPHwAJIFR4sM,3956
163
- annofabcli/statistics/visualization/dataframe/cumulative_productivity.py,sha256=_cirz_xxUFHc3eKBl8Q6RTbprMElIz3jpHaLfHrZ26c,16192
162
+ annofabcli/statistics/visualization/dataframe/annotation_count.py,sha256=gv9iFpSLu_cB63G3Z9dGImT9jr_Q6U_mrmG8VXsxJnk,3940
163
+ annofabcli/statistics/visualization/dataframe/cumulative_productivity.py,sha256=DyaskG9fT3K2rWR04z4QIYgdrAjR_O3YYDmsVT23NQg,16144
164
164
  annofabcli/statistics/visualization/dataframe/custom_production_volume.py,sha256=5ELLiQJ5sNKdVKmYYVeZW4nedDg1CVGxMDdF5TUUX5c,2142
165
165
  annofabcli/statistics/visualization/dataframe/input_data_count.py,sha256=wDRFtoIWw_Gy2bPZ7LBx3eMO3LdUdjbQKS9mncXav6I,1654
166
166
  annofabcli/statistics/visualization/dataframe/inspection_comment_count.py,sha256=RxpQzRy4U2hKEpgbksUXotcxH2sKz__NO20mxpMqK1w,4382
167
- annofabcli/statistics/visualization/dataframe/productivity_per_date.py,sha256=lMk3_h5klINyWG-vYPbrtlrlRcAzoZxWs79TPAlr4uE,27135
167
+ annofabcli/statistics/visualization/dataframe/productivity_per_date.py,sha256=_AibOSwyeGM6KeYqknN40M8vS4Tl6l45tC0ua1AHFFc,27087
168
168
  annofabcli/statistics/visualization/dataframe/project_performance.py,sha256=q480Lz1LwQD6RvyIOq-ZsXqeeKabsVpHRoM0nD_DaGI,8482
169
169
  annofabcli/statistics/visualization/dataframe/task.py,sha256=HBquPn6K17WPgb3nyeMS44M57srD5LpUm8wtOXJLkTU,24098
170
- annofabcli/statistics/visualization/dataframe/task_history.py,sha256=3b9e4ok6yKE5x647KzRqvp01P33XMAHLEEbLJ5GCmRo,2760
170
+ annofabcli/statistics/visualization/dataframe/task_history.py,sha256=FZ3MLqOiM6834fxWZKP0Hy9WDRSSLCYm6kNzdWW7-S8,2744
171
171
  annofabcli/statistics/visualization/dataframe/task_worktime_by_phase_user.py,sha256=TKdZmjr-jvnxOxsSnSCbloV9EQ3RB3nKv1tfIve2EZE,12974
172
172
  annofabcli/statistics/visualization/dataframe/user.py,sha256=EHn7nlf6D6UX-gsVXy8m_3QaCsHsUhr0iy2rbNozOgc,1707
173
173
  annofabcli/statistics/visualization/dataframe/user_performance.py,sha256=2WX_D3I9_mn0mIPfsb2XCJINs31TmID4F9SNfIPccsM,56093
174
- annofabcli/statistics/visualization/dataframe/whole_performance.py,sha256=du0Lit7wLsx-C2DooHYi4n2z-viLsBpj6wbMM5DmWjU,12481
174
+ annofabcli/statistics/visualization/dataframe/whole_performance.py,sha256=kw5Cww0fwDfwriTtxiT0l3wr7YAMA9eGjvp84G9MN9I,12449
175
175
  annofabcli/statistics/visualization/dataframe/whole_productivity_per_date.py,sha256=q3I00aCztXlMX3JW4XLe7apNRS4_gQVhOynlsaYBZVY,51635
176
- annofabcli/statistics/visualization/dataframe/worktime_per_date.py,sha256=UFG5h66NnFyOwZu7Z92tz4RqMPfp_6zZ9mV7qKWHFhM,21251
176
+ annofabcli/statistics/visualization/dataframe/worktime_per_date.py,sha256=9_ZVtXlNDFUKYWwcb_Pd_1IE5JUpTGmZdAPAS0nl1Lo,21235
177
177
  annofabcli/supplementary/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
178
178
  annofabcli/supplementary/delete_supplementary_data.py,sha256=dA4n61SSkTbDKDqjVldHIEAxbPQXyrQciwI4RDuC35U,13537
179
179
  annofabcli/supplementary/list_supplementary_data.py,sha256=Rh9aOa3PwukVxnnbXTtMG0qAASc3JkaqRt7KrMGZQRk,7635
@@ -187,17 +187,17 @@ annofabcli/task/change_status_to_on_hold.py,sha256=vWRyk6IK3HcgTWDIbbhXzsrtuoa7O
187
187
  annofabcli/task/complete_tasks.py,sha256=ssg_Z7ADRQRXvXgK2k5TEmvbRjrJQ33cXeb8kG8Y3jc,24917
188
188
  annofabcli/task/copy_tasks.py,sha256=9TN0oykJbTZHSF8p16CHC4Ezay5Ezx6-S_p0-FRUtms,8667
189
189
  annofabcli/task/delete_metadata_key_of_task.py,sha256=Cjqe3fWKeRzVxxlrGyt3TS-x1riD55LnNXLIS9JPoTw,8029
190
- annofabcli/task/delete_tasks.py,sha256=r-1-AFRJS2WTFnPmIPUxMlAbMvxEO0lxDE5LUEMqj3E,13114
190
+ annofabcli/task/delete_tasks.py,sha256=7T5eNCMW06ABekNGLwhTitDK5qn0tiPKrEXyJXyQNvs,13098
191
191
  annofabcli/task/download_task_json.py,sha256=Ocjecmdf2WV_Sq3u1InfMLIsT3XSw0ojyJmJbhv2sgg,2803
192
192
  annofabcli/task/list_all_tasks.py,sha256=FpFzosCZs2EZNSQMHzWse4z_zjZeiVF5BFmbwb97UYg,6368
193
193
  annofabcli/task/list_all_tasks_added_task_history.py,sha256=fkdiuo64iS7xxvIfGKzSiUPPEMiCVnJjjcAtMxe2Ngs,9551
194
- annofabcli/task/list_tasks.py,sha256=u3lQuq_vb5e7kx0aKc4xb_apDiE0HgE70D7G92iMRfo,10067
194
+ annofabcli/task/list_tasks.py,sha256=cmfqbP2Sr1dlpvpJLJscKq31BUdXVaajr_agiecKWXg,10051
195
195
  annofabcli/task/list_tasks_added_task_history.py,sha256=c8kxh9dssOZw6WK3Zpet1lNYr311xiiPJ1JGv97u1Xs,21470
196
196
  annofabcli/task/put_tasks.py,sha256=HADm-sP8zs523MlDThlwrGIVIEtR4Md2KlpJbWhCCTk,13745
197
197
  annofabcli/task/put_tasks_by_count.py,sha256=kIjvWtgZ53Smcm8N-raZedQCubx1TWoQT-BYyioYDrA,5999
198
198
  annofabcli/task/reject_tasks.py,sha256=2mRxIsP63N2xcVXQ0xeFqF0VkuUQP6C_bsFEqG-qNf0,22027
199
199
  annofabcli/task/subcommand_task.py,sha256=L_5Dwe58eblrtOrUYxjJAvkSmu6savRUxIqGjsFq-R4,2436
200
- annofabcli/task/update_metadata_of_task.py,sha256=Rm2rsGFx7JnkGCAyEQ9f8lXF7hbFifliDFCzZ1LI9O0,12882
200
+ annofabcli/task/update_metadata_of_task.py,sha256=aGy0onyzNj0goiTAZemaIzovhBJbi6eOQhXy9XF9rVg,12866
201
201
  annofabcli/task_history/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
202
202
  annofabcli/task_history/download_task_history_json.py,sha256=xZnGNKkPYT6RXIUd_wUqZfPiVpGdW5MTBUSpNKbOAC4,2370
203
203
  annofabcli/task_history/list_all_task_history.py,sha256=cG7CPeIXemV-KNUIfPQAU4_-4fkKDNcZ8iJeqhi48ok,6715
@@ -208,8 +208,8 @@ annofabcli/task_history_event/download_task_history_event_json.py,sha256=hQLVbQ0
208
208
  annofabcli/task_history_event/list_all_task_history_event.py,sha256=mzFqOS1WjC4_QEz6Yyp1ZvU5h-kU_PU82CtnnjQRSlY,6345
209
209
  annofabcli/task_history_event/list_worktime.py,sha256=J18uLrQwZuaatkA4dAr83Rz_qAF2xsx2gOFDp6ysimI,12968
210
210
  annofabcli/task_history_event/subcommand_task_history_event.py,sha256=mJVJoT4RXk4HWnY7-Nrsl4If-gtaIIEXd2z7eFZwM2I,1260
211
- annofabcli-1.103.0.dist-info/METADATA,sha256=tLQegfxK2gm5M66h63y_GbBbWiHXvWBi3o0emCLBzrU,5286
212
- annofabcli-1.103.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
213
- annofabcli-1.103.0.dist-info/entry_points.txt,sha256=C2uSUc-kkLJpoK_mDL5FEMAdorLEMPfwSf8VBMYnIFM,56
214
- annofabcli-1.103.0.dist-info/licenses/LICENSE,sha256=pcqWYfxFtxBzhvKp3x9MXNM4xciGb2eFewaRhXUNHlo,1081
215
- annofabcli-1.103.0.dist-info/RECORD,,
211
+ annofabcli-1.104.1.dist-info/METADATA,sha256=sgCezmhchWq4KIhpkiYl40lgFwg0rkPEg4aip9wgPqw,5286
212
+ annofabcli-1.104.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
213
+ annofabcli-1.104.1.dist-info/entry_points.txt,sha256=C2uSUc-kkLJpoK_mDL5FEMAdorLEMPfwSf8VBMYnIFM,56
214
+ annofabcli-1.104.1.dist-info/licenses/LICENSE,sha256=pcqWYfxFtxBzhvKp3x9MXNM4xciGb2eFewaRhXUNHlo,1081
215
+ annofabcli-1.104.1.dist-info/RECORD,,