Skip to content

Commit b24cc72

Browse files
authored
Merge pull request #765 from superannotateai/develop
Develop
2 parents b66313c + a08e04f commit b24cc72

File tree

12 files changed

+158
-17
lines changed

12 files changed

+158
-17
lines changed

.github/workflows/Test_PyPI.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: Publish Python 🐍 distributions 📦 to TestPyPI
2+
3+
on:
4+
push:
5+
branches:
6+
- develop
7+
8+
jobs:
9+
build-n-publish:
10+
name: Build and publish Python 🐍 distributions 📦 to TestPyPI
11+
runs-on: ubuntu-20.04
12+
steps:
13+
- name: Checkout repository
14+
uses: actions/checkout@v3
15+
- name: Set up Python
16+
uses: actions/setup-python@v4
17+
with:
18+
python-version: "3.8"
19+
- name: Upgrade pip
20+
run: >-
21+
python -m
22+
pip install
23+
pip --upgrade
24+
--user
25+
- name: Install pypi/build
26+
run: >-
27+
python -m
28+
pip install
29+
build
30+
--user
31+
- name: Build a binary wheel and a source tarball
32+
run: >-
33+
python -m
34+
build
35+
--sdist
36+
--wheel
37+
--outdir dist/
38+
.
39+
- name: Publish distribution 📦 to TestPyPI
40+
uses: pypa/gh-action-pypi-publish@release/v1
41+
with:
42+
repository-url: https://test.pypi.org/legacy/
43+
password: ${{ secrets.TEST_PYPI_API_TOKEN }}
44+
verbose: true

.github/workflows/release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
name: Publish Python 🐍 distributions 📦 to PyPI and TestPyPI
1+
name: Publish Python 🐍 distributions 📦 to PyPI
22

33
on:
44
release:
55
types: [prereleased,released]
66

77
jobs:
88
build-n-publish:
9-
name: Build and publish Python 🐍 distributions 📦 to PyPI and TestPyPI
9+
name: Build and publish Python 🐍 distributions 📦 to PyPI
1010
runs-on: ubuntu-20.04
1111
steps:
1212
- uses: actions/checkout@v3

docs/source/userguide/SDK_Functions_sheet.csv

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Projects,create_project,No,Not Relevant,Not Relevant,Not Relevant,Not Relevant
88
,set_project_status,Yes,Not Relevant,Not Relevant,Not Relevant,Not Relevant
99
,get_project_metadata,Yes,Not Relevant,Not Relevant,Not Relevant,Not Relevant
1010
,upload_images_to_project,Not Relevant,Not Relevant,Not Relevant,Not Relevant,Not Relevant
11-
,attach_items_from_integrated_storage,Yes,Not Relevant,Not Relevant,Not Relevant,"AWS, GCP, Azure"
11+
,attach_items_from_integrated_storage,Yes,Not Relevant,Not Relevant,Not Relevant,"AWS, GCP, Azure, Databricks"
1212
,upload_image_to_project,Not Relevant,Not Relevant,Not Relevant,Not Relevant,Not Relevant
1313
,upload_images_from_folder_to_project,Not Relevant,Not Relevant,Not Relevant,Not Relevant,AWS
1414
,upload_video_to_project,Not Relevant,Not Relevant,Not Relevant,Not Relevant,Not Relevant
@@ -48,7 +48,7 @@ Annotations,upload_annotations(),Yes,Yes,Yes,Yes,Not Relevant
4848
,set_annotation_statuses(),Yes,Not Relevant,Not Relevant,Not Relevant,Not Relevant
4949
,delete_annotations(),Yes,Not Relevant,Not Relevant,Not Relevant,Not Relevant
5050
,upload_annotations_from_folder_to_project(),No,No,Yes,No,AWS
51-
"Annotation
51+
"Annotation
5252
Classes",create_annotation_class(),Not Relevant,Not Relevant,Not Relevant,Not Relevant,Not Relevant
5353
,create_annotation_classes_from_classes_json(),Not Relevant,Not Relevant,Not Relevant,Not Relevant,AWS
5454
,search_annotation_classes(),Not Relevant,Not Relevant,Not Relevant,Not Relevant,Not Relevant
@@ -57,8 +57,8 @@ Classes",create_annotation_class(),Not Relevant,Not Relevant,Not Relevant,Not Re
5757
Exports,prepare_export(),Yes,Yes,Yes,No,Not Relevant
5858
,download_export(),Yes,Yes,Yes,Yes,AWS
5959
,get_exports(),Yes,Not Relevant,Not Relevant,Not Relevant,Not Relevant
60-
"Custom
61-
Metadata
60+
"Custom
61+
Metadata
6262
",create_custom_fields(),Yes,Not Relevant,Not Relevant,Not Relevant,Not Relevant
6363
,get_custom_fields(),Yes,Not Relevant,Not Relevant,Not Relevant,Not Relevant
6464
,delete_custom_fields(),Yes,Not Relevant,Not Relevant,Not Relevant,Not Relevant
@@ -78,10 +78,10 @@ Team,get_team_metadata(),Not Relevant,Not Relevant,Not Relevant,Not Relevant,Not
7878
,get_user_metadata(),Not Relevant,Not Relevant,Not Relevant,Not Relevant,Not Relevant
7979
,set_user_custom_field(),Not Relevant,Not Relevant,Not Relevant,Not Relevant,Not Relevant
8080
,list_users(),Not Relevant,Not Relevant,Not Relevant,Not Relevant,Not Relevant
81-
"Converting
81+
"Converting
8282
Annotations",import_annotation(),Not Relevant,Not Relevant,Not Relevant,Not Relevant,Not Relevant
8383
,export_annotation(),Not Relevant,Not Relevant,Not Relevant,Not Relevant,Not Relevant
8484
,convert_project_type(),Not Relevant,Not Relevant,Not Relevant,Not Relevant,Not Relevant
85-
"Working w/
85+
"Working w/
8686
Annotations",validate_annotations(),Not Relevant,Not Relevant,Not Relevant,Not Relevant,Not Relevant
8787
,aggregate_annotations_as_df(),Not Relevant,Not Relevant,Not Relevant,Not Relevant,Not Relevant

docs/source/userguide/utilities.rst

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,14 @@ You can find more information annotation format conversion :ref:`here <ref_conve
116116
117117
Converting CSV and JSONL Formats for Annotation Management in SuperAnnotate
118118
---------------------------------------------------------------------------
119-
SuperAnnotate primarily uses the **JSONL format** for annotation import/export. However,
120-
many external tools use **CSV**, requiring users to convert between these formats for seamless data management.
119+
SuperAnnotate primarily uses the JSONL format for annotation import/export. However,
120+
many external tools use CSV, requiring users to convert between these formats for seamless data management.
121121

122122
This guide provides:
123123

124-
- CSV to JSONL conversion** for annotation uploads.
125-
- Fetching annotations from SuperAnnotate** and converting them into JSONL/CSV.
126-
- Correct metadata mappings** to ensure consistency in the annotation format.
124+
- CSV to JSONL conversion for annotation uploads.
125+
- Fetching annotations from SuperAnnotate and converting them into JSONL/CSV.
126+
- Correct metadata mappings to ensure consistency in the annotation format.
127127

128128

129129
SuperAnnotate JSONL Schema Overview

src/superannotate/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import sys
44

55

6-
__version__ = "4.4.31"
6+
__version__ = "4.4.32"
77

88
os.environ.update({"sa_version": __version__})
99
sys.path.append(os.path.split(os.path.realpath(__file__))[0])

src/superannotate/lib/core/serviceproviders.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,14 @@ def saqul_query(
672672
) -> ServiceResponse:
673673
raise NotImplementedError
674674

675+
@abstractmethod
676+
def query_item_count(
677+
self,
678+
project: entities.ProjectEntity,
679+
query: str = None,
680+
) -> ServiceResponse:
681+
raise NotImplementedError
682+
675683

676684
class BaseServiceProvider:
677685
projects: BaseProjectService

src/superannotate/lib/core/usecases/annotations.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2046,7 +2046,7 @@ def execute(self):
20462046
f"annotations to the project {self._project.name}."
20472047
)
20482048
if not self._root_folder.is_root:
2049-
if len(distributed_items) > 1 or None not in distributed_items:
2049+
if len(distributed_items) > 1 or "" not in distributed_items:
20502050
raise AppException(
20512051
"You can't include a folder when uploading from within a folder."
20522052
)

src/superannotate/lib/core/usecases/items.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,52 @@ def execute(self) -> Response:
163163
return self._response
164164

165165

166+
class QueryEntitiesCountUseCase(BaseReportableUseCase):
167+
def __init__(
168+
self,
169+
reporter: Reporter,
170+
project: ProjectEntity,
171+
service_provider: BaseServiceProvider,
172+
query: str,
173+
):
174+
super().__init__(reporter)
175+
self._project = project
176+
self._service_provider = service_provider
177+
self._query = query
178+
179+
def validate_arguments(self):
180+
if self._query:
181+
response = self._service_provider.explore.validate_saqul_query(
182+
project=self._project, query=self._query
183+
)
184+
185+
if not response.ok:
186+
raise AppException(response.error)
187+
if response.data["isValidQuery"]:
188+
self._query = response.data["parsedQuery"]
189+
else:
190+
raise AppException("Incorrect query.")
191+
else:
192+
response = self._service_provider.explore.validate_saqul_query(
193+
self._project, "-"
194+
)
195+
if not response.ok:
196+
raise AppException(response.error)
197+
198+
def execute(self) -> Response:
199+
if self.is_valid():
200+
query_kwargs = {"query": self._query}
201+
service_response = self._service_provider.explore.query_item_count(
202+
self._project,
203+
**query_kwargs,
204+
)
205+
if service_response.ok:
206+
self._response.data = service_response.data
207+
else:
208+
self._response.errors = service_response.data
209+
return self._response
210+
211+
166212
class AssignItemsUseCase(BaseUseCase):
167213
CHUNK_SIZE = 500
168214

src/superannotate/lib/infrastructure/annotation_adapter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def get_component_value(self, component_id: str):
4444
return None
4545

4646
def set_component_value(self, component_id: str, value: Any):
47-
self.annotation["data"][component_id] = {"value": value}
47+
self.annotation.setdefault("data", {}).setdefault(component_id, {})["value"] = value
4848
return self
4949

5050

src/superannotate/lib/infrastructure/controller.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1678,3 +1678,17 @@ def query_entities(
16781678
return ItemManager.process_response(
16791679
self.service_provider, items, project, folder, map_fields=False
16801680
)
1681+
1682+
def query_items_count(self, project_name: str, query: str = None) -> int:
1683+
project = self.get_project(project_name)
1684+
1685+
use_case = usecases.QueryEntitiesCountUseCase(
1686+
reporter=self.get_default_reporter(),
1687+
project=project,
1688+
query=query,
1689+
service_provider=self.service_provider,
1690+
)
1691+
response = use_case.execute()
1692+
if response.errors:
1693+
raise AppException(response.errors)
1694+
return response.data["count"]

0 commit comments

Comments
 (0)