Skip to content

Commit 251435d

Browse files
Narek MkhitaryanNarek Mkhitaryan
authored andcommitted
fixed fetch in get annotations
1 parent 14a0632 commit 251435d

File tree

4 files changed

+37
-19
lines changed

4 files changed

+37
-19
lines changed

pytest.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ minversion = 3.7
33
log_cli=true
44
python_files = test_*.py
55
;pytest_plugins = ['pytest_profiling']
6-
addopts = -n 2 --dist loadscope
6+
;addopts = -n 2 --dist loadscope

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

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2663,23 +2663,23 @@ def search_items(
26632663

26642664
def list_items(
26652665
self,
2666-
project: Union[int, str],
2667-
folder: Optional[Union[int, str]] = None,
2666+
project: Union[NotEmptyStr, int],
2667+
folder: Optional[Union[NotEmptyStr, int]] = None,
26682668
*,
26692669
include: List[Literal["custom_metadata"]] = None,
26702670
**filters,
26712671
):
26722672
"""
26732673
Search items by filtering criteria.
26742674
2675-
:param project: The project name, project ID, or folder path (e.g., "project1/folder1") to search within.
2675+
:param project: The project name, project ID, or folder path (e.g., "project1") to search within.
26762676
This can refer to the root of the project or a specific subfolder.
2677-
:type project: Union[int, str]
2677+
:type project: Union[NotEmptyStr, int]
26782678
26792679
:param folder: The folder name or ID to search within. If None, the search will be done in the root folder of
26802680
the project. If both “project” and “folder” specify folders, the “project”
26812681
value will take priority.
2682-
:type folder: Union[int, str], optional
2682+
:type folder: Union[NotEmptyStr, int], optional
26832683
26842684
:param include: Specifies additional fields to include in the response.
26852685
@@ -2694,8 +2694,8 @@ def list_items(
26942694
26952695
26962696
Supported operations:
2697-
- __ne: Value is in the list.
2698-
- __in: Value is not equal.
2697+
- __ne: Value is not equal.
2698+
- __in: Value is in the list.
26992699
- __notin: Value is not in the list.
27002700
- __contains: Value has the substring.
27012701
- __starts: Value starts with the prefix.
@@ -2710,6 +2710,9 @@ def list_items(
27102710
- name__contains: str
27112711
- name__starts: str
27122712
- name__ends: str
2713+
- annotation_status: str
2714+
- annotation_status__in: list[str]
2715+
- annotation_status__ne: list[str]
27132716
- approval_status: Literal["Approved", "Disapproved", None]
27142717
- assignments__user_id: str
27152718
- assignments__user_id__ne: str

src/superannotate/lib/infrastructure/controller.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class ItemFilters(TypedDict, total=False):
5858
name__ends: Optional[str]
5959
annotation_status: Optional[str]
6060
annotation_status__in: Optional[List[str]]
61+
annotation_status__ne: Optional[List[str]]
6162
approval_status: Optional[str]
6263
approval_status__in: Optional[List[str]]
6364
approval_status__ne: Optional[str]

src/superannotate/lib/infrastructure/stream_data_handler.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import copy
22
import json
3+
import logging
34
import os
45
import typing
56
from typing import Callable
@@ -13,6 +14,8 @@
1314
total=_seconds, sock_connect=_seconds, sock_read=_seconds
1415
)
1516

17+
logger = logging.getLogger("sa")
18+
1619

1720
class StreamedAnnotations:
1821
DELIMITER = b"\\n;)\\n"
@@ -46,21 +49,32 @@ async def fetch(
4649
data: dict = None,
4750
params: dict = None,
4851
):
49-
kwargs = {"params": params, "json": {}}
50-
if "folder_id" in kwargs["params"]:
51-
kwargs["json"] = {"folder_id": kwargs["params"].pop("folder_id")}
52+
kwargs = {"params": params, "json": data}
5253
if data:
5354
kwargs["json"].update(data)
5455
response = await session.request(method, url, **kwargs, timeout=TIMEOUT) # noqa
55-
buffer = b""
56+
if not response.ok:
57+
logger.error(response.text)
58+
buffer = ""
59+
line_groups = b""
60+
decoder = json.JSONDecoder()
5661
async for line in response.content.iter_any():
57-
slices = (buffer + line).split(self.DELIMITER)
58-
for _slice in slices[:-1]:
59-
yield self.get_json(_slice)
60-
buffer = slices[-1]
61-
if buffer:
62-
yield self.get_json(buffer)
63-
self._reporter.update_progress()
62+
line_groups += line
63+
try:
64+
buffer += line_groups.decode("utf-8")
65+
line_groups = b""
66+
except UnicodeDecodeError:
67+
continue
68+
while buffer:
69+
try:
70+
json_obj, index = decoder.raw_decode(buffer)
71+
yield json_obj
72+
buffer = buffer[index + len(self.DELIMITER) :].lstrip()
73+
except json.decoder.JSONDecodeError as e:
74+
logger.debug(
75+
f"Failed to parse buffer, buffer_len: {len(buffer)}// buffer_end: ...{buffer[-100:]}, error: {e}"
76+
)
77+
break
6478

6579
async def list_annotations(
6680
self,

0 commit comments

Comments
 (0)