@@ -1941,41 +1941,54 @@ def download_image(
19411941 logger .info (f"Downloaded image { image_name } to { local_dir_path } " )
19421942 return response .data
19431943
1944+
19441945 def upload_annotations (
1945- self , project : NotEmptyStr , annotations : List [dict ], keep_status : bool = None
1946+ self ,
1947+ project : NotEmptyStr ,
1948+ annotations : List [dict ],
1949+ keep_status : bool = None ,
1950+ * ,
1951+ data_spec : Literal ['default' , 'multimodal' ] = 'default'
19461952 ):
1947- """Uploads a list of annotation dicts as annotations to the SuperAnnotate directory .
1953+ """Uploads a list of annotation dictionaries to the specified SuperAnnotate project or folder .
19481954
1949- :param project: project name or folder path (e.g., "project1/folder1")
1950- :type project: str or dict
1955+ :param project: The project name or folder path where annotations will be uploaded
1956+ (e.g., "project1/folder1").
1957+ :type project: str
19511958
1952- :param annotations: list of annotation dictionaries corresponding to SuperAnnotate format
1953- :type annotations: list of dicts
1959+ :param annotations: A list of annotation dictionaries formatted according to the SuperAnnotate standards.
1960+ :type annotations: list of dict
19541961
1955- :param keep_status: If False, the annotation status will be automatically
1956- updated to "InProgress," otherwise the current status will be kept.
1957- :type keep_status: bool
1962+ :param keep_status: If False, the annotation status will be automatically updated to "InProgress."
1963+ If True, the current status will remain unchanged.
1964+ :type keep_status: bool, optional
1965+
1966+ :param data_spec: Specifies the format for processing and transforming annotations before upload.
19581967
1968+ Options are:
1969+ - default: Retains the annotations in their original format.
1970+ - multimodal: Converts annotations for multimodal projects, optimizing for
1971+ compact and modality-specific data representation.
1972+ :type data_spec: str, optional
19591973
1960- :return: a dictionary containing lists of successfully uploaded, failed and skipped name
1974+ :return: A dictionary containing the results of the upload, categorized into successfully uploaded,
1975+ failed, and skipped annotations.
19611976 :rtype: dict
19621977
1963- Response Example:
1964- ::
1978+ Response Example::
19651979
19661980 {
19671981 "succeeded": [],
1968- "failed":[],
1982+ "failed": [],
19691983 "skipped": []
19701984 }
19711985
1972- Example Usage with JSONL Upload:
1973- ::
1986+ Example Usage with JSONL Upload for Multimodal Projects: :
1987+
19741988 import json
19751989 from pathlib import Path
19761990 from superannotate import SAClient
19771991
1978- # Assuming annotations are stored in JSONL format
19791992 annotations_path = Path("annotations.jsonl")
19801993 annotations = []
19811994
@@ -1984,16 +1997,16 @@ def upload_annotations(
19841997 for line in f:
19851998 annotations.append(json.loads(line))
19861999
1987- # Initialize the Superannotate client
2000+ # Initialize the SuperAnnotate client
19882001 sa = SAClient()
19892002
19902003 # Call the upload_annotations function
1991- response = client .upload_annotations(
2004+ response = sa .upload_annotations(
19922005 project="project1/folder1",
19932006 annotations=annotations,
1994- keep_status=True
2007+ keep_status=True,
2008+ data_spec='multimodal'
19952009 )
1996-
19972010 """
19982011 if keep_status is not None :
19992012 warnings .warn (
@@ -2009,6 +2022,7 @@ def upload_annotations(
20092022 annotations = annotations ,
20102023 keep_status = keep_status ,
20112024 user = self .controller .current_user ,
2025+ output_format = data_spec
20122026 )
20132027 if response .errors :
20142028 raise AppException (response .errors )
@@ -2483,6 +2497,8 @@ def get_annotations(
24832497 self ,
24842498 project : Union [NotEmptyStr , int ],
24852499 items : Optional [Union [List [NotEmptyStr ], List [int ]]] = None ,
2500+ * ,
2501+ data_spec : Literal ['default' , 'multimodal' ] = 'default'
24862502 ):
24872503 """Returns annotations for the given list of items.
24882504
@@ -2492,6 +2508,29 @@ def get_annotations(
24922508 :param items: item names. If None, all the items in the specified directory will be used.
24932509 :type items: list of strs or list of ints
24942510
2511+ :param data_spec: Specifies the format for processing and transforming annotations before upload.
2512+
2513+ Options are:
2514+ - default: Retains the annotations in their original format.
2515+ - multimodal: Converts annotations for multimodal projects, optimizing for
2516+ compact and modality-specific data representation.
2517+
2518+ :type data_spec: str, optional
2519+
2520+ Example Usage of Multimodal Projects::
2521+
2522+ from superannotate import SAClient
2523+
2524+
2525+ sa = SAClient()
2526+
2527+ # Call the upload_annotations function
2528+ response = sa.upload_annotations(
2529+ project="project1/folder1",
2530+ items=["item_1", "item_2"],
2531+ data_spec='multimodal'
2532+ )
2533+
24952534 :return: list of annotations
24962535 :rtype: list of dict
24972536 """
@@ -2502,7 +2541,10 @@ def get_annotations(
25022541 folder = self .controller .get_folder_by_id (
25032542 project_id = project .id , folder_id = project .folder_id
25042543 ).data
2505- response = self .controller .annotations .list (project , folder , items )
2544+ response = self .controller .annotations .list (
2545+ project , folder , items ,
2546+ transform_version = 'llmJsonV2' if data_spec == 'multimodal' else None
2547+ )
25062548 if response .errors :
25072549 raise AppException (response .errors )
25082550 return response .data
@@ -2825,7 +2867,7 @@ def list_items(
28252867 project : Union [NotEmptyStr , int ],
28262868 folder : Optional [Union [NotEmptyStr , int ]] = None ,
28272869 * ,
2828- include : List [Literal ["custom_metadata" ]] = None ,
2870+ include : List [Literal ["custom_metadata" , "category" ]] = None ,
28292871 ** filters ,
28302872 ):
28312873 """
0 commit comments