From 64f66f5333d5742956f8487667d5bd1f9a9b1453 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 26 Oct 2026 17:02:17 +0100 Subject: [PATCH 1/4] Store own attributes dictionary in 'own_attrib' - 'fill_own_attribs' stores the dictionary in 'own_attrib'. 'ownAttrib' is still replaced with a copy for backwards compatibility. - Users have 'own_attrib' too. - EntityHub uses 'own_attrib'. Co-Authored-By: Claude Opus 5.5 --- ayon_api/_api.py | 60 ++++++++++++++++++------------- ayon_api/_api_helpers/folders.py | 20 ++++++----- ayon_api/_api_helpers/projects.py | 10 +++--- ayon_api/_api_helpers/tasks.py | 30 +++++++++------- ayon_api/entity_hub.py | 6 ++-- ayon_api/server_api.py | 1 + ayon_api/utils.py | 15 +++++--- 7 files changed, 86 insertions(+), 56 deletions(-) diff --git a/ayon_api/_api.py b/ayon_api/_api.py index c23760665..6f6f47c15 100644 --- a/ayon_api/_api.py +++ b/ayon_api/_api.py @@ -5173,8 +5173,9 @@ def get_projects( include_skeleton (bool): Include skeleton projects. fields (Optional[Iterable[str]]): fields to be queried for project. - own_attributes (Optional[bool]): Attribute values that are - not explicitly set on entity will have 'None' value. + own_attributes (Optional[bool]): Fill 'own_attrib' with + attribute values that are explicitly set on entity, other + attributes have 'None' value. Returns: Generator[ProjectDict, None, None]: Queried projects. @@ -5201,8 +5202,9 @@ def get_project( project_name (str): Name of project. fields (Optional[Iterable[str]]): fields to be queried for project. - own_attributes (Optional[bool]): Attribute values that are - not explicitly set on entity will have 'None' value. + own_attributes (Optional[bool]): Fill 'own_attrib' with + attribute values that are explicitly set on entity, other + attributes have 'None' value. Returns: Optional[ProjectDict]: Project entity data or None @@ -6128,8 +6130,9 @@ def get_folders( fields (Optional[Iterable[str]]): Fields to be queried for folder. All possible folder fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Attribute values that are - not explicitly set on entity will have 'None' value. + own_attributes (Optional[bool]): Fill 'own_attrib' with + attribute values that are explicitly set on entity, other + attributes have 'None' value. Returns: Generator[FolderDict, None, None]: Queried folder entities. @@ -6172,8 +6175,9 @@ def get_folder_by_id( folder_id (str): Folder id. fields (Optional[Iterable[str]]): Fields that should be returned. All fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Attribute values that are - not explicitly set on entity will have 'None' value. + own_attributes (Optional[bool]): Fill 'own_attrib' with + attribute values that are explicitly set on entity, other + attributes have 'None' value. Returns: Optional[FolderDict]: Folder entity data or None @@ -6205,8 +6209,9 @@ def get_folder_by_path( folder_path (str): Folder path. fields (Optional[Iterable[str]]): Fields that should be returned. All fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Attribute values that are - not explicitly set on entity will have 'None' value. + own_attributes (Optional[bool]): Fill 'own_attrib' with + attribute values that are explicitly set on entity, other + attributes have 'None' value. Returns: Optional[FolderDict]: Folder entity data or None @@ -6240,8 +6245,9 @@ def get_folder_by_name( folder_name (str): Folder name. fields (Optional[Iterable[str]]): Fields that should be returned. All fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Attribute values that are - not explicitly set on entity will have 'None' value. + own_attributes (Optional[bool]): Fill 'own_attrib' with + attribute values that are explicitly set on entity, other + attributes have 'None' value. Returns: Optional[FolderDict]: Folder entity data or None @@ -6552,8 +6558,9 @@ def get_tasks( fields (Optional[Iterable[str]]): Fields to be queried for folder. All possible folder fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Attribute values that are - not explicitly set on entity will have 'None' value. + own_attributes (Optional[bool]): Fill 'own_attrib' with + attribute values that are explicitly set on entity, other + attributes have 'None' value. Returns: Generator[TaskDict, None, None]: Queried task entities. @@ -6593,8 +6600,9 @@ def get_task_by_name( task_name (str): Task name fields (Optional[Iterable[str]]): Fields that should be returned. All fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Attribute values that are - not explicitly set on entity will have 'None' value. + own_attributes (Optional[bool]): Fill 'own_attrib' with + attribute values that are explicitly set on entity, other + attributes have 'None' value. Returns: Optional[TaskDict]: Task entity data or None if was not found. @@ -6624,8 +6632,9 @@ def get_task_by_id( task_id (str): Task id. fields (Optional[Iterable[str]]): Fields that should be returned. All fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Attribute values that are - not explicitly set on entity will have 'None' value. + own_attributes (Optional[bool]): Fill 'own_attrib' with + attribute values that are explicitly set on entity, other + attributes have 'None' value. Returns: Optional[TaskDict]: Task entity data or None if was not found. @@ -6677,8 +6686,9 @@ def get_tasks_by_folder_paths( fields (Optional[Iterable[str]]): Fields to be queried for folder. All possible folder fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Attribute values that are - not explicitly set on entity will have 'None' value. + own_attributes (Optional[bool]): Fill 'own_attrib' with + attribute values that are explicitly set on entity, other + attributes have 'None' value. Returns: dict[str, list[TaskDict]]: Task entities by @@ -6737,8 +6747,9 @@ def get_tasks_by_folder_path( fields (Optional[Iterable[str]]): Fields to be queried for folder. All possible folder fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Attribute values that are - not explicitly set on entity will have 'None' value. + own_attributes (Optional[bool]): Fill 'own_attrib' with + attribute values that are explicitly set on entity, other + attributes have 'None' value. """ con = get_server_api_connection() @@ -6772,8 +6783,9 @@ def get_task_by_folder_path( task_name (str): Task name. fields (Optional[Iterable[str]]): Task fields that should be returned. - own_attributes (Optional[bool]): Attribute values that are - not explicitly set on entity will have 'None' value. + own_attributes (Optional[bool]): Fill 'own_attrib' with + attribute values that are explicitly set on entity, other + attributes have 'None' value. Returns: Optional[TaskDict]: Task entity data or None if was not found. diff --git a/ayon_api/_api_helpers/folders.py b/ayon_api/_api_helpers/folders.py index c0cb8341e..366d6f1a5 100644 --- a/ayon_api/_api_helpers/folders.py +++ b/ayon_api/_api_helpers/folders.py @@ -263,8 +263,9 @@ def get_folders( fields (Optional[Iterable[str]]): Fields to be queried for folder. All possible folder fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Attribute values that are - not explicitly set on entity will have 'None' value. + own_attributes (Optional[bool]): Fill 'own_attrib' with + attribute values that are explicitly set on entity, other + attributes have 'None' value. Returns: Generator[FolderDict, None, None]: Queried folder entities. @@ -360,8 +361,9 @@ def get_folder_by_id( folder_id (str): Folder id. fields (Optional[Iterable[str]]): Fields that should be returned. All fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Attribute values that are - not explicitly set on entity will have 'None' value. + own_attributes (Optional[bool]): Fill 'own_attrib' with + attribute values that are explicitly set on entity, other + attributes have 'None' value. Returns: Optional[FolderDict]: Folder entity data or None @@ -396,8 +398,9 @@ def get_folder_by_path( folder_path (str): Folder path. fields (Optional[Iterable[str]]): Fields that should be returned. All fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Attribute values that are - not explicitly set on entity will have 'None' value. + own_attributes (Optional[bool]): Fill 'own_attrib' with + attribute values that are explicitly set on entity, other + attributes have 'None' value. Returns: Optional[FolderDict]: Folder entity data or None @@ -434,8 +437,9 @@ def get_folder_by_name( folder_name (str): Folder name. fields (Optional[Iterable[str]]): Fields that should be returned. All fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Attribute values that are - not explicitly set on entity will have 'None' value. + own_attributes (Optional[bool]): Fill 'own_attrib' with + attribute values that are explicitly set on entity, other + attributes have 'None' value. Returns: Optional[FolderDict]: Folder entity data or None diff --git a/ayon_api/_api_helpers/projects.py b/ayon_api/_api_helpers/projects.py index c7c25d5de..1250606ae 100644 --- a/ayon_api/_api_helpers/projects.py +++ b/ayon_api/_api_helpers/projects.py @@ -369,8 +369,9 @@ def get_projects( include_skeleton (bool): Include skeleton projects. fields (Optional[Iterable[str]]): fields to be queried for project. - own_attributes (Optional[bool]): Attribute values that are - not explicitly set on entity will have 'None' value. + own_attributes (Optional[bool]): Fill 'own_attrib' with + attribute values that are explicitly set on entity, other + attributes have 'None' value. Returns: Generator[ProjectDict, None, None]: Queried projects. @@ -430,8 +431,9 @@ def get_project( project_name (str): Name of project. fields (Optional[Iterable[str]]): fields to be queried for project. - own_attributes (Optional[bool]): Attribute values that are - not explicitly set on entity will have 'None' value. + own_attributes (Optional[bool]): Fill 'own_attrib' with + attribute values that are explicitly set on entity, other + attributes have 'None' value. Returns: Optional[ProjectDict]: Project entity data or None diff --git a/ayon_api/_api_helpers/tasks.py b/ayon_api/_api_helpers/tasks.py index 4c6209443..a26163758 100644 --- a/ayon_api/_api_helpers/tasks.py +++ b/ayon_api/_api_helpers/tasks.py @@ -64,8 +64,9 @@ def get_tasks( fields (Optional[Iterable[str]]): Fields to be queried for folder. All possible folder fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Attribute values that are - not explicitly set on entity will have 'None' value. + own_attributes (Optional[bool]): Fill 'own_attrib' with + attribute values that are explicitly set on entity, other + attributes have 'None' value. Returns: Generator[TaskDict, None, None]: Queried task entities. @@ -137,8 +138,9 @@ def get_task_by_name( task_name (str): Task name fields (Optional[Iterable[str]]): Fields that should be returned. All fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Attribute values that are - not explicitly set on entity will have 'None' value. + own_attributes (Optional[bool]): Fill 'own_attrib' with + attribute values that are explicitly set on entity, other + attributes have 'None' value. Returns: Optional[TaskDict]: Task entity data or None if was not found. @@ -170,8 +172,9 @@ def get_task_by_id( task_id (str): Task id. fields (Optional[Iterable[str]]): Fields that should be returned. All fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Attribute values that are - not explicitly set on entity will have 'None' value. + own_attributes (Optional[bool]): Fill 'own_attrib' with + attribute values that are explicitly set on entity, other + attributes have 'None' value. Returns: Optional[TaskDict]: Task entity data or None if was not found. @@ -225,8 +228,9 @@ def get_tasks_by_folder_paths( fields (Optional[Iterable[str]]): Fields to be queried for folder. All possible folder fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Attribute values that are - not explicitly set on entity will have 'None' value. + own_attributes (Optional[bool]): Fill 'own_attrib' with + attribute values that are explicitly set on entity, other + attributes have 'None' value. Returns: dict[str, list[TaskDict]]: Task entities by @@ -312,8 +316,9 @@ def get_tasks_by_folder_path( fields (Optional[Iterable[str]]): Fields to be queried for folder. All possible folder fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Attribute values that are - not explicitly set on entity will have 'None' value. + own_attributes (Optional[bool]): Fill 'own_attrib' with + attribute values that are explicitly set on entity, other + attributes have 'None' value. """ return self.get_tasks_by_folder_paths( @@ -346,8 +351,9 @@ def get_task_by_folder_path( task_name (str): Task name. fields (Optional[Iterable[str]]): Task fields that should be returned. - own_attributes (Optional[bool]): Attribute values that are - not explicitly set on entity will have 'None' value. + own_attributes (Optional[bool]): Fill 'own_attrib' with + attribute values that are explicitly set on entity, other + attributes have 'None' value. Returns: Optional[TaskDict]: Task entity data or None if was not found. diff --git a/ayon_api/entity_hub.py b/ayon_api/entity_hub.py index 942fa60ea..c727575c3 100644 --- a/ayon_api/entity_hub.py +++ b/ayon_api/entity_hub.py @@ -3151,7 +3151,7 @@ def from_entity_data(cls, project, entity_hub) -> ProjectEntity: folder_types=project["folderTypes"], task_types=project["taskTypes"], statuses=project["statuses"], - attribs=project["ownAttrib"], + attribs=project["own_attrib"], data=project["data"], active=project["active"], entity_hub=entity_hub, @@ -3324,7 +3324,7 @@ def from_entity_data( path=folder["path"], status=folder["status"], tags=folder["tags"], - attribs=folder["ownAttrib"], + attribs=folder["own_attrib"], data=folder.get("data"), thumbnail_id=folder["thumbnailId"], active=folder["active"], @@ -3521,7 +3521,7 @@ def from_entity_data( label=task["label"], status=task["status"], tags=task["tags"], - attribs=task["ownAttrib"], + attribs=task["own_attrib"], data=task.get("data"), assignees=task["assignees"], thumbnail_id=task["thumbnailId"], diff --git a/ayon_api/server_api.py b/ayon_api/server_api.py index b9c8c1f70..dd7d70d4a 100644 --- a/ayon_api/server_api.py +++ b/ayon_api/server_api.py @@ -1210,6 +1210,7 @@ def get_users( own_attrib.setdefault(name, None) user["attrib"] = attrib + user["own_attrib"] = copy.deepcopy(own_attrib) yield user diff --git a/ayon_api/utils.py b/ayon_api/utils.py index f5769e7d8..21fec761e 100644 --- a/ayon_api/utils.py +++ b/ayon_api/utils.py @@ -264,9 +264,11 @@ def get(self, key, default=None): def fill_own_attribs(entity: AnyEntityDict) -> None: """Fill own attributes. - Prepare data with own attributes. Prepare data based on a list of - attribute names in 'ownAttrib' and 'attrib'. If is not attribute in - 'ownAttrib' then it's value is set to 'None'. + Prepare data with own attributes to 'own_attrib'. Prepare data based on + a list of attribute names in 'ownAttrib' and 'attrib'. If is not + attribute in 'ownAttrib' then it's value is set to 'None'. + + 'ownAttrib' is replaced with the same data for backwards compatibility. This can be used with a project, folder or task entity. All other entities don't use hierarchical attributes and 'attrib' values are @@ -285,14 +287,17 @@ def fill_own_attribs(entity: AnyEntityDict) -> None: attributes = set(attributes) own_attrib = {} - entity["ownAttrib"] = own_attrib - for key, value in entity["attrib"].items(): if key not in attributes: own_attrib[key] = None else: own_attrib[key] = copy.deepcopy(value) + entity["own_attrib"] = own_attrib + # TODO remove when nothing uses 'ownAttrib' as dictionary, + # it should be list of attribute names as returned from server + entity["ownAttrib"] = copy.deepcopy(own_attrib) + def _convert_filter_value(value: Any) -> list[Any] | None: if value is None: From 53fe1040a2f7eb44ca01dcb790fb311213bdacb7 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 26 Oct 2026 17:03:56 +0100 Subject: [PATCH 2/4] Rename 'own_attrib' key to 'own_attributes' Co-Authored-By: Claude Opus 5.5 --- ayon_api/_api.py | 24 ++++++++++++------------ ayon_api/_api_helpers/folders.py | 8 ++++---- ayon_api/_api_helpers/projects.py | 4 ++-- ayon_api/_api_helpers/tasks.py | 12 ++++++------ ayon_api/entity_hub.py | 6 +++--- ayon_api/server_api.py | 2 +- ayon_api/utils.py | 4 ++-- 7 files changed, 30 insertions(+), 30 deletions(-) diff --git a/ayon_api/_api.py b/ayon_api/_api.py index 6f6f47c15..a289e03e1 100644 --- a/ayon_api/_api.py +++ b/ayon_api/_api.py @@ -5173,7 +5173,7 @@ def get_projects( include_skeleton (bool): Include skeleton projects. fields (Optional[Iterable[str]]): fields to be queried for project. - own_attributes (Optional[bool]): Fill 'own_attrib' with + own_attributes (Optional[bool]): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -5202,7 +5202,7 @@ def get_project( project_name (str): Name of project. fields (Optional[Iterable[str]]): fields to be queried for project. - own_attributes (Optional[bool]): Fill 'own_attrib' with + own_attributes (Optional[bool]): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -6130,7 +6130,7 @@ def get_folders( fields (Optional[Iterable[str]]): Fields to be queried for folder. All possible folder fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attrib' with + own_attributes (Optional[bool]): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -6175,7 +6175,7 @@ def get_folder_by_id( folder_id (str): Folder id. fields (Optional[Iterable[str]]): Fields that should be returned. All fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attrib' with + own_attributes (Optional[bool]): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -6209,7 +6209,7 @@ def get_folder_by_path( folder_path (str): Folder path. fields (Optional[Iterable[str]]): Fields that should be returned. All fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attrib' with + own_attributes (Optional[bool]): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -6245,7 +6245,7 @@ def get_folder_by_name( folder_name (str): Folder name. fields (Optional[Iterable[str]]): Fields that should be returned. All fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attrib' with + own_attributes (Optional[bool]): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -6558,7 +6558,7 @@ def get_tasks( fields (Optional[Iterable[str]]): Fields to be queried for folder. All possible folder fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attrib' with + own_attributes (Optional[bool]): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -6600,7 +6600,7 @@ def get_task_by_name( task_name (str): Task name fields (Optional[Iterable[str]]): Fields that should be returned. All fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attrib' with + own_attributes (Optional[bool]): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -6632,7 +6632,7 @@ def get_task_by_id( task_id (str): Task id. fields (Optional[Iterable[str]]): Fields that should be returned. All fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attrib' with + own_attributes (Optional[bool]): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -6686,7 +6686,7 @@ def get_tasks_by_folder_paths( fields (Optional[Iterable[str]]): Fields to be queried for folder. All possible folder fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attrib' with + own_attributes (Optional[bool]): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -6747,7 +6747,7 @@ def get_tasks_by_folder_path( fields (Optional[Iterable[str]]): Fields to be queried for folder. All possible folder fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attrib' with + own_attributes (Optional[bool]): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -6783,7 +6783,7 @@ def get_task_by_folder_path( task_name (str): Task name. fields (Optional[Iterable[str]]): Task fields that should be returned. - own_attributes (Optional[bool]): Fill 'own_attrib' with + own_attributes (Optional[bool]): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. diff --git a/ayon_api/_api_helpers/folders.py b/ayon_api/_api_helpers/folders.py index 366d6f1a5..0e0ac6036 100644 --- a/ayon_api/_api_helpers/folders.py +++ b/ayon_api/_api_helpers/folders.py @@ -263,7 +263,7 @@ def get_folders( fields (Optional[Iterable[str]]): Fields to be queried for folder. All possible folder fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attrib' with + own_attributes (Optional[bool]): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -361,7 +361,7 @@ def get_folder_by_id( folder_id (str): Folder id. fields (Optional[Iterable[str]]): Fields that should be returned. All fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attrib' with + own_attributes (Optional[bool]): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -398,7 +398,7 @@ def get_folder_by_path( folder_path (str): Folder path. fields (Optional[Iterable[str]]): Fields that should be returned. All fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attrib' with + own_attributes (Optional[bool]): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -437,7 +437,7 @@ def get_folder_by_name( folder_name (str): Folder name. fields (Optional[Iterable[str]]): Fields that should be returned. All fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attrib' with + own_attributes (Optional[bool]): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. diff --git a/ayon_api/_api_helpers/projects.py b/ayon_api/_api_helpers/projects.py index 1250606ae..2d2ec7364 100644 --- a/ayon_api/_api_helpers/projects.py +++ b/ayon_api/_api_helpers/projects.py @@ -369,7 +369,7 @@ def get_projects( include_skeleton (bool): Include skeleton projects. fields (Optional[Iterable[str]]): fields to be queried for project. - own_attributes (Optional[bool]): Fill 'own_attrib' with + own_attributes (Optional[bool]): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -431,7 +431,7 @@ def get_project( project_name (str): Name of project. fields (Optional[Iterable[str]]): fields to be queried for project. - own_attributes (Optional[bool]): Fill 'own_attrib' with + own_attributes (Optional[bool]): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. diff --git a/ayon_api/_api_helpers/tasks.py b/ayon_api/_api_helpers/tasks.py index a26163758..a6f82d544 100644 --- a/ayon_api/_api_helpers/tasks.py +++ b/ayon_api/_api_helpers/tasks.py @@ -64,7 +64,7 @@ def get_tasks( fields (Optional[Iterable[str]]): Fields to be queried for folder. All possible folder fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attrib' with + own_attributes (Optional[bool]): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -138,7 +138,7 @@ def get_task_by_name( task_name (str): Task name fields (Optional[Iterable[str]]): Fields that should be returned. All fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attrib' with + own_attributes (Optional[bool]): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -172,7 +172,7 @@ def get_task_by_id( task_id (str): Task id. fields (Optional[Iterable[str]]): Fields that should be returned. All fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attrib' with + own_attributes (Optional[bool]): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -228,7 +228,7 @@ def get_tasks_by_folder_paths( fields (Optional[Iterable[str]]): Fields to be queried for folder. All possible folder fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attrib' with + own_attributes (Optional[bool]): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -316,7 +316,7 @@ def get_tasks_by_folder_path( fields (Optional[Iterable[str]]): Fields to be queried for folder. All possible folder fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attrib' with + own_attributes (Optional[bool]): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -351,7 +351,7 @@ def get_task_by_folder_path( task_name (str): Task name. fields (Optional[Iterable[str]]): Task fields that should be returned. - own_attributes (Optional[bool]): Fill 'own_attrib' with + own_attributes (Optional[bool]): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. diff --git a/ayon_api/entity_hub.py b/ayon_api/entity_hub.py index c727575c3..bb8aebf0d 100644 --- a/ayon_api/entity_hub.py +++ b/ayon_api/entity_hub.py @@ -3151,7 +3151,7 @@ def from_entity_data(cls, project, entity_hub) -> ProjectEntity: folder_types=project["folderTypes"], task_types=project["taskTypes"], statuses=project["statuses"], - attribs=project["own_attrib"], + attribs=project["own_attributes"], data=project["data"], active=project["active"], entity_hub=entity_hub, @@ -3324,7 +3324,7 @@ def from_entity_data( path=folder["path"], status=folder["status"], tags=folder["tags"], - attribs=folder["own_attrib"], + attribs=folder["own_attributes"], data=folder.get("data"), thumbnail_id=folder["thumbnailId"], active=folder["active"], @@ -3521,7 +3521,7 @@ def from_entity_data( label=task["label"], status=task["status"], tags=task["tags"], - attribs=task["own_attrib"], + attribs=task["own_attributes"], data=task.get("data"), assignees=task["assignees"], thumbnail_id=task["thumbnailId"], diff --git a/ayon_api/server_api.py b/ayon_api/server_api.py index dd7d70d4a..97581de5e 100644 --- a/ayon_api/server_api.py +++ b/ayon_api/server_api.py @@ -1210,7 +1210,7 @@ def get_users( own_attrib.setdefault(name, None) user["attrib"] = attrib - user["own_attrib"] = copy.deepcopy(own_attrib) + user["own_attributes"] = copy.deepcopy(own_attrib) yield user diff --git a/ayon_api/utils.py b/ayon_api/utils.py index 21fec761e..3e1057f67 100644 --- a/ayon_api/utils.py +++ b/ayon_api/utils.py @@ -264,7 +264,7 @@ def get(self, key, default=None): def fill_own_attribs(entity: AnyEntityDict) -> None: """Fill own attributes. - Prepare data with own attributes to 'own_attrib'. Prepare data based on + Prepare data with own attributes to 'own_attributes'. Prepare data based on a list of attribute names in 'ownAttrib' and 'attrib'. If is not attribute in 'ownAttrib' then it's value is set to 'None'. @@ -293,7 +293,7 @@ def fill_own_attribs(entity: AnyEntityDict) -> None: else: own_attrib[key] = copy.deepcopy(value) - entity["own_attrib"] = own_attrib + entity["own_attributes"] = own_attrib # TODO remove when nothing uses 'ownAttrib' as dictionary, # it should be list of attribute names as returned from server entity["ownAttrib"] = copy.deepcopy(own_attrib) From 68a374883f8bb770a3a91bdbf9f96aa34150d2aa Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 26 Oct 2026 17:09:52 +0100 Subject: [PATCH 3/4] Add 'own_attributes' argument to user getters 'get_users', 'get_user_by_name' and 'get_user' fill 'own_attributes' only when 'own_attributes' is 'True'. 'ownAttrib' is always a dictionary for backwards compatibility. Co-Authored-By: Claude Opus 5.5 --- ayon_api/_api.py | 15 +++++++++++++++ ayon_api/_api_helpers/base.py | 4 +++- ayon_api/server_api.py | 22 ++++++++++++++++++++-- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/ayon_api/_api.py b/ayon_api/_api.py index a289e03e1..f381b29bd 100644 --- a/ayon_api/_api.py +++ b/ayon_api/_api.py @@ -802,6 +802,7 @@ def get_users( usernames: Iterable[str] | None = None, emails: Iterable[str] | None = None, fields: Iterable[str] | None = None, + own_attributes: bool = False, ) -> Generator[dict[str, Any], None, None]: """Get Users. @@ -814,6 +815,9 @@ def get_users( emails (Iterable[str] | None): Filter by emails. fields (Iterable[str] | None): Fields to be queried for users. + own_attributes (bool): Fill 'own_attributes' with + attribute values that are explicitly set on user, other + attributes have 'None' value. Returns: Generator[dict[str, Any], None, None]: Queried users. @@ -825,6 +829,7 @@ def get_users( usernames=usernames, emails=emails, fields=fields, + own_attributes=own_attributes, ) @@ -832,6 +837,7 @@ def get_user_by_name( username: str, project_name: str | None = None, fields: Iterable[str] | None = None, + own_attributes: bool = False, ) -> dict[str, Any] | None: """Get user by name using GraphQl. @@ -842,6 +848,9 @@ def get_user_by_name( username (str): Username. project_name (str | None): Define scope of project. fields (Iterable[str] | None): Fields to be queried for users. + own_attributes (bool): Fill 'own_attributes' with + attribute values that are explicitly set on user, other + attributes have 'None' value. Returns: dict[str, Any] | None: User info or None if user is not found. @@ -852,11 +861,13 @@ def get_user_by_name( username=username, project_name=project_name, fields=fields, + own_attributes=own_attributes, ) def get_user( username: str | None = None, + own_attributes: bool = False, ) -> dict[str, Any] | None: """Get user info using REST endpoint. @@ -864,6 +875,9 @@ def get_user( Args: username (str | None): Username. + own_attributes (bool): Fill 'own_attributes' with + attribute values that are explicitly set on user, other + attributes have 'None' value. Returns: dict[str, Any] | None: User info or None if user is not @@ -873,6 +887,7 @@ def get_user( con = get_server_api_connection() return con.get_user( username=username, + own_attributes=own_attributes, ) diff --git a/ayon_api/_api_helpers/base.py b/ayon_api/_api_helpers/base.py index d852a95b4..6110b5e0d 100644 --- a/ayon_api/_api_helpers/base.py +++ b/ayon_api/_api_helpers/base.py @@ -129,7 +129,9 @@ def get_project( raise NotImplementedError() def get_user( - self, username: Optional[str] = None + self, + username: Optional[str] = None, + own_attributes: bool = False, ) -> Optional[dict[str, Any]]: raise NotImplementedError() diff --git a/ayon_api/server_api.py b/ayon_api/server_api.py index 97581de5e..41ac0eaf9 100644 --- a/ayon_api/server_api.py +++ b/ayon_api/server_api.py @@ -1135,6 +1135,7 @@ def get_users( usernames: Iterable[str] | None = None, emails: Iterable[str] | None = None, fields: Iterable[str] | None = None, + own_attributes: bool = False, ) -> Generator[dict[str, Any], None, None]: """Get Users. @@ -1147,6 +1148,9 @@ def get_users( emails (Iterable[str] | None): Filter by emails. fields (Iterable[str] | None): Fields to be queried for users. + own_attributes (bool): Fill 'own_attributes' with + attribute values that are explicitly set on user, other + attributes have 'None' value. Returns: Generator[dict[str, Any], None, None]: Queried users. @@ -1210,7 +1214,8 @@ def get_users( own_attrib.setdefault(name, None) user["attrib"] = attrib - user["own_attributes"] = copy.deepcopy(own_attrib) + if own_attributes: + user["own_attributes"] = copy.deepcopy(own_attrib) yield user @@ -1219,6 +1224,7 @@ def get_user_by_name( username: str, project_name: str | None = None, fields: Iterable[str] | None = None, + own_attributes: bool = False, ) -> dict[str, Any] | None: """Get user by name using GraphQl. @@ -1229,6 +1235,9 @@ def get_user_by_name( username (str): Username. project_name (str | None): Define scope of project. fields (Iterable[str] | None): Fields to be queried for users. + own_attributes (bool): Fill 'own_attributes' with + attribute values that are explicitly set on user, other + attributes have 'None' value. Returns: dict[str, Any] | None: User info or None if user is not found. @@ -1241,12 +1250,15 @@ def get_user_by_name( project_name=project_name, usernames={username}, fields=fields, + own_attributes=own_attributes, ): return user return None def get_user( - self, username: str | None = None + self, + username: str | None = None, + own_attributes: bool = False, ) -> dict[str, Any] | None: """Get user info using REST endpoint. @@ -1254,6 +1266,9 @@ def get_user( Args: username (str | None): Username. + own_attributes (bool): Fill 'own_attributes' with + attribute values that are explicitly set on user, other + attributes have 'None' value. Returns: dict[str, Any] | None: User info or None if user is not @@ -1273,7 +1288,10 @@ def get_user( for attr_name, attr_data in attributes.items(): user["attrib"].setdefault(attr_name, attr_data["default"]) + # NOTE 'ownAttrib' is always filled for backwards compatibility fill_own_attribs(user) + if not own_attributes: + user.pop("own_attributes", None) return user def get_headers( From 0835e953092740e2ff7697fe2704199964646399 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 26 Oct 2026 17:14:45 +0100 Subject: [PATCH 4/4] Use 'bool' type in 'own_attributes' docstrings Co-Authored-By: Claude Opus 5.5 --- ayon_api/_api.py | 24 ++++++++++++------------ ayon_api/_api_helpers/folders.py | 8 ++++---- ayon_api/_api_helpers/projects.py | 4 ++-- ayon_api/_api_helpers/tasks.py | 12 ++++++------ 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/ayon_api/_api.py b/ayon_api/_api.py index f381b29bd..e7af02f25 100644 --- a/ayon_api/_api.py +++ b/ayon_api/_api.py @@ -5188,7 +5188,7 @@ def get_projects( include_skeleton (bool): Include skeleton projects. fields (Optional[Iterable[str]]): fields to be queried for project. - own_attributes (Optional[bool]): Fill 'own_attributes' with + own_attributes (bool): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -5217,7 +5217,7 @@ def get_project( project_name (str): Name of project. fields (Optional[Iterable[str]]): fields to be queried for project. - own_attributes (Optional[bool]): Fill 'own_attributes' with + own_attributes (bool): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -6145,7 +6145,7 @@ def get_folders( fields (Optional[Iterable[str]]): Fields to be queried for folder. All possible folder fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attributes' with + own_attributes (bool): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -6190,7 +6190,7 @@ def get_folder_by_id( folder_id (str): Folder id. fields (Optional[Iterable[str]]): Fields that should be returned. All fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attributes' with + own_attributes (bool): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -6224,7 +6224,7 @@ def get_folder_by_path( folder_path (str): Folder path. fields (Optional[Iterable[str]]): Fields that should be returned. All fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attributes' with + own_attributes (bool): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -6260,7 +6260,7 @@ def get_folder_by_name( folder_name (str): Folder name. fields (Optional[Iterable[str]]): Fields that should be returned. All fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attributes' with + own_attributes (bool): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -6573,7 +6573,7 @@ def get_tasks( fields (Optional[Iterable[str]]): Fields to be queried for folder. All possible folder fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attributes' with + own_attributes (bool): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -6615,7 +6615,7 @@ def get_task_by_name( task_name (str): Task name fields (Optional[Iterable[str]]): Fields that should be returned. All fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attributes' with + own_attributes (bool): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -6647,7 +6647,7 @@ def get_task_by_id( task_id (str): Task id. fields (Optional[Iterable[str]]): Fields that should be returned. All fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attributes' with + own_attributes (bool): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -6701,7 +6701,7 @@ def get_tasks_by_folder_paths( fields (Optional[Iterable[str]]): Fields to be queried for folder. All possible folder fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attributes' with + own_attributes (bool): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -6762,7 +6762,7 @@ def get_tasks_by_folder_path( fields (Optional[Iterable[str]]): Fields to be queried for folder. All possible folder fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attributes' with + own_attributes (bool): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -6798,7 +6798,7 @@ def get_task_by_folder_path( task_name (str): Task name. fields (Optional[Iterable[str]]): Task fields that should be returned. - own_attributes (Optional[bool]): Fill 'own_attributes' with + own_attributes (bool): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. diff --git a/ayon_api/_api_helpers/folders.py b/ayon_api/_api_helpers/folders.py index 0e0ac6036..b045cd6e4 100644 --- a/ayon_api/_api_helpers/folders.py +++ b/ayon_api/_api_helpers/folders.py @@ -263,7 +263,7 @@ def get_folders( fields (Optional[Iterable[str]]): Fields to be queried for folder. All possible folder fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attributes' with + own_attributes (bool): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -361,7 +361,7 @@ def get_folder_by_id( folder_id (str): Folder id. fields (Optional[Iterable[str]]): Fields that should be returned. All fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attributes' with + own_attributes (bool): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -398,7 +398,7 @@ def get_folder_by_path( folder_path (str): Folder path. fields (Optional[Iterable[str]]): Fields that should be returned. All fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attributes' with + own_attributes (bool): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -437,7 +437,7 @@ def get_folder_by_name( folder_name (str): Folder name. fields (Optional[Iterable[str]]): Fields that should be returned. All fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attributes' with + own_attributes (bool): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. diff --git a/ayon_api/_api_helpers/projects.py b/ayon_api/_api_helpers/projects.py index 2d2ec7364..5cd34037c 100644 --- a/ayon_api/_api_helpers/projects.py +++ b/ayon_api/_api_helpers/projects.py @@ -369,7 +369,7 @@ def get_projects( include_skeleton (bool): Include skeleton projects. fields (Optional[Iterable[str]]): fields to be queried for project. - own_attributes (Optional[bool]): Fill 'own_attributes' with + own_attributes (bool): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -431,7 +431,7 @@ def get_project( project_name (str): Name of project. fields (Optional[Iterable[str]]): fields to be queried for project. - own_attributes (Optional[bool]): Fill 'own_attributes' with + own_attributes (bool): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. diff --git a/ayon_api/_api_helpers/tasks.py b/ayon_api/_api_helpers/tasks.py index a6f82d544..190e43012 100644 --- a/ayon_api/_api_helpers/tasks.py +++ b/ayon_api/_api_helpers/tasks.py @@ -64,7 +64,7 @@ def get_tasks( fields (Optional[Iterable[str]]): Fields to be queried for folder. All possible folder fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attributes' with + own_attributes (bool): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -138,7 +138,7 @@ def get_task_by_name( task_name (str): Task name fields (Optional[Iterable[str]]): Fields that should be returned. All fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attributes' with + own_attributes (bool): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -172,7 +172,7 @@ def get_task_by_id( task_id (str): Task id. fields (Optional[Iterable[str]]): Fields that should be returned. All fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attributes' with + own_attributes (bool): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -228,7 +228,7 @@ def get_tasks_by_folder_paths( fields (Optional[Iterable[str]]): Fields to be queried for folder. All possible folder fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attributes' with + own_attributes (bool): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -316,7 +316,7 @@ def get_tasks_by_folder_path( fields (Optional[Iterable[str]]): Fields to be queried for folder. All possible folder fields are returned if 'None' is passed. - own_attributes (Optional[bool]): Fill 'own_attributes' with + own_attributes (bool): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value. @@ -351,7 +351,7 @@ def get_task_by_folder_path( task_name (str): Task name. fields (Optional[Iterable[str]]): Task fields that should be returned. - own_attributes (Optional[bool]): Fill 'own_attributes' with + own_attributes (bool): Fill 'own_attributes' with attribute values that are explicitly set on entity, other attributes have 'None' value.