superannotate 4.4.27__tar.gz → 4.4.29.dev1__tar.gz
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.
- {superannotate-4.4.27/src/superannotate.egg-info → superannotate-4.4.29.dev1}/PKG-INFO +1 -1
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/__init__.py +3 -1
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/interface/sdk_interface.py +258 -7
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/__init__.py +1 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/enums.py +2 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/exceptions.py +6 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/service_types.py +4 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/serviceproviders.py +39 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/usecases/annotations.py +9 -47
- superannotate-4.4.29.dev1/src/superannotate/lib/core/utils.py +48 -0
- superannotate-4.4.29.dev1/src/superannotate/lib/infrastructure/annotation_adapter.py +120 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/infrastructure/controller.py +60 -1
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/infrastructure/services/annotation.py +89 -24
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/infrastructure/services/http_client.py +5 -4
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/infrastructure/services/item_service.py +1 -1
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/infrastructure/services/project.py +23 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1/src/superannotate.egg-info}/PKG-INFO +1 -1
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate.egg-info/SOURCES.txt +2 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/LICENSE +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/MANIFEST.in +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/README.rst +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/requirements.txt +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/setup.cfg +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/setup.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/__init__.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/__init__.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/analytics/__init__.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/analytics/aggregators.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/analytics/common.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/bin/__init__.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/bin/superannotate.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/common.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/exceptions.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/helpers.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/__init__.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/conversion.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/__init__.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/baseStrategy.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/coco_converters/__init__.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/coco_converters/coco_api.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/coco_converters/coco_converter.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/coco_converters/coco_strategies.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/coco_converters/coco_to_sa_pixel.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/coco_converters/coco_to_sa_vector.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/coco_converters/sa_pixel_to_coco.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/coco_converters/sa_vector_to_coco.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/converters.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/dataloop_converters/__init__.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/dataloop_converters/dataloop_helper.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/dataloop_converters/dataloop_strategies.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/dataloop_converters/dataloop_to_sa_vector.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/googlecloud_converters/__init__.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/googlecloud_converters/googlecloud_strategies.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/googlecloud_converters/googlecloud_to_sa_vector.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/labelbox_converters/__init__.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/labelbox_converters/labelbox_helper.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/labelbox_converters/labelbox_strategies.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/labelbox_converters/labelbox_to_sa_pixel.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/labelbox_converters/labelbox_to_sa_vector.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/sa_json_helper.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/sagemaker_converters/__init__.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/sagemaker_converters/sagemaker_strategies.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/sagemaker_converters/sagemaker_to_sa_pixel.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/sagemaker_converters/sagemaker_to_sa_vector.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/supervisely_converters/__init__.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/supervisely_converters/supervisely_helper.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/supervisely_converters/supervisely_strategies.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/supervisely_converters/supervisely_to_sa_pixel.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/supervisely_converters/supervisely_to_sa_vector.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/vgg_converters/__init__.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/vgg_converters/vgg_helper.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/vgg_converters/vgg_strategies.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/vgg_converters/vgg_to_sa_vector.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/voc_converters/__init__.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/voc_converters/voc_helper.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/voc_converters/voc_strategies.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/voc_converters/voc_to_sa_pixel.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/voc_converters/voc_to_sa_vector.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/vott_converters/__init__.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/vott_converters/vott_strategies.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/vott_converters/vott_to_sa_vector.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/yolo_converters/__init__.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/yolo_converters/yolo_strategies.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/converters/yolo_converters/yolo_to_sa_vector.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/export_from_sa_conversions.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/import_to_sa_conversions.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/input_converters/sa_conversion.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/interface/__init__.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/interface/base_interface.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/interface/cli_interface.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/interface/sdk/__init__.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/interface/sdk/folders.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/interface/sdk/project.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/interface/types.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/app/serializers.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/base_usecases.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/conditions.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/config.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/entities/__init__.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/entities/base.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/entities/classes.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/entities/folder.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/entities/integrations.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/entities/items.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/entities/project.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/entities/project_entities.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/jsx_conditions.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/plugin.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/pydantic_v1.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/reporter.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/repositories.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/response.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/types.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/usecases/__init__.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/usecases/base.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/usecases/classes.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/usecases/custom_fields.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/usecases/folders.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/usecases/images.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/usecases/integrations.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/usecases/items.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/usecases/models.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/usecases/projects.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/video_convertor.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/infrastructure/__init__.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/infrastructure/helpers.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/infrastructure/repositories.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/infrastructure/serviceprovider.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/infrastructure/services/__init__.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/infrastructure/services/annotation_class.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/infrastructure/services/explore.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/infrastructure/services/folder.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/infrastructure/services/integration.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/infrastructure/services/item.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/infrastructure/services/work_management.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/infrastructure/stream_data_handler.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/infrastructure/utils.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/infrastructure/validators.py +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate.egg-info/dependency_links.txt +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate.egg-info/entry_points.txt +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate.egg-info/requires.txt +0 -0
- {superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate.egg-info/top_level.txt +0 -0
|
@@ -3,7 +3,7 @@ import os
|
|
|
3
3
|
import sys
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
__version__ = "4.4.
|
|
6
|
+
__version__ = "4.4.29dev1"
|
|
7
7
|
|
|
8
8
|
os.environ.update({"sa_version": __version__})
|
|
9
9
|
sys.path.append(os.path.split(os.path.realpath(__file__))[0])
|
|
@@ -15,6 +15,7 @@ from lib.core import PACKAGE_VERSION_UPGRADE
|
|
|
15
15
|
from lib.core import PACKAGE_VERSION_INFO_MESSAGE
|
|
16
16
|
from lib.core import PACKAGE_VERSION_MAJOR_UPGRADE
|
|
17
17
|
from lib.core.exceptions import AppException
|
|
18
|
+
from lib.core.exceptions import FileChangedError
|
|
18
19
|
from superannotate.lib.app.input_converters import convert_project_type
|
|
19
20
|
from superannotate.lib.app.input_converters import export_annotation
|
|
20
21
|
from superannotate.lib.app.input_converters import import_annotation
|
|
@@ -30,6 +31,7 @@ __all__ = [
|
|
|
30
31
|
# Utils
|
|
31
32
|
"enums",
|
|
32
33
|
"AppException",
|
|
34
|
+
"FileChangedError",
|
|
33
35
|
"import_annotation",
|
|
34
36
|
"export_annotation",
|
|
35
37
|
"convert_project_type",
|
|
@@ -5,6 +5,7 @@ import json
|
|
|
5
5
|
import logging
|
|
6
6
|
import os
|
|
7
7
|
import sys
|
|
8
|
+
import typing
|
|
8
9
|
import warnings
|
|
9
10
|
from pathlib import Path
|
|
10
11
|
from typing import Any
|
|
@@ -28,11 +29,13 @@ import boto3
|
|
|
28
29
|
from tqdm import tqdm
|
|
29
30
|
|
|
30
31
|
import lib.core as constants
|
|
32
|
+
from lib.infrastructure.controller import Controller
|
|
31
33
|
from lib.app.helpers import get_annotation_paths
|
|
32
34
|
from lib.app.helpers import get_name_url_duplicated_from_csv
|
|
33
35
|
from lib.app.helpers import wrap_error as wrap_validation_errors
|
|
34
36
|
from lib.app.interface.base_interface import BaseInterfaceFacade
|
|
35
37
|
from lib.app.interface.base_interface import TrackableMeta
|
|
38
|
+
|
|
36
39
|
from lib.app.interface.types import EmailStr
|
|
37
40
|
from lib.app.serializers import BaseSerializer
|
|
38
41
|
from lib.app.serializers import FolderSerializer
|
|
@@ -45,7 +48,7 @@ from lib.core.conditions import CONDITION_EQ as EQ
|
|
|
45
48
|
from lib.core.conditions import Condition
|
|
46
49
|
from lib.core.jsx_conditions import Filter, OperatorEnum
|
|
47
50
|
from lib.core.conditions import EmptyCondition
|
|
48
|
-
from lib.core.entities import AttachmentEntity
|
|
51
|
+
from lib.core.entities import AttachmentEntity, FolderEntity, BaseItemEntity
|
|
49
52
|
from lib.core.entities import SettingEntity
|
|
50
53
|
from lib.core.entities.classes import AnnotationClassEntity
|
|
51
54
|
from lib.core.entities.classes import AttributeGroup
|
|
@@ -61,6 +64,9 @@ from lib.core.pydantic_v1 import ValidationError
|
|
|
61
64
|
from lib.core.pydantic_v1 import constr
|
|
62
65
|
from lib.core.pydantic_v1 import conlist
|
|
63
66
|
from lib.core.pydantic_v1 import parse_obj_as
|
|
67
|
+
from lib.infrastructure.annotation_adapter import BaseMultimodalAnnotationAdapter
|
|
68
|
+
from lib.infrastructure.annotation_adapter import MultimodalSmallAnnotationAdapter
|
|
69
|
+
from lib.infrastructure.annotation_adapter import MultimodalLargeAnnotationAdapter
|
|
64
70
|
from lib.infrastructure.utils import extract_project_folder
|
|
65
71
|
from lib.infrastructure.validators import wrap_error
|
|
66
72
|
|
|
@@ -69,7 +75,6 @@ logger = logging.getLogger("sa")
|
|
|
69
75
|
# NotEmptyStr = TypeVar("NotEmptyStr", bound=constr(strict=True, min_length=1))
|
|
70
76
|
NotEmptyStr = constr(strict=True, min_length=1)
|
|
71
77
|
|
|
72
|
-
|
|
73
78
|
PROJECT_STATUS = Literal["NotStarted", "InProgress", "Completed", "OnHold"]
|
|
74
79
|
|
|
75
80
|
PROJECT_TYPE = Literal[
|
|
@@ -82,7 +87,6 @@ PROJECT_TYPE = Literal[
|
|
|
82
87
|
"Multimodal",
|
|
83
88
|
]
|
|
84
89
|
|
|
85
|
-
|
|
86
90
|
APPROVAL_STATUS = Literal["Approved", "Disapproved", None]
|
|
87
91
|
|
|
88
92
|
IMAGE_QUALITY = Literal["compressed", "original"]
|
|
@@ -110,6 +114,87 @@ class Attachment(TypedDict, total=False):
|
|
|
110
114
|
integration: NotRequired[str] # noqa
|
|
111
115
|
|
|
112
116
|
|
|
117
|
+
class ItemContext:
|
|
118
|
+
def __init__(
|
|
119
|
+
self,
|
|
120
|
+
controller: Controller,
|
|
121
|
+
project: Project,
|
|
122
|
+
folder: FolderEntity,
|
|
123
|
+
item: BaseItemEntity,
|
|
124
|
+
overwrite: bool = True,
|
|
125
|
+
):
|
|
126
|
+
self.controller = controller
|
|
127
|
+
self.project = project
|
|
128
|
+
self.folder = folder
|
|
129
|
+
self.item = item
|
|
130
|
+
self._annotation_adapter: Optional[BaseMultimodalAnnotationAdapter] = None
|
|
131
|
+
self._overwrite = overwrite
|
|
132
|
+
self._annotation = None
|
|
133
|
+
|
|
134
|
+
def _set_small_annotation_adapter(self, annotation: dict = None):
|
|
135
|
+
self._annotation_adapter = MultimodalSmallAnnotationAdapter(
|
|
136
|
+
project=self.project,
|
|
137
|
+
folder=self.folder,
|
|
138
|
+
item=self.item,
|
|
139
|
+
controller=self.controller,
|
|
140
|
+
overwrite=self._overwrite,
|
|
141
|
+
annotation=annotation,
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
def _set_large_annotation_adapter(self, annotation: dict = None):
|
|
145
|
+
self._annotation_adapter = MultimodalLargeAnnotationAdapter(
|
|
146
|
+
project=self.project,
|
|
147
|
+
folder=self.folder,
|
|
148
|
+
item=self.item,
|
|
149
|
+
controller=self.controller,
|
|
150
|
+
annotation=annotation,
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
@property
|
|
154
|
+
def annotation_adapter(self) -> BaseMultimodalAnnotationAdapter:
|
|
155
|
+
if self._annotation_adapter is None:
|
|
156
|
+
res = self.controller.service_provider.annotations.get_upload_chunks(
|
|
157
|
+
project=self.project, item_ids=[self.item.id]
|
|
158
|
+
)
|
|
159
|
+
small_item = next(iter(res["small"]), None)
|
|
160
|
+
if small_item:
|
|
161
|
+
self._set_small_annotation_adapter()
|
|
162
|
+
else:
|
|
163
|
+
self._set_large_annotation_adapter()
|
|
164
|
+
return self._annotation_adapter
|
|
165
|
+
|
|
166
|
+
@property
|
|
167
|
+
def annotation(self):
|
|
168
|
+
return self.annotation_adapter.annotation
|
|
169
|
+
|
|
170
|
+
def __enter__(self):
|
|
171
|
+
return self
|
|
172
|
+
|
|
173
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
174
|
+
if exc_type:
|
|
175
|
+
return False
|
|
176
|
+
|
|
177
|
+
self.save()
|
|
178
|
+
return True
|
|
179
|
+
|
|
180
|
+
def save(self):
|
|
181
|
+
if len(json.dumps(self.annotation).encode("utf-8")) > 16 * 1024 * 1024:
|
|
182
|
+
self._set_large_annotation_adapter(self.annotation)
|
|
183
|
+
else:
|
|
184
|
+
self._set_small_annotation_adapter(self.annotation)
|
|
185
|
+
self._annotation_adapter.save()
|
|
186
|
+
|
|
187
|
+
def get_metadata(self):
|
|
188
|
+
return self.annotation["metadata"]
|
|
189
|
+
|
|
190
|
+
def get_component_value(self, component_id: str):
|
|
191
|
+
return self.annotation_adapter.get_component_value(component_id)
|
|
192
|
+
|
|
193
|
+
def set_component_value(self, component_id: str, value: Any):
|
|
194
|
+
self.annotation_adapter.set_component_value(component_id, value)
|
|
195
|
+
return self
|
|
196
|
+
|
|
197
|
+
|
|
113
198
|
class SAClient(BaseInterfaceFacade, metaclass=TrackableMeta):
|
|
114
199
|
"""Create SAClient instance to authorize SDK in a team scope.
|
|
115
200
|
In case of no argument has been provided, SA_TOKEN environmental variable
|
|
@@ -193,6 +278,55 @@ class SAClient(BaseInterfaceFacade, metaclass=TrackableMeta):
|
|
|
193
278
|
response = self.controller.get_team()
|
|
194
279
|
return TeamSerializer(response.data).serialize()
|
|
195
280
|
|
|
281
|
+
def get_component_config(self, project: Union[NotEmptyStr, int], component_id: str):
|
|
282
|
+
"""
|
|
283
|
+
Retrieves the configuration for a given project and component ID.
|
|
284
|
+
|
|
285
|
+
:param project: The identifier of the project, which can be a string or an integer representing the project ID.
|
|
286
|
+
:type project: Union[str, int]
|
|
287
|
+
|
|
288
|
+
:param component_id: The ID of the component for which the context is to be retrieved.
|
|
289
|
+
:type component_id: str
|
|
290
|
+
|
|
291
|
+
:return: The context associated with the `webComponent`.
|
|
292
|
+
:rtype: Any
|
|
293
|
+
|
|
294
|
+
:raises AppException: If the project type is not `MULTIMODAL` or no `webComponent` context is found.
|
|
295
|
+
"""
|
|
296
|
+
|
|
297
|
+
def retrieve_context(
|
|
298
|
+
component_data: List[dict], component_pk: str
|
|
299
|
+
) -> Tuple[bool, typing.Any]:
|
|
300
|
+
for component in component_data:
|
|
301
|
+
if (
|
|
302
|
+
component["type"] == "webComponent"
|
|
303
|
+
and component["id"] == component_pk
|
|
304
|
+
):
|
|
305
|
+
return True, component.get("context")
|
|
306
|
+
if component["type"] == "group" and "children" in component:
|
|
307
|
+
found, val = retrieve_context(component["children"], component_pk)
|
|
308
|
+
if found:
|
|
309
|
+
return found, val
|
|
310
|
+
return False, None
|
|
311
|
+
|
|
312
|
+
project = (
|
|
313
|
+
self.controller.get_project_by_id(project).data
|
|
314
|
+
if isinstance(project, int)
|
|
315
|
+
else self.controller.get_project(project)
|
|
316
|
+
)
|
|
317
|
+
if project.type != ProjectType.MULTIMODAL:
|
|
318
|
+
raise AppException(
|
|
319
|
+
"This function is only supported for Multimodal projects."
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
editor_template = self.controller.projects.get_editor_template(project)
|
|
323
|
+
components = editor_template.get("components", [])
|
|
324
|
+
|
|
325
|
+
_found, _context = retrieve_context(components, component_id)
|
|
326
|
+
if not _found:
|
|
327
|
+
raise AppException("No component context found for project.")
|
|
328
|
+
return _context
|
|
329
|
+
|
|
196
330
|
def search_team_contributors(
|
|
197
331
|
self,
|
|
198
332
|
email: EmailStr = None,
|
|
@@ -2616,7 +2750,7 @@ class SAClient(BaseInterfaceFacade, metaclass=TrackableMeta):
|
|
|
2616
2750
|
]
|
|
2617
2751
|
"""
|
|
2618
2752
|
project, folder = self.controller.get_project_folder_by_path(project)
|
|
2619
|
-
query_kwargs = {}
|
|
2753
|
+
query_kwargs = {"include": ["assignments"]}
|
|
2620
2754
|
if name_contains:
|
|
2621
2755
|
query_kwargs["name__contains"] = name_contains
|
|
2622
2756
|
if annotation_status:
|
|
@@ -2634,7 +2768,9 @@ class SAClient(BaseInterfaceFacade, metaclass=TrackableMeta):
|
|
|
2634
2768
|
f"{project.name}{f'/{folder.name}' if not folder.is_root else ''}"
|
|
2635
2769
|
)
|
|
2636
2770
|
_items = self.controller.items.list_items(
|
|
2637
|
-
project,
|
|
2771
|
+
project,
|
|
2772
|
+
folder,
|
|
2773
|
+
**query_kwargs,
|
|
2638
2774
|
)
|
|
2639
2775
|
for i in _items:
|
|
2640
2776
|
i.path = path
|
|
@@ -2780,7 +2916,10 @@ class SAClient(BaseInterfaceFacade, metaclass=TrackableMeta):
|
|
|
2780
2916
|
).data
|
|
2781
2917
|
else:
|
|
2782
2918
|
folder = self.controller.get_folder(project, folder)
|
|
2783
|
-
|
|
2919
|
+
_include = {"assignments"}
|
|
2920
|
+
if include:
|
|
2921
|
+
_include.update(set(include))
|
|
2922
|
+
include = list(_include)
|
|
2784
2923
|
include_custom_metadata = "custom_metadata" in include
|
|
2785
2924
|
if include_custom_metadata:
|
|
2786
2925
|
include.remove("custom_metadata")
|
|
@@ -2792,7 +2931,7 @@ class SAClient(BaseInterfaceFacade, metaclass=TrackableMeta):
|
|
|
2792
2931
|
project=project, item_ids=[i.id for i in res]
|
|
2793
2932
|
)
|
|
2794
2933
|
for i in res:
|
|
2795
|
-
i
|
|
2934
|
+
i.custom_metadata = item_custom_fields[i.id]
|
|
2796
2935
|
exclude = {"meta", "annotator_email", "qa_email"}
|
|
2797
2936
|
if include:
|
|
2798
2937
|
if "custom_metadata" not in include:
|
|
@@ -3540,3 +3679,115 @@ class SAClient(BaseInterfaceFacade, metaclass=TrackableMeta):
|
|
|
3540
3679
|
)
|
|
3541
3680
|
if response.errors:
|
|
3542
3681
|
raise AppException(response.errors)
|
|
3682
|
+
|
|
3683
|
+
def item_context(
|
|
3684
|
+
self,
|
|
3685
|
+
path: Union[str, Tuple[NotEmptyStr, NotEmptyStr], Tuple[int, int]],
|
|
3686
|
+
item: Union[NotEmptyStr, int],
|
|
3687
|
+
overwrite: bool = True,
|
|
3688
|
+
) -> ItemContext:
|
|
3689
|
+
"""
|
|
3690
|
+
Creates an “ItemContext” for managing item annotations and metadata.
|
|
3691
|
+
|
|
3692
|
+
This function allows you to manage annotations and metadata for an item located within a
|
|
3693
|
+
specified project and folder. The path to the item can be provided either as a string or a tuple,
|
|
3694
|
+
and you can specify the item using its name or ID.
|
|
3695
|
+
It returns an “ItemContext” that automatically saves any changes to annotations when the context is exited.
|
|
3696
|
+
|
|
3697
|
+
:param path: Specifies the project and folder containing the item. Can be one of:
|
|
3698
|
+
- A string path, e.g., "project_name/folder_name".
|
|
3699
|
+
- A tuple of strings, e.g., ("project_name", "folder_name").
|
|
3700
|
+
- A tuple of integers (IDs), e.g., (project_id, folder_id).
|
|
3701
|
+
:type path: Union[str, Tuple[str, str], Tuple[int, int]]
|
|
3702
|
+
|
|
3703
|
+
:param item: The name or ID of the item for which the context is being created.
|
|
3704
|
+
:type item: Union[str, int]
|
|
3705
|
+
|
|
3706
|
+
:param overwrite: If `True`, annotations are overwritten during saving. Defaults is `True`.
|
|
3707
|
+
If `False`, raises a `FileChangedError` if the item was modified concurrently.
|
|
3708
|
+
:type overwrite: bool
|
|
3709
|
+
|
|
3710
|
+
:raises AppException: If the provided `path` is invalid or if the item cannot be located.
|
|
3711
|
+
|
|
3712
|
+
:return: An `ItemContext` object to manage the specified item's annotations and metadata.
|
|
3713
|
+
:rtype: ItemContext
|
|
3714
|
+
|
|
3715
|
+
**Examples:**
|
|
3716
|
+
|
|
3717
|
+
Create an `ItemContext` using a string path and item name:
|
|
3718
|
+
|
|
3719
|
+
.. code-block:: python
|
|
3720
|
+
|
|
3721
|
+
with client.item_context("project_name/folder_name", "item_name") as item_context:
|
|
3722
|
+
metadata = item_context.get_metadata()
|
|
3723
|
+
value = item_context.get_component_value("prompts")
|
|
3724
|
+
item_context.set_component_value("prompts", value)
|
|
3725
|
+
|
|
3726
|
+
Create an `ItemContext` using a tuple of strings and an item ID:
|
|
3727
|
+
|
|
3728
|
+
.. code-block:: python
|
|
3729
|
+
|
|
3730
|
+
with client.item_context(("project_name", "folder_name"), 12345) as context:
|
|
3731
|
+
metadata = context.get_metadata()
|
|
3732
|
+
print(metadata)
|
|
3733
|
+
|
|
3734
|
+
Create an `ItemContext` using a tuple of IDs and an item name:
|
|
3735
|
+
|
|
3736
|
+
.. code-block:: python
|
|
3737
|
+
|
|
3738
|
+
with client.item_context((101, 202), "item_name") as context:
|
|
3739
|
+
value = context.get_component_value("component_id")
|
|
3740
|
+
print(value)
|
|
3741
|
+
|
|
3742
|
+
Save annotations automatically after modifying component values:
|
|
3743
|
+
|
|
3744
|
+
.. code-block:: python
|
|
3745
|
+
|
|
3746
|
+
with client.item_context("project_name/folder_name", "item_name", overwrite=True) as context:
|
|
3747
|
+
context.set_component_value("component_id", "new_value")
|
|
3748
|
+
# No need to call .save(), changes are saved automatically on context exit.
|
|
3749
|
+
|
|
3750
|
+
Handle exceptions during context execution:
|
|
3751
|
+
|
|
3752
|
+
.. code-block:: python
|
|
3753
|
+
|
|
3754
|
+
from superannotate import FileChangedError
|
|
3755
|
+
|
|
3756
|
+
try:
|
|
3757
|
+
with client.item_context((101, 202), "item_name") as context:
|
|
3758
|
+
context.set_component_value("component_id", "new_value")
|
|
3759
|
+
except FileChangedError as e:
|
|
3760
|
+
print(f"An error occurred: {e}")
|
|
3761
|
+
"""
|
|
3762
|
+
if isinstance(path, str):
|
|
3763
|
+
project, folder = self.controller.get_project_folder_by_path(path)
|
|
3764
|
+
elif len(path) == 2 and all([isinstance(i, str) for i in path]):
|
|
3765
|
+
project = self.controller.get_project(path[0])
|
|
3766
|
+
folder = self.controller.get_folder(project, path[1])
|
|
3767
|
+
elif len(path) == 2 and all([isinstance(i, int) for i in path]):
|
|
3768
|
+
project = self.controller.get_project_by_id(path[0]).data
|
|
3769
|
+
folder = self.controller.get_folder_by_id(path[1], project.id).data
|
|
3770
|
+
else:
|
|
3771
|
+
raise AppException("Invalid path provided.")
|
|
3772
|
+
if project.type != ProjectType.MULTIMODAL:
|
|
3773
|
+
raise AppException(
|
|
3774
|
+
"This function is only supported for Multimodal projects."
|
|
3775
|
+
)
|
|
3776
|
+
if isinstance(item, int):
|
|
3777
|
+
_item = self.controller.get_item_by_id(item_id=item, project=project)
|
|
3778
|
+
else:
|
|
3779
|
+
items = self.controller.items.list_items(project, folder, name=item)
|
|
3780
|
+
if not items:
|
|
3781
|
+
raise AppException("Item not found.")
|
|
3782
|
+
_item = items[0]
|
|
3783
|
+
if project.type != ProjectType.MULTIMODAL:
|
|
3784
|
+
raise AppException(
|
|
3785
|
+
f"The function is not supported for {project.type.name} projects."
|
|
3786
|
+
)
|
|
3787
|
+
return ItemContext(
|
|
3788
|
+
controller=self.controller,
|
|
3789
|
+
project=project,
|
|
3790
|
+
folder=folder,
|
|
3791
|
+
item=_item,
|
|
3792
|
+
overwrite=overwrite,
|
|
3793
|
+
)
|
{superannotate-4.4.27 → superannotate-4.4.29.dev1}/src/superannotate/lib/core/serviceproviders.py
RENAMED
|
@@ -97,6 +97,18 @@ class BaseProjectService(SuperannotateServiceProvider):
|
|
|
97
97
|
def create(self, entity: entities.ProjectEntity) -> ProjectResponse:
|
|
98
98
|
raise NotImplementedError
|
|
99
99
|
|
|
100
|
+
@abstractmethod
|
|
101
|
+
def attach_editor_template(
|
|
102
|
+
self, team: entities.TeamEntity, project: entities.ProjectEntity, template: dict
|
|
103
|
+
) -> ServiceResponse:
|
|
104
|
+
raise NotImplementedError
|
|
105
|
+
|
|
106
|
+
@abstractmethod
|
|
107
|
+
def get_editor_template(
|
|
108
|
+
self, team: entities.TeamEntity, project: entities.ProjectEntity
|
|
109
|
+
) -> ServiceResponse:
|
|
110
|
+
raise NotImplementedError
|
|
111
|
+
|
|
100
112
|
@abstractmethod
|
|
101
113
|
def list(self, condition: Condition = None) -> ProjectListResponse:
|
|
102
114
|
raise NotImplementedError
|
|
@@ -346,6 +358,7 @@ class BaseAnnotationService(SuperannotateServiceProvider):
|
|
|
346
358
|
project: entities.ProjectEntity,
|
|
347
359
|
item: entities.BaseItemEntity,
|
|
348
360
|
reporter: Reporter,
|
|
361
|
+
transform_version: str = None,
|
|
349
362
|
) -> dict:
|
|
350
363
|
raise NotImplementedError
|
|
351
364
|
|
|
@@ -357,6 +370,7 @@ class BaseAnnotationService(SuperannotateServiceProvider):
|
|
|
357
370
|
item_ids: List[int],
|
|
358
371
|
reporter: Reporter,
|
|
359
372
|
callback: Callable = None,
|
|
373
|
+
transform_version: str = None,
|
|
360
374
|
) -> List[dict]:
|
|
361
375
|
raise NotImplementedError
|
|
362
376
|
|
|
@@ -396,6 +410,7 @@ class BaseAnnotationService(SuperannotateServiceProvider):
|
|
|
396
410
|
project: entities.ProjectEntity,
|
|
397
411
|
folder: entities.FolderEntity,
|
|
398
412
|
items_name_data_map: Dict[str, dict],
|
|
413
|
+
transform_version: str = None,
|
|
399
414
|
) -> UploadAnnotationsResponse:
|
|
400
415
|
raise NotImplementedError
|
|
401
416
|
|
|
@@ -407,6 +422,7 @@ class BaseAnnotationService(SuperannotateServiceProvider):
|
|
|
407
422
|
item_id: int,
|
|
408
423
|
data: io.StringIO,
|
|
409
424
|
chunk_size: int,
|
|
425
|
+
transform_version: str = None,
|
|
410
426
|
) -> bool:
|
|
411
427
|
raise NotImplementedError
|
|
412
428
|
|
|
@@ -429,6 +445,29 @@ class BaseAnnotationService(SuperannotateServiceProvider):
|
|
|
429
445
|
def get_schema(self, project_type: int, version: str) -> ServiceResponse:
|
|
430
446
|
raise NotImplementedError
|
|
431
447
|
|
|
448
|
+
@abstractmethod
|
|
449
|
+
def get_item_annotations(
|
|
450
|
+
self,
|
|
451
|
+
project: entities.ProjectEntity,
|
|
452
|
+
folder: entities.FolderEntity,
|
|
453
|
+
item_id: int,
|
|
454
|
+
transform_version: str = "llmJsonV2",
|
|
455
|
+
) -> ServiceResponse:
|
|
456
|
+
raise NotImplementedError
|
|
457
|
+
|
|
458
|
+
@abstractmethod
|
|
459
|
+
def set_item_annotations(
|
|
460
|
+
self,
|
|
461
|
+
project: entities.ProjectEntity,
|
|
462
|
+
folder: entities.FolderEntity,
|
|
463
|
+
item_id: int,
|
|
464
|
+
data: dict,
|
|
465
|
+
overwrite: bool,
|
|
466
|
+
transform_version: str = "llmJsonV2",
|
|
467
|
+
etag: str = None,
|
|
468
|
+
) -> ServiceResponse:
|
|
469
|
+
raise NotImplementedError
|
|
470
|
+
|
|
432
471
|
|
|
433
472
|
class BaseIntegrationService(SuperannotateServiceProvider):
|
|
434
473
|
@abstractmethod
|
|
@@ -9,12 +9,10 @@ import platform
|
|
|
9
9
|
import re
|
|
10
10
|
import time
|
|
11
11
|
import traceback
|
|
12
|
-
import typing
|
|
13
12
|
from dataclasses import dataclass
|
|
14
13
|
from itertools import islice
|
|
15
14
|
from operator import itemgetter
|
|
16
15
|
from pathlib import Path
|
|
17
|
-
from threading import Thread
|
|
18
16
|
from typing import Any
|
|
19
17
|
from typing import Callable
|
|
20
18
|
from typing import Dict
|
|
@@ -48,6 +46,7 @@ from lib.core.serviceproviders import ServiceResponse
|
|
|
48
46
|
from lib.core.serviceproviders import UploadAnnotationsResponse
|
|
49
47
|
from lib.core.types import PriorityScoreEntity
|
|
50
48
|
from lib.core.usecases.base import BaseReportableUseCase
|
|
49
|
+
from lib.core.utils import run_async
|
|
51
50
|
from lib.core.video_convertor import VideoFrameGenerator
|
|
52
51
|
from lib.infrastructure.utils import divide_to_chunks
|
|
53
52
|
|
|
@@ -66,51 +65,6 @@ ANNOTATION_CHUNK_SIZE_MB = 10 * 1024 * 1024
|
|
|
66
65
|
URI_THRESHOLD = 4 * 1024 - 120
|
|
67
66
|
|
|
68
67
|
|
|
69
|
-
class AsyncThread(Thread):
|
|
70
|
-
def __init__(
|
|
71
|
-
self, group=None, target=None, name=None, args=(), kwargs=None, *, daemon=None
|
|
72
|
-
):
|
|
73
|
-
super().__init__(
|
|
74
|
-
group=group,
|
|
75
|
-
target=target,
|
|
76
|
-
name=name,
|
|
77
|
-
args=args,
|
|
78
|
-
kwargs=kwargs,
|
|
79
|
-
daemon=daemon,
|
|
80
|
-
)
|
|
81
|
-
self._exc = None
|
|
82
|
-
self._response = None
|
|
83
|
-
|
|
84
|
-
@property
|
|
85
|
-
def response(self):
|
|
86
|
-
return self._response
|
|
87
|
-
|
|
88
|
-
def run(self):
|
|
89
|
-
try:
|
|
90
|
-
self._response = super().run()
|
|
91
|
-
except BaseException as e:
|
|
92
|
-
self._exc = e
|
|
93
|
-
|
|
94
|
-
def join(self, timeout=None) -> typing.Any:
|
|
95
|
-
Thread.join(self, timeout=timeout)
|
|
96
|
-
if self._exc:
|
|
97
|
-
raise self._exc
|
|
98
|
-
return self._response
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
def run_async(f):
|
|
102
|
-
response = [None]
|
|
103
|
-
|
|
104
|
-
def wrapper(func: typing.Callable):
|
|
105
|
-
response[0] = asyncio.run(func) # noqa
|
|
106
|
-
return response[0]
|
|
107
|
-
|
|
108
|
-
thread = AsyncThread(target=wrapper, args=(f,))
|
|
109
|
-
thread.start()
|
|
110
|
-
thread.join()
|
|
111
|
-
return response[0]
|
|
112
|
-
|
|
113
|
-
|
|
114
68
|
@dataclass
|
|
115
69
|
class Report:
|
|
116
70
|
failed_annotations: list
|
|
@@ -188,6 +142,7 @@ async def upload_small_annotations(
|
|
|
188
142
|
reporter: Reporter,
|
|
189
143
|
report: Report,
|
|
190
144
|
callback: Callable = None,
|
|
145
|
+
transform_version: str = None,
|
|
191
146
|
):
|
|
192
147
|
async def upload(_chunk: List[ItemToUpload]):
|
|
193
148
|
failed_annotations, missing_classes, missing_attr_groups, missing_attrs = (
|
|
@@ -204,6 +159,7 @@ async def upload_small_annotations(
|
|
|
204
159
|
project=project,
|
|
205
160
|
folder=folder,
|
|
206
161
|
items_name_data_map=items_name_data_map,
|
|
162
|
+
transform_version=transform_version,
|
|
207
163
|
)
|
|
208
164
|
if response.ok:
|
|
209
165
|
if response.data.failed_items: # noqa
|
|
@@ -304,6 +260,7 @@ class UploadAnnotationsUseCase(BaseReportableUseCase):
|
|
|
304
260
|
service_provider: BaseServiceProvider,
|
|
305
261
|
user: UserEntity,
|
|
306
262
|
keep_status: bool = False,
|
|
263
|
+
transform_version: str = None,
|
|
307
264
|
):
|
|
308
265
|
super().__init__(reporter)
|
|
309
266
|
self._project = project
|
|
@@ -313,6 +270,7 @@ class UploadAnnotationsUseCase(BaseReportableUseCase):
|
|
|
313
270
|
self._keep_status = keep_status
|
|
314
271
|
self._report = Report([], [], [], [])
|
|
315
272
|
self._user = user
|
|
273
|
+
self._transform_version = transform_version
|
|
316
274
|
|
|
317
275
|
def validate_project_type(self):
|
|
318
276
|
if self._project.type == constants.ProjectType.PIXEL.value:
|
|
@@ -420,6 +378,7 @@ class UploadAnnotationsUseCase(BaseReportableUseCase):
|
|
|
420
378
|
service_provider=self._service_provider,
|
|
421
379
|
reporter=self.reporter,
|
|
422
380
|
report=self._report,
|
|
381
|
+
transform_version=self._transform_version,
|
|
423
382
|
)
|
|
424
383
|
)
|
|
425
384
|
|
|
@@ -1474,6 +1433,7 @@ class GetAnnotations(BaseReportableUseCase):
|
|
|
1474
1433
|
service_provider: BaseServiceProvider,
|
|
1475
1434
|
folder: FolderEntity = None,
|
|
1476
1435
|
items: Optional[Union[List[str], List[int]]] = None,
|
|
1436
|
+
transform_version: str = None,
|
|
1477
1437
|
):
|
|
1478
1438
|
super().__init__(reporter)
|
|
1479
1439
|
self._config = config
|
|
@@ -1484,6 +1444,7 @@ class GetAnnotations(BaseReportableUseCase):
|
|
|
1484
1444
|
self._item_id_name_map = {}
|
|
1485
1445
|
self._item_names_provided = True
|
|
1486
1446
|
self._big_annotations_queue = None
|
|
1447
|
+
self._transform_version = transform_version
|
|
1487
1448
|
|
|
1488
1449
|
def validate_project_type(self):
|
|
1489
1450
|
if self._project.type == constants.ProjectType.PIXEL.value:
|
|
@@ -1548,6 +1509,7 @@ class GetAnnotations(BaseReportableUseCase):
|
|
|
1548
1509
|
folder=self._folder,
|
|
1549
1510
|
item_ids=item_ids,
|
|
1550
1511
|
reporter=self.reporter,
|
|
1512
|
+
transform_version=self._transform_version,
|
|
1551
1513
|
)
|
|
1552
1514
|
|
|
1553
1515
|
async def run_workers(
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import typing
|
|
3
|
+
from threading import Thread
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class AsyncThread(Thread):
|
|
7
|
+
def __init__(
|
|
8
|
+
self, group=None, target=None, name=None, args=(), kwargs=None, *, daemon=None
|
|
9
|
+
):
|
|
10
|
+
super().__init__(
|
|
11
|
+
group=group,
|
|
12
|
+
target=target,
|
|
13
|
+
name=name,
|
|
14
|
+
args=args,
|
|
15
|
+
kwargs=kwargs,
|
|
16
|
+
daemon=daemon,
|
|
17
|
+
)
|
|
18
|
+
self._exc = None
|
|
19
|
+
self._response = None
|
|
20
|
+
|
|
21
|
+
@property
|
|
22
|
+
def response(self):
|
|
23
|
+
return self._response
|
|
24
|
+
|
|
25
|
+
def run(self):
|
|
26
|
+
try:
|
|
27
|
+
self._response = super().run()
|
|
28
|
+
except BaseException as e:
|
|
29
|
+
self._exc = e
|
|
30
|
+
|
|
31
|
+
def join(self, timeout=None) -> typing.Any:
|
|
32
|
+
Thread.join(self, timeout=timeout)
|
|
33
|
+
if self._exc:
|
|
34
|
+
raise self._exc
|
|
35
|
+
return self._response
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def run_async(f):
|
|
39
|
+
response = [None]
|
|
40
|
+
|
|
41
|
+
def wrapper(func: typing.Callable):
|
|
42
|
+
response[0] = asyncio.run(func) # noqa
|
|
43
|
+
return response[0]
|
|
44
|
+
|
|
45
|
+
thread = AsyncThread(target=wrapper, args=(f,))
|
|
46
|
+
thread.start()
|
|
47
|
+
thread.join()
|
|
48
|
+
return response[0]
|