ayon-python-api 1.0.12__tar.gz → 1.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ayon-python-api-1.0.12 → ayon-python-api-1.1.0}/PKG-INFO +1 -1
- {ayon-python-api-1.0.12 → ayon-python-api-1.1.0}/ayon_api/__init__.py +2 -0
- {ayon-python-api-1.0.12 → ayon-python-api-1.1.0}/ayon_api/_api.py +37 -4
- {ayon-python-api-1.0.12 → ayon-python-api-1.1.0}/ayon_api/constants.py +1 -0
- {ayon-python-api-1.0.12 → ayon-python-api-1.1.0}/ayon_api/entity_hub.py +8 -70
- {ayon-python-api-1.0.12 → ayon-python-api-1.1.0}/ayon_api/graphql_queries.py +4 -0
- {ayon-python-api-1.0.12 → ayon-python-api-1.1.0}/ayon_api/operations.py +22 -4
- {ayon-python-api-1.0.12 → ayon-python-api-1.1.0}/ayon_api/server_api.py +110 -150
- {ayon-python-api-1.0.12 → ayon-python-api-1.1.0}/ayon_api/utils.py +7 -5
- {ayon-python-api-1.0.12 → ayon-python-api-1.1.0}/ayon_api/version.py +1 -1
- {ayon-python-api-1.0.12 → ayon-python-api-1.1.0}/ayon_python_api.egg-info/PKG-INFO +1 -1
- {ayon-python-api-1.0.12 → ayon-python-api-1.1.0}/ayon_python_api.egg-info/requires.txt +0 -1
- {ayon-python-api-1.0.12 → ayon-python-api-1.1.0}/pyproject.toml +2 -4
- {ayon-python-api-1.0.12 → ayon-python-api-1.1.0}/LICENSE +0 -0
- {ayon-python-api-1.0.12 → ayon-python-api-1.1.0}/README.md +0 -0
- {ayon-python-api-1.0.12 → ayon-python-api-1.1.0}/ayon_api/events.py +0 -0
- {ayon-python-api-1.0.12 → ayon-python-api-1.1.0}/ayon_api/exceptions.py +0 -0
- {ayon-python-api-1.0.12 → ayon-python-api-1.1.0}/ayon_api/graphql.py +0 -0
- {ayon-python-api-1.0.12 → ayon-python-api-1.1.0}/ayon_api/typing.py +0 -0
- {ayon-python-api-1.0.12 → ayon-python-api-1.1.0}/ayon_python_api.egg-info/SOURCES.txt +0 -0
- {ayon-python-api-1.0.12 → ayon-python-api-1.1.0}/ayon_python_api.egg-info/dependency_links.txt +0 -0
- {ayon-python-api-1.0.12 → ayon-python-api-1.1.0}/ayon_python_api.egg-info/top_level.txt +0 -0
- {ayon-python-api-1.0.12 → ayon-python-api-1.1.0}/setup.cfg +0 -0
- {ayon-python-api-1.0.12 → ayon-python-api-1.1.0}/setup.py +0 -0
|
@@ -214,6 +214,7 @@ from ._api import (
|
|
|
214
214
|
get_thumbnail_by_id,
|
|
215
215
|
get_thumbnail,
|
|
216
216
|
get_folder_thumbnail,
|
|
217
|
+
get_task_thumbnail,
|
|
217
218
|
get_version_thumbnail,
|
|
218
219
|
get_workfile_thumbnail,
|
|
219
220
|
create_thumbnail,
|
|
@@ -459,6 +460,7 @@ __all__ = (
|
|
|
459
460
|
"get_thumbnail_by_id",
|
|
460
461
|
"get_thumbnail",
|
|
461
462
|
"get_folder_thumbnail",
|
|
463
|
+
"get_task_thumbnail",
|
|
462
464
|
"get_version_thumbnail",
|
|
463
465
|
"get_workfile_thumbnail",
|
|
464
466
|
"create_thumbnail",
|
|
@@ -706,6 +706,7 @@ def get_server_version_tuple() -> Tuple[int, int, int, str, str]:
|
|
|
706
706
|
def get_users(
|
|
707
707
|
project_name: Optional[str] = None,
|
|
708
708
|
usernames: Optional[Iterable[str]] = None,
|
|
709
|
+
emails: Optional[Iterable[str]] = None,
|
|
709
710
|
fields: Optional[Iterable[str]] = None,
|
|
710
711
|
) -> Generator[Dict[str, Any], None, None]:
|
|
711
712
|
"""Get Users.
|
|
@@ -716,6 +717,7 @@ def get_users(
|
|
|
716
717
|
Args:
|
|
717
718
|
project_name (Optional[str]): Project name.
|
|
718
719
|
usernames (Optional[Iterable[str]]): Filter by usernames.
|
|
720
|
+
emails (Optional[Iterable[str]]): Filter by emails.
|
|
719
721
|
fields (Optional[Iterable[str]]): Fields to be queried
|
|
720
722
|
for users.
|
|
721
723
|
|
|
@@ -727,6 +729,7 @@ def get_users(
|
|
|
727
729
|
return con.get_users(
|
|
728
730
|
project_name=project_name,
|
|
729
731
|
usernames=usernames,
|
|
732
|
+
emails=emails,
|
|
730
733
|
fields=fields,
|
|
731
734
|
)
|
|
732
735
|
|
|
@@ -5472,6 +5475,7 @@ def create_representation(
|
|
|
5472
5475
|
files: Optional[List[Dict[str, Any]]] = None,
|
|
5473
5476
|
attrib: Optional[Dict[str, Any]] = None,
|
|
5474
5477
|
data: Optional[Dict[str, Any]] = None,
|
|
5478
|
+
traits: Optional[Dict[str, Any]] = None,
|
|
5475
5479
|
tags: Optional[List[str]] = None,
|
|
5476
5480
|
status: Optional[str] = None,
|
|
5477
5481
|
active: Optional[bool] = None,
|
|
@@ -5486,6 +5490,8 @@ def create_representation(
|
|
|
5486
5490
|
files (Optional[list[dict]]): Representation files information.
|
|
5487
5491
|
attrib (Optional[dict[str, Any]]): Representation attributes.
|
|
5488
5492
|
data (Optional[dict[str, Any]]): Representation data.
|
|
5493
|
+
traits (Optional[dict[str, Any]]): Representation traits
|
|
5494
|
+
serialized data as dict.
|
|
5489
5495
|
tags (Optional[Iterable[str]]): Representation tags.
|
|
5490
5496
|
status (Optional[str]): Representation status.
|
|
5491
5497
|
active (Optional[bool]): Representation active state.
|
|
@@ -5504,6 +5510,7 @@ def create_representation(
|
|
|
5504
5510
|
files=files,
|
|
5505
5511
|
attrib=attrib,
|
|
5506
5512
|
data=data,
|
|
5513
|
+
traits=traits,
|
|
5507
5514
|
tags=tags,
|
|
5508
5515
|
status=status,
|
|
5509
5516
|
active=active,
|
|
@@ -5519,6 +5526,7 @@ def update_representation(
|
|
|
5519
5526
|
files: Optional[List[Dict[str, Any]]] = None,
|
|
5520
5527
|
attrib: Optional[Dict[str, Any]] = None,
|
|
5521
5528
|
data: Optional[Dict[str, Any]] = None,
|
|
5529
|
+
traits: Optional[Dict[str, Any]] = None,
|
|
5522
5530
|
tags: Optional[List[str]] = None,
|
|
5523
5531
|
status: Optional[str] = None,
|
|
5524
5532
|
active: Optional[bool] = None,
|
|
@@ -5539,6 +5547,7 @@ def update_representation(
|
|
|
5539
5547
|
information.
|
|
5540
5548
|
attrib (Optional[dict[str, Any]]): New attributes.
|
|
5541
5549
|
data (Optional[dict[str, Any]]): New data.
|
|
5550
|
+
traits (Optional[dict[str, Any]]): New traits.
|
|
5542
5551
|
tags (Optional[Iterable[str]]): New tags.
|
|
5543
5552
|
status (Optional[str]): New status.
|
|
5544
5553
|
active (Optional[bool]): New active state.
|
|
@@ -5553,6 +5562,7 @@ def update_representation(
|
|
|
5553
5562
|
files=files,
|
|
5554
5563
|
attrib=attrib,
|
|
5555
5564
|
data=data,
|
|
5565
|
+
traits=traits,
|
|
5556
5566
|
tags=tags,
|
|
5557
5567
|
status=status,
|
|
5558
5568
|
active=active,
|
|
@@ -5698,9 +5708,10 @@ def get_thumbnail_by_id(
|
|
|
5698
5708
|
) -> ThumbnailContent:
|
|
5699
5709
|
"""Get thumbnail from server by id.
|
|
5700
5710
|
|
|
5701
|
-
|
|
5702
|
-
|
|
5703
|
-
|
|
5711
|
+
Warnings:
|
|
5712
|
+
Please keep in mind that used endpoint is allowed only for admins
|
|
5713
|
+
and managers. Use 'get_thumbnail' with entity type and id
|
|
5714
|
+
to allow access for artists.
|
|
5704
5715
|
|
|
5705
5716
|
Notes:
|
|
5706
5717
|
It is recommended to use one of prepared entity type specific
|
|
@@ -5736,7 +5747,7 @@ def get_thumbnail(
|
|
|
5736
5747
|
"""Get thumbnail from server.
|
|
5737
5748
|
|
|
5738
5749
|
Permissions of thumbnails are related to entities so thumbnails must
|
|
5739
|
-
be queried per entity. So an entity type and entity
|
|
5750
|
+
be queried per entity. So an entity type and entity id is required
|
|
5740
5751
|
to be passed.
|
|
5741
5752
|
|
|
5742
5753
|
Notes:
|
|
@@ -5794,6 +5805,28 @@ def get_folder_thumbnail(
|
|
|
5794
5805
|
)
|
|
5795
5806
|
|
|
5796
5807
|
|
|
5808
|
+
def get_task_thumbnail(
|
|
5809
|
+
project_name: str,
|
|
5810
|
+
task_id: str,
|
|
5811
|
+
) -> ThumbnailContent:
|
|
5812
|
+
"""Prepared method to receive thumbnail for task entity.
|
|
5813
|
+
|
|
5814
|
+
Args:
|
|
5815
|
+
project_name (str): Project under which the entity is located.
|
|
5816
|
+
task_id (str): Folder id for which thumbnail should be returned.
|
|
5817
|
+
|
|
5818
|
+
Returns:
|
|
5819
|
+
ThumbnailContent: Thumbnail content wrapper. Does not have to be
|
|
5820
|
+
valid.
|
|
5821
|
+
|
|
5822
|
+
"""
|
|
5823
|
+
con = get_server_api_connection()
|
|
5824
|
+
return con.get_task_thumbnail(
|
|
5825
|
+
project_name=project_name,
|
|
5826
|
+
task_id=task_id,
|
|
5827
|
+
)
|
|
5828
|
+
|
|
5829
|
+
|
|
5797
5830
|
def get_version_thumbnail(
|
|
5798
5831
|
project_name: str,
|
|
5799
5832
|
version_id: str,
|
|
@@ -49,66 +49,22 @@ class EntityHub(object):
|
|
|
49
49
|
Args:
|
|
50
50
|
project_name (str): Name of project where changes will happen.
|
|
51
51
|
connection (ServerAPI): Connection to server with logged user.
|
|
52
|
-
allow_data_changes (bool): This option gives ability to change 'data'
|
|
53
|
-
key on entities. This is not recommended as 'data' may be used for
|
|
54
|
-
secure information and would also slow down server queries. Content
|
|
55
|
-
of 'data' key can't be received only GraphQl.
|
|
56
52
|
|
|
57
53
|
"""
|
|
58
54
|
|
|
59
|
-
def __init__(
|
|
60
|
-
self, project_name, connection=None, allow_data_changes=None
|
|
61
|
-
):
|
|
55
|
+
def __init__(self, project_name, connection=None):
|
|
62
56
|
if not connection:
|
|
63
57
|
connection = get_server_api_connection()
|
|
64
|
-
major, minor, _, _, _ = connection.server_version_tuple
|
|
65
|
-
path_start_with_slash = True
|
|
66
|
-
if (major, minor) < (0, 6):
|
|
67
|
-
path_start_with_slash = False
|
|
68
|
-
|
|
69
|
-
if allow_data_changes is None:
|
|
70
|
-
allow_data_changes = connection.graphql_allows_data_in_query
|
|
71
58
|
|
|
72
59
|
self._connection = connection
|
|
73
|
-
self._path_start_with_slash = path_start_with_slash
|
|
74
60
|
|
|
75
61
|
self._project_name = project_name
|
|
76
62
|
self._entities_by_id = {}
|
|
77
63
|
self._entities_by_parent_id = collections.defaultdict(list)
|
|
78
64
|
self._project_entity = UNKNOWN_VALUE
|
|
79
65
|
|
|
80
|
-
self._allow_data_changes = allow_data_changes
|
|
81
|
-
|
|
82
66
|
self._path_reset_queue = None
|
|
83
67
|
|
|
84
|
-
@property
|
|
85
|
-
def allow_data_changes(self):
|
|
86
|
-
"""Entity hub allows changes of 'data' key on entities.
|
|
87
|
-
|
|
88
|
-
Data are private and not all users may have access to them.
|
|
89
|
-
|
|
90
|
-
Older version of AYON server allowed to get 'data' for entity only
|
|
91
|
-
using REST api calls, which means to query each entity on-by-one
|
|
92
|
-
from server.
|
|
93
|
-
|
|
94
|
-
Returns:
|
|
95
|
-
bool: Data changes are allowed.
|
|
96
|
-
|
|
97
|
-
"""
|
|
98
|
-
return self._allow_data_changes
|
|
99
|
-
|
|
100
|
-
@property
|
|
101
|
-
def path_start_with_slash(self):
|
|
102
|
-
"""Folder path should start with slash.
|
|
103
|
-
|
|
104
|
-
This changed in 0.6.x server version.
|
|
105
|
-
|
|
106
|
-
Returns:
|
|
107
|
-
bool: Path starts with slash.
|
|
108
|
-
|
|
109
|
-
"""
|
|
110
|
-
return self._path_start_with_slash
|
|
111
|
-
|
|
112
68
|
@property
|
|
113
69
|
def project_name(self):
|
|
114
70
|
"""Project name which is maintained by hub.
|
|
@@ -898,8 +854,7 @@ class EntityHub(object):
|
|
|
898
854
|
self._connection.get_default_fields_for_type("folder")
|
|
899
855
|
)
|
|
900
856
|
folder_fields.add("hasProducts")
|
|
901
|
-
|
|
902
|
-
folder_fields.add("data")
|
|
857
|
+
folder_fields.add("data")
|
|
903
858
|
return folder_fields
|
|
904
859
|
|
|
905
860
|
def _get_task_fields(self) -> Set[str]:
|
|
@@ -1717,10 +1672,7 @@ class BaseEntity(ABC):
|
|
|
1717
1672
|
|
|
1718
1673
|
"""
|
|
1719
1674
|
changes = {}
|
|
1720
|
-
if
|
|
1721
|
-
self._entity_hub.allow_data_changes
|
|
1722
|
-
and self._data is not UNKNOWN_VALUE
|
|
1723
|
-
):
|
|
1675
|
+
if self._data is not UNKNOWN_VALUE:
|
|
1724
1676
|
data_changes = self._data.get_changes()
|
|
1725
1677
|
if data_changes:
|
|
1726
1678
|
changes["data"] = data_changes
|
|
@@ -3149,10 +3101,8 @@ class FolderEntity(BaseEntity):
|
|
|
3149
3101
|
if parent.entity_type == "folder":
|
|
3150
3102
|
parent_path = parent.path
|
|
3151
3103
|
path = "/".join([parent_path, self.name])
|
|
3152
|
-
elif self._entity_hub.path_start_with_slash:
|
|
3153
|
-
path = "/{}".format(self.name)
|
|
3154
3104
|
else:
|
|
3155
|
-
path = self.name
|
|
3105
|
+
path = "/{}".format(self.name)
|
|
3156
3106
|
self._path = path
|
|
3157
3107
|
return self._path
|
|
3158
3108
|
|
|
@@ -3260,10 +3210,7 @@ class FolderEntity(BaseEntity):
|
|
|
3260
3210
|
if self.thumbnail_id is not UNKNOWN_VALUE:
|
|
3261
3211
|
output["thumbnailId"] = self.thumbnail_id
|
|
3262
3212
|
|
|
3263
|
-
if
|
|
3264
|
-
self._entity_hub.allow_data_changes
|
|
3265
|
-
and self._data is not UNKNOWN_VALUE
|
|
3266
|
-
):
|
|
3213
|
+
if self._data is not UNKNOWN_VALUE:
|
|
3267
3214
|
output["data"] = self._data.get_new_entity_value()
|
|
3268
3215
|
return output
|
|
3269
3216
|
|
|
@@ -3451,10 +3398,7 @@ class TaskEntity(BaseEntity):
|
|
|
3451
3398
|
if self.assignees:
|
|
3452
3399
|
output["assignees"] = self.assignees
|
|
3453
3400
|
|
|
3454
|
-
if
|
|
3455
|
-
self._entity_hub.allow_data_changes
|
|
3456
|
-
and self._data is not UNKNOWN_VALUE
|
|
3457
|
-
):
|
|
3401
|
+
if self._data is not UNKNOWN_VALUE:
|
|
3458
3402
|
output["data"] = self._data.get_new_entity_value()
|
|
3459
3403
|
return output
|
|
3460
3404
|
|
|
@@ -3561,10 +3505,7 @@ class ProductEntity(BaseEntity):
|
|
|
3561
3505
|
if self.tags:
|
|
3562
3506
|
output["tags"] = self.tags
|
|
3563
3507
|
|
|
3564
|
-
if
|
|
3565
|
-
self._entity_hub.allow_data_changes
|
|
3566
|
-
and self._data is not UNKNOWN_VALUE
|
|
3567
|
-
):
|
|
3508
|
+
if self._data is not UNKNOWN_VALUE:
|
|
3568
3509
|
output["data"] = self._data.get_new_entity_value()
|
|
3569
3510
|
return output
|
|
3570
3511
|
|
|
@@ -3693,9 +3634,6 @@ class VersionEntity(BaseEntity):
|
|
|
3693
3634
|
if self.status:
|
|
3694
3635
|
output["status"] = self.status
|
|
3695
3636
|
|
|
3696
|
-
if
|
|
3697
|
-
self._entity_hub.allow_data_changes
|
|
3698
|
-
and self._data is not UNKNOWN_VALUE
|
|
3699
|
-
):
|
|
3637
|
+
if self._data is not UNKNOWN_VALUE:
|
|
3700
3638
|
output["data"] = self._data.get_new_entity_value()
|
|
3701
3639
|
return output
|
|
@@ -341,6 +341,7 @@ def versions_graphql_query(fields):
|
|
|
341
341
|
project_name_var = query.add_variable("projectName", "String!")
|
|
342
342
|
product_ids_var = query.add_variable("productIds", "[String!]")
|
|
343
343
|
version_ids_var = query.add_variable("versionIds", "[String!]")
|
|
344
|
+
task_ids_var = query.add_variable("taskIds", "[String!]")
|
|
344
345
|
versions_var = query.add_variable("versions", "[Int!]")
|
|
345
346
|
hero_only_var = query.add_variable("heroOnly", "Boolean")
|
|
346
347
|
latest_only_var = query.add_variable("latestOnly", "Boolean")
|
|
@@ -357,6 +358,7 @@ def versions_graphql_query(fields):
|
|
|
357
358
|
versions_field.set_filter("ids", version_ids_var)
|
|
358
359
|
versions_field.set_filter("productIds", product_ids_var)
|
|
359
360
|
versions_field.set_filter("versions", versions_var)
|
|
361
|
+
versions_field.set_filter("taskIds", task_ids_var)
|
|
360
362
|
versions_field.set_filter("heroOnly", hero_only_var)
|
|
361
363
|
versions_field.set_filter("latestOnly", latest_only_var)
|
|
362
364
|
versions_field.set_filter("heroOrLatestOnly", hero_or_latest_only_var)
|
|
@@ -617,10 +619,12 @@ def events_graphql_query(fields, order, use_states=False):
|
|
|
617
619
|
def users_graphql_query(fields):
|
|
618
620
|
query = GraphQlQuery("Users")
|
|
619
621
|
names_var = query.add_variable("userNames", "[String!]")
|
|
622
|
+
emails_var = query.add_variable("emails", "[String!]")
|
|
620
623
|
project_name_var = query.add_variable("projectName", "String!")
|
|
621
624
|
|
|
622
625
|
users_field = query.add_field_with_edges("users")
|
|
623
626
|
users_field.set_filter("names", names_var)
|
|
627
|
+
users_field.set_filter("emails", emails_var)
|
|
624
628
|
users_field.set_filter("projectName", project_name_var)
|
|
625
629
|
|
|
626
630
|
nested_fields = fields_to_dict(set(fields))
|
|
@@ -276,7 +276,8 @@ def new_representation_entity(
|
|
|
276
276
|
tags=None,
|
|
277
277
|
attribs=None,
|
|
278
278
|
data=None,
|
|
279
|
-
|
|
279
|
+
traits=None,
|
|
280
|
+
entity_id=None,
|
|
280
281
|
):
|
|
281
282
|
"""Create skeleton data of representation entity.
|
|
282
283
|
|
|
@@ -290,6 +291,8 @@ def new_representation_entity(
|
|
|
290
291
|
attribs (Optional[Dict[str, Any]]): Explicitly set attributes
|
|
291
292
|
of representation.
|
|
292
293
|
data (Optional[Dict[str, Any]]): Representation entity data.
|
|
294
|
+
traits (Optional[Dict[str, Any]]): Representation traits. Empty
|
|
295
|
+
if not passed.
|
|
293
296
|
entity_id (Optional[str]): Predefined id of entity. New id is created
|
|
294
297
|
if not passed.
|
|
295
298
|
|
|
@@ -309,8 +312,10 @@ def new_representation_entity(
|
|
|
309
312
|
"files": files,
|
|
310
313
|
"name": name,
|
|
311
314
|
"data": data,
|
|
312
|
-
"attrib": attribs
|
|
315
|
+
"attrib": attribs,
|
|
313
316
|
}
|
|
317
|
+
if traits:
|
|
318
|
+
output["traits"] = traits
|
|
314
319
|
if tags:
|
|
315
320
|
output["tags"] = tags
|
|
316
321
|
if status:
|
|
@@ -1188,7 +1193,10 @@ class OperationsSession(object):
|
|
|
1188
1193
|
update_data[key] = value
|
|
1189
1194
|
|
|
1190
1195
|
return self.update_entity(
|
|
1191
|
-
project_name,
|
|
1196
|
+
project_name,
|
|
1197
|
+
"product",
|
|
1198
|
+
product_id,
|
|
1199
|
+
update_data
|
|
1192
1200
|
)
|
|
1193
1201
|
|
|
1194
1202
|
def delete_product(self, project_name, product_id):
|
|
@@ -1356,6 +1364,7 @@ class OperationsSession(object):
|
|
|
1356
1364
|
files=None,
|
|
1357
1365
|
attrib=None,
|
|
1358
1366
|
data=None,
|
|
1367
|
+
traits=None,
|
|
1359
1368
|
tags=None,
|
|
1360
1369
|
status=None,
|
|
1361
1370
|
active=None,
|
|
@@ -1370,6 +1379,8 @@ class OperationsSession(object):
|
|
|
1370
1379
|
files (Optional[list[dict]]): Representation files information.
|
|
1371
1380
|
attrib (Optional[dict[str, Any]]): Representation attributes.
|
|
1372
1381
|
data (Optional[dict[str, Any]]): Representation data.
|
|
1382
|
+
traits (Optional[Dict[str, Any]]): Representation traits. Empty
|
|
1383
|
+
if not passed.
|
|
1373
1384
|
tags (Optional[Iterable[str]]): Representation tags.
|
|
1374
1385
|
status (Optional[str]): Representation status.
|
|
1375
1386
|
active (Optional[bool]): Representation active state.
|
|
@@ -1391,6 +1402,7 @@ class OperationsSession(object):
|
|
|
1391
1402
|
("files", files),
|
|
1392
1403
|
("attrib", attrib),
|
|
1393
1404
|
("data", data),
|
|
1405
|
+
("traits", traits),
|
|
1394
1406
|
("tags", tags),
|
|
1395
1407
|
("status", status),
|
|
1396
1408
|
("active", active),
|
|
@@ -1413,6 +1425,7 @@ class OperationsSession(object):
|
|
|
1413
1425
|
files=None,
|
|
1414
1426
|
attrib=None,
|
|
1415
1427
|
data=None,
|
|
1428
|
+
traits=None,
|
|
1416
1429
|
tags=None,
|
|
1417
1430
|
status=None,
|
|
1418
1431
|
active=None,
|
|
@@ -1433,6 +1446,7 @@ class OperationsSession(object):
|
|
|
1433
1446
|
information.
|
|
1434
1447
|
attrib (Optional[dict[str, Any]]): New attributes.
|
|
1435
1448
|
data (Optional[dict[str, Any]]): New data.
|
|
1449
|
+
traits (Optional[Dict[str, Any]]): New representation traits.
|
|
1436
1450
|
tags (Optional[Iterable[str]]): New tags.
|
|
1437
1451
|
status (Optional[str]): New status.
|
|
1438
1452
|
active (Optional[bool]): New active state.
|
|
@@ -1448,6 +1462,7 @@ class OperationsSession(object):
|
|
|
1448
1462
|
("files", files),
|
|
1449
1463
|
("attrib", attrib),
|
|
1450
1464
|
("data", data),
|
|
1465
|
+
("traits", traits),
|
|
1451
1466
|
("tags", tags),
|
|
1452
1467
|
("status", status),
|
|
1453
1468
|
("active", active),
|
|
@@ -1456,7 +1471,10 @@ class OperationsSession(object):
|
|
|
1456
1471
|
update_data[key] = value
|
|
1457
1472
|
|
|
1458
1473
|
return self.update_entity(
|
|
1459
|
-
project_name,
|
|
1474
|
+
project_name,
|
|
1475
|
+
"representation",
|
|
1476
|
+
representation_id,
|
|
1477
|
+
update_data
|
|
1460
1478
|
)
|
|
1461
1479
|
|
|
1462
1480
|
def delete_representation(self, project_name, representation_id):
|
|
@@ -52,7 +52,6 @@ from .constants import (
|
|
|
52
52
|
DEFAULT_EVENT_FIELDS,
|
|
53
53
|
DEFAULT_ACTIVITY_FIELDS,
|
|
54
54
|
DEFAULT_USER_FIELDS,
|
|
55
|
-
DEFAULT_LINK_FIELDS,
|
|
56
55
|
)
|
|
57
56
|
from .graphql import GraphQlQuery, INTROSPECTION_QUERY
|
|
58
57
|
from .graphql_queries import (
|
|
@@ -520,7 +519,7 @@ class ServerAPI(object):
|
|
|
520
519
|
self._server_version = None
|
|
521
520
|
self._server_version_tuple = None
|
|
522
521
|
|
|
523
|
-
self.
|
|
522
|
+
self._graphql_allows_traits_in_representations: Optional[bool] = None
|
|
524
523
|
|
|
525
524
|
self._session = None
|
|
526
525
|
|
|
@@ -1097,24 +1096,15 @@ class ServerAPI(object):
|
|
|
1097
1096
|
)
|
|
1098
1097
|
|
|
1099
1098
|
@property
|
|
1100
|
-
def
|
|
1101
|
-
"""
|
|
1102
|
-
|
|
1103
|
-
This applies only to project hierarchy entities 'project', 'folder',
|
|
1104
|
-
'task', 'product', 'version' and 'representation'. Others like 'user'
|
|
1105
|
-
still require to use rest api to access 'data'.
|
|
1106
|
-
|
|
1107
|
-
Returns:
|
|
1108
|
-
bool: True if server supports 'data' field in GraphQl query.
|
|
1109
|
-
|
|
1110
|
-
"""
|
|
1111
|
-
if self._graphql_allows_data_in_query is None:
|
|
1099
|
+
def graphql_allows_traits_in_representations(self) -> bool:
|
|
1100
|
+
"""Check server support for representation traits."""
|
|
1101
|
+
if self._graphql_allows_traits_in_representations is None:
|
|
1112
1102
|
major, minor, patch, _, _ = self.server_version_tuple
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1103
|
+
self._graphql_allows_traits_in_representations = (
|
|
1104
|
+
(major, minor, patch) >= (1, 7, 5)
|
|
1105
|
+
)
|
|
1106
|
+
return self._graphql_allows_traits_in_representations
|
|
1107
|
+
|
|
1118
1108
|
|
|
1119
1109
|
def _get_user_info(self) -> Optional[Dict[str, Any]]:
|
|
1120
1110
|
if self._access_token is None:
|
|
@@ -1143,6 +1133,7 @@ class ServerAPI(object):
|
|
|
1143
1133
|
self,
|
|
1144
1134
|
project_name: Optional[str] = None,
|
|
1145
1135
|
usernames: Optional[Iterable[str]] = None,
|
|
1136
|
+
emails: Optional[Iterable[str]] = None,
|
|
1146
1137
|
fields: Optional[Iterable[str]] = None,
|
|
1147
1138
|
) -> Generator[Dict[str, Any], None, None]:
|
|
1148
1139
|
"""Get Users.
|
|
@@ -1153,6 +1144,7 @@ class ServerAPI(object):
|
|
|
1153
1144
|
Args:
|
|
1154
1145
|
project_name (Optional[str]): Project name.
|
|
1155
1146
|
usernames (Optional[Iterable[str]]): Filter by usernames.
|
|
1147
|
+
emails (Optional[Iterable[str]]): Filter by emails.
|
|
1156
1148
|
fields (Optional[Iterable[str]]): Fields to be queried
|
|
1157
1149
|
for users.
|
|
1158
1150
|
|
|
@@ -1167,6 +1159,22 @@ class ServerAPI(object):
|
|
|
1167
1159
|
return
|
|
1168
1160
|
filters["userNames"] = list(usernames)
|
|
1169
1161
|
|
|
1162
|
+
if emails is not None:
|
|
1163
|
+
emails = set(emails)
|
|
1164
|
+
if not emails:
|
|
1165
|
+
return
|
|
1166
|
+
|
|
1167
|
+
major, minor, patch, _, _ = self.server_version_tuple
|
|
1168
|
+
emails_filter_available = (major, minor, patch) > (1, 7, 3)
|
|
1169
|
+
if not emails_filter_available:
|
|
1170
|
+
server_version = self.get_server_version()
|
|
1171
|
+
raise ValueError(
|
|
1172
|
+
"Filtering by emails is not supported by"
|
|
1173
|
+
f" server version {server_version}."
|
|
1174
|
+
)
|
|
1175
|
+
|
|
1176
|
+
filters["emails"] = list(emails)
|
|
1177
|
+
|
|
1170
1178
|
if project_name is not None:
|
|
1171
1179
|
filters["projectName"] = project_name
|
|
1172
1180
|
|
|
@@ -1656,21 +1664,6 @@ class ServerAPI(object):
|
|
|
1656
1664
|
)
|
|
1657
1665
|
if value is not None
|
|
1658
1666
|
}
|
|
1659
|
-
# 'progress' and 'retries' are available since 0.5.x server version
|
|
1660
|
-
major, minor, _, _, _ = self.server_version_tuple
|
|
1661
|
-
if (major, minor) < (0, 5):
|
|
1662
|
-
args = []
|
|
1663
|
-
if progress is not None:
|
|
1664
|
-
args.append("progress")
|
|
1665
|
-
if retries is not None:
|
|
1666
|
-
args.append("retries")
|
|
1667
|
-
fields = ", ".join(f"'{f}'" for f in args)
|
|
1668
|
-
ending = "s" if len(args) > 1 else ""
|
|
1669
|
-
raise ValueError(
|
|
1670
|
-
f"Your server version '{self.server_version}' does not"
|
|
1671
|
-
f" support update of {fields} field{ending} on event."
|
|
1672
|
-
" The fields are supported since server version '0.5'."
|
|
1673
|
-
)
|
|
1674
1667
|
|
|
1675
1668
|
response = self.patch(
|
|
1676
1669
|
f"events/{event_id}",
|
|
@@ -2730,36 +2723,27 @@ class ServerAPI(object):
|
|
|
2730
2723
|
|
|
2731
2724
|
if entity_type == "project":
|
|
2732
2725
|
entity_type_defaults = set(DEFAULT_PROJECT_FIELDS)
|
|
2733
|
-
if not self.graphql_allows_data_in_query:
|
|
2734
|
-
entity_type_defaults.discard("data")
|
|
2735
2726
|
|
|
2736
2727
|
elif entity_type == "folder":
|
|
2737
2728
|
entity_type_defaults = set(DEFAULT_FOLDER_FIELDS)
|
|
2738
|
-
if not self.graphql_allows_data_in_query:
|
|
2739
|
-
entity_type_defaults.discard("data")
|
|
2740
2729
|
|
|
2741
2730
|
elif entity_type == "task":
|
|
2742
2731
|
entity_type_defaults = set(DEFAULT_TASK_FIELDS)
|
|
2743
|
-
if not self.graphql_allows_data_in_query:
|
|
2744
|
-
entity_type_defaults.discard("data")
|
|
2745
2732
|
|
|
2746
2733
|
elif entity_type == "product":
|
|
2747
2734
|
entity_type_defaults = set(DEFAULT_PRODUCT_FIELDS)
|
|
2748
|
-
if not self.graphql_allows_data_in_query:
|
|
2749
|
-
entity_type_defaults.discard("data")
|
|
2750
2735
|
|
|
2751
2736
|
elif entity_type == "version":
|
|
2752
2737
|
entity_type_defaults = set(DEFAULT_VERSION_FIELDS)
|
|
2753
|
-
if not self.graphql_allows_data_in_query:
|
|
2754
|
-
entity_type_defaults.discard("data")
|
|
2755
2738
|
|
|
2756
2739
|
elif entity_type == "representation":
|
|
2757
2740
|
entity_type_defaults = (
|
|
2758
2741
|
DEFAULT_REPRESENTATION_FIELDS
|
|
2759
2742
|
| REPRESENTATION_FILES_FIELDS
|
|
2760
2743
|
)
|
|
2761
|
-
|
|
2762
|
-
|
|
2744
|
+
|
|
2745
|
+
if not self.graphql_allows_traits_in_representations:
|
|
2746
|
+
entity_type_defaults.discard("traits")
|
|
2763
2747
|
|
|
2764
2748
|
elif entity_type == "folderType":
|
|
2765
2749
|
entity_type_defaults = set(DEFAULT_FOLDER_TYPE_FIELDS)
|
|
@@ -2772,8 +2756,6 @@ class ServerAPI(object):
|
|
|
2772
2756
|
|
|
2773
2757
|
elif entity_type == "workfile":
|
|
2774
2758
|
entity_type_defaults = set(DEFAULT_WORKFILE_INFO_FIELDS)
|
|
2775
|
-
if not self.graphql_allows_data_in_query:
|
|
2776
|
-
entity_type_defaults.discard("data")
|
|
2777
2759
|
|
|
2778
2760
|
elif entity_type == "user":
|
|
2779
2761
|
entity_type_defaults = set(DEFAULT_USER_FIELDS)
|
|
@@ -4646,10 +4628,14 @@ class ServerAPI(object):
|
|
|
4646
4628
|
return
|
|
4647
4629
|
|
|
4648
4630
|
self._prepare_fields("project", fields, own_attributes)
|
|
4631
|
+
if active is not None:
|
|
4632
|
+
fields.add("active")
|
|
4649
4633
|
|
|
4650
4634
|
query = projects_graphql_query(fields)
|
|
4651
4635
|
for parsed_data in query.continuous_query(self):
|
|
4652
4636
|
for project in parsed_data["projects"]:
|
|
4637
|
+
if active is not None and active is not project["active"]:
|
|
4638
|
+
continue
|
|
4653
4639
|
if own_attributes:
|
|
4654
4640
|
fill_own_attribs(project)
|
|
4655
4641
|
yield project
|
|
@@ -4930,15 +4916,10 @@ class ServerAPI(object):
|
|
|
4930
4916
|
fields = set(fields)
|
|
4931
4917
|
self._prepare_fields("folder", fields)
|
|
4932
4918
|
|
|
4933
|
-
use_rest = False
|
|
4934
|
-
if "data" in fields and not self.graphql_allows_data_in_query:
|
|
4935
|
-
use_rest = True
|
|
4936
|
-
fields = {"id"}
|
|
4937
|
-
|
|
4938
4919
|
if active is not None:
|
|
4939
4920
|
fields.add("active")
|
|
4940
4921
|
|
|
4941
|
-
if own_attributes
|
|
4922
|
+
if own_attributes:
|
|
4942
4923
|
fields.add("ownAttrib")
|
|
4943
4924
|
|
|
4944
4925
|
query = folders_graphql_query(fields)
|
|
@@ -4950,10 +4931,7 @@ class ServerAPI(object):
|
|
|
4950
4931
|
if active is not None and active is not folder["active"]:
|
|
4951
4932
|
continue
|
|
4952
4933
|
|
|
4953
|
-
|
|
4954
|
-
folder = self.get_rest_folder(project_name, folder["id"])
|
|
4955
|
-
else:
|
|
4956
|
-
self._convert_entity_data(folder)
|
|
4934
|
+
self._convert_entity_data(folder)
|
|
4957
4935
|
|
|
4958
4936
|
if own_attributes:
|
|
4959
4937
|
fill_own_attribs(folder)
|
|
@@ -5325,11 +5303,6 @@ class ServerAPI(object):
|
|
|
5325
5303
|
fields = set(fields)
|
|
5326
5304
|
self._prepare_fields("task", fields, own_attributes)
|
|
5327
5305
|
|
|
5328
|
-
use_rest = False
|
|
5329
|
-
if "data" in fields and not self.graphql_allows_data_in_query:
|
|
5330
|
-
use_rest = True
|
|
5331
|
-
fields = {"id"}
|
|
5332
|
-
|
|
5333
5306
|
if active is not None:
|
|
5334
5307
|
fields.add("active")
|
|
5335
5308
|
|
|
@@ -5342,10 +5315,7 @@ class ServerAPI(object):
|
|
|
5342
5315
|
if active is not None and active is not task["active"]:
|
|
5343
5316
|
continue
|
|
5344
5317
|
|
|
5345
|
-
|
|
5346
|
-
task = self.get_rest_task(project_name, task["id"])
|
|
5347
|
-
else:
|
|
5348
|
-
self._convert_entity_data(task)
|
|
5318
|
+
self._convert_entity_data(task)
|
|
5349
5319
|
|
|
5350
5320
|
if own_attributes:
|
|
5351
5321
|
fill_own_attribs(task)
|
|
@@ -5487,11 +5457,6 @@ class ServerAPI(object):
|
|
|
5487
5457
|
fields = set(fields)
|
|
5488
5458
|
self._prepare_fields("task", fields, own_attributes)
|
|
5489
5459
|
|
|
5490
|
-
use_rest = False
|
|
5491
|
-
if "data" in fields and not self.graphql_allows_data_in_query:
|
|
5492
|
-
use_rest = True
|
|
5493
|
-
fields = {"id"}
|
|
5494
|
-
|
|
5495
5460
|
if active is not None:
|
|
5496
5461
|
fields.add("active")
|
|
5497
5462
|
|
|
@@ -5510,10 +5475,7 @@ class ServerAPI(object):
|
|
|
5510
5475
|
if active is not None and active is not task["active"]:
|
|
5511
5476
|
continue
|
|
5512
5477
|
|
|
5513
|
-
|
|
5514
|
-
task = self.get_rest_task(project_name, task["id"])
|
|
5515
|
-
else:
|
|
5516
|
-
self._convert_entity_data(task)
|
|
5478
|
+
self._convert_entity_data(task)
|
|
5517
5479
|
|
|
5518
5480
|
if own_attributes:
|
|
5519
5481
|
fill_own_attribs(task)
|
|
@@ -5763,15 +5725,11 @@ class ServerAPI(object):
|
|
|
5763
5725
|
project_name: str,
|
|
5764
5726
|
product: "ProductDict",
|
|
5765
5727
|
active: "Union[bool, None]",
|
|
5766
|
-
use_rest: bool,
|
|
5767
5728
|
) -> Optional["ProductDict"]:
|
|
5768
5729
|
if active is not None and product["active"] is not active:
|
|
5769
5730
|
return None
|
|
5770
5731
|
|
|
5771
|
-
|
|
5772
|
-
product = self.get_rest_product(project_name, product["id"])
|
|
5773
|
-
else:
|
|
5774
|
-
self._convert_entity_data(product)
|
|
5732
|
+
self._convert_entity_data(product)
|
|
5775
5733
|
|
|
5776
5734
|
return product
|
|
5777
5735
|
|
|
@@ -5864,11 +5822,6 @@ class ServerAPI(object):
|
|
|
5864
5822
|
else:
|
|
5865
5823
|
fields = self.get_default_fields_for_type("product")
|
|
5866
5824
|
|
|
5867
|
-
use_rest = False
|
|
5868
|
-
if "data" in fields and not self.graphql_allows_data_in_query:
|
|
5869
|
-
use_rest = True
|
|
5870
|
-
fields = {"id"}
|
|
5871
|
-
|
|
5872
5825
|
if active is not None:
|
|
5873
5826
|
fields.add("active")
|
|
5874
5827
|
|
|
@@ -5926,7 +5879,7 @@ class ServerAPI(object):
|
|
|
5926
5879
|
products_by_folder_id = collections.defaultdict(list)
|
|
5927
5880
|
for product in products:
|
|
5928
5881
|
filtered_product = self._filter_product(
|
|
5929
|
-
project_name, product, active
|
|
5882
|
+
project_name, product, active
|
|
5930
5883
|
)
|
|
5931
5884
|
if filtered_product is not None:
|
|
5932
5885
|
folder_id = filtered_product["folderId"]
|
|
@@ -5940,7 +5893,7 @@ class ServerAPI(object):
|
|
|
5940
5893
|
else:
|
|
5941
5894
|
for product in products:
|
|
5942
5895
|
filtered_product = self._filter_product(
|
|
5943
|
-
project_name, product, active
|
|
5896
|
+
project_name, product, active
|
|
5944
5897
|
)
|
|
5945
5898
|
if filtered_product is not None:
|
|
5946
5899
|
yield filtered_product
|
|
@@ -6287,11 +6240,6 @@ class ServerAPI(object):
|
|
|
6287
6240
|
# Make sure fields have minimum required fields
|
|
6288
6241
|
fields |= {"id", "version"}
|
|
6289
6242
|
|
|
6290
|
-
use_rest = False
|
|
6291
|
-
if "data" in fields and not self.graphql_allows_data_in_query:
|
|
6292
|
-
use_rest = True
|
|
6293
|
-
fields = {"id"}
|
|
6294
|
-
|
|
6295
6243
|
if active is not None:
|
|
6296
6244
|
fields.add("active")
|
|
6297
6245
|
|
|
@@ -6364,12 +6312,7 @@ class ServerAPI(object):
|
|
|
6364
6312
|
if not hero and version["version"] < 0:
|
|
6365
6313
|
continue
|
|
6366
6314
|
|
|
6367
|
-
|
|
6368
|
-
version = self.get_rest_version(
|
|
6369
|
-
project_name, version["id"]
|
|
6370
|
-
)
|
|
6371
|
-
else:
|
|
6372
|
-
self._convert_entity_data(version)
|
|
6315
|
+
self._convert_entity_data(version)
|
|
6373
6316
|
|
|
6374
6317
|
yield version
|
|
6375
6318
|
|
|
@@ -6931,11 +6874,6 @@ class ServerAPI(object):
|
|
|
6931
6874
|
fields = set(fields)
|
|
6932
6875
|
self._prepare_fields("representation", fields)
|
|
6933
6876
|
|
|
6934
|
-
use_rest = False
|
|
6935
|
-
if "data" in fields and not self.graphql_allows_data_in_query:
|
|
6936
|
-
use_rest = True
|
|
6937
|
-
fields = {"id"}
|
|
6938
|
-
|
|
6939
6877
|
if active is not None:
|
|
6940
6878
|
fields.add("active")
|
|
6941
6879
|
|
|
@@ -7017,12 +6955,7 @@ class ServerAPI(object):
|
|
|
7017
6955
|
if active is not None and active is not repre["active"]:
|
|
7018
6956
|
continue
|
|
7019
6957
|
|
|
7020
|
-
|
|
7021
|
-
repre = self.get_rest_representation(
|
|
7022
|
-
project_name, repre["id"]
|
|
7023
|
-
)
|
|
7024
|
-
else:
|
|
7025
|
-
self._convert_entity_data(repre)
|
|
6958
|
+
self._convert_entity_data(repre)
|
|
7026
6959
|
|
|
7027
6960
|
self._representation_conversion(repre)
|
|
7028
6961
|
|
|
@@ -7452,6 +7385,7 @@ class ServerAPI(object):
|
|
|
7452
7385
|
files: Optional[List[Dict[str, Any]]] = None,
|
|
7453
7386
|
attrib: Optional[Dict[str, Any]] = None,
|
|
7454
7387
|
data: Optional[Dict[str, Any]] = None,
|
|
7388
|
+
traits: Optional[Dict[str, Any]] = None,
|
|
7455
7389
|
tags: Optional[List[str]]=None,
|
|
7456
7390
|
status: Optional[str] = None,
|
|
7457
7391
|
active: Optional[bool] = None,
|
|
@@ -7466,6 +7400,8 @@ class ServerAPI(object):
|
|
|
7466
7400
|
files (Optional[list[dict]]): Representation files information.
|
|
7467
7401
|
attrib (Optional[dict[str, Any]]): Representation attributes.
|
|
7468
7402
|
data (Optional[dict[str, Any]]): Representation data.
|
|
7403
|
+
traits (Optional[dict[str, Any]]): Representation traits
|
|
7404
|
+
serialized data as dict.
|
|
7469
7405
|
tags (Optional[Iterable[str]]): Representation tags.
|
|
7470
7406
|
status (Optional[str]): Representation status.
|
|
7471
7407
|
active (Optional[bool]): Representation active state.
|
|
@@ -7487,6 +7423,7 @@ class ServerAPI(object):
|
|
|
7487
7423
|
("files", files),
|
|
7488
7424
|
("attrib", attrib),
|
|
7489
7425
|
("data", data),
|
|
7426
|
+
("traits", traits),
|
|
7490
7427
|
("tags", tags),
|
|
7491
7428
|
("status", status),
|
|
7492
7429
|
("active", active),
|
|
@@ -7510,6 +7447,7 @@ class ServerAPI(object):
|
|
|
7510
7447
|
files: Optional[List[Dict[str, Any]]] = None,
|
|
7511
7448
|
attrib: Optional[Dict[str, Any]] = None,
|
|
7512
7449
|
data: Optional[Dict[str, Any]] = None,
|
|
7450
|
+
traits: Optional[Dict[str, Any]] = None,
|
|
7513
7451
|
tags: Optional[List[str]] = None,
|
|
7514
7452
|
status: Optional[str] = None,
|
|
7515
7453
|
active: Optional[bool] = None,
|
|
@@ -7530,6 +7468,7 @@ class ServerAPI(object):
|
|
|
7530
7468
|
information.
|
|
7531
7469
|
attrib (Optional[dict[str, Any]]): New attributes.
|
|
7532
7470
|
data (Optional[dict[str, Any]]): New data.
|
|
7471
|
+
traits (Optional[dict[str, Any]]): New traits.
|
|
7533
7472
|
tags (Optional[Iterable[str]]): New tags.
|
|
7534
7473
|
status (Optional[str]): New status.
|
|
7535
7474
|
active (Optional[bool]): New active state.
|
|
@@ -7542,6 +7481,7 @@ class ServerAPI(object):
|
|
|
7542
7481
|
("files", files),
|
|
7543
7482
|
("attrib", attrib),
|
|
7544
7483
|
("data", data),
|
|
7484
|
+
("traits", traits),
|
|
7545
7485
|
("tags", tags),
|
|
7546
7486
|
("status", status),
|
|
7547
7487
|
("active", active),
|
|
@@ -7765,9 +7705,10 @@ class ServerAPI(object):
|
|
|
7765
7705
|
) -> ThumbnailContent:
|
|
7766
7706
|
"""Get thumbnail from server by id.
|
|
7767
7707
|
|
|
7768
|
-
|
|
7769
|
-
|
|
7770
|
-
|
|
7708
|
+
Warnings:
|
|
7709
|
+
Please keep in mind that used endpoint is allowed only for admins
|
|
7710
|
+
and managers. Use 'get_thumbnail' with entity type and id
|
|
7711
|
+
to allow access for artists.
|
|
7771
7712
|
|
|
7772
7713
|
Notes:
|
|
7773
7714
|
It is recommended to use one of prepared entity type specific
|
|
@@ -7802,7 +7743,7 @@ class ServerAPI(object):
|
|
|
7802
7743
|
"""Get thumbnail from server.
|
|
7803
7744
|
|
|
7804
7745
|
Permissions of thumbnails are related to entities so thumbnails must
|
|
7805
|
-
be queried per entity. So an entity type and entity
|
|
7746
|
+
be queried per entity. So an entity type and entity id is required
|
|
7806
7747
|
to be passed.
|
|
7807
7748
|
|
|
7808
7749
|
Notes:
|
|
@@ -7826,10 +7767,17 @@ class ServerAPI(object):
|
|
|
7826
7767
|
|
|
7827
7768
|
"""
|
|
7828
7769
|
if thumbnail_id:
|
|
7829
|
-
|
|
7770
|
+
warnings.warn(
|
|
7771
|
+
(
|
|
7772
|
+
"Function 'get_thumbnail' got 'thumbnail_id' which"
|
|
7773
|
+
" is deprecated and will be removed in future version."
|
|
7774
|
+
),
|
|
7775
|
+
DeprecationWarning
|
|
7776
|
+
)
|
|
7830
7777
|
|
|
7831
7778
|
if entity_type in (
|
|
7832
7779
|
"folder",
|
|
7780
|
+
"task",
|
|
7833
7781
|
"version",
|
|
7834
7782
|
"workfile",
|
|
7835
7783
|
):
|
|
@@ -7859,10 +7807,36 @@ class ServerAPI(object):
|
|
|
7859
7807
|
valid.
|
|
7860
7808
|
|
|
7861
7809
|
"""
|
|
7810
|
+
if thumbnail_id:
|
|
7811
|
+
warnings.warn(
|
|
7812
|
+
(
|
|
7813
|
+
"Function 'get_folder_thumbnail' got 'thumbnail_id' which"
|
|
7814
|
+
" is deprecated and will be removed in future version."
|
|
7815
|
+
),
|
|
7816
|
+
DeprecationWarning
|
|
7817
|
+
)
|
|
7862
7818
|
return self.get_thumbnail(
|
|
7863
|
-
project_name, "folder", folder_id
|
|
7819
|
+
project_name, "folder", folder_id
|
|
7864
7820
|
)
|
|
7865
7821
|
|
|
7822
|
+
def get_task_thumbnail(
|
|
7823
|
+
self,
|
|
7824
|
+
project_name: str,
|
|
7825
|
+
task_id: str,
|
|
7826
|
+
) -> ThumbnailContent:
|
|
7827
|
+
"""Prepared method to receive thumbnail for task entity.
|
|
7828
|
+
|
|
7829
|
+
Args:
|
|
7830
|
+
project_name (str): Project under which the entity is located.
|
|
7831
|
+
task_id (str): Folder id for which thumbnail should be returned.
|
|
7832
|
+
|
|
7833
|
+
Returns:
|
|
7834
|
+
ThumbnailContent: Thumbnail content wrapper. Does not have to be
|
|
7835
|
+
valid.
|
|
7836
|
+
|
|
7837
|
+
"""
|
|
7838
|
+
return self.get_thumbnail(project_name, "task", task_id)
|
|
7839
|
+
|
|
7866
7840
|
def get_version_thumbnail(
|
|
7867
7841
|
self,
|
|
7868
7842
|
project_name: str,
|
|
@@ -7883,8 +7857,16 @@ class ServerAPI(object):
|
|
|
7883
7857
|
valid.
|
|
7884
7858
|
|
|
7885
7859
|
"""
|
|
7860
|
+
if thumbnail_id:
|
|
7861
|
+
warnings.warn(
|
|
7862
|
+
(
|
|
7863
|
+
"Function 'get_version_thumbnail' got 'thumbnail_id' which"
|
|
7864
|
+
" is deprecated and will be removed in future version."
|
|
7865
|
+
),
|
|
7866
|
+
DeprecationWarning
|
|
7867
|
+
)
|
|
7886
7868
|
return self.get_thumbnail(
|
|
7887
|
-
project_name, "version", version_id
|
|
7869
|
+
project_name, "version", version_id
|
|
7888
7870
|
)
|
|
7889
7871
|
|
|
7890
7872
|
def get_workfile_thumbnail(
|
|
@@ -7907,8 +7889,17 @@ class ServerAPI(object):
|
|
|
7907
7889
|
valid.
|
|
7908
7890
|
|
|
7909
7891
|
"""
|
|
7892
|
+
if thumbnail_id:
|
|
7893
|
+
warnings.warn(
|
|
7894
|
+
(
|
|
7895
|
+
"Function 'get_workfile_thumbnail' got 'thumbnail_id'"
|
|
7896
|
+
" which is deprecated and will be removed in future"
|
|
7897
|
+
" version."
|
|
7898
|
+
),
|
|
7899
|
+
DeprecationWarning
|
|
7900
|
+
)
|
|
7910
7901
|
return self.get_thumbnail(
|
|
7911
|
-
project_name, "workfile", workfile_id
|
|
7902
|
+
project_name, "workfile", workfile_id
|
|
7912
7903
|
)
|
|
7913
7904
|
|
|
7914
7905
|
def create_thumbnail(
|
|
@@ -8345,22 +8336,8 @@ class ServerAPI(object):
|
|
|
8345
8336
|
kwargs = {
|
|
8346
8337
|
"input": input_id,
|
|
8347
8338
|
"output": output_id,
|
|
8339
|
+
"linkType": full_link_type_name,
|
|
8348
8340
|
}
|
|
8349
|
-
major, minor, patch, rel, _ = self.server_version_tuple
|
|
8350
|
-
rel_regex = re.compile(r"rc\.[0-5]")
|
|
8351
|
-
if (
|
|
8352
|
-
((major, minor, patch) == (1, 0, 0) and rel_regex.match(rel))
|
|
8353
|
-
or (major, minor, patch) < (1, 0, 0)
|
|
8354
|
-
):
|
|
8355
|
-
kwargs["link"] = full_link_type_name
|
|
8356
|
-
if link_name:
|
|
8357
|
-
raise UnsupportedServerVersion(
|
|
8358
|
-
"Link name is not supported"
|
|
8359
|
-
f" for version of AYON server {self.server_version}"
|
|
8360
|
-
)
|
|
8361
|
-
else:
|
|
8362
|
-
kwargs["linkType"] = full_link_type_name
|
|
8363
|
-
|
|
8364
8341
|
if link_name:
|
|
8365
8342
|
kwargs["name"] = link_name
|
|
8366
8343
|
|
|
@@ -8522,23 +8499,6 @@ class ServerAPI(object):
|
|
|
8522
8499
|
return output
|
|
8523
8500
|
|
|
8524
8501
|
link_fields = {"id", "links"}
|
|
8525
|
-
# Backwards compatibility for server version 1.0.0-rc.5 and lower
|
|
8526
|
-
# ---------
|
|
8527
|
-
major, minor, patch, rel, _ = self.server_version_tuple
|
|
8528
|
-
rel_regex = re.compile(r"rc\.[0-5]")
|
|
8529
|
-
if (
|
|
8530
|
-
((major, minor, patch) == (1, 0, 0) and rel_regex.match(rel))
|
|
8531
|
-
or (major, minor, patch) < (1, 0, 0)
|
|
8532
|
-
):
|
|
8533
|
-
fields = set(DEFAULT_LINK_FIELDS)
|
|
8534
|
-
fields.discard("name")
|
|
8535
|
-
link_fields.discard("links")
|
|
8536
|
-
link_fields |= {
|
|
8537
|
-
f"links.{field}"
|
|
8538
|
-
for field in fields
|
|
8539
|
-
}
|
|
8540
|
-
# ---------
|
|
8541
|
-
|
|
8542
8502
|
query = query_func(link_fields)
|
|
8543
8503
|
for attr, filter_value in filters.items():
|
|
8544
8504
|
query.set_variable_value(attr, filter_value)
|
|
@@ -855,11 +855,13 @@ def _get_media_mime_type_for_content_base(content: bytes) -> Optional[str]:
|
|
|
855
855
|
if content[0:4] == b"\211PNG":
|
|
856
856
|
return "image/png"
|
|
857
857
|
|
|
858
|
-
# JPEG
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
)
|
|
858
|
+
# JPEG
|
|
859
|
+
# - [0:2] is constant b"\xff\xd8"
|
|
860
|
+
# (ref. https://www.file-recovery.com/jpg-signature-format.htm)
|
|
861
|
+
# - [2:4] Marker identifier b"\xff{?}"
|
|
862
|
+
# (ref. https://www.disktuna.com/list-of-jpeg-markers/)
|
|
863
|
+
# NOTE: File ends with b"\xff\xd9"
|
|
864
|
+
if content[0:3] == b"\xff\xd8\xff":
|
|
863
865
|
return "image/jpeg"
|
|
864
866
|
|
|
865
867
|
# Webp
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""Package declaring Python API for AYON server."""
|
|
2
|
-
__version__ = "1.0
|
|
2
|
+
__version__ = "1.1.0"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "ayon-python-api"
|
|
3
|
-
version = "1.0
|
|
3
|
+
version = "1.1.0"
|
|
4
4
|
description = "AYON Python API"
|
|
5
5
|
license = {file = "LICENSE"}
|
|
6
6
|
readme = {file = "README.md", content-type = "text/markdown"}
|
|
@@ -16,7 +16,6 @@ classifiers = [
|
|
|
16
16
|
dependencies = [
|
|
17
17
|
"requests >= 2.27.1",
|
|
18
18
|
"Unidecode >= 1.3.0",
|
|
19
|
-
"appdirs >=1, <2",
|
|
20
19
|
]
|
|
21
20
|
|
|
22
21
|
[project.urls]
|
|
@@ -29,7 +28,7 @@ build-backend = "poetry.core.masonry.api"
|
|
|
29
28
|
|
|
30
29
|
[tool.poetry]
|
|
31
30
|
name = "ayon-python-api"
|
|
32
|
-
version = "1.0
|
|
31
|
+
version = "1.1.0"
|
|
33
32
|
description = "AYON Python API"
|
|
34
33
|
authors = [
|
|
35
34
|
"ynput.io <info@ynput.io>"
|
|
@@ -42,7 +41,6 @@ packages = [
|
|
|
42
41
|
python = ">=3.6.5"
|
|
43
42
|
requests = "^2.27"
|
|
44
43
|
Unidecode = "^1.3"
|
|
45
|
-
appdirs = "^1.4"
|
|
46
44
|
|
|
47
45
|
[tool.poetry.group.dev.dependencies]
|
|
48
46
|
sphinx = "*"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ayon-python-api-1.0.12 → ayon-python-api-1.1.0}/ayon_python_api.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|