annofabcli 1.110.0__py3-none-any.whl → 1.111.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.
@@ -254,8 +254,8 @@ class AnnotationConverter:
254
254
  for attribute_name, attribute_value in attributes.items():
255
255
  try:
256
256
  specs_additional_data = self.annotation_specs_accessor.get_attribute(attribute_name=attribute_name, label=label)
257
- except ValueError:
258
- logger.warning(f"アノテーション仕様に属性名(英語)が'{attribute_name}'である属性情報が存在しないか、複数存在します。 :: {log_message_suffix}")
257
+ except ValueError as e:
258
+ logger.warning(f"アノテーション仕様に属性名(英語)が'{attribute_name}'である属性情報が存在しないか、複数存在します。 :: {log_message_suffix} :: error={e}")
259
259
  if self.is_strict:
260
260
  raise
261
261
  continue
@@ -298,12 +298,11 @@ class AnnotationConverter:
298
298
  ValueError: 存在しないラベル名が指定された場合(`self.is_strict`がFalseでもraiseされる9
299
299
 
300
300
  """
301
- log_message_suffix = f"task_id='{parser.task_id}', input_data_id='{parser.input_data_id}', label_name='{detail.label}', annotation_id='{detail.annotation_id}'"
302
301
 
303
302
  try:
304
303
  label_info = self.annotation_specs_accessor.get_label(label_name=detail.label)
305
- except ValueError:
306
- logger.warning(f"アノテーション仕様にラベル名(英語)が'{detail.label}'であるラベル情報が存在しないか、または複数存在します。 :: {log_message_suffix}")
304
+ except ValueError as e:
305
+ logger.warning(f"アノテーション仕様にラベル名(英語)が'{detail.label}'であるラベル情報が存在しないか、または複数存在します。 :: {log_message_suffix} :: error={e}")
307
306
  raise
308
307
 
309
308
  if detail.attributes is not None:
@@ -361,9 +360,12 @@ class AnnotationConverter:
361
360
  old_dict_detail[old_detail["annotation_id"]] = old_detail
362
361
 
363
362
  new_request_details: list[dict[str, Any]] = []
364
- for detail in details:
363
+ for detail_index, detail in enumerate(details):
365
364
  try:
366
- log_message_suffix = f"task_id='{parser.task_id}', input_data_id='{parser.input_data_id}', label_name='{detail.label}', annotation_id='{detail.annotation_id}'"
365
+ # detail_indexを出力する理由: annotation_idはNoneだとどれが問題なのか分からないため
366
+ log_message_suffix = (
367
+ f"task_id='{parser.task_id}', input_data_id='{parser.input_data_id}', label_name='{detail.label}', annotation_id='{detail.annotation_id}', detail_index={detail_index}"
368
+ )
367
369
 
368
370
  request_detail = self.convert_annotation_detail(parser, detail, log_message_suffix=log_message_suffix)
369
371
  except Exception as e:
@@ -0,0 +1,317 @@
1
+ import argparse
2
+ import logging
3
+ import sys
4
+ import tempfile
5
+ from collections.abc import Collection
6
+ from dataclasses import dataclass
7
+ from pathlib import Path
8
+ from typing import Any, Optional
9
+
10
+ import pandas
11
+ from annofabapi.models import InputDataType, ProjectMemberRole
12
+ from dataclasses_json import DataClassJsonMixin
13
+
14
+ import annofabcli
15
+ import annofabcli.common.cli
16
+ from annofabcli.common.annofab.annotation_zip import lazy_parse_simple_annotation_by_input_data
17
+ from annofabcli.common.cli import COMMAND_LINE_ERROR_STATUS_CODE, ArgumentParser, CommandLine, build_annofabapi_resource_and_login, get_list_from_args
18
+ from annofabcli.common.download import DownloadingFile
19
+ from annofabcli.common.enums import FormatArgument
20
+ from annofabcli.common.facade import (
21
+ AnnofabApiFacade,
22
+ TaskQuery,
23
+ match_annotation_with_task_query,
24
+ )
25
+ from annofabcli.common.utils import print_csv, print_json
26
+
27
+ logger = logging.getLogger(__name__)
28
+
29
+
30
+ @dataclass(frozen=True)
31
+ class AnnotationSinglePointInfo(DataClassJsonMixin):
32
+ project_id: str
33
+ task_id: str
34
+ task_status: str
35
+ task_phase: str
36
+ task_phase_stage: int
37
+
38
+ input_data_id: str
39
+ input_data_name: str
40
+
41
+ updated_datetime: Optional[str]
42
+ """アノテーションJSONに格納されているアノテーションの更新日時"""
43
+
44
+ label: str
45
+ annotation_id: str
46
+ point: dict[str, int]
47
+
48
+
49
+ def get_annotation_single_point_info_list(simple_annotation: dict[str, Any], *, target_label_names: Optional[Collection[str]] = None) -> list[AnnotationSinglePointInfo]:
50
+ result = []
51
+ target_label_names_set = set(target_label_names) if target_label_names is not None else None
52
+ for detail in simple_annotation["details"]:
53
+ if detail["data"]["_type"] == "SinglePoint":
54
+ label = detail["label"]
55
+ # ラベル名によるフィルタリング
56
+ if target_label_names_set is not None and label not in target_label_names_set:
57
+ continue
58
+
59
+ point = detail["data"]["point"]
60
+
61
+ result.append(
62
+ AnnotationSinglePointInfo(
63
+ project_id=simple_annotation["project_id"],
64
+ task_id=simple_annotation["task_id"],
65
+ task_phase=simple_annotation["task_phase"],
66
+ task_phase_stage=simple_annotation["task_phase_stage"],
67
+ task_status=simple_annotation["task_status"],
68
+ input_data_id=simple_annotation["input_data_id"],
69
+ input_data_name=simple_annotation["input_data_name"],
70
+ label=label,
71
+ annotation_id=detail["annotation_id"],
72
+ point=point,
73
+ updated_datetime=simple_annotation["updated_datetime"],
74
+ )
75
+ )
76
+
77
+ return result
78
+
79
+
80
+ def get_annotation_single_point_info_list_from_annotation_path(
81
+ annotation_path: Path,
82
+ *,
83
+ target_task_ids: Optional[Collection[str]] = None,
84
+ task_query: Optional[TaskQuery] = None,
85
+ target_label_names: Optional[Collection[str]] = None,
86
+ ) -> list[AnnotationSinglePointInfo]:
87
+ annotation_point_list = []
88
+ target_task_ids = set(target_task_ids) if target_task_ids is not None else None
89
+ iter_parser = lazy_parse_simple_annotation_by_input_data(annotation_path)
90
+ logger.info(f"アノテーションZIPまたはディレクトリ'{annotation_path}'を読み込みます。")
91
+ for index, parser in enumerate(iter_parser):
92
+ if (index + 1) % 10000 == 0:
93
+ logger.info(f"{index + 1} 件目のJSONを読み込み中")
94
+ if target_task_ids is not None and parser.task_id not in target_task_ids:
95
+ continue
96
+ dict_simple_annotation = parser.load_json()
97
+ if task_query is not None and not match_annotation_with_task_query(dict_simple_annotation, task_query):
98
+ continue
99
+ sub_annotation_point_list = get_annotation_single_point_info_list(dict_simple_annotation, target_label_names=target_label_names)
100
+ annotation_point_list.extend(sub_annotation_point_list)
101
+ return annotation_point_list
102
+
103
+
104
+ def create_df(
105
+ annotation_point_list: list[AnnotationSinglePointInfo],
106
+ ) -> pandas.DataFrame:
107
+ columns = [
108
+ "project_id",
109
+ "task_id",
110
+ "task_status",
111
+ "task_phase",
112
+ "task_phase_stage",
113
+ "input_data_id",
114
+ "input_data_name",
115
+ "updated_datetime",
116
+ "label",
117
+ "annotation_id",
118
+ "point.x",
119
+ "point.y",
120
+ ]
121
+ df = pandas.DataFrame(
122
+ [
123
+ {
124
+ "project_id": e.project_id,
125
+ "task_id": e.task_id,
126
+ "task_status": e.task_status,
127
+ "task_phase": e.task_phase,
128
+ "task_phase_stage": e.task_phase_stage,
129
+ "input_data_id": e.input_data_id,
130
+ "input_data_name": e.input_data_name,
131
+ "updated_datetime": e.updated_datetime,
132
+ "label": e.label,
133
+ "annotation_id": e.annotation_id,
134
+ "point.x": e.point["x"],
135
+ "point.y": e.point["y"],
136
+ }
137
+ for e in annotation_point_list
138
+ ],
139
+ columns=columns,
140
+ )
141
+
142
+ return df[columns]
143
+
144
+
145
+ def print_annotation_single_point(
146
+ annotation_path: Path,
147
+ output_file: Path,
148
+ output_format: FormatArgument,
149
+ *,
150
+ target_task_ids: Optional[Collection[str]] = None,
151
+ task_query: Optional[TaskQuery] = None,
152
+ target_label_names: Optional[Collection[str]] = None,
153
+ ) -> None:
154
+ annotation_point_list = get_annotation_single_point_info_list_from_annotation_path(
155
+ annotation_path,
156
+ target_task_ids=target_task_ids,
157
+ task_query=task_query,
158
+ target_label_names=target_label_names,
159
+ )
160
+
161
+ logger.info(f"{len(annotation_point_list)} 件の点アノテーションの情報を出力します。 :: output='{output_file}'")
162
+
163
+ if output_format == FormatArgument.CSV:
164
+ df = create_df(annotation_point_list)
165
+ print_csv(df, output_file)
166
+
167
+ elif output_format in [FormatArgument.PRETTY_JSON, FormatArgument.JSON]:
168
+ json_is_pretty = output_format == FormatArgument.PRETTY_JSON
169
+ # DataClassJsonMixinを使用したtoJSON処理
170
+ print_json(
171
+ [e.to_dict(encode_json=True) for e in annotation_point_list],
172
+ is_pretty=json_is_pretty,
173
+ output=output_file,
174
+ )
175
+
176
+ else:
177
+ raise ValueError(f"出力形式 '{output_format}' はサポートされていません。")
178
+
179
+
180
+ class ListAnnotationSinglePoint(CommandLine):
181
+ COMMON_MESSAGE = "annofabcli annotation_zip list_single_point_annotation: error:"
182
+
183
+ def validate(self, args: argparse.Namespace) -> bool:
184
+ if args.project_id is None and args.annotation is None:
185
+ print( # noqa: T201
186
+ f"{self.COMMON_MESSAGE} argument --project_id: '--annotation'が未指定のときは、'--project_id' を指定してください。",
187
+ file=sys.stderr,
188
+ )
189
+ return False
190
+ return True
191
+
192
+ def main(self) -> None:
193
+ args = self.args
194
+
195
+ if not self.validate(args):
196
+ sys.exit(COMMAND_LINE_ERROR_STATUS_CODE)
197
+
198
+ project_id: Optional[str] = args.project_id
199
+ if project_id is not None:
200
+ super().validate_project(project_id, project_member_roles=[ProjectMemberRole.OWNER, ProjectMemberRole.TRAINING_DATA_USER])
201
+ project, _ = self.service.api.get_project(project_id)
202
+ if project["input_data_type"] != InputDataType.IMAGE.value:
203
+ print(f"project_id='{project_id}'であるプロジェクトは画像プロジェクトでないので、終了します", file=sys.stderr) # noqa: T201
204
+ sys.exit(COMMAND_LINE_ERROR_STATUS_CODE)
205
+
206
+ annotation_path = Path(args.annotation) if args.annotation is not None else None
207
+
208
+ task_id_list = get_list_from_args(args.task_id) if args.task_id is not None else None
209
+ task_query = TaskQuery.from_dict(annofabcli.common.cli.get_json_from_args(args.task_query)) if args.task_query is not None else None
210
+ label_name_list = get_list_from_args(args.label_name) if args.label_name is not None else None
211
+
212
+ output_file: Path = args.output
213
+ output_format = FormatArgument(args.format)
214
+
215
+ downloading_obj = DownloadingFile(self.service)
216
+
217
+ def download_and_print_annotation_point(project_id: str, temp_dir: Path, *, is_latest: bool) -> None:
218
+ local_annotation_path = temp_dir / f"{project_id}__annotation.zip"
219
+ downloading_obj.download_annotation_zip(
220
+ project_id,
221
+ dest_path=local_annotation_path,
222
+ is_latest=is_latest,
223
+ )
224
+ print_annotation_single_point(
225
+ local_annotation_path,
226
+ output_file,
227
+ output_format,
228
+ target_task_ids=task_id_list,
229
+ task_query=task_query,
230
+ target_label_names=label_name_list,
231
+ )
232
+
233
+ if project_id is not None:
234
+ if args.temp_dir is not None:
235
+ download_and_print_annotation_point(project_id=project_id, temp_dir=args.temp_dir, is_latest=args.latest)
236
+ else:
237
+ with tempfile.TemporaryDirectory() as str_temp_dir:
238
+ download_and_print_annotation_point(
239
+ project_id=project_id,
240
+ temp_dir=Path(str_temp_dir),
241
+ is_latest=args.latest,
242
+ )
243
+ else:
244
+ assert annotation_path is not None
245
+ print_annotation_single_point(
246
+ annotation_path,
247
+ output_file,
248
+ output_format,
249
+ target_task_ids=task_id_list,
250
+ task_query=task_query,
251
+ target_label_names=label_name_list,
252
+ )
253
+
254
+
255
+ def parse_args(parser: argparse.ArgumentParser) -> None:
256
+ argument_parser = ArgumentParser(parser)
257
+
258
+ group = parser.add_mutually_exclusive_group(required=True)
259
+ group.add_argument(
260
+ "--annotation",
261
+ type=str,
262
+ help="アノテーションzip、またはzipを展開したディレクトリを指定します。",
263
+ )
264
+
265
+ group.add_argument("-p", "--project_id", type=str, help="project_id。アノテーションZIPをダウンロードします。")
266
+
267
+ argument_parser.add_format(
268
+ choices=[FormatArgument.CSV, FormatArgument.JSON, FormatArgument.PRETTY_JSON],
269
+ default=FormatArgument.CSV,
270
+ )
271
+
272
+ argument_parser.add_output()
273
+
274
+ parser.add_argument(
275
+ "-tq",
276
+ "--task_query",
277
+ type=str,
278
+ help="集計対象タスクを絞り込むためのクエリ条件をJSON形式で指定します。使用できるキーは task_id, status, phase, phase_stage です。"
279
+ " ``file://`` を先頭に付けると、JSON形式のファイルを指定できます。",
280
+ )
281
+ argument_parser.add_task_id(required=False)
282
+
283
+ parser.add_argument(
284
+ "--label_name",
285
+ type=str,
286
+ nargs="*",
287
+ help="指定したラベル名の点アノテーションのみを対象にします。複数指定できます。",
288
+ )
289
+
290
+ parser.add_argument(
291
+ "--latest",
292
+ action="store_true",
293
+ help="``--annotation`` を指定しないとき、最新のアノテーションzipを参照します。このオプションを指定すると、アノテーションzipを更新するのに数分待ちます。",
294
+ )
295
+
296
+ parser.add_argument(
297
+ "--temp_dir",
298
+ type=Path,
299
+ help="指定したディレクトリに、アノテーションZIPなどの一時ファイルをダウンロードします。",
300
+ )
301
+
302
+ parser.set_defaults(subcommand_func=main)
303
+
304
+
305
+ def main(args: argparse.Namespace) -> None:
306
+ service = build_annofabapi_resource_and_login(args)
307
+ facade = AnnofabApiFacade(service)
308
+ ListAnnotationSinglePoint(service, facade, args).main()
309
+
310
+
311
+ def add_parser(subparsers: Optional[argparse._SubParsersAction] = None) -> argparse.ArgumentParser:
312
+ subcommand_name = "list_single_point_annotation"
313
+ subcommand_help = "アノテーションZIPから点アノテーションの座標情報を出力します。"
314
+ epilog = "アノテーションZIPをダウンロードする場合は、オーナロールまたはアノテーションユーザロールを持つユーザで実行してください。"
315
+ parser = annofabcli.common.cli.add_parser(subparsers, subcommand_name, subcommand_help, description=subcommand_help, epilog=epilog)
316
+ parse_args(parser)
317
+ return parser
@@ -6,6 +6,7 @@ from typing import Optional
6
6
  import annofabcli
7
7
  from annofabcli.annotation_zip.list_annotation_bounding_box_2d import add_parser as add_parser_list_annotation_bounding_box_2d
8
8
  from annofabcli.annotation_zip.list_range_annotation import add_parser as add_parser_list_range_annotation
9
+ from annofabcli.annotation_zip.list_single_point_annotation import add_parser as add_parser_list_single_point_annotation
9
10
 
10
11
 
11
12
  def parse_args(parser: argparse.ArgumentParser) -> None:
@@ -19,6 +20,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
19
20
  # サブコマンドの定義
20
21
  add_parser_list_annotation_bounding_box_2d(subparsers)
21
22
  add_parser_list_range_annotation(subparsers)
23
+ add_parser_list_single_point_annotation(subparsers)
22
24
  # 作成中のためコメントアウト
23
25
  # add_parser_validate_annotation(subparsers)
24
26
 
@@ -141,7 +141,7 @@ class WholeProductivityPerCompletedDate:
141
141
  return pandas.DataFrame(index=[e.strftime("%Y-%m-%d") for e in pandas.date_range(start_date, end_date)])
142
142
 
143
143
  @classmethod
144
- def from_df_wrapper(cls, task: Task, worktime_per_date: WorktimePerDate, task_completion_criteria: TaskCompletionCriteria) -> WholeProductivityPerCompletedDate:
144
+ def from_df_wrapper(cls, task: Task, worktime_per_date: WorktimePerDate, task_completion_criteria: TaskCompletionCriteria) -> WholeProductivityPerCompletedDate: # noqa: PLR0912
145
145
  """
146
146
  完了日毎の全体の生産量、生産性を算出する。
147
147
 
@@ -172,6 +172,8 @@ class WholeProductivityPerCompletedDate:
172
172
  datetime_column = "first_acceptance_reached_datetime"
173
173
  elif task_completion_criteria == TaskCompletionCriteria.INSPECTION_REACHED:
174
174
  datetime_column = "first_inspection_reached_datetime"
175
+ elif task_completion_criteria == TaskCompletionCriteria.ANNOTATION_STARTED:
176
+ datetime_column = "first_annotation_started_datetime"
175
177
  else:
176
178
  assert_noreturn(task_completion_criteria)
177
179
 
@@ -280,6 +282,8 @@ class WholeProductivityPerCompletedDate:
280
282
  str_task = "受入フェーズに到達した"
281
283
  elif self.task_completion_criteria == TaskCompletionCriteria.INSPECTION_REACHED:
282
284
  str_task = "検査フェーズに到達した"
285
+ elif self.task_completion_criteria == TaskCompletionCriteria.ANNOTATION_STARTED:
286
+ str_task = "教師付フェーズが着手された"
283
287
  else:
284
288
  assert_noreturn(self.task_completion_criteria)
285
289
 
@@ -884,6 +888,9 @@ class WholeProductivityPerFirstAnnotationStartedDate:
884
888
  df_sub_task = df_task[df_task["phase"] == TaskPhase.ACCEPTANCE.value]
885
889
  elif task_completion_criteria == TaskCompletionCriteria.INSPECTION_REACHED:
886
890
  df_sub_task = df_task[df_task["phase"].isin([TaskPhase.INSPECTION.value, TaskPhase.ACCEPTANCE.value])]
891
+ elif task_completion_criteria == TaskCompletionCriteria.ANNOTATION_STARTED:
892
+ # 教師付フェーズが着手されたタスク(first_annotation_started_datetimeがNoneでない)を抽出する
893
+ df_sub_task = df_task[df_task["first_annotation_started_datetime"].notna()]
887
894
  else:
888
895
  assert_noreturn(task_completion_criteria)
889
896
 
@@ -1013,6 +1020,8 @@ class WholeProductivityPerFirstAnnotationStartedDate:
1013
1020
  str_task = "受入フェーズ"
1014
1021
  elif self.task_completion_criteria == TaskCompletionCriteria.INSPECTION_REACHED:
1015
1022
  str_task = "検査フェーズまたは受入フェーズ"
1023
+ elif self.task_completion_criteria == TaskCompletionCriteria.ANNOTATION_STARTED:
1024
+ str_task = "教師付フェーズが着手されたタスク"
1016
1025
  else:
1017
1026
  assert_noreturn(self.task_completion_criteria)
1018
1027
 
@@ -40,6 +40,8 @@ class TaskCompletionCriteria(Enum):
40
40
  """タスクが受入フェーズに到達したら「タスクの完了」とみなす"""
41
41
  INSPECTION_REACHED = "inspection_reached"
42
42
  """タスクが検査フェーズに到達したら「タスクの完了」とみなす"""
43
+ ANNOTATION_STARTED = "annotation_started"
44
+ """教師付フェーズが着手されたら「タスクの完了」とみなす"""
43
45
 
44
46
  def is_task_completed(self, task: dict[str, Any]) -> bool:
45
47
  """指定したタスクが、タスクの完了条件に合致するかどうかを判定します。
@@ -48,6 +50,7 @@ class TaskCompletionCriteria(Enum):
48
50
  task: タスク情報。以下のキーを参照します。
49
51
  * phase
50
52
  * status
53
+ * work_time_span (ANNOTATION_STARTEDの場合のみ)
51
54
 
52
55
  Returns:
53
56
  タスクの完了条件に合致する場合はTrue、そうでない場合はFalse
@@ -62,5 +65,10 @@ class TaskCompletionCriteria(Enum):
62
65
  # 受入フェーズも含む理由:検査フェーズに到達したタスクを「完了」とみなすならば、検査フェーズより後段フェーズである受入フェーズも「完了」とみなせるため
63
66
  return task["phase"] in {TaskPhase.INSPECTION.value, TaskPhase.ACCEPTANCE.value}
64
67
 
68
+ elif self == TaskCompletionCriteria.ANNOTATION_STARTED:
69
+ # 教師付フェーズが着手されたタスクを「完了」とみなす
70
+ # work_time_span > 0 であれば教師付フェーズが着手されたとみなす
71
+ return task["work_time_span"] > 0
72
+
65
73
  else:
66
74
  assert_noreturn(self)
@@ -42,7 +42,7 @@ class ProjectDir(DataClassJsonMixin):
42
42
  - acceptance_completed: 受入フェーズの完了状態
43
43
  - acceptance_reached: 受入フェーズに到達
44
44
  - inspection_reached: 検査フェーズまたは受入フェーズに到達
45
- - annotation_started: 教師付フェーズを着手
45
+ - annotation_started: 教師付フェーズが着手された
46
46
  """
47
47
 
48
48
  FILENAME_WHOLE_PERFORMANCE = "全体の生産性と品質.csv"
@@ -710,7 +710,9 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
710
710
  default=TaskCompletionCriteria.ACCEPTANCE_COMPLETED.value,
711
711
  help="タスクの完了条件を指定します。\n"
712
712
  "* ``acceptance_completed``: タスクが受入フェーズの完了状態であれば「タスクの完了」とみなす\n"
713
- "* ``acceptance_reached``: タスクが受入フェーズに到達したら「タスクの完了」とみなす\n",
713
+ "* ``acceptance_reached``: タスクが受入フェーズに到達したら「タスクの完了」とみなす\n"
714
+ "* ``inspection_reached``: タスクが検査フェーズに到達したら「タスクの完了」とみなす\n"
715
+ "* ``annotation_started``: 教師付フェーズが着手されたら「タスクの完了」とみなす\n",
714
716
  )
715
717
 
716
718
  parser.add_argument(
@@ -286,7 +286,7 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
286
286
  "--api",
287
287
  type=str,
288
288
  choices=[e.value for e in ApiWithCreatingTask],
289
- help="タスク作成に使うWebAPIを指定できます。 ``--csv`` or ``--json`` を指定したときのみ有効なオプションです。\n未指定の場合は、作成するタスク数に応じて、適切なWebAPIを選択します。\n",
289
+ help="タスク作成に使うWebAPIを指定できます。未指定の場合は、作成するタスク数に応じて適切なWebAPIを選択します。",
290
290
  )
291
291
 
292
292
  parser.add_argument(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: annofabcli
3
- Version: 1.110.0
3
+ Version: 1.111.1
4
4
  Summary: Utility Command Line Interface for AnnoFab
5
5
  Author: Kurusugawa Computer Inc.
6
6
  License: MIT
@@ -11,7 +11,7 @@ annofabcli/annotation/create_classification_annotation.py,sha256=Ex9kSVNHZu71UbL
11
11
  annofabcli/annotation/delete_annotation.py,sha256=bU87ov7NhYFPe-Cldn3nBSK_CY9A9x3mSLN1Ame-cKk,25144
12
12
  annofabcli/annotation/download_annotation_zip.py,sha256=SMtfxt6NKkpHGRDoKRCjPqpQB5DBpQ-PD2_3ts51h0Q,3314
13
13
  annofabcli/annotation/dump_annotation.py,sha256=Q-p6f5XBs7khDgrfY5Q3CGLBMKEerJWO_CQ8_73UXVM,9972
14
- annofabcli/annotation/import_annotation.py,sha256=maaxlje3VZ7oN94gdtZFgfZnAQlBfYmljgGJzMcI9HE,35811
14
+ annofabcli/annotation/import_annotation.py,sha256=M0osVbY06Xs2DXkQLwCKx7WmK9cPc9EFuvHbAKMKv-0,35898
15
15
  annofabcli/annotation/list_annotation.py,sha256=uKcOuGC7lzd6vVbzizkiZtYdXJ7EzY0iifuiqKl2wQM,10707
16
16
  annofabcli/annotation/list_annotation_count.py,sha256=T9fbaoxWeDJIVgW_YgHRldbwrVZWiE-57lfJrDQrj80,6474
17
17
  annofabcli/annotation/merge_segmentation.py,sha256=kIsCeXtJxzd6nobQPpi0fscaRDlTx3tg1qpy5PDfSJI,18107
@@ -37,7 +37,8 @@ annofabcli/annotation_specs/subcommand_annotation_specs.py,sha256=yqSjV1S3CSB0sF
37
37
  annofabcli/annotation_zip/__init__.py,sha256=wAeKgkUYvgzdGFS3iJ3h0WogWbg9i-0c4xSg-mzbBpY,64
38
38
  annofabcli/annotation_zip/list_annotation_bounding_box_2d.py,sha256=306qSxOXzXSU1AaaveWSToyBCCt3hGbTuWqBaS5wn44,13363
39
39
  annofabcli/annotation_zip/list_range_annotation.py,sha256=70U3vvb-M5jxQlUlbqX-DSenp8oxXja3tj1gzq-7_DU,12282
40
- annofabcli/annotation_zip/subcommand_annotation_zip.py,sha256=SBpdjNhp4s-u4DBjpl5_OR91GbW5hUAi3kt5dhNbyA4,1397
40
+ annofabcli/annotation_zip/list_single_point_annotation.py,sha256=qW5i4pozl9wx2BPue9rbQX8zvdyTVRfaeQzjhOf-OUU,12575
41
+ annofabcli/annotation_zip/subcommand_annotation_zip.py,sha256=xU8WGXRhSh3gjOpOMD2qLMeN3rtPnE7glSsKBLIBXjE,1574
41
42
  annofabcli/annotation_zip/validate_annotation.py,sha256=Kf1p312CINbZZTbniVAphQrcrMmr5WGQZja30kc7ewc,16645
42
43
  annofabcli/comment/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
44
  annofabcli/comment/delete_comment.py,sha256=HZG1BOEKEbi3ISqM-2KZS5iq6aI16jDFBRLFpT-30e4,11385
@@ -161,12 +162,12 @@ annofabcli/statistics/summarize_task_count_by_task_id_group.py,sha256=K4FFED1pza
161
162
  annofabcli/statistics/summarize_task_count_by_user.py,sha256=KUGVUwn_KO4RSA2twAz60nX1OQE1pd5TL5gBmL1bgMA,7421
162
163
  annofabcli/statistics/visualize_annotation_count.py,sha256=7OATuGa2okq80unuTe-X30CBVkrlMLDN5Y-Q_5mB6eI,22138
163
164
  annofabcli/statistics/visualize_annotation_duration.py,sha256=9JH9MirhOyCmjcChFJMtfnFIV2k4sucP9PAwNKMcbtE,21022
164
- annofabcli/statistics/visualize_statistics.py,sha256=iwGhrYylBTsK-DT_MU-eYkFgZI0ITt9r59BbiaSbfQE,44041
165
+ annofabcli/statistics/visualize_statistics.py,sha256=njhjbHBhhQ5ksJmOWrcLYh2pLHZdn0uAk8dCufjtfAI,44281
165
166
  annofabcli/statistics/visualize_video_duration.py,sha256=yY18H0-boNy4-MQWUM_xBTMzxDUQ51TrVtz8mbsB_dI,16623
166
167
  annofabcli/statistics/visualization/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
167
168
  annofabcli/statistics/visualization/filtering_query.py,sha256=kqGOa1YdQ62kTLlkiIHFiYNju4Pg9rXpsC4Cph-QjLo,4355
168
- annofabcli/statistics/visualization/model.py,sha256=sKk4gC7qkt6etCnbpCNZpJEhFJf5Vf7eVOG53gyfWvk,2426
169
- annofabcli/statistics/visualization/project_dir.py,sha256=-60n29ySvgsfRTbFgTOYr6E7LHJezVQm3FON88LQMKU,24291
169
+ annofabcli/statistics/visualization/model.py,sha256=LXFuelx9_6n1mU418Mw5FOCBQTlnNBlOijZ7oUIfQ_Q,2928
170
+ annofabcli/statistics/visualization/project_dir.py,sha256=g1Jb9-CW32BcuwS3Z2dTgJ9bo3_Edlc7wWtrKhLzFcc,24300
170
171
  annofabcli/statistics/visualization/visualization_source_files.py,sha256=SFY7WXUtjECB8l7zP-exawocrTiZ0UI7Z5sjgq4J_g4,8641
171
172
  annofabcli/statistics/visualization/dataframe/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
172
173
  annofabcli/statistics/visualization/dataframe/actual_worktime.py,sha256=7nsHlvN5cDzXIw-u_MSAZf4nlSSY56IlunSmnODXTbY,1916
@@ -184,7 +185,7 @@ annofabcli/statistics/visualization/dataframe/task_worktime_by_phase_user.py,sha
184
185
  annofabcli/statistics/visualization/dataframe/user.py,sha256=EHn7nlf6D6UX-gsVXy8m_3QaCsHsUhr0iy2rbNozOgc,1707
185
186
  annofabcli/statistics/visualization/dataframe/user_performance.py,sha256=X0jXV0wY8AZC8hoV62sJd9GRThqTf5RsaVciLeCvGlk,56628
186
187
  annofabcli/statistics/visualization/dataframe/whole_performance.py,sha256=kw5Cww0fwDfwriTtxiT0l3wr7YAMA9eGjvp84G9MN9I,12449
187
- annofabcli/statistics/visualization/dataframe/whole_productivity_per_date.py,sha256=F6KhXvzrUx61E0jqOiU2IGb6ycLH82T80JyzYVpSaC8,53683
188
+ annofabcli/statistics/visualization/dataframe/whole_productivity_per_date.py,sha256=J-QW2Mvt-hGTpDUGGJKFvo0REzIWwrbDAzcMf9iqx_U,54480
188
189
  annofabcli/statistics/visualization/dataframe/worktime_per_date.py,sha256=wt0paPy2cVVzLUJhbV12-6bInikbQoxRFnOHY7BcI9o,21342
189
190
  annofabcli/supplementary/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
190
191
  annofabcli/supplementary/delete_supplementary_data.py,sha256=dA4n61SSkTbDKDqjVldHIEAxbPQXyrQciwI4RDuC35U,13537
@@ -205,7 +206,7 @@ annofabcli/task/list_all_tasks.py,sha256=FpFzosCZs2EZNSQMHzWse4z_zjZeiVF5BFmbwb9
205
206
  annofabcli/task/list_all_tasks_added_task_history.py,sha256=fkdiuo64iS7xxvIfGKzSiUPPEMiCVnJjjcAtMxe2Ngs,9551
206
207
  annofabcli/task/list_tasks.py,sha256=cmfqbP2Sr1dlpvpJLJscKq31BUdXVaajr_agiecKWXg,10051
207
208
  annofabcli/task/list_tasks_added_task_history.py,sha256=JI3Rxn9MwXN07Cu2wDfaIXAzm3MlNm1kIh1SZHbxZr4,22488
208
- annofabcli/task/put_tasks.py,sha256=HADm-sP8zs523MlDThlwrGIVIEtR4Md2KlpJbWhCCTk,13745
209
+ annofabcli/task/put_tasks.py,sha256=tqgGtaYkAwTznLhcvl9eZNS2U6eqsoqSbL67jBqyfJk,13653
209
210
  annofabcli/task/put_tasks_by_count.py,sha256=kIjvWtgZ53Smcm8N-raZedQCubx1TWoQT-BYyioYDrA,5999
210
211
  annofabcli/task/reject_tasks.py,sha256=2mRxIsP63N2xcVXQ0xeFqF0VkuUQP6C_bsFEqG-qNf0,22027
211
212
  annofabcli/task/subcommand_task.py,sha256=L_5Dwe58eblrtOrUYxjJAvkSmu6savRUxIqGjsFq-R4,2436
@@ -220,8 +221,8 @@ annofabcli/task_history_event/download_task_history_event_json.py,sha256=hQLVbQ0
220
221
  annofabcli/task_history_event/list_all_task_history_event.py,sha256=EeKMyPUxGwYCFtWQHHW954ZserGm8lUqrwNnV1iX9X4,6830
221
222
  annofabcli/task_history_event/list_worktime.py,sha256=Y7Pu5DP7scPf7HPt6CTiTvB1_5_Nfi1bStUIaCpkhII,15507
222
223
  annofabcli/task_history_event/subcommand_task_history_event.py,sha256=mJVJoT4RXk4HWnY7-Nrsl4If-gtaIIEXd2z7eFZwM2I,1260
223
- annofabcli-1.110.0.dist-info/METADATA,sha256=IkiHLkw9nFBKWbtVvoy_aedwGZ7Xl0d-gFTF4xDNnSE,5134
224
- annofabcli-1.110.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
225
- annofabcli-1.110.0.dist-info/entry_points.txt,sha256=C2uSUc-kkLJpoK_mDL5FEMAdorLEMPfwSf8VBMYnIFM,56
226
- annofabcli-1.110.0.dist-info/licenses/LICENSE,sha256=pcqWYfxFtxBzhvKp3x9MXNM4xciGb2eFewaRhXUNHlo,1081
227
- annofabcli-1.110.0.dist-info/RECORD,,
224
+ annofabcli-1.111.1.dist-info/METADATA,sha256=_p6y1IWSFtptJzWmxklxObVfFZSZEEYeai7Xrl5fC-A,5134
225
+ annofabcli-1.111.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
226
+ annofabcli-1.111.1.dist-info/entry_points.txt,sha256=C2uSUc-kkLJpoK_mDL5FEMAdorLEMPfwSf8VBMYnIFM,56
227
+ annofabcli-1.111.1.dist-info/licenses/LICENSE,sha256=pcqWYfxFtxBzhvKp3x9MXNM4xciGb2eFewaRhXUNHlo,1081
228
+ annofabcli-1.111.1.dist-info/RECORD,,