Skip to content

Commit 0df5905

Browse files
authored
Merge pull request #198 from superannotateai/sdk_argumnets_validation
Add validator decorator
2 parents 9f9f925 + d5ac83a commit 0df5905

File tree

2 files changed

+123
-70
lines changed

2 files changed

+123
-70
lines changed

src/superannotate/lib/app/interface/sdk_interface.py

Lines changed: 111 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
from lib.app.helpers import extract_project_folder
3232
from lib.app.helpers import get_annotation_paths
3333
from lib.app.helpers import reformat_metrics_json
34+
from lib.app.interface.types import AnnotationType
3435
from lib.app.interface.types import ClassesJson
3536
from lib.app.interface.types import NotEmptyStr
3637
from lib.app.interface.types import Status
@@ -2742,7 +2743,7 @@ def benchmark(
27422743
folder_names: List[str],
27432744
export_root: Optional[Union[str, Path]] = None,
27442745
image_list=None,
2745-
annot_type="bbox",
2746+
annot_type: Optional[AnnotationType] = "bbox",
27462747
show_plots=False,
27472748
):
27482749
"""Computes benchmark score for each instance of given images that are present both gt_project_name project and projects in folder_names list:
@@ -2798,13 +2799,14 @@ def benchmark(
27982799

27992800

28002801
@Trackable
2802+
@validate_arguments
28012803
def consensus(
2802-
project: str,
2803-
folder_names,
2804-
export_root=None,
2805-
image_list=None,
2806-
annot_type="bbox",
2807-
show_plots=False,
2804+
project: NotEmptyStr,
2805+
folder_names: NotEmptyStr,
2806+
export_root: Optional[Union[NotEmptyStr, Path]] = None,
2807+
image_list: Optional[List[NotEmptyStr]] = None,
2808+
annot_type: Optional[AnnotationType] = "bbox",
2809+
show_plots: Optional[StrictBool] = False,
28082810
):
28092811
"""Computes consensus score for each instance of given images that are present in at least 2 of the given projects:
28102812
@@ -2852,11 +2854,18 @@ def consensus(
28522854

28532855

28542856
@Trackable
2855-
def run_segmentation(project, images_list, model):
2857+
@validate_arguments
2858+
def run_segmentation(
2859+
project: Union[NotEmptyStr, dict],
2860+
images_list: List[NotEmptyStr],
2861+
model: Union[NotEmptyStr, dict],
2862+
):
28562863
"""Starts smart segmentation on a list of images using the specified model
28572864
28582865
:param project: project name of metadata of the project
28592866
:type project: str or dict
2867+
:param images_list: image list
2868+
:type images_list: list of str
28602869
:param model: The model name or metadata of the model
28612870
:type model: str or dict
28622871
:return: tupe of two lists, list of images on which the segmentation has succeeded and failed respectively
@@ -2887,7 +2896,12 @@ def run_segmentation(project, images_list, model):
28872896

28882897

28892898
@Trackable
2890-
def run_prediction(project, images_list, model):
2899+
@validate_arguments
2900+
def run_prediction(
2901+
project: Union[NotEmptyStr, dict],
2902+
images_list: List[NotEmptyStr],
2903+
model: Union[NotEmptyStr, dict],
2904+
):
28912905
"""This function runs smart prediction on given list of images from a given project using the neural network of your choice
28922906
28932907
:param project: the project in which the target images are uploaded.
@@ -2922,8 +2936,9 @@ def run_prediction(project, images_list, model):
29222936

29232937

29242938
@Trackable
2939+
@validate_arguments
29252940
# todo test
2926-
def plot_model_metrics(metric_json_list):
2941+
def plot_model_metrics(metric_json_list=List[NotEmptyStr]):
29272942
"""plots the metrics generated by neural network using plotly
29282943
29292944
:param metric_json_list: list of <model_name>.json files
@@ -2983,13 +2998,14 @@ def get_plottable_cols(df):
29832998

29842999

29853000
@Trackable
3001+
@validate_arguments
29863002
def add_annotation_bbox_to_image(
2987-
project,
2988-
image_name,
2989-
bbox,
2990-
annotation_class_name,
2991-
annotation_class_attributes=None,
2992-
error=None,
3003+
project: NotEmptyStr,
3004+
image_name: NotEmptyStr,
3005+
bbox: List[float],
3006+
annotation_class_name: NotEmptyStr,
3007+
annotation_class_attributes: Optional[List[NotEmptyStr]] = None,
3008+
error: Optional[StrictBool] = None,
29933009
):
29943010
"""Add a bounding box annotation to image annotations
29953011
@@ -3017,13 +3033,14 @@ def add_annotation_bbox_to_image(
30173033

30183034

30193035
@Trackable
3036+
@validate_arguments
30203037
def add_annotation_polyline_to_image(
3021-
project,
3022-
image_name,
3023-
polyline,
3024-
annotation_class_name,
3025-
annotation_class_attributes=None,
3026-
error=None,
3038+
project: NotEmptyStr,
3039+
image_name: NotEmptyStr,
3040+
polyline: List[float],
3041+
annotation_class_name: NotEmptyStr,
3042+
annotation_class_attributes: Optional[List[NotEmptyStr]] = None,
3043+
error: Optional[StrictBool] = None,
30273044
):
30283045
"""Add a polyline annotation to image annotations
30293046
@@ -3050,13 +3067,14 @@ def add_annotation_polyline_to_image(
30503067

30513068

30523069
@Trackable
3070+
@validate_arguments
30533071
def add_annotation_polygon_to_image(
3054-
project,
3055-
image_name,
3056-
polygon,
3057-
annotation_class_name,
3072+
project: NotEmptyStr,
3073+
image_name: NotEmptyStr,
3074+
polygon: List[float],
3075+
annotation_class_name: NotEmptyStr,
30583076
annotation_class_attributes=None,
3059-
error=None,
3077+
error: Optional[StrictBool] = None,
30603078
):
30613079
"""Add a polygon annotation to image annotations
30623080
@@ -3084,13 +3102,14 @@ def add_annotation_polygon_to_image(
30843102

30853103

30863104
@Trackable
3105+
@validate_arguments
30873106
def add_annotation_point_to_image(
3088-
project,
3089-
image_name,
3090-
point,
3091-
annotation_class_name,
3092-
annotation_class_attributes=None,
3093-
error=None,
3107+
project: NotEmptyStr,
3108+
image_name: NotEmptyStr,
3109+
point: List[float],
3110+
annotation_class_name: NotEmptyStr,
3111+
annotation_class_attributes: Optional[List[NotEmptyStr]] = None,
3112+
error: Optional[StrictBool] = None,
30943113
):
30953114
"""Add a point annotation to image annotations
30963115
@@ -3118,12 +3137,12 @@ def add_annotation_point_to_image(
31183137

31193138
@Trackable
31203139
def add_annotation_ellipse_to_image(
3121-
project,
3122-
image_name,
3123-
ellipse,
3124-
annotation_class_name,
3125-
annotation_class_attributes=None,
3126-
error=None,
3140+
project: NotEmptyStr,
3141+
image_name: NotEmptyStr,
3142+
ellipse: List[float],
3143+
annotation_class_name: NotEmptyStr,
3144+
annotation_class_attributes: Optional[List[NotEmptyStr]] = None,
3145+
error: Optional[StrictBool] = None,
31273146
):
31283147
"""Add an ellipse annotation to image annotations
31293148
@@ -3150,14 +3169,15 @@ def add_annotation_ellipse_to_image(
31503169

31513170

31523171
@Trackable
3172+
@validate_arguments
31533173
def add_annotation_template_to_image(
3154-
project,
3155-
image_name,
3156-
template_points,
3157-
template_connections,
3158-
annotation_class_name,
3159-
annotation_class_attributes=None,
3160-
error=None,
3174+
project: NotEmptyStr,
3175+
image_name: NotEmptyStr,
3176+
template_points: List[float],
3177+
template_connections: List[int],
3178+
annotation_class_name: NotEmptyStr,
3179+
annotation_class_attributes: Optional[List[NotEmptyStr]] = None,
3180+
error: Optional[StrictBool] = None,
31613181
):
31623182
"""Add a template annotation to image annotations
31633183
@@ -3195,13 +3215,14 @@ def add_annotation_template_to_image(
31953215

31963216

31973217
@Trackable
3218+
@validate_arguments
31983219
def add_annotation_cuboid_to_image(
3199-
project,
3200-
image_name,
3201-
cuboid,
3202-
annotation_class_name,
3203-
annotation_class_attributes=None,
3204-
error=None,
3220+
project: NotEmptyStr,
3221+
image_name: NotEmptyStr,
3222+
cuboid: List[float],
3223+
annotation_class_name: NotEmptyStr,
3224+
annotation_class_attributes: Optional[List[NotEmptyStr]] = None,
3225+
error: Optional[StrictBool] = None,
32053226
):
32063227
"""Add a cuboid annotation to image annotations
32073228
@@ -3232,7 +3253,12 @@ def add_annotation_cuboid_to_image(
32323253

32333254
@Trackable
32343255
def add_annotation_comment_to_image(
3235-
project, image_name, comment_text, comment_coords, comment_author, resolved=False
3256+
project: NotEmptyStr,
3257+
image_name: NotEmptyStr,
3258+
comment_text: NotEmptyStr,
3259+
comment_coords: List[float],
3260+
comment_author: NotEmptyStr,
3261+
resolved: Optional[StrictBool] = False,
32363262
):
32373263
"""Add a comment to SuperAnnotate format annotation JSON
32383264
@@ -3256,8 +3282,12 @@ def add_annotation_comment_to_image(
32563282
upload_image_annotations(project, image_name, annotations, verbose=False)
32573283

32583284

3285+
@validate_arguments
32593286
def search_images_all_folders(
3260-
project, image_name_prefix=None, annotation_status=None, return_metadata=False
3287+
project: NotEmptyStr,
3288+
image_name_prefix: Optional[NotEmptyStr] = None,
3289+
annotation_status: Optional[NotEmptyStr] = None,
3290+
return_metadata: Optional[StrictBool] = False,
32613291
):
32623292
"""Search images by name_prefix (case-insensitive) and annotation status in
32633293
project and all of its folders
@@ -3288,13 +3318,14 @@ def search_images_all_folders(
32883318

32893319

32903320
@Trackable
3321+
@validate_arguments
32913322
def upload_image_to_project(
3292-
project,
3323+
project: NotEmptyStr,
32933324
img,
3294-
image_name=None,
3295-
annotation_status="NotStarted",
3325+
image_name: Optional[NotEmptyStr] = None,
3326+
annotation_status: Optional[Status] = "NotStarted",
32963327
from_s3_bucket=None,
3297-
image_quality_in_editor=None,
3328+
image_quality_in_editor: Optional[NotEmptyStr] = None,
32983329
):
32993330
"""Uploads image (io.BytesIO() or filepath to image) to project.
33003331
Sets status of the uploaded image to set_status if it is not None.
@@ -3345,7 +3376,11 @@ def upload_image_to_project(
33453376

33463377

33473378
def search_models(
3348-
name=None, type_=None, project_id=None, task=None, include_global=True,
3379+
name: Optional[NotEmptyStr] = None,
3380+
type_: Optional[NotEmptyStr] = None,
3381+
project_id: Optional[int] = None,
3382+
task: Optional[NotEmptyStr] = None,
3383+
include_global: Optional[StrictBool] = True,
33493384
):
33503385
"""Search for ML models.
33513386
@@ -3374,12 +3409,13 @@ def search_models(
33743409

33753410

33763411
@Trackable
3412+
@validate_arguments
33773413
def upload_images_to_project(
3378-
project,
3379-
img_paths,
3380-
annotation_status="NotStarted",
3414+
project: NotEmptyStr,
3415+
img_paths: List[NotEmptyStr],
3416+
annotation_status: Optional[Status] = "NotStarted",
33813417
from_s3_bucket=None,
3382-
image_quality_in_editor=None,
3418+
image_quality_in_editor: Optional[NotEmptyStr] = None,
33833419
):
33843420
"""Uploads all images given in list of path objects in img_paths to the project.
33853421
Sets status of all the uploaded images to set_status if it is not None.
@@ -3503,13 +3539,14 @@ def _upload_s3_image(image_path: str):
35033539

35043540

35053541
@Trackable
3542+
@validate_arguments
35063543
def aggregate_annotations_as_df(
3507-
project_root,
3508-
include_classes_wo_annotations=False,
3509-
include_comments=False,
3510-
include_tags=False,
3511-
verbose=True,
3512-
folder_names=None,
3544+
project_root: Union[NotEmptyStr, Path],
3545+
include_classes_wo_annotations: Optional[StrictBool] = False,
3546+
include_comments: Optional[StrictBool] = False,
3547+
include_tags: Optional[StrictBool] = False,
3548+
verbose: Optional[StrictBool] = True,
3549+
folder_names: Optional[NotEmptyStr] = None,
35133550
):
35143551
"""Aggregate annotations as pandas dataframe from project root.
35153552
@@ -3522,6 +3559,8 @@ def aggregate_annotations_as_df(
35223559
:type include_comments: bool
35233560
:param include_tags: enables inclusion of tags info as tag column
35243561
:type include_tags: bool
3562+
:param verbose: enables logging
3563+
:type verbose: bool
35253564
:param folder_names: Aggregate the specified folders from project_root.
35263565
If None aggregate all folders in the project_root.
35273566
:type folder_names: (list of str)
@@ -3550,7 +3589,9 @@ def aggregate_annotations_as_df(
35503589

35513590
@Trackable
35523591
@validate_arguments
3553-
def delete_annotations(project: str, image_names: List[str] = None):
3592+
def delete_annotations(
3593+
project: NotEmptyStr, image_names: Optional[List[NotEmptyStr]] = None
3594+
):
35543595
"""
35553596
Delete image annotations from a given list of images.
35563597

src/superannotate/lib/app/interface/types.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,18 @@ def validate(cls, value: Union[str]) -> Union[str]:
2424
return value
2525

2626

27+
class AnnotationType(StrictStr):
28+
VALID_TYPES = ["bbox", "polygon", "point"]
29+
30+
@classmethod
31+
def validate(cls, value: Union[str]) -> Union[str]:
32+
if value.lower() not in cls.VALID_TYPES:
33+
raise TypeError(
34+
f"Available annotation_types are {', '.join(cls.VALID_TYPES)}. "
35+
)
36+
return value
37+
38+
2739
class AttributeGroup(BaseModel):
2840
name: StrictStr
2941
is_multiselect: Optional[bool]

0 commit comments

Comments
 (0)