Skip to content
9 changes: 9 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ History

All release highlights of this project will be documented in this file.


4.5.8 - July 12, 2026
______________________

**Updated**

- ``SAClient.generate_items()`` The name key now supports values with up to 200 characters.


4.5.6 - July 5, 2026
______________________

Expand Down
2 changes: 1 addition & 1 deletion src/superannotate/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import os
import sys

__version__ = "4.5.7"
__version__ = "4.5.8"


os.environ.update({"sa_version": __version__})
Expand Down
3 changes: 2 additions & 1 deletion src/superannotate/lib/core/usecases/items.py
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@ def execute(self) -> Response:

class GenerateItems(BaseReportableUseCase):
CHUNK_SIZE = 500
ITEM_NAME_PREFIX_LIMIT = 194
INVALID_CHARS_PATTERN = re.compile(r"[<>:\"'/\\|?*&$!+]")

def __init__(
Expand All @@ -445,7 +446,7 @@ def __init__(

def validate_name(self):
if (
len(self._name_prefix) > 114
len(self._name_prefix) > self.ITEM_NAME_PREFIX_LIMIT
or self.INVALID_CHARS_PATTERN.search(self._name_prefix) is not None
):
raise AppException("Invalid item name.")
Expand Down
16 changes: 16 additions & 0 deletions tests/integration/items/test_generate_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,22 @@ def test_invalid_name(self):
):
sa.generate_items(self.PROJECT_NAME, 100, name="m<:")

def test_long_item_names(self):
# Max allowed prefix is 114 chars; with the "_00001" suffix the full
# item name is 120 chars, which is under the backend limit of 200 chars,
# so names must be stored in full without being truncated.
name = "a" * 194
sa.generate_items(self.PROJECT_NAME, 100, name=name)
items = sa.list_items(self.PROJECT_NAME)

assert len(items) == 100

expected_names = {f"{name}_{i:05d}" for i in range(1, 101)}
actual_names = {item["name"] for item in items}

assert actual_names == expected_names
assert all(len(n) == 200 for n in actual_names)

def test_item_count(self):
with self.assertRaisesRegex(
AppException,
Expand Down
Loading