Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
b8e1050
:sparkles: add support for product base types
antirotor May 30, 2025
1eeae55
:bug: remove the stray character in comment
antirotor May 30, 2025
4d83ab8
:sparkles: add `productBaseType` to PRODUCT_FIELDS
antirotor Jun 6, 2025
ceff641
:recycle: better handling of product base type in entity operations
antirotor Jun 10, 2025
e3bc2c5
:sparkles: add product base type getters to init and linting
antirotor Jun 10, 2025
3a96dd6
fix used function to create query
iLLiCiTiT Jun 26, 2025
cb4a9f9
remove unnecessary 'get_product_base_type_names' function
iLLiCiTiT Jun 26, 2025
07bcdb3
Merge branch 'develop' into enhancement/254-product-base-types-add-su…
antirotor Sep 18, 2025
67c4557
remove functions that are not needed
iLLiCiTiT Sep 19, 2025
6813200
remove 'get_product_base_type_names' again
iLLiCiTiT Sep 19, 2025
44d139a
remove 'get_product_base_types' from '_api'
iLLiCiTiT Sep 19, 2025
819a69f
remove icon and color from product base types fields
iLLiCiTiT Sep 19, 2025
26a3f84
remove unused 'ProductBaseTypeDict'
iLLiCiTiT Sep 19, 2025
937ada3
remove 'productBaseType' fields handling
iLLiCiTiT Sep 19, 2025
7d63720
handle 'productBaseType' field if passed in as is
iLLiCiTiT Sep 19, 2025
0691d8e
remove 'get_product_base_types'
iLLiCiTiT Sep 19, 2025
7d984af
added base of product base type support logic
iLLiCiTiT Sep 19, 2025
818e762
implement product base type handling in entity hub
iLLiCiTiT Sep 19, 2025
a52c1f9
added product base type to products api methods
iLLiCiTiT Sep 19, 2025
3dae224
change order of product_base_type argument
iLLiCiTiT Sep 19, 2025
82291c6
change one more argument order
iLLiCiTiT Sep 19, 2025
7c83f11
remove unused import
iLLiCiTiT Sep 19, 2025
072bef1
:recycle: add check and more support in graphql
antirotor Sep 22, 2025
16551af
Merge branch 'develop' into enhancement/254-product-base-types-add-su…
antirotor Oct 22, 2025
0965474
Merge remote-tracking branch 'origin/develop' into enhancement/254-pr…
antirotor Nov 10, 2025
735de48
Merge remote-tracking branch 'origin/enhancement/254-product-base-typ…
antirotor Nov 10, 2025
10e49d7
:recycle: add server version for product base types
antirotor Nov 10, 2025
5c04bad
Update ayon_api/operations.py
antirotor Nov 13, 2025
daef6b9
rename 'product_base_type_supported' to 'is_product_base_type_supported'
iLLiCiTiT Nov 14, 2025
da9c871
add 'productBaseType' only if is supported
iLLiCiTiT Nov 14, 2025
dae95dd
raise error if product base type is not supported but is passed in
iLLiCiTiT Nov 14, 2025
9d31f0e
Merge branch 'develop' into enhancement/254-product-base-types-add-su…
iLLiCiTiT Nov 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions ayon_api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
get_info,
get_server_version,
get_server_version_tuple,
is_product_base_type_supported,
get_users,
get_user_by_name,
get_user,
Expand Down Expand Up @@ -332,6 +333,7 @@
"get_info",
"get_server_version",
"get_server_version_tuple",
"is_product_base_type_supported",
"get_users",
"get_user_by_name",
"get_user",
Expand Down
15 changes: 15 additions & 0 deletions ayon_api/_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,13 @@ def get_server_version_tuple() -> ServerVersion:
return con.get_server_version_tuple()


def is_product_base_type_supported() -> bool:
"""Product base types are available on server.
"""
con = get_server_api_connection()
return con.is_product_base_type_supported()


def get_users(
project_name: Optional[str] = None,
usernames: Optional[Iterable[str]] = None,
Expand Down Expand Up @@ -4900,6 +4907,7 @@ def get_products(
product_names: Optional[Iterable[str]] = None,
folder_ids: Optional[Iterable[str]] = None,
product_types: Optional[Iterable[str]] = None,
product_base_types: Optional[Iterable[str]] = None,
product_name_regex: Optional[str] = None,
product_path_regex: Optional[str] = None,
names_by_folder_ids: Optional[dict[str, Iterable[str]]] = None,
Expand Down Expand Up @@ -4952,6 +4960,7 @@ def get_products(
product_names=product_names,
folder_ids=folder_ids,
product_types=product_types,
product_base_types=product_base_types,
product_name_regex=product_name_regex,
product_path_regex=product_path_regex,
names_by_folder_ids=names_by_folder_ids,
Expand Down Expand Up @@ -5110,6 +5119,7 @@ def create_product(
tags: Optional[Iterable[str]] = None,
status: Optional[str] = None,
active: Optional[bool] = None,
product_base_type: Optional[str] = None,
product_id: Optional[str] = None,
) -> str:
"""Create new product.
Expand All @@ -5124,6 +5134,7 @@ def create_product(
tags (Optional[Iterable[str]]): Product tags.
status (Optional[str]): Product status.
active (Optional[bool]): Product active state.
product_base_type (Optional[str]): Product base type.
product_id (Optional[str]): Product id. If not passed new id is
generated.

Expand All @@ -5142,6 +5153,7 @@ def create_product(
tags=tags,
status=status,
active=active,
product_base_type=product_base_type,
product_id=product_id,
)

Expand All @@ -5152,6 +5164,7 @@ def update_product(
name: Optional[str] = None,
folder_id: Optional[str] = None,
product_type: Optional[str] = None,
product_base_type: Optional[str] = None,
attrib: Optional[dict[str, Any]] = None,
data: Optional[dict[str, Any]] = None,
tags: Optional[Iterable[str]] = None,
Expand All @@ -5171,6 +5184,7 @@ def update_product(
name (Optional[str]): New product name.
folder_id (Optional[str]): New product id.
product_type (Optional[str]): New product type.
product_base_type (Optional[str]): New product base type.
attrib (Optional[dict[str, Any]]): New product attributes.
data (Optional[dict[str, Any]]): New product data.
tags (Optional[Iterable[str]]): New product tags.
Expand All @@ -5185,6 +5199,7 @@ def update_product(
name=name,
folder_id=folder_id,
product_type=product_type,
product_base_type=product_base_type,
attrib=attrib,
data=data,
tags=tags,
Expand Down
3 changes: 3 additions & 0 deletions ayon_api/_api_helpers/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ class BaseServerAPI:
def log(self) -> logging.Logger:
raise NotImplementedError()

def is_product_base_type_supported(self) -> bool:
raise NotImplementedError()

def get_server_version(self) -> str:
raise NotImplementedError()

Expand Down
38 changes: 35 additions & 3 deletions ayon_api/_api_helpers/products.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import typing
from typing import Optional, Iterable, Generator, Any

from ayon_api.exceptions import UnsupportedServerVersion
from ayon_api.utils import (
prepare_list_filters,
create_entity_id,
Expand Down Expand Up @@ -32,9 +33,10 @@ def get_products(
self,
project_name: str,
product_ids: Optional[Iterable[str]] = None,
product_names: Optional[Iterable[str]]=None,
folder_ids: Optional[Iterable[str]]=None,
product_types: Optional[Iterable[str]]=None,
product_names: Optional[Iterable[str]] = None,
folder_ids: Optional[Iterable[str]] = None,
product_types: Optional[Iterable[str]] = None,
product_base_types: Optional[Iterable[str]] = None,
product_name_regex: Optional[str] = None,
product_path_regex: Optional[str] = None,
names_by_folder_ids: Optional[dict[str, Iterable[str]]] = None,
Expand All @@ -59,6 +61,8 @@ def get_products(
Use 'None' if folder is direct child of project.
product_types (Optional[Iterable[str]]): Product types used for
filtering.
product_base_types (Optional[Iterable[str]]): Product base types
used for filtering.
product_name_regex (Optional[str]): Filter products by name regex.
product_path_regex (Optional[str]): Filter products by path regex.
Path starts with folder path and ends with product name.
Expand All @@ -83,6 +87,11 @@ def get_products(
if not project_name:
return

if product_base_types and not self.is_product_base_type_supported():
raise UnsupportedServerVersion(
"Product base type is not supported for your server version."
)

# Prepare these filters before 'name_by_filter_ids' filter
filter_product_names = None
if product_names is not None:
Expand Down Expand Up @@ -150,6 +159,7 @@ def get_products(
filters,
("productIds", product_ids),
("productTypes", product_types),
("productBaseTypes", product_base_types),
("productStatuses", statuses),
("productTags", tags),
):
Expand Down Expand Up @@ -378,6 +388,7 @@ def create_product(
tags: Optional[Iterable[str]] =None,
status: Optional[str] = None,
active: Optional[bool] = None,
product_base_type: Optional[str] = None,
product_id: Optional[str] = None,
) -> str:
"""Create new product.
Expand All @@ -392,13 +403,22 @@ def create_product(
tags (Optional[Iterable[str]]): Product tags.
status (Optional[str]): Product status.
active (Optional[bool]): Product active state.
product_base_type (Optional[str]): Product base type.
product_id (Optional[str]): Product id. If not passed new id is
generated.

Returns:
str: Product id.

"""
if (
product_base_type is not None
and not self.is_product_base_type_supported()
):
raise UnsupportedServerVersion(
"Product base type is not supported for your server version."
)

if not product_id:
product_id = create_entity_id()
create_data = {
Expand All @@ -408,6 +428,7 @@ def create_product(
"folderId": folder_id,
}
for key, value in (
("productBaseType", product_base_type),
("attrib", attrib),
("data", data),
("tags", tags),
Expand All @@ -431,6 +452,7 @@ def update_product(
name: Optional[str] = None,
folder_id: Optional[str] = None,
product_type: Optional[str] = None,
product_base_type: Optional[str] = None,
attrib: Optional[dict[str, Any]] = None,
data: Optional[dict[str, Any]] = None,
tags: Optional[Iterable[str]] = None,
Expand All @@ -450,17 +472,27 @@ def update_product(
name (Optional[str]): New product name.
folder_id (Optional[str]): New product id.
product_type (Optional[str]): New product type.
product_base_type (Optional[str]): New product base type.
attrib (Optional[dict[str, Any]]): New product attributes.
data (Optional[dict[str, Any]]): New product data.
tags (Optional[Iterable[str]]): New product tags.
status (Optional[str]): New product status.
active (Optional[bool]): New product active state.

"""
if (
product_base_type is not None
and not self.is_product_base_type_supported()
):
raise UnsupportedServerVersion(
"Product base type is not supported for your server version."
)

update_data = {}
for key, value in (
("name", name),
("productType", product_type),
("productBaseType", product_base_type),
("folderId", folder_id),
("attrib", attrib),
("data", data),
Expand Down
14 changes: 9 additions & 5 deletions ayon_api/_api_helpers/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@
import typing
from typing import Optional, Generator, Iterable, Any

from ayon_api.constants import PROJECT_NAME_REGEX
from ayon_api.constants import (
PROJECT_NAME_REGEX,
DEFAULT_PRODUCT_BASE_TYPE_FIELDS,
DEFAULT_PRODUCT_TYPE_FIELDS,
)
from ayon_api.utils import prepare_query_string, fill_own_attribs
from ayon_api.graphql_queries import projects_graphql_query

Expand Down Expand Up @@ -679,9 +683,8 @@ def _get_project_graphql_fields(
elif field == "productTypes":
must_use_graphql = True
fields.discard(field)
graphql_fields.add("productTypes.name")
graphql_fields.add("productTypes.icon")
graphql_fields.add("productTypes.color")
for f_name in DEFAULT_PRODUCT_TYPE_FIELDS:
fields.add(f"{field}.{f_name}")

elif field.startswith("productTypes"):
must_use_graphql = True
Expand All @@ -690,7 +693,8 @@ def _get_project_graphql_fields(
elif field == "productBaseTypes":
must_use_graphql = True
fields.discard(field)
graphql_fields.add("productBaseTypes.name")
for f_name in DEFAULT_PRODUCT_BASE_TYPE_FIELDS:
fields.add(f"{field}.{f_name}")

elif field.startswith("productBaseTypes"):
must_use_graphql = True
Expand Down
7 changes: 7 additions & 0 deletions ayon_api/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,13 @@
"color",
}

# --- Product base type ---
DEFAULT_PRODUCT_BASE_TYPE_FIELDS = {
# Ignore 'icon' and 'color'
# - current server implementation always returns 'null'
"name",
}

# --- Project ---
DEFAULT_PROJECT_FIELDS = {
"active",
Expand Down
Loading