superannotate 4.4.26.dev1__tar.gz → 4.4.28__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.
Files changed (143) hide show
  1. {superannotate-4.4.26.dev1/src/superannotate.egg-info → superannotate-4.4.28}/PKG-INFO +1 -1
  2. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/__init__.py +6 -4
  3. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/interface/sdk_interface.py +205 -22
  4. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/__init__.py +1 -0
  5. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/enums.py +2 -0
  6. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/exceptions.py +6 -0
  7. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/jsx_conditions.py +12 -0
  8. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/service_types.py +4 -0
  9. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/serviceproviders.py +39 -0
  10. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/usecases/annotations.py +23 -76
  11. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/usecases/images.py +12 -24
  12. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/usecases/items.py +32 -50
  13. superannotate-4.4.28/src/superannotate/lib/core/utils.py +48 -0
  14. superannotate-4.4.28/src/superannotate/lib/infrastructure/annotation_adapter.py +120 -0
  15. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/infrastructure/controller.py +50 -6
  16. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/infrastructure/services/annotation.py +89 -24
  17. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/infrastructure/services/http_client.py +5 -4
  18. superannotate-4.4.28/src/superannotate/lib/infrastructure/services/item_service.py +143 -0
  19. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/infrastructure/services/project.py +23 -0
  20. {superannotate-4.4.26.dev1 → superannotate-4.4.28/src/superannotate.egg-info}/PKG-INFO +1 -1
  21. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate.egg-info/SOURCES.txt +2 -0
  22. superannotate-4.4.26.dev1/src/superannotate/lib/infrastructure/services/item_service.py +0 -46
  23. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/LICENSE +0 -0
  24. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/MANIFEST.in +0 -0
  25. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/README.rst +0 -0
  26. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/requirements.txt +0 -0
  27. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/setup.cfg +0 -0
  28. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/setup.py +0 -0
  29. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/__init__.py +0 -0
  30. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/__init__.py +0 -0
  31. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/analytics/__init__.py +0 -0
  32. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/analytics/aggregators.py +0 -0
  33. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/analytics/common.py +0 -0
  34. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/bin/__init__.py +0 -0
  35. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/bin/superannotate.py +0 -0
  36. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/common.py +0 -0
  37. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/exceptions.py +0 -0
  38. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/helpers.py +0 -0
  39. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/__init__.py +0 -0
  40. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/conversion.py +0 -0
  41. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/__init__.py +0 -0
  42. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/baseStrategy.py +0 -0
  43. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/coco_converters/__init__.py +0 -0
  44. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/coco_converters/coco_api.py +0 -0
  45. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/coco_converters/coco_converter.py +0 -0
  46. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/coco_converters/coco_strategies.py +0 -0
  47. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/coco_converters/coco_to_sa_pixel.py +0 -0
  48. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/coco_converters/coco_to_sa_vector.py +0 -0
  49. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/coco_converters/sa_pixel_to_coco.py +0 -0
  50. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/coco_converters/sa_vector_to_coco.py +0 -0
  51. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/converters.py +0 -0
  52. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/dataloop_converters/__init__.py +0 -0
  53. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/dataloop_converters/dataloop_helper.py +0 -0
  54. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/dataloop_converters/dataloop_strategies.py +0 -0
  55. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/dataloop_converters/dataloop_to_sa_vector.py +0 -0
  56. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/googlecloud_converters/__init__.py +0 -0
  57. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/googlecloud_converters/googlecloud_strategies.py +0 -0
  58. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/googlecloud_converters/googlecloud_to_sa_vector.py +0 -0
  59. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/labelbox_converters/__init__.py +0 -0
  60. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/labelbox_converters/labelbox_helper.py +0 -0
  61. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/labelbox_converters/labelbox_strategies.py +0 -0
  62. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/labelbox_converters/labelbox_to_sa_pixel.py +0 -0
  63. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/labelbox_converters/labelbox_to_sa_vector.py +0 -0
  64. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/sa_json_helper.py +0 -0
  65. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/sagemaker_converters/__init__.py +0 -0
  66. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/sagemaker_converters/sagemaker_strategies.py +0 -0
  67. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/sagemaker_converters/sagemaker_to_sa_pixel.py +0 -0
  68. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/sagemaker_converters/sagemaker_to_sa_vector.py +0 -0
  69. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/supervisely_converters/__init__.py +0 -0
  70. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/supervisely_converters/supervisely_helper.py +0 -0
  71. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/supervisely_converters/supervisely_strategies.py +0 -0
  72. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/supervisely_converters/supervisely_to_sa_pixel.py +0 -0
  73. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/supervisely_converters/supervisely_to_sa_vector.py +0 -0
  74. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/vgg_converters/__init__.py +0 -0
  75. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/vgg_converters/vgg_helper.py +0 -0
  76. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/vgg_converters/vgg_strategies.py +0 -0
  77. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/vgg_converters/vgg_to_sa_vector.py +0 -0
  78. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/voc_converters/__init__.py +0 -0
  79. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/voc_converters/voc_helper.py +0 -0
  80. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/voc_converters/voc_strategies.py +0 -0
  81. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/voc_converters/voc_to_sa_pixel.py +0 -0
  82. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/voc_converters/voc_to_sa_vector.py +0 -0
  83. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/vott_converters/__init__.py +0 -0
  84. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/vott_converters/vott_strategies.py +0 -0
  85. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/vott_converters/vott_to_sa_vector.py +0 -0
  86. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/yolo_converters/__init__.py +0 -0
  87. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/yolo_converters/yolo_strategies.py +0 -0
  88. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/converters/yolo_converters/yolo_to_sa_vector.py +0 -0
  89. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/export_from_sa_conversions.py +0 -0
  90. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/import_to_sa_conversions.py +0 -0
  91. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/input_converters/sa_conversion.py +0 -0
  92. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/interface/__init__.py +0 -0
  93. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/interface/base_interface.py +0 -0
  94. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/interface/cli_interface.py +0 -0
  95. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/interface/sdk/__init__.py +0 -0
  96. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/interface/sdk/folders.py +0 -0
  97. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/interface/sdk/project.py +0 -0
  98. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/interface/types.py +0 -0
  99. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/app/serializers.py +0 -0
  100. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/base_usecases.py +0 -0
  101. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/conditions.py +0 -0
  102. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/config.py +0 -0
  103. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/entities/__init__.py +0 -0
  104. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/entities/base.py +0 -0
  105. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/entities/classes.py +0 -0
  106. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/entities/folder.py +0 -0
  107. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/entities/integrations.py +0 -0
  108. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/entities/items.py +0 -0
  109. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/entities/project.py +0 -0
  110. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/entities/project_entities.py +0 -0
  111. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/plugin.py +0 -0
  112. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/pydantic_v1.py +0 -0
  113. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/reporter.py +0 -0
  114. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/repositories.py +0 -0
  115. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/response.py +0 -0
  116. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/types.py +0 -0
  117. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/usecases/__init__.py +0 -0
  118. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/usecases/base.py +0 -0
  119. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/usecases/classes.py +0 -0
  120. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/usecases/custom_fields.py +0 -0
  121. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/usecases/folders.py +0 -0
  122. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/usecases/integrations.py +0 -0
  123. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/usecases/models.py +0 -0
  124. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/usecases/projects.py +0 -0
  125. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/core/video_convertor.py +0 -0
  126. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/infrastructure/__init__.py +0 -0
  127. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/infrastructure/helpers.py +0 -0
  128. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/infrastructure/repositories.py +0 -0
  129. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/infrastructure/serviceprovider.py +0 -0
  130. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/infrastructure/services/__init__.py +0 -0
  131. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/infrastructure/services/annotation_class.py +0 -0
  132. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/infrastructure/services/explore.py +0 -0
  133. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/infrastructure/services/folder.py +0 -0
  134. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/infrastructure/services/integration.py +0 -0
  135. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/infrastructure/services/item.py +0 -0
  136. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/infrastructure/services/work_management.py +0 -0
  137. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/infrastructure/stream_data_handler.py +0 -0
  138. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/infrastructure/utils.py +0 -0
  139. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate/lib/infrastructure/validators.py +0 -0
  140. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate.egg-info/dependency_links.txt +0 -0
  141. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate.egg-info/entry_points.txt +0 -0
  142. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate.egg-info/requires.txt +0 -0
  143. {superannotate-4.4.26.dev1 → superannotate-4.4.28}/src/superannotate.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: superannotate
3
- Version: 4.4.26.dev1
3
+ Version: 4.4.28
4
4
  Summary: Python SDK to SuperAnnotate platform
5
5
  Home-page: https://github.com/superannotateai/superannotate-python-sdk
6
6
  Author: SuperAnnotate AI
@@ -3,7 +3,7 @@ import os
3
3
  import sys
4
4
 
5
5
 
6
- __version__ = "4.4.26dev1"
6
+ __version__ = "4.4.28"
7
7
 
8
8
  os.environ.update({"sa_version": __version__})
9
9
  sys.path.append(os.path.split(os.path.realpath(__file__))[0])
@@ -15,9 +15,10 @@ 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.app.input_converters import convert_project_type
19
- from lib.app.input_converters import export_annotation
20
- from lib.app.input_converters import import_annotation
18
+ from lib.core.exceptions import FileChangedError
19
+ from superannotate.lib.app.input_converters import convert_project_type
20
+ from superannotate.lib.app.input_converters import export_annotation
21
+ from superannotate.lib.app.input_converters import import_annotation
21
22
  from superannotate.lib.app.interface.sdk_interface import SAClient
22
23
 
23
24
 
@@ -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",
@@ -28,11 +28,13 @@ import boto3
28
28
  from tqdm import tqdm
29
29
 
30
30
  import lib.core as constants
31
+ from lib.infrastructure.controller import Controller
31
32
  from lib.app.helpers import get_annotation_paths
32
33
  from lib.app.helpers import get_name_url_duplicated_from_csv
33
34
  from lib.app.helpers import wrap_error as wrap_validation_errors
34
35
  from lib.app.interface.base_interface import BaseInterfaceFacade
35
36
  from lib.app.interface.base_interface import TrackableMeta
37
+
36
38
  from lib.app.interface.types import EmailStr
37
39
  from lib.app.serializers import BaseSerializer
38
40
  from lib.app.serializers import FolderSerializer
@@ -45,7 +47,7 @@ from lib.core.conditions import CONDITION_EQ as EQ
45
47
  from lib.core.conditions import Condition
46
48
  from lib.core.jsx_conditions import Filter, OperatorEnum
47
49
  from lib.core.conditions import EmptyCondition
48
- from lib.core.entities import AttachmentEntity
50
+ from lib.core.entities import AttachmentEntity, FolderEntity, BaseItemEntity
49
51
  from lib.core.entities import SettingEntity
50
52
  from lib.core.entities.classes import AnnotationClassEntity
51
53
  from lib.core.entities.classes import AttributeGroup
@@ -61,6 +63,9 @@ from lib.core.pydantic_v1 import ValidationError
61
63
  from lib.core.pydantic_v1 import constr
62
64
  from lib.core.pydantic_v1 import conlist
63
65
  from lib.core.pydantic_v1 import parse_obj_as
66
+ from lib.infrastructure.annotation_adapter import BaseMultimodalAnnotationAdapter
67
+ from lib.infrastructure.annotation_adapter import MultimodalSmallAnnotationAdapter
68
+ from lib.infrastructure.annotation_adapter import MultimodalLargeAnnotationAdapter
64
69
  from lib.infrastructure.utils import extract_project_folder
65
70
  from lib.infrastructure.validators import wrap_error
66
71
 
@@ -69,7 +74,6 @@ logger = logging.getLogger("sa")
69
74
  # NotEmptyStr = TypeVar("NotEmptyStr", bound=constr(strict=True, min_length=1))
70
75
  NotEmptyStr = constr(strict=True, min_length=1)
71
76
 
72
-
73
77
  PROJECT_STATUS = Literal["NotStarted", "InProgress", "Completed", "OnHold"]
74
78
 
75
79
  PROJECT_TYPE = Literal[
@@ -82,7 +86,6 @@ PROJECT_TYPE = Literal[
82
86
  "Multimodal",
83
87
  ]
84
88
 
85
-
86
89
  APPROVAL_STATUS = Literal["Approved", "Disapproved", None]
87
90
 
88
91
  IMAGE_QUALITY = Literal["compressed", "original"]
@@ -110,6 +113,87 @@ class Attachment(TypedDict, total=False):
110
113
  integration: NotRequired[str] # noqa
111
114
 
112
115
 
116
+ class ItemContext:
117
+ def __init__(
118
+ self,
119
+ controller: Controller,
120
+ project: Project,
121
+ folder: FolderEntity,
122
+ item: BaseItemEntity,
123
+ overwrite: bool = True,
124
+ ):
125
+ self.controller = controller
126
+ self.project = project
127
+ self.folder = folder
128
+ self.item = item
129
+ self._annotation_adapter: Optional[BaseMultimodalAnnotationAdapter] = None
130
+ self._overwrite = overwrite
131
+ self._annotation = None
132
+
133
+ def _set_small_annotation_adapter(self, annotation: dict = None):
134
+ self._annotation_adapter = MultimodalSmallAnnotationAdapter(
135
+ project=self.project,
136
+ folder=self.folder,
137
+ item=self.item,
138
+ controller=self.controller,
139
+ overwrite=self._overwrite,
140
+ annotation=annotation,
141
+ )
142
+
143
+ def _set_large_annotation_adapter(self, annotation: dict = None):
144
+ self._annotation_adapter = MultimodalLargeAnnotationAdapter(
145
+ project=self.project,
146
+ folder=self.folder,
147
+ item=self.item,
148
+ controller=self.controller,
149
+ annotation=annotation,
150
+ )
151
+
152
+ @property
153
+ def annotation_adapter(self) -> BaseMultimodalAnnotationAdapter:
154
+ if self._annotation_adapter is None:
155
+ res = self.controller.service_provider.annotations.get_upload_chunks(
156
+ project=self.project, item_ids=[self.item.id]
157
+ )
158
+ small_item = next(iter(res["small"]), None)
159
+ if small_item:
160
+ self._set_small_annotation_adapter()
161
+ else:
162
+ self._set_large_annotation_adapter()
163
+ return self._annotation_adapter
164
+
165
+ @property
166
+ def annotation(self):
167
+ return self.annotation_adapter.annotation
168
+
169
+ def __enter__(self):
170
+ return self
171
+
172
+ def __exit__(self, exc_type, exc_val, exc_tb):
173
+ if exc_type:
174
+ return False
175
+
176
+ self.save()
177
+ return True
178
+
179
+ def save(self):
180
+ if len(json.dumps(self.annotation).encode("utf-8")) > 16 * 1024 * 1024:
181
+ self._set_large_annotation_adapter(self.annotation)
182
+ else:
183
+ self._set_small_annotation_adapter(self.annotation)
184
+ self._annotation_adapter.save()
185
+
186
+ def get_metadata(self):
187
+ return self.annotation["metadata"]
188
+
189
+ def get_component_value(self, component_id: str):
190
+ return self.annotation_adapter.get_component_value(component_id)
191
+
192
+ def set_component_value(self, component_id: str, value: Any):
193
+ self.annotation_adapter.set_component_value(component_id, value)
194
+ return self
195
+
196
+
113
197
  class SAClient(BaseInterfaceFacade, metaclass=TrackableMeta):
114
198
  """Create SAClient instance to authorize SDK in a team scope.
115
199
  In case of no argument has been provided, SA_TOKEN environmental variable
@@ -2556,19 +2640,13 @@ class SAClient(BaseInterfaceFacade, metaclass=TrackableMeta):
2556
2640
  If recursive=False=True, then only the project name is required.
2557
2641
  :type project: str
2558
2642
 
2559
- :param name_contains: Returns those items, where the given string is found anywhere within an item’s name.
2643
+ :param name_contains: returns those items, where the given string is found anywhere within an item’s name.
2560
2644
  If None, all items returned, in accordance with the recursive=False parameter.
2561
2645
  :type name_contains: str
2562
2646
 
2563
- :param annotation_status: if not None, filters items by annotation status. \n
2564
- Available statuses are::
2647
+ :param annotation_status: returns items with the specified annotation status, which must match a predefined
2648
+ status in the project workflow. If None, all items are returned.
2565
2649
 
2566
- * NotStarted
2567
- * InProgress
2568
- * QualityCheck
2569
- * Returned
2570
- * Completed
2571
- * Skipped
2572
2650
  :type annotation_status: str
2573
2651
 
2574
2652
  :param annotator_email: returns those items’ names that are assigned to the specified annotator.
@@ -3049,20 +3127,13 @@ class SAClient(BaseInterfaceFacade, metaclass=TrackableMeta):
3049
3127
  annotation_status: NotEmptyStr,
3050
3128
  items: Optional[List[NotEmptyStr]] = None,
3051
3129
  ):
3052
- """Sets annotation statuses of items
3130
+ """Sets annotation statuses of items.
3053
3131
 
3054
3132
  :param project: project name or folder path (e.g., “project1/folder1”).
3055
3133
  :type project: str
3056
3134
 
3057
- :param annotation_status: annotation status to set. \n
3058
- Available statuses are::
3059
-
3060
- * NotStarted
3061
- * InProgress
3062
- * QualityCheck
3063
- * Returned
3064
- * Completed
3065
- * Skipped
3135
+ :param annotation_status: The desired status to set for the annotation.
3136
+ This status should match one of the predefined statuses available in the project workflow.
3066
3137
  :type annotation_status: str
3067
3138
 
3068
3139
  :param items: item names. If None, all the items in the specified directory will be used.
@@ -3553,3 +3624,115 @@ class SAClient(BaseInterfaceFacade, metaclass=TrackableMeta):
3553
3624
  )
3554
3625
  if response.errors:
3555
3626
  raise AppException(response.errors)
3627
+
3628
+ def item_context(
3629
+ self,
3630
+ path: Union[str, Tuple[NotEmptyStr, NotEmptyStr], Tuple[int, int]],
3631
+ item: Union[NotEmptyStr, int],
3632
+ overwrite: bool = True,
3633
+ ) -> ItemContext:
3634
+ """
3635
+ Creates an “ItemContext” for managing item annotations and metadata.
3636
+
3637
+ This function allows you to manage annotations and metadata for an item located within a
3638
+ specified project and folder. The path to the item can be provided either as a string or a tuple,
3639
+ and you can specify the item using its name or ID.
3640
+ It returns an “ItemContext” that automatically saves any changes to annotations when the context is exited.
3641
+
3642
+ :param path: Specifies the project and folder containing the item. Can be one of:
3643
+ - A string path, e.g., "project_name/folder_name".
3644
+ - A tuple of strings, e.g., ("project_name", "folder_name").
3645
+ - A tuple of integers (IDs), e.g., (project_id, folder_id).
3646
+ :type path: Union[str, Tuple[str, str], Tuple[int, int]]
3647
+
3648
+ :param item: The name or ID of the item for which the context is being created.
3649
+ :type item: Union[str, int]
3650
+
3651
+ :param overwrite: If `True`, annotations are overwritten during saving. Defaults is `True`.
3652
+ If `False`, raises a `FileChangedError` if the item was modified concurrently.
3653
+ :type overwrite: bool
3654
+
3655
+ :raises AppException: If the provided `path` is invalid or if the item cannot be located.
3656
+
3657
+ :return: An `ItemContext` object to manage the specified item's annotations and metadata.
3658
+ :rtype: ItemContext
3659
+
3660
+ **Examples:**
3661
+
3662
+ Create an `ItemContext` using a string path and item name:
3663
+
3664
+ .. code-block:: python
3665
+
3666
+ with client.item_context("project_name/folder_name", "item_name") as item_context:
3667
+ metadata = item_context.get_metadata()
3668
+ value = item_context.get_component_value("prompts")
3669
+ item_context.set_component_value("prompts", value)
3670
+
3671
+ Create an `ItemContext` using a tuple of strings and an item ID:
3672
+
3673
+ .. code-block:: python
3674
+
3675
+ with client.item_context(("project_name", "folder_name"), 12345) as context:
3676
+ metadata = context.get_metadata()
3677
+ print(metadata)
3678
+
3679
+ Create an `ItemContext` using a tuple of IDs and an item name:
3680
+
3681
+ .. code-block:: python
3682
+
3683
+ with client.item_context((101, 202), "item_name") as context:
3684
+ value = context.get_component_value("component_id")
3685
+ print(value)
3686
+
3687
+ Save annotations automatically after modifying component values:
3688
+
3689
+ .. code-block:: python
3690
+
3691
+ with client.item_context("project_name/folder_name", "item_name", overwrite=True) as context:
3692
+ context.set_component_value("component_id", "new_value")
3693
+ # No need to call .save(), changes are saved automatically on context exit.
3694
+
3695
+ Handle exceptions during context execution:
3696
+
3697
+ .. code-block:: python
3698
+
3699
+ from superannotate import FileChangedError
3700
+
3701
+ try:
3702
+ with client.item_context((101, 202), "item_name") as context:
3703
+ context.set_component_value("component_id", "new_value")
3704
+ except FileChangedError as e:
3705
+ print(f"An error occurred: {e}")
3706
+ """
3707
+ if isinstance(path, str):
3708
+ project, folder = self.controller.get_project_folder_by_path(path)
3709
+ elif len(path) == 2 and all([isinstance(i, str) for i in path]):
3710
+ project = self.controller.get_project(path[0])
3711
+ folder = self.controller.get_folder(project, path[1])
3712
+ elif len(path) == 2 and all([isinstance(i, int) for i in path]):
3713
+ project = self.controller.get_project_by_id(path[0]).data
3714
+ folder = self.controller.get_folder_by_id(path[1], project.id).data
3715
+ else:
3716
+ raise AppException("Invalid path provided.")
3717
+ if project.type != ProjectType.MULTIMODAL:
3718
+ raise AppException(
3719
+ "This function is only supported for Multimodal projects."
3720
+ )
3721
+ if isinstance(item, int):
3722
+ _item = self.controller.get_item_by_id(item_id=item, project=project)
3723
+ else:
3724
+ items = self.controller.items.list_items(project, folder, name=item)
3725
+ if not items:
3726
+ raise AppException("Item not found.")
3727
+ _item = items[0]
3728
+ if project.type != ProjectType.MULTIMODAL:
3729
+ raise AppException(
3730
+ f"The function is not supported for {project.type.name} projects."
3731
+ )
3732
+ return ItemContext(
3733
+ controller=self.controller,
3734
+ project=project,
3735
+ folder=folder,
3736
+ item=_item,
3737
+ overwrite=overwrite,
3738
+ )
@@ -178,6 +178,7 @@ PROJECT_SETTINGS_VALID_ATTRIBUTES = [
178
178
  "UploadFileType",
179
179
  "Tokenization",
180
180
  "ImageAutoAssignEnable",
181
+ "TemplateState",
181
182
  ]
182
183
 
183
184
  __alL__ = (
@@ -174,6 +174,8 @@ class IntegrationTypeEnum(BaseTitledEnum):
174
174
  GCP = "gcp", 2
175
175
  AZURE = "azure", 3
176
176
  CUSTOM = "custom", 4
177
+ DATABRICKS = "databricks", 5
178
+ SNOWFLAKE = "snowflake", 6
177
179
 
178
180
 
179
181
  class TrainingStatus(BaseTitledEnum):
@@ -35,3 +35,9 @@ class PathError(AppException):
35
35
  """
36
36
  User input Error
37
37
  """
38
+
39
+
40
+ class FileChangedError(AppException):
41
+ """
42
+ User input Error
43
+ """
@@ -54,6 +54,18 @@ class Filter(Query):
54
54
  self._operator = operator
55
55
  self.condition_set = [self]
56
56
 
57
+ @property
58
+ def key(self) -> str:
59
+ return self._key
60
+
61
+ @property
62
+ def operator(self) -> OperatorEnum:
63
+ return self._operator
64
+
65
+ @property
66
+ def value(self) -> Any:
67
+ return self._value
68
+
57
69
  def _build(self):
58
70
  if isinstance(self._value, (list, set, tuple)):
59
71
  return f"{self._key}||{self._operator.value}||{','.join(map(urllib.parse.quote, map(str, self._value)))}"
@@ -114,6 +114,10 @@ class ServiceResponse(BaseModel):
114
114
  return 199 < self.status < 300
115
115
  return False
116
116
 
117
+ def raise_for_status(self):
118
+ if not self.ok:
119
+ raise AppException(self.error)
120
+
117
121
  @property
118
122
  def error(self):
119
123
  if self.res_error:
@@ -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