annofabcli 1.111.1__py3-none-any.whl → 1.112.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.
- annofabcli/__main__.py +1 -2
- annofabcli/annotation/annotation_query.py +10 -10
- annofabcli/annotation/change_annotation_attributes.py +9 -9
- annofabcli/annotation/change_annotation_attributes_per_annotation.py +3 -4
- annofabcli/annotation/change_annotation_properties.py +13 -13
- annofabcli/annotation/copy_annotation.py +5 -5
- annofabcli/annotation/create_classification_annotation.py +6 -6
- annofabcli/annotation/delete_annotation.py +8 -8
- annofabcli/annotation/download_annotation_zip.py +1 -3
- annofabcli/annotation/dump_annotation.py +7 -7
- annofabcli/annotation/import_annotation.py +12 -12
- annofabcli/annotation/list_annotation.py +8 -8
- annofabcli/annotation/list_annotation_count.py +1 -2
- annofabcli/annotation/merge_segmentation.py +5 -5
- annofabcli/annotation/remove_segmentation_overlap.py +4 -4
- annofabcli/annotation/restore_annotation.py +6 -6
- annofabcli/annotation/subcommand_annotation.py +1 -2
- annofabcli/annotation_specs/add_attribute_restriction.py +4 -5
- annofabcli/annotation_specs/attribute_restriction.py +8 -8
- annofabcli/annotation_specs/export_annotation_specs.py +4 -5
- annofabcli/annotation_specs/get_annotation_specs_with_attribute_id_replaced.py +3 -4
- annofabcli/annotation_specs/get_annotation_specs_with_choice_id_replaced.py +3 -4
- annofabcli/annotation_specs/get_annotation_specs_with_label_id_replaced.py +3 -4
- annofabcli/annotation_specs/list_annotation_specs_attribute.py +9 -10
- annofabcli/annotation_specs/list_annotation_specs_choice.py +9 -10
- annofabcli/annotation_specs/list_annotation_specs_history.py +2 -2
- annofabcli/annotation_specs/list_annotation_specs_label.py +8 -9
- annofabcli/annotation_specs/list_annotation_specs_label_attribute.py +10 -11
- annofabcli/annotation_specs/list_attribute_restriction.py +2 -4
- annofabcli/annotation_specs/list_label_color.py +2 -3
- annofabcli/annotation_specs/put_label_color.py +3 -4
- annofabcli/annotation_specs/subcommand_annotation_specs.py +1 -3
- annofabcli/annotation_zip/list_annotation_3d_bounding_box.py +365 -0
- annofabcli/annotation_zip/list_annotation_bounding_box_2d.py +11 -12
- annofabcli/annotation_zip/list_range_annotation.py +24 -14
- annofabcli/annotation_zip/list_single_point_annotation.py +11 -12
- annofabcli/annotation_zip/subcommand_annotation_zip.py +3 -2
- annofabcli/annotation_zip/validate_annotation.py +8 -7
- annofabcli/comment/delete_comment.py +4 -6
- annofabcli/comment/download_comment_json.py +4 -6
- annofabcli/comment/list_all_comment.py +5 -6
- annofabcli/comment/list_comment.py +3 -4
- annofabcli/comment/put_comment.py +9 -10
- annofabcli/comment/put_comment_simply.py +5 -6
- annofabcli/comment/put_inspection_comment.py +1 -3
- annofabcli/comment/put_inspection_comment_simply.py +1 -3
- annofabcli/comment/put_onhold_comment.py +1 -3
- annofabcli/comment/put_onhold_comment_simply.py +1 -3
- annofabcli/comment/subcommand_comment.py +1 -3
- annofabcli/common/bokeh.py +4 -4
- annofabcli/common/cli.py +17 -17
- annofabcli/common/download.py +28 -29
- annofabcli/common/facade.py +37 -38
- annofabcli/common/image.py +14 -14
- annofabcli/common/utils.py +8 -8
- annofabcli/common/visualize.py +13 -13
- annofabcli/experimental/list_out_of_range_annotation_for_movie.py +3 -4
- annofabcli/experimental/subcommand_experimental.py +1 -3
- annofabcli/filesystem/draw_annotation.py +26 -26
- annofabcli/filesystem/filter_annotation.py +9 -10
- annofabcli/filesystem/mask_user_info.py +14 -14
- annofabcli/filesystem/merge_annotation.py +8 -8
- annofabcli/filesystem/subcommand_filesystem.py +1 -3
- annofabcli/input_data/copy_input_data.py +8 -9
- annofabcli/input_data/delete_input_data.py +2 -2
- annofabcli/input_data/delete_metadata_key_of_input_data.py +3 -5
- annofabcli/input_data/download_input_data_json.py +4 -6
- annofabcli/input_data/list_all_input_data.py +8 -8
- annofabcli/input_data/list_all_input_data_merged_task.py +4 -4
- annofabcli/input_data/list_input_data.py +4 -4
- annofabcli/input_data/put_input_data.py +5 -5
- annofabcli/input_data/put_input_data_with_zip.py +2 -3
- annofabcli/input_data/subcommand_input_data.py +1 -3
- annofabcli/input_data/update_input_data.py +6 -8
- annofabcli/input_data/update_metadata_of_input_data.py +3 -5
- annofabcli/instruction/copy_instruction.py +4 -5
- annofabcli/instruction/download_instruction.py +4 -5
- annofabcli/instruction/list_instruction_history.py +2 -2
- annofabcli/instruction/subcommand_instruction.py +1 -3
- annofabcli/instruction/upload_instruction.py +2 -3
- annofabcli/job/delete_job.py +1 -2
- annofabcli/job/list_job.py +4 -4
- annofabcli/job/list_last_job.py +3 -3
- annofabcli/job/subcommand_job.py +1 -3
- annofabcli/job/wait_job.py +4 -5
- annofabcli/my_account/get_my_account.py +1 -2
- annofabcli/my_account/subcommand_my_account.py +1 -3
- annofabcli/organization/list_organization.py +1 -2
- annofabcli/organization/subcommand_organization.py +1 -3
- annofabcli/organization_member/change_organization_member.py +3 -4
- annofabcli/organization_member/delete_organization_member.py +3 -4
- annofabcli/organization_member/invite_organization_member.py +1 -3
- annofabcli/organization_member/list_organization_member.py +2 -2
- annofabcli/organization_member/subcommand_organization_member.py +1 -3
- annofabcli/project/change_organization_of_project.py +3 -3
- annofabcli/project/change_project_status.py +3 -3
- annofabcli/project/copy_project.py +4 -4
- annofabcli/project/create_project.py +7 -7
- annofabcli/project/diff_projects.py +4 -5
- annofabcli/project/list_project.py +4 -4
- annofabcli/project/put_project.py +1 -2
- annofabcli/project/subcommand_project.py +1 -2
- annofabcli/project/update_configuration.py +3 -3
- annofabcli/project/update_project.py +6 -8
- annofabcli/project_member/change_project_members.py +7 -7
- annofabcli/project_member/copy_project_members.py +3 -3
- annofabcli/project_member/drop_project_members.py +1 -2
- annofabcli/project_member/invite_project_members.py +1 -3
- annofabcli/project_member/list_users.py +1 -2
- annofabcli/project_member/put_project_members.py +5 -5
- annofabcli/project_member/subcommand_project_member.py +1 -3
- annofabcli/stat_visualization/mask_visualization_dir.py +8 -9
- annofabcli/stat_visualization/merge_visualization_dir.py +6 -7
- annofabcli/stat_visualization/subcommand_stat_visualization.py +1 -2
- annofabcli/stat_visualization/summarize_whole_performance_csv.py +1 -2
- annofabcli/stat_visualization/write_graph.py +2 -3
- annofabcli/stat_visualization/write_performance_rating_csv.py +20 -27
- annofabcli/statistics/histogram.py +5 -6
- annofabcli/statistics/linegraph.py +13 -14
- annofabcli/statistics/list_annotation_area.py +38 -13
- annofabcli/statistics/list_annotation_attribute.py +9 -10
- annofabcli/statistics/list_annotation_attribute_filled_count.py +30 -31
- annofabcli/statistics/list_annotation_count.py +57 -58
- annofabcli/statistics/list_annotation_duration.py +33 -34
- annofabcli/statistics/list_video_duration.py +4 -5
- annofabcli/statistics/list_worktime.py +3 -3
- annofabcli/statistics/scatter.py +9 -8
- annofabcli/statistics/subcommand_statistics.py +1 -4
- annofabcli/statistics/summarize_task_count.py +4 -6
- annofabcli/statistics/summarize_task_count_by_task_id_group.py +2 -4
- annofabcli/statistics/summarize_task_count_by_user.py +1 -3
- annofabcli/statistics/visualization/dataframe/annotation_count.py +5 -4
- annofabcli/statistics/visualization/dataframe/annotation_duration.py +6 -7
- annofabcli/statistics/visualization/dataframe/cumulative_productivity.py +15 -17
- annofabcli/statistics/visualization/dataframe/productivity_per_date.py +17 -19
- annofabcli/statistics/visualization/dataframe/project_performance.py +3 -12
- annofabcli/statistics/visualization/dataframe/task.py +11 -12
- annofabcli/statistics/visualization/dataframe/task_worktime_by_phase_user.py +9 -10
- annofabcli/statistics/visualization/dataframe/user_performance.py +21 -19
- annofabcli/statistics/visualization/dataframe/whole_performance.py +3 -4
- annofabcli/statistics/visualization/dataframe/whole_productivity_per_date.py +12 -14
- annofabcli/statistics/visualization/dataframe/worktime_per_date.py +11 -13
- annofabcli/statistics/visualization/filtering_query.py +7 -7
- annofabcli/statistics/visualization/project_dir.py +27 -14
- annofabcli/statistics/visualization/visualization_source_files.py +49 -0
- annofabcli/statistics/visualize_annotation_count.py +22 -23
- annofabcli/statistics/visualize_annotation_duration.py +21 -22
- annofabcli/statistics/visualize_statistics.py +126 -69
- annofabcli/statistics/visualize_video_duration.py +18 -20
- annofabcli/supplementary/delete_supplementary_data.py +4 -4
- annofabcli/supplementary/list_supplementary_data.py +3 -3
- annofabcli/supplementary/put_supplementary_data.py +8 -8
- annofabcli/supplementary/subcommand_supplementary.py +1 -3
- annofabcli/task/cancel_acceptance.py +16 -17
- annofabcli/task/change_operator.py +10 -12
- annofabcli/task/change_status_to_break.py +7 -9
- annofabcli/task/change_status_to_on_hold.py +10 -12
- annofabcli/task/complete_tasks.py +17 -18
- annofabcli/task/copy_tasks.py +3 -5
- annofabcli/task/delete_metadata_key_of_task.py +4 -6
- annofabcli/task/delete_tasks.py +6 -6
- annofabcli/task/download_task_json.py +4 -6
- annofabcli/task/list_all_tasks.py +7 -7
- annofabcli/task/list_all_tasks_added_task_history.py +12 -12
- annofabcli/task/list_tasks.py +6 -6
- annofabcli/task/list_tasks_added_task_history.py +9 -9
- annofabcli/task/put_tasks.py +4 -5
- annofabcli/task/put_tasks_by_count.py +1 -2
- annofabcli/task/reject_tasks.py +18 -20
- annofabcli/task/subcommand_task.py +1 -3
- annofabcli/task/update_metadata_of_task.py +5 -6
- annofabcli/task_history/download_task_history_json.py +4 -6
- annofabcli/task_history/list_all_task_history.py +5 -6
- annofabcli/task_history/list_task_history.py +3 -4
- annofabcli/task_history/subcommand_task_history.py +1 -3
- annofabcli/task_history_event/download_task_history_event_json.py +4 -6
- annofabcli/task_history_event/list_all_task_history_event.py +6 -6
- annofabcli/task_history_event/list_worktime.py +15 -15
- annofabcli/task_history_event/subcommand_task_history_event.py +1 -2
- {annofabcli-1.111.1.dist-info → annofabcli-1.112.0.dist-info}/METADATA +9 -15
- annofabcli-1.112.0.dist-info/RECORD +229 -0
- {annofabcli-1.111.1.dist-info → annofabcli-1.112.0.dist-info}/WHEEL +1 -1
- annofabcli-1.111.1.dist-info/RECORD +0 -228
- {annofabcli-1.111.1.dist-info → annofabcli-1.112.0.dist-info}/entry_points.txt +0 -0
- {annofabcli-1.111.1.dist-info → annofabcli-1.112.0.dist-info}/licenses/LICENSE +0 -0
annofabcli/common/bokeh.py
CHANGED
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
4
|
import math
|
|
5
|
-
from typing import Any
|
|
5
|
+
from typing import Any
|
|
6
6
|
|
|
7
7
|
from bokeh.models import LayoutDOM
|
|
8
8
|
from bokeh.models.widgets.markups import PreText
|
|
@@ -15,16 +15,16 @@ def create_pretext_from_metadata(metadata: dict[str, Any]) -> PreText:
|
|
|
15
15
|
return PreText(text=text)
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
def convert_1d_figure_list_to_2d(figure_list: list[figure], *, ncols: int = 4) -> list[list[
|
|
18
|
+
def convert_1d_figure_list_to_2d(figure_list: list[figure], *, ncols: int = 4) -> list[list[LayoutDOM | None]]:
|
|
19
19
|
"""
|
|
20
20
|
1次元のfigure_listを、grid layout用に2次元のfigureリストに変換する。
|
|
21
21
|
"""
|
|
22
|
-
row_list: list[list[
|
|
22
|
+
row_list: list[list[LayoutDOM | None]] = []
|
|
23
23
|
|
|
24
24
|
for i in range(math.ceil(len(figure_list) / ncols)):
|
|
25
25
|
start = i * ncols
|
|
26
26
|
end = (i + 1) * ncols
|
|
27
|
-
row: list[
|
|
27
|
+
row: list[LayoutDOM | None] = []
|
|
28
28
|
row.extend(figure_list[start:end])
|
|
29
29
|
if len(row) < ncols:
|
|
30
30
|
row.extend([None] * (ncols - len(row)))
|
annofabcli/common/cli.py
CHANGED
|
@@ -9,7 +9,7 @@ import logging
|
|
|
9
9
|
import os
|
|
10
10
|
import pkgutil
|
|
11
11
|
from pathlib import Path
|
|
12
|
-
from typing import Any
|
|
12
|
+
from typing import Any
|
|
13
13
|
|
|
14
14
|
import annofabapi
|
|
15
15
|
import pandas
|
|
@@ -81,12 +81,12 @@ def build_annofabapi_resource_and_login(args: argparse.Namespace) -> annofabapi.
|
|
|
81
81
|
|
|
82
82
|
|
|
83
83
|
def add_parser(
|
|
84
|
-
subparsers:
|
|
84
|
+
subparsers: argparse._SubParsersAction | None,
|
|
85
85
|
command_name: str,
|
|
86
86
|
command_help: str,
|
|
87
|
-
description:
|
|
87
|
+
description: str | None = None,
|
|
88
88
|
is_subcommand: bool = True, # noqa: FBT001, FBT002
|
|
89
|
-
epilog:
|
|
89
|
+
epilog: str | None = None,
|
|
90
90
|
) -> argparse.ArgumentParser:
|
|
91
91
|
"""
|
|
92
92
|
サブコマンド用にparserを追加する
|
|
@@ -159,7 +159,7 @@ def add_parser(
|
|
|
159
159
|
return parser
|
|
160
160
|
|
|
161
161
|
|
|
162
|
-
def get_list_from_args(str_list:
|
|
162
|
+
def get_list_from_args(str_list: list[str] | None = None) -> list[str]:
|
|
163
163
|
"""
|
|
164
164
|
文字列のListのサイズが1で、プレフィックスが`file://`ならば、ファイルパスとしてファイルを読み込み、行をListとして返す。
|
|
165
165
|
そうでなければ、引数の値をそのまま返す。
|
|
@@ -185,7 +185,7 @@ def get_list_from_args(str_list: Optional[list[str]] = None) -> list[str]:
|
|
|
185
185
|
return str_list
|
|
186
186
|
|
|
187
187
|
|
|
188
|
-
def get_json_from_args(target:
|
|
188
|
+
def get_json_from_args(target: str | None = None) -> Any: # noqa: ANN401
|
|
189
189
|
"""
|
|
190
190
|
JSON形式をPythonオブジェクトに変換する。
|
|
191
191
|
プレフィックスが`file://`ならば、ファイルパスとしてファイルを読み込み、Pythonオブジェクトを返す。
|
|
@@ -202,7 +202,7 @@ def get_json_from_args(target: Optional[str] = None) -> Any: # noqa: ANN401
|
|
|
202
202
|
return json.loads(target)
|
|
203
203
|
|
|
204
204
|
|
|
205
|
-
def get_input_data_size(str_input_data_size: str) ->
|
|
205
|
+
def get_input_data_size(str_input_data_size: str) -> InputDataSize | None:
|
|
206
206
|
"""400x300を(400,300)に変換する"""
|
|
207
207
|
splitted_list = str_input_data_size.split("x")
|
|
208
208
|
if len(splitted_list) < 2:
|
|
@@ -380,7 +380,7 @@ class ArgumentParser:
|
|
|
380
380
|
def __init__(self, parser: argparse.ArgumentParser) -> None:
|
|
381
381
|
self.parser = parser
|
|
382
382
|
|
|
383
|
-
def add_project_id(self, help_message:
|
|
383
|
+
def add_project_id(self, help_message: str | None = None) -> None:
|
|
384
384
|
"""
|
|
385
385
|
'--project_id` 引数を追加
|
|
386
386
|
"""
|
|
@@ -389,7 +389,7 @@ class ArgumentParser:
|
|
|
389
389
|
|
|
390
390
|
self.parser.add_argument("-p", "--project_id", type=str, required=True, help=help_message)
|
|
391
391
|
|
|
392
|
-
def add_task_id(self, *, required: bool = True, help_message:
|
|
392
|
+
def add_task_id(self, *, required: bool = True, help_message: str | None = None) -> None:
|
|
393
393
|
"""
|
|
394
394
|
'--task_id` 引数を追加
|
|
395
395
|
"""
|
|
@@ -398,7 +398,7 @@ class ArgumentParser:
|
|
|
398
398
|
|
|
399
399
|
self.parser.add_argument("-t", "--task_id", type=str, required=required, nargs="+", help=help_message)
|
|
400
400
|
|
|
401
|
-
def add_input_data_id(self, *, required: bool = True, help_message:
|
|
401
|
+
def add_input_data_id(self, *, required: bool = True, help_message: str | None = None) -> None:
|
|
402
402
|
"""
|
|
403
403
|
'--input_data_id` 引数を追加
|
|
404
404
|
"""
|
|
@@ -407,7 +407,7 @@ class ArgumentParser:
|
|
|
407
407
|
|
|
408
408
|
self.parser.add_argument("-i", "--input_data_id", type=str, required=required, nargs="+", help=help_message)
|
|
409
409
|
|
|
410
|
-
def add_format(self, choices: list[FormatArgument], default: FormatArgument, help_message:
|
|
410
|
+
def add_format(self, choices: list[FormatArgument], default: FormatArgument, help_message: str | None = None) -> None:
|
|
411
411
|
"""
|
|
412
412
|
'--format` 引数を追加
|
|
413
413
|
"""
|
|
@@ -416,7 +416,7 @@ class ArgumentParser:
|
|
|
416
416
|
|
|
417
417
|
self.parser.add_argument("-f", "--format", type=str, choices=[e.value for e in choices], default=default.value, help=help_message)
|
|
418
418
|
|
|
419
|
-
def add_output(self, *, required: bool = False, help_message:
|
|
419
|
+
def add_output(self, *, required: bool = False, help_message: str | None = None) -> None:
|
|
420
420
|
"""
|
|
421
421
|
'--output` 引数を追加
|
|
422
422
|
"""
|
|
@@ -425,7 +425,7 @@ class ArgumentParser:
|
|
|
425
425
|
|
|
426
426
|
self.parser.add_argument("-o", "--output", type=str, required=required, help=help_message)
|
|
427
427
|
|
|
428
|
-
def add_task_query(self, *, required: bool = False, help_message:
|
|
428
|
+
def add_task_query(self, *, required: bool = False, help_message: str | None = None) -> None:
|
|
429
429
|
if help_message is None:
|
|
430
430
|
help_message = (
|
|
431
431
|
"タスクを絞り込むためのクエリ条件をJSON形式で指定します。"
|
|
@@ -476,10 +476,10 @@ class CommandLineWithoutWebapi:
|
|
|
476
476
|
all_yes: bool = False
|
|
477
477
|
|
|
478
478
|
#: 出力先
|
|
479
|
-
output:
|
|
479
|
+
output: str | None = None
|
|
480
480
|
|
|
481
481
|
#: 出力フォーマット
|
|
482
|
-
str_format:
|
|
482
|
+
str_format: str | None = None
|
|
483
483
|
|
|
484
484
|
def __init__(self, args: argparse.Namespace) -> None:
|
|
485
485
|
self.args = args
|
|
@@ -575,8 +575,8 @@ class CommandLine(CommandLineWithoutWebapi):
|
|
|
575
575
|
def validate_project(
|
|
576
576
|
self,
|
|
577
577
|
project_id: str,
|
|
578
|
-
project_member_roles:
|
|
579
|
-
organization_member_roles:
|
|
578
|
+
project_member_roles: list[ProjectMemberRole] | None = None,
|
|
579
|
+
organization_member_roles: list[OrganizationMemberRole] | None = None,
|
|
580
580
|
) -> None:
|
|
581
581
|
"""
|
|
582
582
|
プロジェクト or 組織に対して、必要な権限が付与されているかを確認する。
|
annofabcli/common/download.py
CHANGED
|
@@ -3,7 +3,6 @@ import datetime
|
|
|
3
3
|
import logging.config
|
|
4
4
|
from functools import partial
|
|
5
5
|
from pathlib import Path
|
|
6
|
-
from typing import Optional, Union
|
|
7
6
|
|
|
8
7
|
import annofabapi
|
|
9
8
|
import requests
|
|
@@ -23,7 +22,7 @@ DOWNLOADING_FILETYPE_DICT = {
|
|
|
23
22
|
DEFAULT_WAIT_OPTIONS = WaitOptions(interval=60, max_tries=360)
|
|
24
23
|
|
|
25
24
|
|
|
26
|
-
def _get_annofab_error_message(http_error: requests.HTTPError) ->
|
|
25
|
+
def _get_annofab_error_message(http_error: requests.HTTPError) -> str | None:
|
|
27
26
|
obj = http_error.response.json()
|
|
28
27
|
errors = obj.get("errors")
|
|
29
28
|
if errors is None:
|
|
@@ -48,8 +47,8 @@ class DownloadingFile:
|
|
|
48
47
|
self,
|
|
49
48
|
project_id: str,
|
|
50
49
|
job_type: ProjectJobType,
|
|
51
|
-
wait_options:
|
|
52
|
-
job_id:
|
|
50
|
+
wait_options: WaitOptions | None = None,
|
|
51
|
+
job_id: str | None = None,
|
|
53
52
|
):
|
|
54
53
|
if wait_options is None:
|
|
55
54
|
wait_options = DEFAULT_WAIT_OPTIONS
|
|
@@ -69,9 +68,9 @@ class DownloadingFile:
|
|
|
69
68
|
async def download_annotation_zip_with_async(
|
|
70
69
|
self,
|
|
71
70
|
project_id: str,
|
|
72
|
-
dest_path:
|
|
71
|
+
dest_path: str | Path,
|
|
73
72
|
is_latest: bool = False, # noqa: FBT001, FBT002
|
|
74
|
-
wait_options:
|
|
73
|
+
wait_options: WaitOptions | None = None,
|
|
75
74
|
) -> None:
|
|
76
75
|
loop = asyncio.get_event_loop()
|
|
77
76
|
partial_func = partial(self.download_annotation_zip, project_id, dest_path, is_latest, wait_options)
|
|
@@ -80,9 +79,9 @@ class DownloadingFile:
|
|
|
80
79
|
def download_annotation_zip(
|
|
81
80
|
self,
|
|
82
81
|
project_id: str,
|
|
83
|
-
dest_path:
|
|
82
|
+
dest_path: str | Path,
|
|
84
83
|
is_latest: bool = False, # noqa: FBT001, FBT002
|
|
85
|
-
wait_options:
|
|
84
|
+
wait_options: WaitOptions | None = None,
|
|
86
85
|
should_download_full_annotation: bool = False, # noqa: FBT001, FBT002
|
|
87
86
|
) -> None:
|
|
88
87
|
"""アノテーションZIPをダウンロードします。"""
|
|
@@ -108,7 +107,7 @@ class DownloadingFile:
|
|
|
108
107
|
else:
|
|
109
108
|
raise e # noqa: TRY201
|
|
110
109
|
|
|
111
|
-
def wait_until_updated_annotation_zip(self, project_id: str, wait_options:
|
|
110
|
+
def wait_until_updated_annotation_zip(self, project_id: str, wait_options: WaitOptions | None = None) -> None:
|
|
112
111
|
job_id = None
|
|
113
112
|
try:
|
|
114
113
|
job = self.service.api.post_annotation_archive_update(project_id)[0]["job"]
|
|
@@ -125,9 +124,9 @@ class DownloadingFile:
|
|
|
125
124
|
async def download_input_data_json_with_async(
|
|
126
125
|
self,
|
|
127
126
|
project_id: str,
|
|
128
|
-
dest_path:
|
|
127
|
+
dest_path: str | Path,
|
|
129
128
|
is_latest: bool = False, # noqa: FBT001, FBT002
|
|
130
|
-
wait_options:
|
|
129
|
+
wait_options: WaitOptions | None = None,
|
|
131
130
|
) -> None:
|
|
132
131
|
loop = asyncio.get_event_loop()
|
|
133
132
|
partial_func = partial(self.download_input_data_json, project_id, dest_path, is_latest, wait_options)
|
|
@@ -136,9 +135,9 @@ class DownloadingFile:
|
|
|
136
135
|
def download_input_data_json(
|
|
137
136
|
self,
|
|
138
137
|
project_id: str,
|
|
139
|
-
dest_path:
|
|
138
|
+
dest_path: str | Path,
|
|
140
139
|
is_latest: bool = False, # noqa: FBT001, FBT002
|
|
141
|
-
wait_options:
|
|
140
|
+
wait_options: WaitOptions | None = None,
|
|
142
141
|
) -> None:
|
|
143
142
|
if is_latest:
|
|
144
143
|
self.wait_until_updated_input_data_json(project_id, wait_options)
|
|
@@ -155,7 +154,7 @@ class DownloadingFile:
|
|
|
155
154
|
else:
|
|
156
155
|
raise e # noqa: TRY201
|
|
157
156
|
|
|
158
|
-
def wait_until_updated_input_data_json(self, project_id: str, wait_options:
|
|
157
|
+
def wait_until_updated_input_data_json(self, project_id: str, wait_options: WaitOptions | None = None) -> None:
|
|
159
158
|
job_id = None
|
|
160
159
|
try:
|
|
161
160
|
job = self.service.api.post_project_inputs_update(project_id)[0]["job"]
|
|
@@ -172,15 +171,15 @@ class DownloadingFile:
|
|
|
172
171
|
async def download_task_json_with_async(
|
|
173
172
|
self,
|
|
174
173
|
project_id: str,
|
|
175
|
-
dest_path:
|
|
174
|
+
dest_path: str | Path,
|
|
176
175
|
is_latest: bool = False, # noqa: FBT001, FBT002
|
|
177
|
-
wait_options:
|
|
176
|
+
wait_options: WaitOptions | None = None,
|
|
178
177
|
) -> None:
|
|
179
178
|
loop = asyncio.get_event_loop()
|
|
180
179
|
partial_func = partial(self.download_task_json, project_id, dest_path, is_latest=is_latest, wait_options=wait_options)
|
|
181
180
|
await loop.run_in_executor(None, partial_func)
|
|
182
181
|
|
|
183
|
-
def download_task_json(self, project_id: str, dest_path:
|
|
182
|
+
def download_task_json(self, project_id: str, dest_path: str | Path, *, is_latest: bool = False, wait_options: WaitOptions | None = None) -> None:
|
|
184
183
|
if is_latest:
|
|
185
184
|
self.wait_until_updated_task_json(project_id, wait_options)
|
|
186
185
|
self.service.wrapper.download_project_tasks_url(project_id, dest_path)
|
|
@@ -196,7 +195,7 @@ class DownloadingFile:
|
|
|
196
195
|
else:
|
|
197
196
|
raise e # noqa: TRY201
|
|
198
197
|
|
|
199
|
-
def wait_until_updated_task_json(self, project_id: str, wait_options:
|
|
198
|
+
def wait_until_updated_task_json(self, project_id: str, wait_options: WaitOptions | None = None) -> None:
|
|
200
199
|
job_id = None
|
|
201
200
|
try:
|
|
202
201
|
job = self.service.api.post_project_tasks_update(project_id)[0]["job"]
|
|
@@ -210,7 +209,7 @@ class DownloadingFile:
|
|
|
210
209
|
|
|
211
210
|
self._wait_for_completion(project_id, job_type=ProjectJobType.GEN_TASKS_LIST, wait_options=wait_options, job_id=job_id)
|
|
212
211
|
|
|
213
|
-
async def download_task_history_json_with_async(self, project_id: str, dest_path:
|
|
212
|
+
async def download_task_history_json_with_async(self, project_id: str, dest_path: str | Path) -> None:
|
|
214
213
|
"""
|
|
215
214
|
非同期でタスク履歴全件ファイルをダウンロードする。
|
|
216
215
|
|
|
@@ -219,7 +218,7 @@ class DownloadingFile:
|
|
|
219
218
|
"""
|
|
220
219
|
return self.download_task_history_json(project_id, dest_path=dest_path)
|
|
221
220
|
|
|
222
|
-
def download_task_history_json(self, project_id: str, dest_path:
|
|
221
|
+
def download_task_history_json(self, project_id: str, dest_path: str | Path) -> None:
|
|
223
222
|
"""
|
|
224
223
|
タスク履歴全件ファイルをダウンロードする。
|
|
225
224
|
|
|
@@ -237,7 +236,7 @@ class DownloadingFile:
|
|
|
237
236
|
raise DownloadingFileNotFoundError(f"project_id='{project_id}'のプロジェクトに、タスク履歴全件ファイルが存在しないため、ダウンロードできませんでした。") from e
|
|
238
237
|
raise e # noqa: TRY201
|
|
239
238
|
|
|
240
|
-
def download_task_history_event_json(self, project_id: str, dest_path:
|
|
239
|
+
def download_task_history_event_json(self, project_id: str, dest_path: str | Path) -> None:
|
|
241
240
|
"""
|
|
242
241
|
タスク履歴イベント全件ファイルをダウンロードする。
|
|
243
242
|
|
|
@@ -255,7 +254,7 @@ class DownloadingFile:
|
|
|
255
254
|
raise DownloadingFileNotFoundError(f"project_id='{project_id}'のプロジェクトに、タスク履歴イベント全件ファイルが存在しないため、ダウンロードできませんでした。") from e
|
|
256
255
|
raise e # noqa: TRY201
|
|
257
256
|
|
|
258
|
-
async def download_task_history_event_json_with_async(self, project_id: str, dest_path:
|
|
257
|
+
async def download_task_history_event_json_with_async(self, project_id: str, dest_path: str | Path) -> None:
|
|
259
258
|
"""
|
|
260
259
|
非同期でタスク履歴全件ファイルをダウンロードする。
|
|
261
260
|
|
|
@@ -265,7 +264,7 @@ class DownloadingFile:
|
|
|
265
264
|
"""
|
|
266
265
|
return self.download_task_history_event_json(project_id, dest_path=dest_path)
|
|
267
266
|
|
|
268
|
-
async def download_inspection_json_with_async(self, project_id: str, dest_path:
|
|
267
|
+
async def download_inspection_json_with_async(self, project_id: str, dest_path: str | Path) -> None:
|
|
269
268
|
"""
|
|
270
269
|
非同期で検査コメント全件ファイルをダウンロードする。
|
|
271
270
|
|
|
@@ -275,7 +274,7 @@ class DownloadingFile:
|
|
|
275
274
|
|
|
276
275
|
return self.download_inspection_comment_json(project_id, dest_path=dest_path)
|
|
277
276
|
|
|
278
|
-
def download_inspection_comment_json(self, project_id: str, dest_path:
|
|
277
|
+
def download_inspection_comment_json(self, project_id: str, dest_path: str | Path) -> None:
|
|
279
278
|
"""
|
|
280
279
|
検査コメント全件ファイルをダウンロードする。
|
|
281
280
|
|
|
@@ -290,7 +289,7 @@ class DownloadingFile:
|
|
|
290
289
|
raise DownloadingFileNotFoundError(f"project_id='{project_id}'のプロジェクトに、検査コメント全件ファイルが存在しないため、ダウンロードできませんでした。") from e
|
|
291
290
|
raise e # noqa: TRY201
|
|
292
291
|
|
|
293
|
-
async def download_comment_json_with_async(self, project_id: str, dest_path:
|
|
292
|
+
async def download_comment_json_with_async(self, project_id: str, dest_path: str | Path) -> None:
|
|
294
293
|
"""
|
|
295
294
|
非同期でコメント全件ファイルをダウンロードする。
|
|
296
295
|
|
|
@@ -300,7 +299,7 @@ class DownloadingFile:
|
|
|
300
299
|
|
|
301
300
|
return self.download_comment_json(project_id, dest_path=dest_path)
|
|
302
301
|
|
|
303
|
-
def download_comment_json(self, project_id: str, dest_path:
|
|
302
|
+
def download_comment_json(self, project_id: str, dest_path: str | Path) -> None:
|
|
304
303
|
"""
|
|
305
304
|
コメント全件ファイルをダウンロードする。
|
|
306
305
|
|
|
@@ -322,7 +321,7 @@ class DownloadingFile:
|
|
|
322
321
|
output_dir: Path,
|
|
323
322
|
*,
|
|
324
323
|
is_latest: bool = False,
|
|
325
|
-
wait_options:
|
|
324
|
+
wait_options: WaitOptions | None = None,
|
|
326
325
|
) -> Path:
|
|
327
326
|
"""
|
|
328
327
|
アノテーションZIPをoutput_dirに統一された命名規則でダウンロードする。
|
|
@@ -352,7 +351,7 @@ class DownloadingFile:
|
|
|
352
351
|
output_dir: Path,
|
|
353
352
|
*,
|
|
354
353
|
is_latest: bool = False,
|
|
355
|
-
wait_options:
|
|
354
|
+
wait_options: WaitOptions | None = None,
|
|
356
355
|
) -> Path:
|
|
357
356
|
"""
|
|
358
357
|
タスクJSONをoutput_dirに統一された命名規則でダウンロードする。
|
|
@@ -382,7 +381,7 @@ class DownloadingFile:
|
|
|
382
381
|
output_dir: Path,
|
|
383
382
|
*,
|
|
384
383
|
is_latest: bool = False,
|
|
385
|
-
wait_options:
|
|
384
|
+
wait_options: WaitOptions | None = None,
|
|
386
385
|
) -> Path:
|
|
387
386
|
"""
|
|
388
387
|
入力データJSONをoutput_dirに統一された命名規則でダウンロードする。
|
annofabcli/common/facade.py
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
-
from collections.abc import Collection
|
|
4
|
+
from collections.abc import Callable, Collection
|
|
5
5
|
from dataclasses import dataclass
|
|
6
|
-
from typing import Any
|
|
6
|
+
from typing import Any
|
|
7
7
|
|
|
8
8
|
import annofabapi
|
|
9
|
-
import annofabapi.utils
|
|
10
9
|
import more_itertools
|
|
11
10
|
from annofabapi.dataclass.annotation import AdditionalDataV1
|
|
12
11
|
from annofabapi.dataclass.input import InputData
|
|
@@ -33,27 +32,27 @@ class AnnotationQuery(DataClassJsonMixin):
|
|
|
33
32
|
"""
|
|
34
33
|
|
|
35
34
|
label_id: str
|
|
36
|
-
attributes:
|
|
35
|
+
attributes: list[AdditionalDataV1] | None = None
|
|
37
36
|
|
|
38
37
|
|
|
39
38
|
@dataclass
|
|
40
39
|
class AdditionalDataForCli(DataClassJsonMixin):
|
|
41
|
-
additional_data_definition_id:
|
|
40
|
+
additional_data_definition_id: str | None = None
|
|
42
41
|
"""属性ID"""
|
|
43
42
|
|
|
44
|
-
additional_data_definition_name_en:
|
|
43
|
+
additional_data_definition_name_en: str | None = None
|
|
45
44
|
"""属性の英語名"""
|
|
46
45
|
|
|
47
|
-
flag:
|
|
46
|
+
flag: bool | None = None
|
|
48
47
|
|
|
49
|
-
integer:
|
|
48
|
+
integer: int | None = None
|
|
50
49
|
|
|
51
|
-
comment:
|
|
50
|
+
comment: str | None = None
|
|
52
51
|
|
|
53
|
-
choice:
|
|
52
|
+
choice: str | None = None
|
|
54
53
|
"""選択肢ID"""
|
|
55
54
|
|
|
56
|
-
choice_name_en:
|
|
55
|
+
choice_name_en: str | None = None
|
|
57
56
|
"""選択肢の英語名"""
|
|
58
57
|
|
|
59
58
|
|
|
@@ -63,10 +62,10 @@ class AnnotationQueryForCli(DataClassJsonMixin):
|
|
|
63
62
|
コマンドライン上で指定するアノテーション検索条件
|
|
64
63
|
"""
|
|
65
64
|
|
|
66
|
-
label_name_en:
|
|
65
|
+
label_name_en: str | None = None
|
|
67
66
|
"""ラベルの英語名"""
|
|
68
|
-
label_id:
|
|
69
|
-
attributes:
|
|
67
|
+
label_id: str | None = None
|
|
68
|
+
attributes: list[AdditionalDataForCli] | None = None
|
|
70
69
|
|
|
71
70
|
|
|
72
71
|
@dataclass
|
|
@@ -75,12 +74,12 @@ class TaskQuery(DataClassJsonMixin):
|
|
|
75
74
|
コマンドライン上で指定するタスクの検索条件
|
|
76
75
|
"""
|
|
77
76
|
|
|
78
|
-
task_id:
|
|
79
|
-
phase:
|
|
80
|
-
status:
|
|
81
|
-
phase_stage:
|
|
82
|
-
user_id:
|
|
83
|
-
account_id:
|
|
77
|
+
task_id: str | None = None
|
|
78
|
+
phase: TaskPhase | None = None
|
|
79
|
+
status: TaskStatus | None = None
|
|
80
|
+
phase_stage: int | None = None
|
|
81
|
+
user_id: str | None = None
|
|
82
|
+
account_id: str | None = None
|
|
84
83
|
no_user: bool = False
|
|
85
84
|
"""Trueなら未割り当てのタスクで絞り込む"""
|
|
86
85
|
|
|
@@ -91,12 +90,12 @@ class InputDataQuery(DataClassJsonMixin):
|
|
|
91
90
|
コマンドライン上で指定する入力データの検索条件
|
|
92
91
|
"""
|
|
93
92
|
|
|
94
|
-
input_data_id:
|
|
95
|
-
input_data_name:
|
|
96
|
-
input_data_path:
|
|
93
|
+
input_data_id: str | None = None
|
|
94
|
+
input_data_name: str | None = None
|
|
95
|
+
input_data_path: str | None = None
|
|
97
96
|
|
|
98
97
|
|
|
99
|
-
def match_annotation_with_task_query(annotation: dict[str, Any], task_query:
|
|
98
|
+
def match_annotation_with_task_query(annotation: dict[str, Any], task_query: TaskQuery | None) -> bool:
|
|
100
99
|
"""
|
|
101
100
|
Simple Annotationが、タスククエリ条件に合致するか
|
|
102
101
|
|
|
@@ -130,7 +129,7 @@ def match_annotation_with_task_query(annotation: dict[str, Any], task_query: Opt
|
|
|
130
129
|
|
|
131
130
|
|
|
132
131
|
def match_task_with_query( # pylint: disable=too-many-return-statements # noqa: PLR0911
|
|
133
|
-
task: Task, task_query:
|
|
132
|
+
task: Task, task_query: TaskQuery | None
|
|
134
133
|
) -> bool:
|
|
135
134
|
"""
|
|
136
135
|
タスク情報が、タスククエリ条件に合致するかどうか。
|
|
@@ -175,7 +174,7 @@ def match_task_with_query( # pylint: disable=too-many-return-statements # noqa
|
|
|
175
174
|
|
|
176
175
|
|
|
177
176
|
def match_input_data_with_query( # pylint: disable=too-many-return-statements
|
|
178
|
-
input_data: InputData, input_data_query:
|
|
177
|
+
input_data: InputData, input_data_query: InputDataQuery | None
|
|
179
178
|
) -> bool:
|
|
180
179
|
"""
|
|
181
180
|
入力データが、クエリ条件に合致するかどうか。
|
|
@@ -222,7 +221,7 @@ def convert_annotation_specs_labels_v2_to_v1(labels_v2: list[dict[str, Any]], ad
|
|
|
222
221
|
List[LabelV1]: V1版のラベル情報
|
|
223
222
|
"""
|
|
224
223
|
|
|
225
|
-
def get_additional(additional_data_definition_id: str) ->
|
|
224
|
+
def get_additional(additional_data_definition_id: str) -> dict[str, Any] | None:
|
|
226
225
|
return more_itertools.first_true(additionals_v2, pred=lambda e: e["additional_data_definition_id"] == additional_data_definition_id)
|
|
227
226
|
|
|
228
227
|
def to_label_v1(label_v2: dict[str, Any]) -> dict[str, Any]:
|
|
@@ -249,7 +248,7 @@ class AnnofabApiFacade:
|
|
|
249
248
|
"""
|
|
250
249
|
|
|
251
250
|
#: 組織メンバ一覧のキャッシュ
|
|
252
|
-
_organization_members:
|
|
251
|
+
_organization_members: tuple[str, list[OrganizationMember]] | None = None
|
|
253
252
|
|
|
254
253
|
_project_members_dict: dict[str, list[ProjectMember]] = {} # noqa: RUF012
|
|
255
254
|
"""プロジェクトメンバ一覧の情報。key:project_id, value:プロジェクトメンバ一覧"""
|
|
@@ -258,7 +257,7 @@ class AnnofabApiFacade:
|
|
|
258
257
|
self.service = service
|
|
259
258
|
|
|
260
259
|
@staticmethod
|
|
261
|
-
def get_account_id_last_annotation_phase(task_histories: list[dict[str, Any]]) ->
|
|
260
|
+
def get_account_id_last_annotation_phase(task_histories: list[dict[str, Any]]) -> str | None:
|
|
262
261
|
"""
|
|
263
262
|
タスク履歴の最後のannotation phaseを担当したaccount_idを取得する. なければNoneを返す
|
|
264
263
|
Args:
|
|
@@ -303,7 +302,7 @@ class AnnofabApiFacade:
|
|
|
303
302
|
project, _ = self.service.api.get_project(project_id)
|
|
304
303
|
return project["title"]
|
|
305
304
|
|
|
306
|
-
def _get_organization_member_with_predicate(self, project_id: str, predicate: Callable[[Any], bool]) ->
|
|
305
|
+
def _get_organization_member_with_predicate(self, project_id: str, predicate: Callable[[Any], bool]) -> OrganizationMember | None:
|
|
307
306
|
"""
|
|
308
307
|
account_idから組織メンバを取得する。
|
|
309
308
|
インスタンス変数に組織メンバがあれば、WebAPIは実行しない。
|
|
@@ -335,7 +334,7 @@ class AnnofabApiFacade:
|
|
|
335
334
|
update_organization_members()
|
|
336
335
|
return self._get_organization_member_with_predicate(project_id, predicate)
|
|
337
336
|
|
|
338
|
-
def _get_project_member_with_predicate(self, project_id: str, predicate: Callable[[Any], bool]) ->
|
|
337
|
+
def _get_project_member_with_predicate(self, project_id: str, predicate: Callable[[Any], bool]) -> ProjectMember | None:
|
|
339
338
|
"""
|
|
340
339
|
project_memberを取得する
|
|
341
340
|
|
|
@@ -352,7 +351,7 @@ class AnnofabApiFacade:
|
|
|
352
351
|
self._project_members_dict[project_id] = project_member_list
|
|
353
352
|
return more_itertools.first_true(project_member_list, pred=predicate)
|
|
354
353
|
|
|
355
|
-
def get_project_member_from_account_id(self, project_id: str, account_id: str) ->
|
|
354
|
+
def get_project_member_from_account_id(self, project_id: str, account_id: str) -> ProjectMember | None:
|
|
356
355
|
"""
|
|
357
356
|
account_idからプロジェクトメンバを取得する。
|
|
358
357
|
|
|
@@ -365,7 +364,7 @@ class AnnofabApiFacade:
|
|
|
365
364
|
"""
|
|
366
365
|
return self._get_project_member_with_predicate(project_id, predicate=lambda e: e["account_id"] == account_id)
|
|
367
366
|
|
|
368
|
-
def get_project_member_from_user_id(self, project_id: str, user_id: str) ->
|
|
367
|
+
def get_project_member_from_user_id(self, project_id: str, user_id: str) -> ProjectMember | None:
|
|
369
368
|
"""
|
|
370
369
|
user_idからプロジェクトメンバを取得する。
|
|
371
370
|
|
|
@@ -378,7 +377,7 @@ class AnnofabApiFacade:
|
|
|
378
377
|
"""
|
|
379
378
|
return self._get_project_member_with_predicate(project_id, predicate=lambda e: e["user_id"] == user_id)
|
|
380
379
|
|
|
381
|
-
def get_organization_member_from_user_id(self, project_id: str, user_id: str) ->
|
|
380
|
+
def get_organization_member_from_user_id(self, project_id: str, user_id: str) -> OrganizationMember | None:
|
|
382
381
|
"""
|
|
383
382
|
user_idから組織メンバを取得する。
|
|
384
383
|
インスタンス変数に組織メンバがあれば、WebAPIは実行しない。
|
|
@@ -392,7 +391,7 @@ class AnnofabApiFacade:
|
|
|
392
391
|
"""
|
|
393
392
|
return self._get_organization_member_with_predicate(project_id, lambda e: e["user_id"] == user_id)
|
|
394
393
|
|
|
395
|
-
def get_user_id_from_account_id(self, project_id: str, account_id: str) ->
|
|
394
|
+
def get_user_id_from_account_id(self, project_id: str, account_id: str) -> str | None:
|
|
396
395
|
"""
|
|
397
396
|
account_idからuser_idを取得する.
|
|
398
397
|
インスタンス変数に組織メンバがあれば、WebAPIは実行しない。
|
|
@@ -411,7 +410,7 @@ class AnnofabApiFacade:
|
|
|
411
410
|
else:
|
|
412
411
|
return member.get("user_id")
|
|
413
412
|
|
|
414
|
-
def get_account_id_from_user_id(self, project_id: str, user_id: str) ->
|
|
413
|
+
def get_account_id_from_user_id(self, project_id: str, user_id: str) -> str | None:
|
|
415
414
|
"""
|
|
416
415
|
user_idからaccount_idを取得する。
|
|
417
416
|
インスタンス変数に組織メンバがあれば、WebAPIは実行しない。
|
|
@@ -502,8 +501,8 @@ class AnnofabApiFacade:
|
|
|
502
501
|
def validate_project(
|
|
503
502
|
self,
|
|
504
503
|
project_id: str,
|
|
505
|
-
project_member_roles:
|
|
506
|
-
organization_member_roles:
|
|
504
|
+
project_member_roles: list[ProjectMemberRole] | None = None,
|
|
505
|
+
organization_member_roles: list[OrganizationMemberRole] | None = None,
|
|
507
506
|
) -> None:
|
|
508
507
|
"""
|
|
509
508
|
プロジェクト or 組織に対して、必要な権限が付与されているかを確認する。
|
annofabcli/common/image.py
CHANGED
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
|
|
6
6
|
import logging
|
|
7
7
|
import zipfile
|
|
8
|
+
from collections.abc import Callable
|
|
8
9
|
from pathlib import Path
|
|
9
|
-
from typing import Any
|
|
10
|
+
from typing import Any
|
|
10
11
|
|
|
11
|
-
import PIL
|
|
12
12
|
import PIL.Image
|
|
13
13
|
import PIL.ImageDraw
|
|
14
14
|
from annofabapi.dataclass.annotation import SimpleAnnotationDetail
|
|
@@ -24,7 +24,7 @@ IsParserFunc = Callable[[SimpleAnnotationParser], bool]
|
|
|
24
24
|
"""アノテーションparserに対してboolを返す関数"""
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
def get_data_uri_of_outer_file(annotation: SimpleAnnotationDetail) ->
|
|
27
|
+
def get_data_uri_of_outer_file(annotation: SimpleAnnotationDetail) -> str | None:
|
|
28
28
|
"""
|
|
29
29
|
外部ファイルの data_uri を取得する
|
|
30
30
|
Args:
|
|
@@ -45,7 +45,7 @@ def fill_annotation(
|
|
|
45
45
|
draw: PIL.ImageDraw.ImageDraw,
|
|
46
46
|
annotation: SimpleAnnotationDetail,
|
|
47
47
|
label_color_dict: dict[str, RGB],
|
|
48
|
-
outer_image:
|
|
48
|
+
outer_image: Any | None = None, # noqa: ANN401
|
|
49
49
|
) -> PIL.ImageDraw.ImageDraw:
|
|
50
50
|
"""
|
|
51
51
|
1個のアノテーションを、塗りつぶしで描画する。(矩形、ポリゴン、塗りつぶし、塗りつぶしv2)
|
|
@@ -94,7 +94,7 @@ def fill_annotation_list(
|
|
|
94
94
|
draw: PIL.ImageDraw.ImageDraw,
|
|
95
95
|
parser: SimpleAnnotationParser,
|
|
96
96
|
label_color_dict: dict[str, RGB],
|
|
97
|
-
label_name_list:
|
|
97
|
+
label_name_list: list[str] | None = None,
|
|
98
98
|
) -> PIL.ImageDraw.ImageDraw:
|
|
99
99
|
"""
|
|
100
100
|
1個の入力データに属するアノテーションlistを描画する
|
|
@@ -142,8 +142,8 @@ def write_annotation_image( # noqa: ANN201
|
|
|
142
142
|
image_size: InputDataSize,
|
|
143
143
|
label_color_dict: dict[str, RGB],
|
|
144
144
|
output_image_file: Path,
|
|
145
|
-
background_color:
|
|
146
|
-
label_name_list:
|
|
145
|
+
background_color: Any | None = None, # noqa: ANN401
|
|
146
|
+
label_name_list: list[str] | None = None,
|
|
147
147
|
):
|
|
148
148
|
"""
|
|
149
149
|
JSONファイルに記載されているアノテーション情報を、画像化する。
|
|
@@ -191,7 +191,7 @@ def write_annotation_grayscale_image(
|
|
|
191
191
|
parser: SimpleAnnotationParser,
|
|
192
192
|
image_size: InputDataSize,
|
|
193
193
|
output_image_file: Path,
|
|
194
|
-
label_name_list:
|
|
194
|
+
label_name_list: list[str] | None = None,
|
|
195
195
|
) -> None:
|
|
196
196
|
"""
|
|
197
197
|
JSONファイルに記載されているアノテーション情報を、グレースケール(8bit 1channel)で画像化します。
|
|
@@ -267,12 +267,12 @@ def write_annotation_images_from_path(
|
|
|
267
267
|
annotation_path: Path,
|
|
268
268
|
label_color_dict: dict[str, RGB],
|
|
269
269
|
output_dir_path: Path,
|
|
270
|
-
image_size:
|
|
271
|
-
input_data_dict:
|
|
270
|
+
image_size: InputDataSize | None = None,
|
|
271
|
+
input_data_dict: dict[str, InputData] | None = None,
|
|
272
272
|
output_image_extension: str = "png",
|
|
273
|
-
background_color:
|
|
274
|
-
label_name_list:
|
|
275
|
-
is_target_parser_func:
|
|
273
|
+
background_color: Any | None = None, # noqa: ANN401
|
|
274
|
+
label_name_list: list[str] | None = None,
|
|
275
|
+
is_target_parser_func: IsParserFunc | None = None,
|
|
276
276
|
) -> bool:
|
|
277
277
|
"""
|
|
278
278
|
Annofabからダウンロードしたアノテーションzipファイル、またはそのzipを展開したディレクトリから、アノテーション情報を画像化します。
|
|
@@ -297,7 +297,7 @@ def write_annotation_images_from_path(
|
|
|
297
297
|
|
|
298
298
|
"""
|
|
299
299
|
|
|
300
|
-
def _get_image_size(input_data_id: str) ->
|
|
300
|
+
def _get_image_size(input_data_id: str) -> InputDataSize | None:
|
|
301
301
|
def _get_image_size_from_system_metadata(arg_input_data: dict[str, Any]): # noqa: ANN202
|
|
302
302
|
# 入力データの`input_data.system_metadata.original_resolution`を参照して、画像サイズを決める。
|
|
303
303
|
original_resolution = arg_input_data["system_metadata"]["original_resolution"]
|