Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ History
All release highlights of this project will be documented in this file.

4.4.32 - March 4, 2025
_____________________
______________________

**Fixed**

- ``SAClient.item_context`` Fixed an issue where setting a component value would overwrite existing comments and other associated data.
- ``SAClient.item_context`` Fixed an issue where setting a component value would overwrite existing comments and other associated data.

4.4.31 - Feb 27, 2025
_____________________
Expand Down
4 changes: 4 additions & 0 deletions docs/source/api_reference/api_item.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ Items
.. automethod:: superannotate.SAClient.search_items
.. automethod:: superannotate.SAClient.attach_items
.. automethod:: superannotate.SAClient.item_context
.. autoclass:: superannotate.ItemContext
:members: get_metadata, get_component_value, set_component_value
:member-order: bysource

.. automethod:: superannotate.SAClient.copy_items
.. automethod:: superannotate.SAClient.move_items
.. automethod:: superannotate.SAClient.delete_items
Expand Down
2 changes: 2 additions & 0 deletions src/superannotate/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from superannotate.lib.app.input_converters import export_annotation
from superannotate.lib.app.input_converters import import_annotation
from superannotate.lib.app.interface.sdk_interface import SAClient
from superannotate.lib.app.interface.sdk_interface import ItemContext


SESSIONS = {}
Expand All @@ -29,6 +30,7 @@
__all__ = [
"__version__",
"SAClient",
"ItemContext",
# Utils
"enums",
"AppException",
Expand Down
86 changes: 86 additions & 0 deletions src/superannotate/lib/app/interface/sdk_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,20 @@ class Attachment(TypedDict, total=False):


class ItemContext:
"""
A context manager for handling annotations and metadata of an item.

The ItemContext class provides methods to retrieve and manage metadata and component
values for items in the specified context. Below are the descriptions and usage examples for each method.

Example:
::

with sa_client.item_context("project_name/folder_name", "item_name") as context:
metadata = context.get_metadata()
print(metadata)
"""

def __init__(
self,
controller: Controller,
Expand Down Expand Up @@ -171,9 +185,26 @@ def annotation(self):
return self.annotation_adapter.annotation

def __enter__(self):
"""
Enters the context manager.

Returns:
ItemContext: The instance itself.
"""
return self

def __exit__(self, exc_type, exc_val, exc_tb):
"""
Exits the context manager, saving changes if no exception occurred.

Args:
exc_type (Optional[Type[BaseException]]): Exception type if raised.
exc_val (Optional[BaseException]): Exception instance if raised.
exc_tb (Optional[TracebackType]): Traceback if an exception occurred.

Returns:
bool: True if no exception occurred, False otherwise.
"""
if exc_type:
return False

Expand All @@ -188,12 +219,62 @@ def save(self):
self._annotation_adapter.save()

def get_metadata(self):
"""
Retrieves the metadata associated with the current item context.

:return: A dictionary containing metadata for the current item.
:rtype: dict

Request Example:
::

with client.item_context(("project_name", "folder_name"), 12345) as context:
metadata = context.get_metadata()
print(metadata)
"""
return self.annotation["metadata"]

def get_component_value(self, component_id: str):
"""
Retrieves the value of a specific component within the item context.

:param component_id: The name of the component whose value is to be retrieved.
:type component_id: str

:return: The value of the specified component.
:rtype: Any

Request Example:
::

with client.item_context((101, 202), "item_name") as context: # (101, 202) project and folder IDs
value = context.get_component_value("component_id")
print(value)
"""
return self.annotation_adapter.get_component_value(component_id)

def set_component_value(self, component_id: str, value: Any):
"""
Updates the value of a specific component within the item context.

:param component_id: The component identifier.
:type component_id: str

:param value: The new value to set for the specified component.
:type value: Any

:return: The instance itself to allow method chaining.
:rtype: ItemContext

Request Example:
::

with client.item_context("project_name/folder_name", "item_name") as item_context:
metadata = item_context.get_metadata()
value = item_context.get_component_value("component_id")
item_context.set_component_value("component_id", value)

"""
self.annotation_adapter.set_component_value(component_id, value)
return self

Expand Down Expand Up @@ -381,6 +462,7 @@ def list_users(
):
"""
Search users by filtering criteria

:param project: Project name or ID, if provided, results will be for project-level,
otherwise results will be for team level.
:type project: str or int
Expand Down Expand Up @@ -4357,6 +4439,10 @@ def item_context(
:return: An `ItemContext` object to manage the specified item's annotations and metadata.
:rtype: ItemContext

.. seealso::
For more details, see :class:`ItemContext`.


**Examples:**

Create an `ItemContext` using a string path and item name:
Expand Down