Skip to content

Commit 2e616b6

Browse files
authored
Merge pull request #337 from ynput/enhancement/update-lists-api
Updated lists api
2 parents 9600430 + b035208 commit 2e616b6

6 files changed

Lines changed: 446 additions & 43 deletions

File tree

automated_api.py

Lines changed: 13 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -197,40 +197,9 @@ def _get_typehint(annotation, api_globals):
197197
# Test if typehint is valid for known '_api' content
198198
exec(f"_: {typehint} = None", api_globals)
199199
return typehint
200-
except NameError:
201-
print("Unknown typehint:", typehint)
202-
203-
_typehint = typehint
204-
_typehing_parents = []
205-
while True:
206-
# Too hard to manage typehints with commas
207-
if "[" not in _typehint:
208-
break
209-
210-
parts = _typehint.split("[")
211-
parent = parts.pop(0)
212-
213-
try:
214-
# Test if typehint is valid for known '_api' content
215-
exec(f"_: {parent} = None", api_globals)
216-
except NameError:
217-
_typehint = parent
218-
break
219-
220-
_typehint = "[".join(parts)[:-1]
221-
if "," in _typehint:
222-
_typing = parent
223-
break
224-
225-
_typehing_parents.append(parent)
226-
227-
if _typehing_parents:
228-
typehint = _typehint
229-
for parent in reversed(_typehing_parents):
230-
typehint = f"{parent}[{typehint}]"
231-
return typehint
232-
233-
return typehint
200+
except Exception:
201+
print("Error while processing typehint:", typehint)
202+
raise
234203

235204

236205
def _get_param_typehint(param, api_globals):
@@ -452,12 +421,20 @@ def main():
452421
formatting_init_content = prepare_init_without_api(init_filepath)
453422

454423
# Read content of first part of `_api.py` to get global variables
455-
# - disable type checking so imports done only during typechecking are
456-
# not executed
424+
# - first with disabled type checking so other files from ayon_api are
425+
# loded without any issues
457426
typing.TYPE_CHECKING = False
458427
api_globals = {"__name__": "ayon_api._api"}
459428
exec(parts[0], api_globals)
460429

430+
# - second with enabled type checking to get all available types in the
431+
# file
432+
# NOTE The file contains 'from __future__ import annotations' so any
433+
# typehints can be used, but we should validate if are available.
434+
typing.TYPE_CHECKING = True
435+
api_globals = {"__name__": "ayon_api._api"}
436+
exec(parts[0], api_globals)
437+
461438
for attr_name in dir(__builtins__):
462439
api_globals[attr_name] = getattr(__builtins__, attr_name)
463440

ayon_api/__init__.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,13 @@
298298
update_entity_list_items,
299299
update_entity_list_item,
300300
delete_entity_list_item,
301+
get_entity_list_entities,
302+
get_entity_list_folders_raw,
303+
get_entity_list_folders,
304+
create_entity_list_folder,
305+
update_entity_list_folder,
306+
delete_entity_list_folder,
307+
set_entity_list_folders_order,
301308
get_thumbnail_by_id,
302309
get_thumbnail,
303310
get_folder_thumbnail,
@@ -609,6 +616,13 @@
609616
"update_entity_list_items",
610617
"update_entity_list_item",
611618
"delete_entity_list_item",
619+
"get_entity_list_entities",
620+
"get_entity_list_folders_raw",
621+
"get_entity_list_folders",
622+
"create_entity_list_folder",
623+
"update_entity_list_folder",
624+
"delete_entity_list_folder",
625+
"set_entity_list_folders_order",
612626
"get_thumbnail_by_id",
613627
"get_thumbnail",
614628
"get_folder_thumbnail",

ayon_api/_api.py

Lines changed: 187 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,10 @@
4848
ActivityReferenceType,
4949
EntityListEntityType,
5050
EntityListItemMode,
51+
EntityListScope,
5152
BackgroundOperationTask,
5253
LinkDirection,
54+
CreateLinkData,
5355
EventFilter,
5456
EventStatus,
5557
EnrollEventData,
@@ -85,7 +87,6 @@
8587
EntityListAttributeDefinitionDict,
8688
AdvancedFilterDict,
8789
)
88-
from ._api_helpers.links import CreateLinkData
8990

9091

9192
class GlobalServerAPI(ServerAPI):
@@ -7981,6 +7982,7 @@ def create_entity_list(
79817982
data: Optional[list[dict[str, Any]]] = None,
79827983
tags: Optional[list[str]] = None,
79837984
template: Optional[dict[str, Any]] = None,
7985+
entity_list_folder_id: Optional[str] = None,
79847986
owner: Optional[str] = None,
79857987
active: Optional[bool] = None,
79867988
items: Optional[list[dict[str, Any]]] = None,
@@ -8000,6 +8002,7 @@ def create_entity_list(
80008002
data (Optional[dict[str, Any]]): Custom data of entity list.
80018003
tags (Optional[list[str]]): Entity list tags.
80028004
template (Optional[dict[str, Any]]): Dynamic list template.
8005+
entity_list_folder_id (Optional[str]): Entity list folder id.
80038006
owner (Optional[str]): New owner of the list.
80048007
active (Optional[bool]): Change active state of entity list.
80058008
items (Optional[list[dict[str, Any]]]): Initial items in
@@ -8018,6 +8021,7 @@ def create_entity_list(
80188021
data=data,
80198022
tags=tags,
80208023
template=template,
8024+
entity_list_folder_id=entity_list_folder_id,
80218025
owner=owner,
80228026
active=active,
80238027
items=items,
@@ -8034,6 +8038,7 @@ def update_entity_list(
80348038
attrib: Optional[list[dict[str, Any]]] = None,
80358039
data: Optional[list[dict[str, Any]]] = None,
80368040
tags: Optional[list[str]] = None,
8041+
entity_list_folder_id: str | None | type[NOT_SET] = NOT_SET,
80378042
owner: Optional[str] = None,
80388043
active: Optional[bool] = None,
80398044
) -> None:
@@ -8048,6 +8053,9 @@ def update_entity_list(
80488053
entity list.
80498054
data (Optional[dict[str, Any]]): Custom data of entity list.
80508055
tags (Optional[list[str]]): Entity list tags.
8056+
entity_list_folder_id (str | None | type[NOT_SET]): New entity
8057+
list folder id. Use ``None`` to move entity list to root.
8058+
Use 'NOT_SET' to keep current folder.
80518059
owner (Optional[str]): New owner of the list.
80528060
active (Optional[bool]): Change active state of entity list.
80538061
@@ -8061,6 +8069,7 @@ def update_entity_list(
80618069
attrib=attrib,
80628070
data=data,
80638071
tags=tags,
8072+
entity_list_folder_id=entity_list_folder_id,
80648073
owner=owner,
80658074
active=active,
80668075
)
@@ -8259,6 +8268,183 @@ def delete_entity_list_item(
82598268
)
82608269

82618270

8271+
def get_entity_list_entities(
8272+
project_name: str,
8273+
entity_list_id: str,
8274+
) -> dict[str, Any]:
8275+
"""Get entity list items using REST API.
8276+
8277+
Args:
8278+
project_name (str): Project name.
8279+
entity_list_id (str): Entity list id.
8280+
8281+
Returns:
8282+
dict[str, Any]: Information about entities on the list.
8283+
8284+
"""
8285+
con = get_server_api_connection()
8286+
return con.get_entity_list_entities(
8287+
project_name=project_name,
8288+
entity_list_id=entity_list_id,
8289+
)
8290+
8291+
8292+
def get_entity_list_folders_raw(
8293+
project_name: str,
8294+
) -> dict[str, Any]:
8295+
"""Get entity list folders.
8296+
8297+
Args:
8298+
project_name (str): Project name.
8299+
8300+
Returns:
8301+
dict[str, Any]: Raw output of entity list folders output. At this
8302+
moment contains only "folders" key with list of folders,
8303+
but it can be extended in the future.
8304+
8305+
"""
8306+
con = get_server_api_connection()
8307+
return con.get_entity_list_folders_raw(
8308+
project_name=project_name,
8309+
)
8310+
8311+
8312+
def get_entity_list_folders(
8313+
project_name: str,
8314+
) -> list[dict[str, Any]]:
8315+
"""Get entity list folders.
8316+
8317+
Returns:
8318+
list[dict[str, Any]]: List of entity list folders.
8319+
8320+
"""
8321+
con = get_server_api_connection()
8322+
return con.get_entity_list_folders(
8323+
project_name=project_name,
8324+
)
8325+
8326+
8327+
def create_entity_list_folder(
8328+
project_name: str,
8329+
label: str,
8330+
*,
8331+
parent_id: str | None = None,
8332+
color: str | None = None,
8333+
icon: str | None = None,
8334+
scope: list[EntityListScope] | None = None,
8335+
data: dict[str, Any] | None = None,
8336+
access: dict[str, Any] | None = None,
8337+
entity_list_folder_id: str | None = None,
8338+
) -> str:
8339+
"""Create entity list folder.
8340+
8341+
Args:
8342+
project_name (str): Project name.
8343+
label (str): Folder label.
8344+
parent_id (str | None): Parent folder id. If None, the folder will
8345+
be created in root.
8346+
color (str | None): Folder color.
8347+
icon (str | None): Folder icon.
8348+
scope (list[EntityListScope] | None): Folder scope. Empty list can
8349+
be used to scope folder for all views.
8350+
data (dict[str, Any] | None): Custom data of entity list folder.
8351+
access (dict[str, Any] | None): Access control for
8352+
entity list folder.
8353+
entity_list_folder_id (str | None): Id of folder that will be
8354+
created. If None, a new id will be generated.
8355+
8356+
Returns:
8357+
str: Created entity list folder id.
8358+
8359+
"""
8360+
con = get_server_api_connection()
8361+
return con.create_entity_list_folder(
8362+
project_name=project_name,
8363+
label=label,
8364+
parent_id=parent_id,
8365+
color=color,
8366+
icon=icon,
8367+
scope=scope,
8368+
data=data,
8369+
access=access,
8370+
entity_list_folder_id=entity_list_folder_id,
8371+
)
8372+
8373+
8374+
def update_entity_list_folder(
8375+
project_name: str,
8376+
entity_list_folder_id: str,
8377+
*,
8378+
label: str | None = None,
8379+
parent_id: str | None | type[NOT_SET] = NOT_SET,
8380+
color: str | None = None,
8381+
icon: str | None = None,
8382+
scope: list[EntityListScope] | None = None,
8383+
data: dict[str, Any] | None = None,
8384+
access: dict[str, Any] | None = None,
8385+
) -> None:
8386+
"""Update entity list folder.
8387+
8388+
Args:
8389+
project_name (str): Project name.
8390+
entity_list_folder_id (str): Folder id that will be updated.
8391+
label (str | None): New label of entity list folder.
8392+
parent_id (str | None | type[NOT_SET]): New parent id of entity
8393+
list folder. If None, the folder will be moved to root.
8394+
color (str | None): New color of entity list folder.
8395+
icon (str | None): New icon of entity list folder.
8396+
scope (list[EntityListScope] | None): New scope of entity list
8397+
folder. Empty list can be used to scope folder for all views.
8398+
data (dict[str, Any] | None): Custom data of entity list folder.
8399+
access (dict[str, Any] | None): Access control for
8400+
entity list folder.
8401+
8402+
"""
8403+
con = get_server_api_connection()
8404+
return con.update_entity_list_folder(
8405+
project_name=project_name,
8406+
entity_list_folder_id=entity_list_folder_id,
8407+
label=label,
8408+
parent_id=parent_id,
8409+
color=color,
8410+
icon=icon,
8411+
scope=scope,
8412+
data=data,
8413+
access=access,
8414+
)
8415+
8416+
8417+
def delete_entity_list_folder(
8418+
project_name: str,
8419+
entity_list_folder_id: str,
8420+
) -> None:
8421+
"""Delete entity list folder.
8422+
"""
8423+
con = get_server_api_connection()
8424+
return con.delete_entity_list_folder(
8425+
project_name=project_name,
8426+
entity_list_folder_id=entity_list_folder_id,
8427+
)
8428+
8429+
8430+
def set_entity_list_folders_order(
8431+
project_name: str,
8432+
order: list[str],
8433+
) -> None:
8434+
"""Change order of entity list folders.
8435+
8436+
Args:
8437+
project_name (str): Project name.
8438+
order (list[str]): List of folder ids in desired order.
8439+
8440+
"""
8441+
con = get_server_api_connection()
8442+
return con.set_entity_list_folders_order(
8443+
project_name=project_name,
8444+
order=order,
8445+
)
8446+
8447+
82628448
def get_thumbnail_by_id(
82638449
project_name: str,
82648450
thumbnail_id: str,

ayon_api/_api_helpers/links.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,7 @@
1515
from .base import BaseServerAPI
1616

1717
if typing.TYPE_CHECKING:
18-
from typing import TypedDict
19-
from ayon_api.typing import LinkDirection
20-
21-
class CreateLinkData(TypedDict):
22-
id: str
18+
from ayon_api.typing import LinkDirection, CreateLinkData
2319

2420

2521
class LinksAPI(BaseServerAPI):

0 commit comments

Comments
 (0)