From 7f81a75d88567509d647e5b4c5ef8f5009b71559 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Tue, 9 Jun 2026 18:12:21 +0200 Subject: [PATCH 1/9] updated lists api --- ayon_api/_api_helpers/lists.py | 214 ++++++++++++++++++++++++++++++++- 1 file changed, 213 insertions(+), 1 deletion(-) diff --git a/ayon_api/_api_helpers/lists.py b/ayon_api/_api_helpers/lists.py index 17827266d..a009fab5d 100644 --- a/ayon_api/_api_helpers/lists.py +++ b/ayon_api/_api_helpers/lists.py @@ -4,11 +4,12 @@ import typing from typing import Optional, Iterable, Any, Generator -from ayon_api.utils import create_entity_id +from ayon_api.utils import NOT_SET, create_entity_id from ayon_api.graphql_queries import entity_lists_graphql_query from .base import BaseServerAPI + if typing.TYPE_CHECKING: from ayon_api.typing import ( EntityListEntityType, @@ -159,6 +160,7 @@ def create_entity_list( data: Optional[list[dict[str, Any]]] = None, tags: Optional[list[str]] = None, template: Optional[dict[str, Any]] = None, + entity_list_folder_id: Optional[str] = None, owner: Optional[str] = None, active: Optional[bool] = None, items: Optional[list[dict[str, Any]]] = None, @@ -178,6 +180,8 @@ def create_entity_list( data (Optional[dict[str, Any]]): Custom data of entity list. tags (Optional[list[str]]): Entity list tags. template (Optional[dict[str, Any]]): Dynamic list template. + entity_list_folder_id (Optional[dict[str, Any]]): Entity list + folder id. owner (Optional[str]): New owner of the list. active (Optional[bool]): Change active state of entity list. items (Optional[list[dict[str, Any]]]): Initial items in @@ -199,6 +203,7 @@ def create_entity_list( ("template", template), ("tags", tags), ("owner", owner), + ("entityListFolderId", entity_list_folder_id), ("data", data), ("active", active), ("items", items), @@ -223,6 +228,7 @@ def update_entity_list( attrib: Optional[list[dict[str, Any]]] = None, data: Optional[list[dict[str, Any]]] = None, tags: Optional[list[str]] = None, + entity_list_folder_id: str | None | NOT_SET = NOT_SET, owner: Optional[str] = None, active: Optional[bool] = None, ) -> None: @@ -237,6 +243,9 @@ def update_entity_list( entity list. data (Optional[dict[str, Any]]): Custom data of entity list. tags (Optional[list[str]]): Entity list tags. + entity_list_folder_id (dict[str, Any] | None | NOT_SET): New + entity list folder id. Use 'None' to move entity list to root. + Use 'NOT_SET' to keep current folder. owner (Optional[str]): New owner of the list. active (Optional[bool]): Change active state of entity list. @@ -254,6 +263,9 @@ def update_entity_list( ) if value is not None } + if entity_list_folder_id is not NOT_SET: + kwargs["entityListFolderId"] = entity_list_folder_id + response = self.patch( f"projects/{project_name}/lists/{list_id}", **kwargs @@ -454,3 +466,203 @@ def delete_entity_list_item( f"projects/{project_name}/lists/{list_id}/items/{item_id}", ) response.raise_for_status() + + def get_entity_list_entities( + self, project_name: str, entity_list_id: str + ) -> dict[str, Any]: + """Get entity list items using REST API. + + Args: + project_name (str): Project name. + entity_list_id (str): Entity list id. + + Returns: + dict[str, Any]: Information about entities on the list. + + """ + response = self.get( + f"projects/{project_name}/lists/{entity_list_id}/entities" + ) + response.raise_for_status() + return response.data + + def get_entity_list_folders_raw(self, project_name: str) -> dict: + """Get entity list folders. + + Returns: + dict[str, Any]: Raw output of entity list folders output. At this + moment contains only "folders" key with list of folders, + but it can be extended in the future. + + """ + response = self.get(f"projects/{project_name}/entityListFolders") + response.raise_for_status() + return response.data + + def get_entity_list_folders( + self, project_name: str + ) -> list[dict[str, Any]]: + """Get entity list folders. + + Returns: + list[dict[str, Any]]: List of entity list folders. + + """ + data = self.get_entity_list_folders_raw(project_name) + return data["folders"] + + def create_entity_list_folder( + self, + project_name: str, + label: str, + *, + parent_id: str | None = None, + color: str | None = None, + icon: str | None = None, + scope: list[str] | None = None, + data: dict | None = None, + access: dict | None = None, + entity_list_folder_id: str | None = None, + ) -> str: + """Create entity list folder. + + Args: + project_name (str): Project name. + label (str): Folder label. + parent_id (str | None): Parent folder id. If None, the folder will + be created in root. + color (str | None): Folder color. + icon (str | None): Folder icon. + scope (list[str] | None): Folder scope. + data (dict | None): Custom data of entity list folder. + access (dict | None): Access control for entity list folder. + entity_list_folder_id (str | None): Id of folder that will be + created. If None, a new id will be generated. + + Returns: + str: Created entity list folder id. + + """ + if data is None: + data = {} + + for key, value in ( + ("color", color), + ("icon", icon), + ("scope", scope), + ): + if value: + data[key] = value + + if not entity_list_folder_id: + entity_list_folder_id = create_entity_id() + body = { + "id": entity_list_folder_id, + "label": label, + } + if parent_id: + body["parentId"] = parent_id + + if data: + body["data"] = data + + if access: + body["access"] = access + + response = self.post( + f"projects/{project_name}/entityListFolders", + **body + ) + response.raise_for_status() + return entity_list_folder_id + + def update_entity_list_folder( + self, + project_name: str, + entity_list_folder_id: str, + *, + label: str | None = None, + parent_id: str | None| NOT_SET = NOT_SET, + color: str | None = None, + icon: str | None = None, + scope: list[str] | None = None, + data: dict | None = None, + access: dict | None = None, + ) -> None: + """Update entity list folder. + + Args: + project_name (str): Project name. + entity_list_folder_id (str): Folder id that will be updated. + label (str | None): New label of entity list folder. + parent_id (str | None | NOT_SET): New parent id of entity list + folder. If None, the folder will be moved to root. + color (str | None): New color of entity list folder. + icon (str | None): New icon of entity list folder. + scope (list[str] | None): New scope of entity list folder. + data (dict | None): Custom data of entity list folder. + access (dict | None): Access control for entity list folder. + + """ + if data is None: + data = {} + + for key, value in ( + ("color", color), + ("icon", icon), + ): + if value: + data[key] = value + + if scope is not None: + data["scope"] = scope + + body = {} + if data: + body["data"] = data + if label: + body["label"] = label + if access is not None: + body["access"] = access + if parent_id is not NOT_SET: + body["parentId"] = parent_id + + if not body: + return + + response = self.patch( + ( + f"projects/{project_name}/" + f"entityListFolders/{entity_list_folder_id}" + ), + **body + ) + response.raise_for_status() + + def delete_entity_list_folder( + self, + project_name: str, + entity_list_folder_id: str, + ) -> None: + """Delete entity list folder.""" + response = self.delete( + f"projects/{project_name}/" + f"entityListFolders/{entity_list_folder_id}" + ) + response.raise_for_status() + + def set_entity_list_folders_order( + self, project_name: str, order: list[str] + ) -> None: + """Change order of entity list folders. + + Args: + project_name (str): Project name. + order (list[str]): List of folder ids in desired order. + + """ + response = self.post( + f"projects/{project_name}/entityListFolders/order", + order=order, + ) + response.raise_for_status() From 633626aa7fcf53b48065bbdf81089f5013a376d0 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Thu, 11 Jun 2026 16:06:05 +0200 Subject: [PATCH 2/9] print wrong typehint in automated api --- automated_api.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/automated_api.py b/automated_api.py index 766cd4bc3..f7c1d01ea 100644 --- a/automated_api.py +++ b/automated_api.py @@ -199,6 +199,9 @@ def _get_typehint(annotation, api_globals): return typehint except NameError: print("Unknown typehint:", typehint) + except Exception: + print("Error while processing typehint:", typehint) + raise _typehint = typehint _typehing_parents = [] From 693ba6e244b3b0cca5d1c1b4d07b8f782c7a05cf Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Thu, 11 Jun 2026 16:06:22 +0200 Subject: [PATCH 3/9] fix typehints using NOT_SET --- ayon_api/_api_helpers/lists.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ayon_api/_api_helpers/lists.py b/ayon_api/_api_helpers/lists.py index a009fab5d..7baf049eb 100644 --- a/ayon_api/_api_helpers/lists.py +++ b/ayon_api/_api_helpers/lists.py @@ -228,7 +228,7 @@ def update_entity_list( attrib: Optional[list[dict[str, Any]]] = None, data: Optional[list[dict[str, Any]]] = None, tags: Optional[list[str]] = None, - entity_list_folder_id: str | None | NOT_SET = NOT_SET, + entity_list_folder_id: str | None | type[NOT_SET] = NOT_SET, owner: Optional[str] = None, active: Optional[bool] = None, ) -> None: @@ -243,7 +243,7 @@ def update_entity_list( entity list. data (Optional[dict[str, Any]]): Custom data of entity list. tags (Optional[list[str]]): Entity list tags. - entity_list_folder_id (dict[str, Any] | None | NOT_SET): New + entity_list_folder_id (dict[str, Any] | None | type[NOT_SET]): New entity list folder id. Use 'None' to move entity list to root. Use 'NOT_SET' to keep current folder. owner (Optional[str]): New owner of the list. @@ -582,7 +582,7 @@ def update_entity_list_folder( entity_list_folder_id: str, *, label: str | None = None, - parent_id: str | None| NOT_SET = NOT_SET, + parent_id: str | None| type[NOT_SET] = NOT_SET, color: str | None = None, icon: str | None = None, scope: list[str] | None = None, @@ -595,8 +595,8 @@ def update_entity_list_folder( project_name (str): Project name. entity_list_folder_id (str): Folder id that will be updated. label (str | None): New label of entity list folder. - parent_id (str | None | NOT_SET): New parent id of entity list - folder. If None, the folder will be moved to root. + parent_id (str | None | type[NOT_SET]): New parent id of entity + list folder. If None, the folder will be moved to root. color (str | None): New color of entity list folder. icon (str | None): New icon of entity list folder. scope (list[str] | None): New scope of entity list folder. From 57302c11d065fb29c58d20e4d3073896baf7bf0d Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Thu, 11 Jun 2026 16:06:36 +0200 Subject: [PATCH 4/9] update public api --- ayon_api/__init__.py | 14 ++++ ayon_api/_api.py | 179 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 193 insertions(+) diff --git a/ayon_api/__init__.py b/ayon_api/__init__.py index a125e8993..3d5f89311 100644 --- a/ayon_api/__init__.py +++ b/ayon_api/__init__.py @@ -298,6 +298,13 @@ update_entity_list_items, update_entity_list_item, delete_entity_list_item, + get_entity_list_entities, + get_entity_list_folders_raw, + get_entity_list_folders, + create_entity_list_folder, + update_entity_list_folder, + delete_entity_list_folder, + set_entity_list_folders_order, get_thumbnail_by_id, get_thumbnail, get_folder_thumbnail, @@ -609,6 +616,13 @@ "update_entity_list_items", "update_entity_list_item", "delete_entity_list_item", + "get_entity_list_entities", + "get_entity_list_folders_raw", + "get_entity_list_folders", + "create_entity_list_folder", + "update_entity_list_folder", + "delete_entity_list_folder", + "set_entity_list_folders_order", "get_thumbnail_by_id", "get_thumbnail", "get_folder_thumbnail", diff --git a/ayon_api/_api.py b/ayon_api/_api.py index 5c843360f..1c0bb9861 100644 --- a/ayon_api/_api.py +++ b/ayon_api/_api.py @@ -7981,6 +7981,7 @@ def create_entity_list( data: Optional[list[dict[str, Any]]] = None, tags: Optional[list[str]] = None, template: Optional[dict[str, Any]] = None, + entity_list_folder_id: Optional[str] = None, owner: Optional[str] = None, active: Optional[bool] = None, items: Optional[list[dict[str, Any]]] = None, @@ -8000,6 +8001,8 @@ def create_entity_list( data (Optional[dict[str, Any]]): Custom data of entity list. tags (Optional[list[str]]): Entity list tags. template (Optional[dict[str, Any]]): Dynamic list template. + entity_list_folder_id (Optional[dict[str, Any]]): Entity list + folder id. owner (Optional[str]): New owner of the list. active (Optional[bool]): Change active state of entity list. items (Optional[list[dict[str, Any]]]): Initial items in @@ -8018,6 +8021,7 @@ def create_entity_list( data=data, tags=tags, template=template, + entity_list_folder_id=entity_list_folder_id, owner=owner, active=active, items=items, @@ -8034,6 +8038,7 @@ def update_entity_list( attrib: Optional[list[dict[str, Any]]] = None, data: Optional[list[dict[str, Any]]] = None, tags: Optional[list[str]] = None, + entity_list_folder_id: str | None | type[NOT_SET] = NOT_SET, owner: Optional[str] = None, active: Optional[bool] = None, ) -> None: @@ -8048,6 +8053,9 @@ def update_entity_list( entity list. data (Optional[dict[str, Any]]): Custom data of entity list. tags (Optional[list[str]]): Entity list tags. + entity_list_folder_id (dict[str, Any] | None | type[NOT_SET]): New + entity list folder id. Use 'None' to move entity list to root. + Use 'NOT_SET' to keep current folder. owner (Optional[str]): New owner of the list. active (Optional[bool]): Change active state of entity list. @@ -8061,6 +8069,7 @@ def update_entity_list( attrib=attrib, data=data, tags=tags, + entity_list_folder_id=entity_list_folder_id, owner=owner, active=active, ) @@ -8259,6 +8268,176 @@ def delete_entity_list_item( ) +def get_entity_list_entities( + project_name: str, + entity_list_id: str, +) -> dict[str, Any]: + """Get entity list items using REST API. + + Args: + project_name (str): Project name. + entity_list_id (str): Entity list id. + + Returns: + dict[str, Any]: Information about entities on the list. + + """ + con = get_server_api_connection() + return con.get_entity_list_entities( + project_name=project_name, + entity_list_id=entity_list_id, + ) + + +def get_entity_list_folders_raw( + project_name: str, +) -> dict: + """Get entity list folders. + + Returns: + dict[str, Any]: Raw output of entity list folders output. At this + moment contains only "folders" key with list of folders, + but it can be extended in the future. + + """ + con = get_server_api_connection() + return con.get_entity_list_folders_raw( + project_name=project_name, + ) + + +def get_entity_list_folders( + project_name: str, +) -> list[dict[str, Any]]: + """Get entity list folders. + + Returns: + list[dict[str, Any]]: List of entity list folders. + + """ + con = get_server_api_connection() + return con.get_entity_list_folders( + project_name=project_name, + ) + + +def create_entity_list_folder( + project_name: str, + label: str, + *, + parent_id: str | None = None, + color: str | None = None, + icon: str | None = None, + scope: list[str] | None = None, + data: dict | None = None, + access: dict | None = None, + entity_list_folder_id: str | None = None, +) -> str: + """Create entity list folder. + + Args: + project_name (str): Project name. + label (str): Folder label. + parent_id (str | None): Parent folder id. If None, the folder will + be created in root. + color (str | None): Folder color. + icon (str | None): Folder icon. + scope (list[str] | None): Folder scope. + data (dict | None): Custom data of entity list folder. + access (dict | None): Access control for entity list folder. + entity_list_folder_id (str | None): Id of folder that will be + created. If None, a new id will be generated. + + Returns: + str: Created entity list folder id. + + """ + con = get_server_api_connection() + return con.create_entity_list_folder( + project_name=project_name, + label=label, + parent_id=parent_id, + color=color, + icon=icon, + scope=scope, + data=data, + access=access, + entity_list_folder_id=entity_list_folder_id, + ) + + +def update_entity_list_folder( + project_name: str, + entity_list_folder_id: str, + *, + label: str | None = None, + parent_id: str | None | type[NOT_SET] = NOT_SET, + color: str | None = None, + icon: str | None = None, + scope: list[str] | None = None, + data: dict | None = None, + access: dict | None = None, +) -> None: + """Update entity list folder. + + Args: + project_name (str): Project name. + entity_list_folder_id (str): Folder id that will be updated. + label (str | None): New label of entity list folder. + parent_id (str | None | type[NOT_SET]): New parent id of entity + list folder. If None, the folder will be moved to root. + color (str | None): New color of entity list folder. + icon (str | None): New icon of entity list folder. + scope (list[str] | None): New scope of entity list folder. + data (dict | None): Custom data of entity list folder. + access (dict | None): Access control for entity list folder. + + """ + con = get_server_api_connection() + return con.update_entity_list_folder( + project_name=project_name, + entity_list_folder_id=entity_list_folder_id, + label=label, + parent_id=parent_id, + color=color, + icon=icon, + scope=scope, + data=data, + access=access, + ) + + +def delete_entity_list_folder( + project_name: str, + entity_list_folder_id: str, +) -> None: + """Delete entity list folder. + """ + con = get_server_api_connection() + return con.delete_entity_list_folder( + project_name=project_name, + entity_list_folder_id=entity_list_folder_id, + ) + + +def set_entity_list_folders_order( + project_name: str, + order: list[str], +) -> None: + """Change order of entity list folders. + + Args: + project_name (str): Project name. + order (list[str]): List of folder ids in desired order. + + """ + con = get_server_api_connection() + return con.set_entity_list_folders_order( + project_name=project_name, + order=order, + ) + + def get_thumbnail_by_id( project_name: str, thumbnail_id: str, From 49bf525ce695c018a228fcd57098671516c7373c Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Thu, 11 Jun 2026 16:44:56 +0200 Subject: [PATCH 5/9] remove trailing spaces --- ayon_api/_api_helpers/lists.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ayon_api/_api_helpers/lists.py b/ayon_api/_api_helpers/lists.py index 7baf049eb..e5b4a2b25 100644 --- a/ayon_api/_api_helpers/lists.py +++ b/ayon_api/_api_helpers/lists.py @@ -655,7 +655,7 @@ def set_entity_list_folders_order( self, project_name: str, order: list[str] ) -> None: """Change order of entity list folders. - + Args: project_name (str): Project name. order (list[str]): List of folder ids in desired order. From dce11755ff2e074ce229b98c4c109262fc35abe2 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Fri, 12 Jun 2026 09:53:26 +0200 Subject: [PATCH 6/9] type fixes --- ayon_api/_api.py | 39 +++++++++++++++++------------- ayon_api/_api_helpers/lists.py | 43 ++++++++++++++++++++-------------- ayon_api/typing.py | 5 ++++ 3 files changed, 54 insertions(+), 33 deletions(-) diff --git a/ayon_api/_api.py b/ayon_api/_api.py index 1c0bb9861..dba95f59f 100644 --- a/ayon_api/_api.py +++ b/ayon_api/_api.py @@ -48,6 +48,7 @@ ActivityReferenceType, EntityListEntityType, EntityListItemMode, + EntityListScope, BackgroundOperationTask, LinkDirection, EventFilter, @@ -8001,8 +8002,7 @@ def create_entity_list( data (Optional[dict[str, Any]]): Custom data of entity list. tags (Optional[list[str]]): Entity list tags. template (Optional[dict[str, Any]]): Dynamic list template. - entity_list_folder_id (Optional[dict[str, Any]]): Entity list - folder id. + entity_list_folder_id (Optional[str]): Entity list folder id. owner (Optional[str]): New owner of the list. active (Optional[bool]): Change active state of entity list. items (Optional[list[dict[str, Any]]]): Initial items in @@ -8053,7 +8053,7 @@ def update_entity_list( entity list. data (Optional[dict[str, Any]]): Custom data of entity list. tags (Optional[list[str]]): Entity list tags. - entity_list_folder_id (dict[str, Any] | None | type[NOT_SET]): New + entity_list_folder_id (str | None | type[NOT_SET]): New entity list folder id. Use 'None' to move entity list to root. Use 'NOT_SET' to keep current folder. owner (Optional[str]): New owner of the list. @@ -8291,9 +8291,12 @@ def get_entity_list_entities( def get_entity_list_folders_raw( project_name: str, -) -> dict: +) -> dict[str, Any]: """Get entity list folders. + Args: + project_name (str): Project name. + Returns: dict[str, Any]: Raw output of entity list folders output. At this moment contains only "folders" key with list of folders, @@ -8328,9 +8331,9 @@ def create_entity_list_folder( parent_id: str | None = None, color: str | None = None, icon: str | None = None, - scope: list[str] | None = None, - data: dict | None = None, - access: dict | None = None, + scope: list[EntityListScope] | Non] = None, + data: dict[str, Any] | None = None, + access: dict[str, Any] | None = None, entity_list_folder_id: str | None = None, ) -> str: """Create entity list folder. @@ -8342,9 +8345,11 @@ def create_entity_list_folder( be created in root. color (str | None): Folder color. icon (str | None): Folder icon. - scope (list[str] | None): Folder scope. - data (dict | None): Custom data of entity list folder. - access (dict | None): Access control for entity list folder. + scope (list[EntityListScope] | None): Folder scope. Empty list can + be used to scope folder for all views. + data (dict[str, Any] | None): Custom data of entity list folder. + access (dict[str, Any] | None): Access control for + entity list folder. entity_list_folder_id (str | None): Id of folder that will be created. If None, a new id will be generated. @@ -8374,9 +8379,9 @@ def update_entity_list_folder( parent_id: str | None | type[NOT_SET] = NOT_SET, color: str | None = None, icon: str | None = None, - scope: list[str] | None = None, - data: dict | None = None, - access: dict | None = None, + scope: list[EntityListScope] | Non] = None, + data: dict[str, Any] | None = None, + access: dict[str, Any] | None = None, ) -> None: """Update entity list folder. @@ -8388,9 +8393,11 @@ def update_entity_list_folder( list folder. If None, the folder will be moved to root. color (str | None): New color of entity list folder. icon (str | None): New icon of entity list folder. - scope (list[str] | None): New scope of entity list folder. - data (dict | None): Custom data of entity list folder. - access (dict | None): Access control for entity list folder. + scope (list[EntityListScope] | None): New scope of entity list + folder. Empty list can be used to scope folder for all views. + data (dict[str, Any] | None): Custom data of entity list folder. + access (dict[str, Any] | None): Access control for + entity list folder. """ con = get_server_api_connection() diff --git a/ayon_api/_api_helpers/lists.py b/ayon_api/_api_helpers/lists.py index e5b4a2b25..76fa14572 100644 --- a/ayon_api/_api_helpers/lists.py +++ b/ayon_api/_api_helpers/lists.py @@ -15,6 +15,7 @@ EntityListEntityType, EntityListAttributeDefinitionDict, EntityListItemMode, + EntityListScope, ) @@ -180,8 +181,7 @@ def create_entity_list( data (Optional[dict[str, Any]]): Custom data of entity list. tags (Optional[list[str]]): Entity list tags. template (Optional[dict[str, Any]]): Dynamic list template. - entity_list_folder_id (Optional[dict[str, Any]]): Entity list - folder id. + entity_list_folder_id (Optional[str]): Entity list folder id. owner (Optional[str]): New owner of the list. active (Optional[bool]): Change active state of entity list. items (Optional[list[dict[str, Any]]]): Initial items in @@ -243,7 +243,7 @@ def update_entity_list( entity list. data (Optional[dict[str, Any]]): Custom data of entity list. tags (Optional[list[str]]): Entity list tags. - entity_list_folder_id (dict[str, Any] | None | type[NOT_SET]): New + entity_list_folder_id (str | None | type[NOT_SET]): New entity list folder id. Use 'None' to move entity list to root. Use 'NOT_SET' to keep current folder. owner (Optional[str]): New owner of the list. @@ -486,9 +486,14 @@ def get_entity_list_entities( response.raise_for_status() return response.data - def get_entity_list_folders_raw(self, project_name: str) -> dict: + def get_entity_list_folders_raw( + self, project_name: str + ) -> dict[str, Any]: """Get entity list folders. + Args: + project_name (str): Project name. + Returns: dict[str, Any]: Raw output of entity list folders output. At this moment contains only "folders" key with list of folders, @@ -519,9 +524,9 @@ def create_entity_list_folder( parent_id: str | None = None, color: str | None = None, icon: str | None = None, - scope: list[str] | None = None, - data: dict | None = None, - access: dict | None = None, + scope: list[EntityListScope] | None = None, + data: dict[str, Any] | None = None, + access: dict[str, Any] | None = None, entity_list_folder_id: str | None = None, ) -> str: """Create entity list folder. @@ -533,9 +538,11 @@ def create_entity_list_folder( be created in root. color (str | None): Folder color. icon (str | None): Folder icon. - scope (list[str] | None): Folder scope. - data (dict | None): Custom data of entity list folder. - access (dict | None): Access control for entity list folder. + scope (list[EntityListScope] | None): Folder scope. Empty list can + be used to scope folder for all views. + data (dict[str, Any] | None): Custom data of entity list folder. + access (dict[str, Any] | None): Access control for + entity list folder. entity_list_folder_id (str | None): Id of folder that will be created. If None, a new id will be generated. @@ -582,12 +589,12 @@ def update_entity_list_folder( entity_list_folder_id: str, *, label: str | None = None, - parent_id: str | None| type[NOT_SET] = NOT_SET, + parent_id: str | None | type[NOT_SET] = NOT_SET, color: str | None = None, icon: str | None = None, - scope: list[str] | None = None, - data: dict | None = None, - access: dict | None = None, + scope: list[EntityListScope] | None = None, + data: dict[str, Any] | None = None, + access: dict[str, Any] | None = None, ) -> None: """Update entity list folder. @@ -599,9 +606,11 @@ def update_entity_list_folder( list folder. If None, the folder will be moved to root. color (str | None): New color of entity list folder. icon (str | None): New icon of entity list folder. - scope (list[str] | None): New scope of entity list folder. - data (dict | None): Custom data of entity list folder. - access (dict | None): Access control for entity list folder. + scope (list[EntityListScope] | None): New scope of entity list + folder. Empty list can be used to scope folder for all views. + data (dict[str, Any] | None): Custom data of entity list folder. + access (dict[str, Any] | None): Access control for + entity list folder. """ if data is None: diff --git a/ayon_api/typing.py b/ayon_api/typing.py index f8016524f..dd1df5085 100644 --- a/ayon_api/typing.py +++ b/ayon_api/typing.py @@ -47,6 +47,11 @@ "delete", ] +EntityListScope = Literal[ + "generic", + "review-session", +] + EventFilterValueType = Union[ None, str, int, float, From 00eb34ee9536a73162b45af7ae1d147058f89aff Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Fri, 12 Jun 2026 10:11:16 +0200 Subject: [PATCH 7/9] better automated api --- automated_api.py | 46 ++++++++++------------------------------------ 1 file changed, 10 insertions(+), 36 deletions(-) diff --git a/automated_api.py b/automated_api.py index f7c1d01ea..ab6ced2d9 100644 --- a/automated_api.py +++ b/automated_api.py @@ -197,44 +197,10 @@ def _get_typehint(annotation, api_globals): # Test if typehint is valid for known '_api' content exec(f"_: {typehint} = None", api_globals) return typehint - except NameError: - print("Unknown typehint:", typehint) except Exception: print("Error while processing typehint:", typehint) raise - _typehint = typehint - _typehing_parents = [] - while True: - # Too hard to manage typehints with commas - if "[" not in _typehint: - break - - parts = _typehint.split("[") - parent = parts.pop(0) - - try: - # Test if typehint is valid for known '_api' content - exec(f"_: {parent} = None", api_globals) - except NameError: - _typehint = parent - break - - _typehint = "[".join(parts)[:-1] - if "," in _typehint: - _typing = parent - break - - _typehing_parents.append(parent) - - if _typehing_parents: - typehint = _typehint - for parent in reversed(_typehing_parents): - typehint = f"{parent}[{typehint}]" - return typehint - - return typehint - def _get_param_typehint(param, api_globals): if param.annotation is inspect.Parameter.empty: @@ -455,12 +421,20 @@ def main(): formatting_init_content = prepare_init_without_api(init_filepath) # Read content of first part of `_api.py` to get global variables - # - disable type checking so imports done only during typechecking are - # not executed + # - first with disabled type checking so other files from ayon_api are + # loded without any issues typing.TYPE_CHECKING = False api_globals = {"__name__": "ayon_api._api"} exec(parts[0], api_globals) + # - second with enabled type checking to get all available types in the + # file + # NOTE The file contains 'from __future__ import annotations' so any + # typehints can be used, but we should validate if are available. + typing.TYPE_CHECKING = True + api_globals = {"__name__": "ayon_api._api"} + exec(parts[0], api_globals) + for attr_name in dir(__builtins__): api_globals[attr_name] = getattr(__builtins__, attr_name) From 1e6fde5937ca2f0c063c5c068acbbf10ef14e1d0 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Fri, 12 Jun 2026 10:11:40 +0200 Subject: [PATCH 8/9] move 'CreateLinkData' to typing --- ayon_api/_api.py | 2 +- ayon_api/_api_helpers/links.py | 6 +----- ayon_api/typing.py | 4 ++++ 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ayon_api/_api.py b/ayon_api/_api.py index dba95f59f..ba0af2aba 100644 --- a/ayon_api/_api.py +++ b/ayon_api/_api.py @@ -51,6 +51,7 @@ EntityListScope, BackgroundOperationTask, LinkDirection, + CreateLinkData, EventFilter, EventStatus, EnrollEventData, @@ -86,7 +87,6 @@ EntityListAttributeDefinitionDict, AdvancedFilterDict, ) - from ._api_helpers.links import CreateLinkData class GlobalServerAPI(ServerAPI): diff --git a/ayon_api/_api_helpers/links.py b/ayon_api/_api_helpers/links.py index b2b8d0973..a50b21817 100644 --- a/ayon_api/_api_helpers/links.py +++ b/ayon_api/_api_helpers/links.py @@ -15,11 +15,7 @@ from .base import BaseServerAPI if typing.TYPE_CHECKING: - from typing import TypedDict - from ayon_api.typing import LinkDirection - - class CreateLinkData(TypedDict): - id: str + from ayon_api.typing import LinkDirection, CreateLinkData class LinksAPI(BaseServerAPI): diff --git a/ayon_api/typing.py b/ayon_api/typing.py index dd1df5085..e620de085 100644 --- a/ayon_api/typing.py +++ b/ayon_api/typing.py @@ -128,6 +128,10 @@ class BackgroundOperationTask(TypedDict): LinkDirection = Literal["in", "out"] +class CreateLinkData(TypedDict): + id: str + + class AttributeEnumItemDict(TypedDict): value: Union[str, int, float, bool] label: str From b035208914d63521fc30717fc3f8a56268c5629f Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Fri, 12 Jun 2026 10:11:53 +0200 Subject: [PATCH 9/9] fix typehints --- ayon_api/_api.py | 8 ++++---- ayon_api/_api_helpers/lists.py | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ayon_api/_api.py b/ayon_api/_api.py index ba0af2aba..42eac9827 100644 --- a/ayon_api/_api.py +++ b/ayon_api/_api.py @@ -8053,8 +8053,8 @@ def update_entity_list( entity list. data (Optional[dict[str, Any]]): Custom data of entity list. tags (Optional[list[str]]): Entity list tags. - entity_list_folder_id (str | None | type[NOT_SET]): New - entity list folder id. Use 'None' to move entity list to root. + entity_list_folder_id (str | None | type[NOT_SET]): New entity + list folder id. Use ``None`` to move entity list to root. Use 'NOT_SET' to keep current folder. owner (Optional[str]): New owner of the list. active (Optional[bool]): Change active state of entity list. @@ -8331,7 +8331,7 @@ def create_entity_list_folder( parent_id: str | None = None, color: str | None = None, icon: str | None = None, - scope: list[EntityListScope] | Non] = None, + scope: list[EntityListScope] | None = None, data: dict[str, Any] | None = None, access: dict[str, Any] | None = None, entity_list_folder_id: str | None = None, @@ -8379,7 +8379,7 @@ def update_entity_list_folder( parent_id: str | None | type[NOT_SET] = NOT_SET, color: str | None = None, icon: str | None = None, - scope: list[EntityListScope] | Non] = None, + scope: list[EntityListScope] | None = None, data: dict[str, Any] | None = None, access: dict[str, Any] | None = None, ) -> None: diff --git a/ayon_api/_api_helpers/lists.py b/ayon_api/_api_helpers/lists.py index 76fa14572..329ccdf66 100644 --- a/ayon_api/_api_helpers/lists.py +++ b/ayon_api/_api_helpers/lists.py @@ -243,8 +243,8 @@ def update_entity_list( entity list. data (Optional[dict[str, Any]]): Custom data of entity list. tags (Optional[list[str]]): Entity list tags. - entity_list_folder_id (str | None | type[NOT_SET]): New - entity list folder id. Use 'None' to move entity list to root. + entity_list_folder_id (str | None | type[NOT_SET]): New entity + list folder id. Use ``None`` to move entity list to root. Use 'NOT_SET' to keep current folder. owner (Optional[str]): New owner of the list. active (Optional[bool]): Change active state of entity list.