Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,10 @@
html_static_path = []

autodoc_typehints = "description"
html_show_sourcelink = False

html_context = {
"display_github": False, # Add 'Edit on Github' link instead of 'View page source'
"last_updated": True,
"commit": False,
}
2 changes: 1 addition & 1 deletion requirements_dev.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
superannotate_schemas>=v1.0.45dev1
superannotate_schemas>=v1.0.45dev5

16 changes: 10 additions & 6 deletions src/superannotate/lib/app/interface/sdk_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -2049,7 +2049,7 @@ def upload_image_to_project(
def search_models(
self,
name: Optional[NotEmptyStr] = None,
type_: Optional[NotEmptyStr] = None,
type_: Optional[NotEmptyStr] = None, # noqa
project_id: Optional[int] = None,
task: Optional[NotEmptyStr] = None,
include_global: Optional[StrictBool] = True,
Expand All @@ -2058,17 +2058,21 @@ def search_models(

:param name: search string
:type name: str
:param type_: ml model type string
:type type_: str

:param type\_: ml model type string
:type type\_: str

:param project_id: project id
:type project_id: int

:param task: training task
:type task: str

:param include_global: include global ml models
:type include_global: bool

:return: ml model metadata
:rtype: list of dicts
:return: ml model metadata
:rtype: list of dicts
"""
res = self.controller.search_models(
name=name,
Expand Down Expand Up @@ -2227,7 +2231,7 @@ def validate_annotations(
with open(annotations_json) as file:
annotation_data = json.loads(file.read())
response = Controller.validate_annotations(
project_type, annotation_data, allow_extra=False
project_type, annotation_data
)
if response.errors:
raise AppException(response.errors)
Expand Down
2 changes: 1 addition & 1 deletion src/superannotate/lib/core/usecases/items.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ def validate_arguments(self):
raise AppException(
"The query and subset params cannot have the value None at the same time."
)
if all([self._query, self._subset]) and not self._folder.is_root:
if self._subset and not self._folder.is_root:
raise AppException(
"The folder name should be specified in the query string."
)
Expand Down
20 changes: 7 additions & 13 deletions src/superannotate/lib/core/video_convertor.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class Annotation(BaseModel):
classId: Optional[int]
x: Optional[Any]
y: Optional[Any]
points: Optional[Dict]
points: Any
attributes: Optional[List[Any]] = []
keyframe: bool = False

Expand All @@ -30,10 +30,11 @@ class FrameAnnotation(BaseModel):

class VideoFrameGenerator:
def __init__(self, annotation_data: dict, fps: int):
self.validate_annotations(annotation_data)
self.id_generator = iter(itertools.count(0))
self._annotation_data = annotation_data
self.duration = annotation_data["metadata"]["duration"] / (1000 * 1000)
duration = annotation_data["metadata"]["duration"]
duration = 0 if not duration else duration
self.duration = duration / (1000 * 1000)
self.fps = fps
self.ratio = 1000 * 1000 / fps
self._frame_id = 1
Expand All @@ -42,12 +43,6 @@ def __init__(self, annotation_data: dict, fps: int):
self._mapping = {}
self._process()

@staticmethod
def validate_annotations(annotation_data: dict):
duration = annotation_data["metadata"].get("duration")
if duration is None:
raise AppException("Video not annotated yet")

def get_frame(self, frame_no: int):
try:
return self.annotations[frame_no]
Expand Down Expand Up @@ -81,10 +76,9 @@ def _interpolate(
"x": round(data["x"] + steps["x"] * idx, 2),
"y": round(data["y"] + steps["y"] * idx, 2),
}
elif annotation_type in (AnnotationTypes.POLYGON, AnnotationTypes.POLYLINE):
tmp_data["points"] = [
point + steps[idx] * 2 for idx, point in enumerate(data["points"])
]
else:
tmp_data["points"] = data["points"]

annotations[frame_idx] = Annotation(
instanceId=instance_id,
type=annotation_type,
Expand Down
2 changes: 1 addition & 1 deletion src/superannotate/lib/infrastructure/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -1355,7 +1355,7 @@ def delete_annotations(

@staticmethod
def validate_annotations(
project_type: str, annotation: dict, allow_extra: bool = False
project_type: str, annotation: dict, allow_extra: bool = True
):
use_case = usecases.ValidateAnnotationUseCase(
project_type,
Expand Down
2 changes: 1 addition & 1 deletion src/superannotate/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "4.3.5dev17"
__version__ = "4.3.5dev23"
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def annotations_path(self):
return os.path.join(self.folder_path, self.ANNOTATIONS_PATH)

def test_video_annotation_upload(self):
# sa.create_annotation_classes_from_classes_json(self.PROJECT_NAME, self.classes_path)
sa.create_annotation_classes_from_classes_json(self.PROJECT_NAME, self.classes_path)

_, _, _ = sa.attach_items(
self.PROJECT_NAME,
Expand Down
9 changes: 3 additions & 6 deletions tests/unit/test_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@
import tempfile
from os.path import dirname
from unittest import TestCase
`from unittest.mock import patch
`
from pydantic import ValidationError
from unittest.mock import patch

from src.superannotate import SAClient
sa = SAClient()
from superannotate_schemas.validators import AnnotationValidators

from src.superannotate import SAClient

sa = SAClient()
VECTOR_ANNOTATION_JSON_WITH_BBOX = """
{
"metadata": {
Expand Down Expand Up @@ -1668,7 +1666,6 @@ def test_validate_video_point_labels(self, mock_print):
"instances[0].meta.pointLabels value is not a valid dict",
)


def test_validate_video_point_labels_bad_keys(self):
with tempfile.TemporaryDirectory() as tmpdir_name:
with open(f"{tmpdir_name}/test_validate_video_point_labels_bad_keys.json",
Expand Down
Loading