Ayon-Python-Api 0.2.0__py3-none-any.whl → 0.2.2__py3-none-any.whl
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_api/__init__.py +43 -2
- ayon_api/_api.py +97 -0
- ayon_api/entity_hub.py +88 -0
- ayon_api/server_api.py +655 -55
- ayon_api/version.py +1 -1
- {ayon_python_api-0.2.0.dist-info → ayon_python_api-0.2.2.dist-info}/METADATA +1 -1
- {ayon_python_api-0.2.0.dist-info → ayon_python_api-0.2.2.dist-info}/RECORD +10 -10
- {ayon_python_api-0.2.0.dist-info → ayon_python_api-0.2.2.dist-info}/LICENSE +0 -0
- {ayon_python_api-0.2.0.dist-info → ayon_python_api-0.2.2.dist-info}/WHEEL +0 -0
- {ayon_python_api-0.2.0.dist-info → ayon_python_api-0.2.2.dist-info}/top_level.txt +0 -0
ayon_api/__init__.py
CHANGED
|
@@ -59,13 +59,31 @@ from ._api import (
|
|
|
59
59
|
get_addon_url,
|
|
60
60
|
download_addon_private_file,
|
|
61
61
|
|
|
62
|
+
get_installers,
|
|
63
|
+
create_installer,
|
|
64
|
+
update_installer,
|
|
65
|
+
delete_installer,
|
|
66
|
+
download_installer,
|
|
67
|
+
upload_installer,
|
|
68
|
+
|
|
62
69
|
get_dependencies_info,
|
|
63
70
|
update_dependency_info,
|
|
71
|
+
get_dependency_packages,
|
|
72
|
+
create_dependency_package,
|
|
73
|
+
update_dependency_package,
|
|
74
|
+
delete_dependency_package,
|
|
64
75
|
|
|
65
76
|
download_dependency_package,
|
|
66
77
|
upload_dependency_package,
|
|
67
|
-
delete_dependency_package,
|
|
68
78
|
|
|
79
|
+
get_bundles,
|
|
80
|
+
create_bundle,
|
|
81
|
+
update_bundle,
|
|
82
|
+
delete_bundle,
|
|
83
|
+
|
|
84
|
+
get_info,
|
|
85
|
+
get_server_version,
|
|
86
|
+
get_server_version_tuple,
|
|
69
87
|
get_user,
|
|
70
88
|
get_users,
|
|
71
89
|
|
|
@@ -87,15 +105,18 @@ from ._api import (
|
|
|
87
105
|
get_addons_project_settings,
|
|
88
106
|
get_addons_settings,
|
|
89
107
|
|
|
108
|
+
get_project_names,
|
|
90
109
|
get_projects,
|
|
91
110
|
get_project,
|
|
92
111
|
create_project,
|
|
112
|
+
update_project,
|
|
93
113
|
delete_project,
|
|
94
114
|
|
|
95
115
|
get_folder_by_id,
|
|
96
116
|
get_folder_by_name,
|
|
97
117
|
get_folder_by_path,
|
|
98
118
|
get_folders,
|
|
119
|
+
get_folders_hierarchy,
|
|
99
120
|
|
|
100
121
|
get_tasks,
|
|
101
122
|
|
|
@@ -218,13 +239,31 @@ __all__ = (
|
|
|
218
239
|
"get_addon_url",
|
|
219
240
|
"download_addon_private_file",
|
|
220
241
|
|
|
242
|
+
"get_installers",
|
|
243
|
+
"create_installer",
|
|
244
|
+
"update_installer",
|
|
245
|
+
"delete_installer",
|
|
246
|
+
"download_installer",
|
|
247
|
+
"upload_installer",
|
|
248
|
+
|
|
221
249
|
"get_dependencies_info",
|
|
222
250
|
"update_dependency_info",
|
|
251
|
+
"get_dependency_packages",
|
|
252
|
+
"create_dependency_package",
|
|
253
|
+
"update_dependency_package",
|
|
254
|
+
"delete_dependency_package",
|
|
223
255
|
|
|
224
256
|
"download_dependency_package",
|
|
225
257
|
"upload_dependency_package",
|
|
226
|
-
"delete_dependency_package",
|
|
227
258
|
|
|
259
|
+
"get_bundles",
|
|
260
|
+
"create_bundle",
|
|
261
|
+
"update_bundle",
|
|
262
|
+
"delete_bundle",
|
|
263
|
+
|
|
264
|
+
"get_info",
|
|
265
|
+
"get_server_version",
|
|
266
|
+
"get_server_version_tuple",
|
|
228
267
|
"get_user",
|
|
229
268
|
"get_users",
|
|
230
269
|
|
|
@@ -245,9 +284,11 @@ __all__ = (
|
|
|
245
284
|
"get_addons_project_settings",
|
|
246
285
|
"get_addons_settings",
|
|
247
286
|
|
|
287
|
+
"get_project_names",
|
|
248
288
|
"get_projects",
|
|
249
289
|
"get_project",
|
|
250
290
|
"create_project",
|
|
291
|
+
"update_project",
|
|
251
292
|
"delete_project",
|
|
252
293
|
|
|
253
294
|
"get_folder_by_id",
|
ayon_api/_api.py
CHANGED
|
@@ -531,6 +531,53 @@ def download_addon_private_file(*args, **kwargs):
|
|
|
531
531
|
return con.download_addon_private_file(*args, **kwargs)
|
|
532
532
|
|
|
533
533
|
|
|
534
|
+
def get_info(*args, **kwargs):
|
|
535
|
+
con = get_server_api_connection()
|
|
536
|
+
return con.get_info(*args, **kwargs)
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
def get_server_version(*args, **kwargs):
|
|
540
|
+
con = get_server_api_connection()
|
|
541
|
+
return con.get_server_version(*args, **kwargs)
|
|
542
|
+
|
|
543
|
+
|
|
544
|
+
def get_server_version_tuple(*args, **kwargs):
|
|
545
|
+
con = get_server_api_connection()
|
|
546
|
+
return con.get_server_version_tuple(*args, **kwargs)
|
|
547
|
+
|
|
548
|
+
|
|
549
|
+
# Installers
|
|
550
|
+
def get_installers(*args, **kwargs):
|
|
551
|
+
con = get_server_api_connection()
|
|
552
|
+
return con.get_installers(*args, **kwargs)
|
|
553
|
+
|
|
554
|
+
|
|
555
|
+
def create_installer(*args, **kwargs):
|
|
556
|
+
con = get_server_api_connection()
|
|
557
|
+
return con.create_installer(*args, **kwargs)
|
|
558
|
+
|
|
559
|
+
|
|
560
|
+
def update_installer(*args, **kwargs):
|
|
561
|
+
con = get_server_api_connection()
|
|
562
|
+
return con.update_installer(*args, **kwargs)
|
|
563
|
+
|
|
564
|
+
|
|
565
|
+
def delete_installer(*args, **kwargs):
|
|
566
|
+
con = get_server_api_connection()
|
|
567
|
+
return con.delete_installer(*args, **kwargs)
|
|
568
|
+
|
|
569
|
+
|
|
570
|
+
def download_installer(*args, **kwargs):
|
|
571
|
+
con = get_server_api_connection()
|
|
572
|
+
con.download_installer(*args, **kwargs)
|
|
573
|
+
|
|
574
|
+
|
|
575
|
+
def upload_installer(*args, **kwargs):
|
|
576
|
+
con = get_server_api_connection()
|
|
577
|
+
con.upload_installer(*args, **kwargs)
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
# Dependency packages
|
|
534
581
|
def get_dependencies_info(*args, **kwargs):
|
|
535
582
|
con = get_server_api_connection()
|
|
536
583
|
return con.get_dependencies_info(*args, **kwargs)
|
|
@@ -551,6 +598,21 @@ def upload_dependency_package(*args, **kwargs):
|
|
|
551
598
|
return con.upload_dependency_package(*args, **kwargs)
|
|
552
599
|
|
|
553
600
|
|
|
601
|
+
def get_dependency_packages(*args, **kwargs):
|
|
602
|
+
con = get_server_api_connection()
|
|
603
|
+
return con.get_dependency_packages(*args, **kwargs)
|
|
604
|
+
|
|
605
|
+
|
|
606
|
+
def create_dependency_package(*args, **kwargs):
|
|
607
|
+
con = get_server_api_connection()
|
|
608
|
+
return con.create_dependency_package(*args, **kwargs)
|
|
609
|
+
|
|
610
|
+
|
|
611
|
+
def update_dependency_package(*args, **kwargs):
|
|
612
|
+
con = get_server_api_connection()
|
|
613
|
+
return con.update_dependency_package(*args, **kwargs)
|
|
614
|
+
|
|
615
|
+
|
|
554
616
|
def delete_dependency_package(*args, **kwargs):
|
|
555
617
|
con = get_server_api_connection()
|
|
556
618
|
return con.delete_dependency_package(*args, **kwargs)
|
|
@@ -561,6 +623,26 @@ def get_project_anatomy_presets(*args, **kwargs):
|
|
|
561
623
|
return con.get_project_anatomy_presets(*args, **kwargs)
|
|
562
624
|
|
|
563
625
|
|
|
626
|
+
def get_bundles(*args, **kwargs):
|
|
627
|
+
con = get_server_api_connection()
|
|
628
|
+
return con.get_bundles(*args, **kwargs)
|
|
629
|
+
|
|
630
|
+
|
|
631
|
+
def create_bundle(*args, **kwargs):
|
|
632
|
+
con = get_server_api_connection()
|
|
633
|
+
return con.create_bundle(*args, **kwargs)
|
|
634
|
+
|
|
635
|
+
|
|
636
|
+
def update_bundle(*args, **kwargs):
|
|
637
|
+
con = get_server_api_connection()
|
|
638
|
+
return con.update_bundle(*args, **kwargs)
|
|
639
|
+
|
|
640
|
+
|
|
641
|
+
def delete_bundle(*args, **kwargs):
|
|
642
|
+
con = get_server_api_connection()
|
|
643
|
+
return con.delete_bundle(*args, **kwargs)
|
|
644
|
+
|
|
645
|
+
|
|
564
646
|
def get_project_anatomy_preset(*args, **kwargs):
|
|
565
647
|
con = get_server_api_connection()
|
|
566
648
|
return con.get_project_anatomy_preset(*args, **kwargs)
|
|
@@ -621,6 +703,11 @@ def get_addons_settings(*args, **kwargs):
|
|
|
621
703
|
return con.get_addons_settings(*args, **kwargs)
|
|
622
704
|
|
|
623
705
|
|
|
706
|
+
def get_project_names(*args, **kwargs):
|
|
707
|
+
con = get_server_api_connection()
|
|
708
|
+
return con.get_project_names(*args, **kwargs)
|
|
709
|
+
|
|
710
|
+
|
|
624
711
|
def get_project(*args, **kwargs):
|
|
625
712
|
con = get_server_api_connection()
|
|
626
713
|
return con.get_project(*args, **kwargs)
|
|
@@ -636,6 +723,11 @@ def get_folders(*args, **kwargs):
|
|
|
636
723
|
return con.get_folders(*args, **kwargs)
|
|
637
724
|
|
|
638
725
|
|
|
726
|
+
def get_folders_hierarchy(*args, **kwargs):
|
|
727
|
+
con = get_server_api_connection()
|
|
728
|
+
return con.get_folders_hierarchy(*args, **kwargs)
|
|
729
|
+
|
|
730
|
+
|
|
639
731
|
def get_tasks(*args, **kwargs):
|
|
640
732
|
con = get_server_api_connection()
|
|
641
733
|
return con.get_tasks(*args, **kwargs)
|
|
@@ -801,6 +893,11 @@ def create_project(
|
|
|
801
893
|
)
|
|
802
894
|
|
|
803
895
|
|
|
896
|
+
def update_project(project_name, *args, **kwargs):
|
|
897
|
+
con = get_server_api_connection()
|
|
898
|
+
return con.update_project(project_name, *args, **kwargs)
|
|
899
|
+
|
|
900
|
+
|
|
804
901
|
def delete_project(project_name):
|
|
805
902
|
con = get_server_api_connection()
|
|
806
903
|
return con.delete_project(project_name)
|
ayon_api/entity_hub.py
CHANGED
|
@@ -683,6 +683,82 @@ class EntityHub(object):
|
|
|
683
683
|
"entityId": entity.id
|
|
684
684
|
}
|
|
685
685
|
|
|
686
|
+
def _pre_commit_types_changes(
|
|
687
|
+
self, project_changes, orig_types, changes_key, post_changes
|
|
688
|
+
):
|
|
689
|
+
"""Compare changes of types on a project.
|
|
690
|
+
|
|
691
|
+
Compare old and new types. Change project changes content if some old
|
|
692
|
+
types were removed. In that case the final change of types will
|
|
693
|
+
happen when all other entities have changed.
|
|
694
|
+
|
|
695
|
+
Args:
|
|
696
|
+
project_changes (dict[str, Any]): Project changes.
|
|
697
|
+
orig_types (list[dict[str, Any]]): Original types.
|
|
698
|
+
changes_key (Literal[folderTypes, taskTypes]): Key of type changes
|
|
699
|
+
in project changes.
|
|
700
|
+
post_changes (dict[str, Any]): An object where post changes will
|
|
701
|
+
be stored.
|
|
702
|
+
"""
|
|
703
|
+
|
|
704
|
+
if changes_key not in project_changes:
|
|
705
|
+
return
|
|
706
|
+
|
|
707
|
+
new_types = project_changes[changes_key]
|
|
708
|
+
|
|
709
|
+
orig_types_by_name = {
|
|
710
|
+
type_info["name"]: type_info
|
|
711
|
+
for type_info in orig_types
|
|
712
|
+
}
|
|
713
|
+
new_names = {
|
|
714
|
+
type_info["name"]
|
|
715
|
+
for type_info in new_types
|
|
716
|
+
}
|
|
717
|
+
diff_names = set(orig_types_by_name) - new_names
|
|
718
|
+
if not diff_names:
|
|
719
|
+
return
|
|
720
|
+
|
|
721
|
+
# Create copy of folder type changes to post changes
|
|
722
|
+
# - post changes will be commited at the end
|
|
723
|
+
post_changes[changes_key] = copy.deepcopy(new_types)
|
|
724
|
+
|
|
725
|
+
for type_name in diff_names:
|
|
726
|
+
new_types.append(orig_types_by_name[type_name])
|
|
727
|
+
|
|
728
|
+
def _pre_commit_project(self):
|
|
729
|
+
"""Some project changes cannot be committed before hierarchy changes.
|
|
730
|
+
|
|
731
|
+
It is not possible to change folder types or task types if there are
|
|
732
|
+
existing hierarchy items using the removed types. For that purposes
|
|
733
|
+
is first committed union of all old and new types and post changes
|
|
734
|
+
are prepared when all existing entities are changed.
|
|
735
|
+
|
|
736
|
+
Returns:
|
|
737
|
+
dict[str, Any]: Changes that will be committed after hierarchy
|
|
738
|
+
changes.
|
|
739
|
+
"""
|
|
740
|
+
|
|
741
|
+
project_changes = self.project_entity.changes
|
|
742
|
+
|
|
743
|
+
post_changes = {}
|
|
744
|
+
if not project_changes:
|
|
745
|
+
return post_changes
|
|
746
|
+
|
|
747
|
+
self._pre_commit_types_changes(
|
|
748
|
+
project_changes,
|
|
749
|
+
self.project_entity.get_orig_folder_types(),
|
|
750
|
+
"folderType",
|
|
751
|
+
post_changes
|
|
752
|
+
)
|
|
753
|
+
self._pre_commit_types_changes(
|
|
754
|
+
project_changes,
|
|
755
|
+
self.project_entity.get_orig_task_types(),
|
|
756
|
+
"taskType",
|
|
757
|
+
post_changes
|
|
758
|
+
)
|
|
759
|
+
self._connection.update_project(self.project_name, **project_changes)
|
|
760
|
+
return post_changes
|
|
761
|
+
|
|
686
762
|
def commit_changes(self):
|
|
687
763
|
"""Commit any changes that happened on entities.
|
|
688
764
|
|
|
@@ -690,6 +766,9 @@ class EntityHub(object):
|
|
|
690
766
|
Use Operations Session instead of known operations body.
|
|
691
767
|
"""
|
|
692
768
|
|
|
769
|
+
post_project_changes = self._pre_commit_project()
|
|
770
|
+
self.project_entity.lock()
|
|
771
|
+
|
|
693
772
|
project_changes = self.project_entity.changes
|
|
694
773
|
if project_changes:
|
|
695
774
|
response = self._connection.patch(
|
|
@@ -760,6 +839,9 @@ class EntityHub(object):
|
|
|
760
839
|
self._connection.send_batch_operations(
|
|
761
840
|
self.project_name, operations_body
|
|
762
841
|
)
|
|
842
|
+
if post_project_changes:
|
|
843
|
+
self._connection.update_project(
|
|
844
|
+
self.project_name, **post_project_changes)
|
|
763
845
|
|
|
764
846
|
self.lock()
|
|
765
847
|
|
|
@@ -1463,6 +1545,9 @@ class ProjectEntity(BaseEntity):
|
|
|
1463
1545
|
|
|
1464
1546
|
parent = property(get_parent, set_parent)
|
|
1465
1547
|
|
|
1548
|
+
def get_orig_folder_types(self):
|
|
1549
|
+
return copy.deepcopy(self._orig_folder_types)
|
|
1550
|
+
|
|
1466
1551
|
def get_folder_types(self):
|
|
1467
1552
|
return copy.deepcopy(self._folder_types)
|
|
1468
1553
|
|
|
@@ -1474,6 +1559,9 @@ class ProjectEntity(BaseEntity):
|
|
|
1474
1559
|
new_folder_types.append(folder_type)
|
|
1475
1560
|
self._folder_types = new_folder_types
|
|
1476
1561
|
|
|
1562
|
+
def get_orig_task_types(self):
|
|
1563
|
+
return copy.deepcopy(self._orig_task_types)
|
|
1564
|
+
|
|
1477
1565
|
def get_task_types(self):
|
|
1478
1566
|
return copy.deepcopy(self._task_types)
|
|
1479
1567
|
|
ayon_api/server_api.py
CHANGED
|
@@ -4,6 +4,7 @@ import io
|
|
|
4
4
|
import json
|
|
5
5
|
import logging
|
|
6
6
|
import collections
|
|
7
|
+
import datetime
|
|
7
8
|
import platform
|
|
8
9
|
import copy
|
|
9
10
|
import uuid
|
|
@@ -70,6 +71,14 @@ PROJECT_NAME_REGEX = re.compile(
|
|
|
70
71
|
"^[{}]+$".format(PROJECT_NAME_ALLOWED_SYMBOLS)
|
|
71
72
|
)
|
|
72
73
|
|
|
74
|
+
VERSION_REGEX = re.compile(
|
|
75
|
+
r"(?P<major>0|[1-9]\d*)"
|
|
76
|
+
r"\.(?P<minor>0|[1-9]\d*)"
|
|
77
|
+
r"\.(?P<patch>0|[1-9]\d*)"
|
|
78
|
+
r"(?:-(?P<prerelease>[a-zA-Z\d\-.]*))?"
|
|
79
|
+
r"(?:\+(?P<buildmetadata>[a-zA-Z\d\-.]*))?"
|
|
80
|
+
)
|
|
81
|
+
|
|
73
82
|
|
|
74
83
|
def _get_description(response):
|
|
75
84
|
if HTTPStatus is None:
|
|
@@ -304,6 +313,11 @@ class ServerAPI(object):
|
|
|
304
313
|
default_settings_variant (Optional[str]): Settings variant used by
|
|
305
314
|
default if a method for settings won't get any (by default is
|
|
306
315
|
'production').
|
|
316
|
+
ssl_verify (Union[bool, str, None]): Verify SSL certificate
|
|
317
|
+
Looks for env variable value 'AYON_CA_FILE' by default. If not
|
|
318
|
+
available then 'True' is used.
|
|
319
|
+
cert (Optional[str]): Path to certificate file. Looks for env
|
|
320
|
+
variable value 'AYON_CERT_FILE' by default.
|
|
307
321
|
"""
|
|
308
322
|
|
|
309
323
|
def __init__(
|
|
@@ -312,7 +326,9 @@ class ServerAPI(object):
|
|
|
312
326
|
token=None,
|
|
313
327
|
site_id=None,
|
|
314
328
|
client_version=None,
|
|
315
|
-
default_settings_variant=None
|
|
329
|
+
default_settings_variant=None,
|
|
330
|
+
ssl_verify=None,
|
|
331
|
+
cert=None,
|
|
316
332
|
):
|
|
317
333
|
if not base_url:
|
|
318
334
|
raise ValueError("Invalid server URL {}".format(str(base_url)))
|
|
@@ -326,9 +342,24 @@ class ServerAPI(object):
|
|
|
326
342
|
self._site_id = site_id
|
|
327
343
|
self._client_version = client_version
|
|
328
344
|
self._default_settings_variant = default_settings_variant
|
|
345
|
+
|
|
346
|
+
if ssl_verify is None:
|
|
347
|
+
# Custom AYON env variable for CA file or 'True'
|
|
348
|
+
# - that should cover most default behaviors in 'requests'
|
|
349
|
+
# with 'certifi'
|
|
350
|
+
ssl_verify = os.environ.get("AYON_CA_FILE") or True
|
|
351
|
+
|
|
352
|
+
if cert is None:
|
|
353
|
+
cert = os.environ.get("AYON_CERT_FILE")
|
|
354
|
+
|
|
355
|
+
self._ssl_verify = ssl_verify
|
|
356
|
+
self._cert = cert
|
|
357
|
+
|
|
329
358
|
self._access_token_is_service = None
|
|
330
359
|
self._token_is_valid = None
|
|
331
360
|
self._server_available = None
|
|
361
|
+
self._server_version = None
|
|
362
|
+
self._server_version_tuple = None
|
|
332
363
|
|
|
333
364
|
self._session = None
|
|
334
365
|
|
|
@@ -363,6 +394,54 @@ class ServerAPI(object):
|
|
|
363
394
|
base_url = property(get_base_url)
|
|
364
395
|
rest_url = property(get_rest_url)
|
|
365
396
|
|
|
397
|
+
def get_ssl_verify(self):
|
|
398
|
+
"""Enable ssl verification.
|
|
399
|
+
|
|
400
|
+
Returns:
|
|
401
|
+
bool: Current state of ssl verification.
|
|
402
|
+
"""
|
|
403
|
+
|
|
404
|
+
return self._ssl_verify
|
|
405
|
+
|
|
406
|
+
def set_ssl_verify(self, ssl_verify):
|
|
407
|
+
"""Change ssl verification state.
|
|
408
|
+
|
|
409
|
+
Args:
|
|
410
|
+
ssl_verify (Union[bool, str, None]): Enabled/disable
|
|
411
|
+
ssl verification, can be a path to file.
|
|
412
|
+
"""
|
|
413
|
+
|
|
414
|
+
if self._ssl_verify == ssl_verify:
|
|
415
|
+
return
|
|
416
|
+
self._ssl_verify = ssl_verify
|
|
417
|
+
if self._session is not None:
|
|
418
|
+
self._session.verify = ssl_verify
|
|
419
|
+
|
|
420
|
+
def get_cert(self):
|
|
421
|
+
"""Current cert file used for connection to server.
|
|
422
|
+
|
|
423
|
+
Returns:
|
|
424
|
+
Union[str, None]: Path to cert file.
|
|
425
|
+
"""
|
|
426
|
+
|
|
427
|
+
return self._cert
|
|
428
|
+
|
|
429
|
+
def set_cert(self, cert):
|
|
430
|
+
"""Change cert file used for connection to server.
|
|
431
|
+
|
|
432
|
+
Args:
|
|
433
|
+
cert (Union[str, None]): Path to cert file.
|
|
434
|
+
"""
|
|
435
|
+
|
|
436
|
+
if cert == self._cert:
|
|
437
|
+
return
|
|
438
|
+
self._cert = cert
|
|
439
|
+
if self._session is not None:
|
|
440
|
+
self._session.cert = cert
|
|
441
|
+
|
|
442
|
+
ssl_verify = property(get_ssl_verify, set_ssl_verify)
|
|
443
|
+
cert = property(get_cert, set_cert)
|
|
444
|
+
|
|
366
445
|
@property
|
|
367
446
|
def access_token(self):
|
|
368
447
|
"""Access token used for authorization to server.
|
|
@@ -534,7 +613,11 @@ class ServerAPI(object):
|
|
|
534
613
|
@property
|
|
535
614
|
def is_server_available(self):
|
|
536
615
|
if self._server_available is None:
|
|
537
|
-
response = requests.get(
|
|
616
|
+
response = requests.get(
|
|
617
|
+
self._base_url,
|
|
618
|
+
cert=self._cert,
|
|
619
|
+
verify=self._ssl_verify
|
|
620
|
+
)
|
|
538
621
|
self._server_available = response.status_code == 200
|
|
539
622
|
return self._server_available
|
|
540
623
|
|
|
@@ -585,6 +668,8 @@ class ServerAPI(object):
|
|
|
585
668
|
self.validate_token()
|
|
586
669
|
|
|
587
670
|
session = requests.Session()
|
|
671
|
+
session.cert = self._cert
|
|
672
|
+
session.verify = self._ssl_verify
|
|
588
673
|
session.headers.update(self.get_headers())
|
|
589
674
|
|
|
590
675
|
self._session_functions_mapping = {
|
|
@@ -631,12 +716,52 @@ class ServerAPI(object):
|
|
|
631
716
|
Use this method for validation of token instead of 'get_user'.
|
|
632
717
|
|
|
633
718
|
Returns:
|
|
634
|
-
|
|
719
|
+
dict[str, Any]: Information from server.
|
|
635
720
|
"""
|
|
636
721
|
|
|
637
722
|
response = self.get("info")
|
|
638
723
|
return response.data
|
|
639
724
|
|
|
725
|
+
def get_server_version(self):
|
|
726
|
+
"""Get server version.
|
|
727
|
+
|
|
728
|
+
Version should match semantic version (https://semver.org/).
|
|
729
|
+
|
|
730
|
+
Returns:
|
|
731
|
+
str: Server version.
|
|
732
|
+
"""
|
|
733
|
+
|
|
734
|
+
if self._server_version is None:
|
|
735
|
+
self._server_version = self.get_info()["version"]
|
|
736
|
+
return self._server_version
|
|
737
|
+
|
|
738
|
+
def get_server_version_tuple(self):
|
|
739
|
+
"""Get server version as tuple.
|
|
740
|
+
|
|
741
|
+
Version should match semantic version (https://semver.org/).
|
|
742
|
+
|
|
743
|
+
This function only returns first three numbers of version.
|
|
744
|
+
|
|
745
|
+
Returns:
|
|
746
|
+
Tuple[int, int, int, Union[str, None], Union[str, None]]: Server
|
|
747
|
+
version.
|
|
748
|
+
"""
|
|
749
|
+
|
|
750
|
+
if self._server_version_tuple is None:
|
|
751
|
+
re_match = VERSION_REGEX.fullmatch(
|
|
752
|
+
self.get_server_version())
|
|
753
|
+
self._server_version_tuple = (
|
|
754
|
+
int(re_match.group("major")),
|
|
755
|
+
int(re_match.group("minor")),
|
|
756
|
+
int(re_match.group("patch")),
|
|
757
|
+
re_match.group("prerelease"),
|
|
758
|
+
re_match.group("buildmetadata")
|
|
759
|
+
)
|
|
760
|
+
return self._server_version_tuple
|
|
761
|
+
|
|
762
|
+
server_version = property(get_server_version)
|
|
763
|
+
server_version_tuple = property(get_server_version_tuple)
|
|
764
|
+
|
|
640
765
|
def _get_user_info(self):
|
|
641
766
|
if self._access_token is None:
|
|
642
767
|
return None
|
|
@@ -869,7 +994,7 @@ class ServerAPI(object):
|
|
|
869
994
|
event_id (str): Id of event.
|
|
870
995
|
|
|
871
996
|
Returns:
|
|
872
|
-
|
|
997
|
+
dict[str, Any]: Full event data.
|
|
873
998
|
"""
|
|
874
999
|
|
|
875
1000
|
response = self.get("events/{}".format(event_id))
|
|
@@ -902,7 +1027,7 @@ class ServerAPI(object):
|
|
|
902
1027
|
for each event.
|
|
903
1028
|
|
|
904
1029
|
Returns:
|
|
905
|
-
Generator[
|
|
1030
|
+
Generator[dict[str, Any]]: Available events matching filters.
|
|
906
1031
|
"""
|
|
907
1032
|
|
|
908
1033
|
filters = {}
|
|
@@ -1269,7 +1394,7 @@ class ServerAPI(object):
|
|
|
1269
1394
|
Cache schema - How to find out it is outdated?
|
|
1270
1395
|
|
|
1271
1396
|
Returns:
|
|
1272
|
-
|
|
1397
|
+
dict[str, Any]: Full server schema.
|
|
1273
1398
|
"""
|
|
1274
1399
|
|
|
1275
1400
|
url = "{}/openapi.json".format(self._base_url)
|
|
@@ -1287,7 +1412,7 @@ class ServerAPI(object):
|
|
|
1287
1412
|
e.g. 'config' has just object definition without reference schema.
|
|
1288
1413
|
|
|
1289
1414
|
Returns:
|
|
1290
|
-
|
|
1415
|
+
dict[str, Any]: Component schemas.
|
|
1291
1416
|
"""
|
|
1292
1417
|
|
|
1293
1418
|
server_schema = self.get_server_schema()
|
|
@@ -1395,7 +1520,7 @@ class ServerAPI(object):
|
|
|
1395
1520
|
received.
|
|
1396
1521
|
|
|
1397
1522
|
Returns:
|
|
1398
|
-
|
|
1523
|
+
dict[str, dict[str, Any]]: Attribute schemas that are available
|
|
1399
1524
|
for entered entity type.
|
|
1400
1525
|
"""
|
|
1401
1526
|
attributes = self._entity_type_attributes_cache.get(entity_type)
|
|
@@ -1563,6 +1688,148 @@ class ServerAPI(object):
|
|
|
1563
1688
|
)
|
|
1564
1689
|
return dst_filepath
|
|
1565
1690
|
|
|
1691
|
+
def get_installers(self, version=None, platform_name=None):
|
|
1692
|
+
"""Information about desktop application installers on server.
|
|
1693
|
+
|
|
1694
|
+
Desktop application installers are helpers to download/update AYON
|
|
1695
|
+
desktop application for artists.
|
|
1696
|
+
|
|
1697
|
+
Args:
|
|
1698
|
+
version (Optional[str]): Filter installers by version.
|
|
1699
|
+
platform_name (Optional[str]): Filter installers by platform name.
|
|
1700
|
+
|
|
1701
|
+
Returns:
|
|
1702
|
+
list[dict[str, Any]]:
|
|
1703
|
+
"""
|
|
1704
|
+
|
|
1705
|
+
query_fields = [
|
|
1706
|
+
"{}={}".format(key, value)
|
|
1707
|
+
for key, value in (
|
|
1708
|
+
("version", version),
|
|
1709
|
+
("platform", platform_name),
|
|
1710
|
+
)
|
|
1711
|
+
if value
|
|
1712
|
+
]
|
|
1713
|
+
query = ""
|
|
1714
|
+
if query_fields:
|
|
1715
|
+
query = "?{}".format(",".join(query_fields))
|
|
1716
|
+
|
|
1717
|
+
response = self.get("desktop/installers{}".format(query))
|
|
1718
|
+
response.raise_for_status()
|
|
1719
|
+
return response.data
|
|
1720
|
+
|
|
1721
|
+
def create_installer(
|
|
1722
|
+
self,
|
|
1723
|
+
filename,
|
|
1724
|
+
version,
|
|
1725
|
+
python_version,
|
|
1726
|
+
platform_name,
|
|
1727
|
+
python_modules,
|
|
1728
|
+
checksum,
|
|
1729
|
+
checksum_type,
|
|
1730
|
+
file_size,
|
|
1731
|
+
sources=None,
|
|
1732
|
+
):
|
|
1733
|
+
"""Create new installer information on server.
|
|
1734
|
+
|
|
1735
|
+
This step will create only metadata. Make sure to upload installer
|
|
1736
|
+
to the server using 'upload_installer' method.
|
|
1737
|
+
|
|
1738
|
+
Args:
|
|
1739
|
+
filename (str): Installer filename.
|
|
1740
|
+
version (str): Version of installer.
|
|
1741
|
+
python_version (str): Version of Python.
|
|
1742
|
+
platform_name (str): Name of platform.
|
|
1743
|
+
python_modules (dict[str, str]): Python modules that are available
|
|
1744
|
+
in installer.
|
|
1745
|
+
checksum (str): Installer file checksum.
|
|
1746
|
+
checksum_type (str): Type of checksum used to create checksum.
|
|
1747
|
+
file_size (int): File size.
|
|
1748
|
+
sources (Optional[list[dict[str, Any]]]): List of sources that
|
|
1749
|
+
can be used to download file.
|
|
1750
|
+
"""
|
|
1751
|
+
|
|
1752
|
+
body = {
|
|
1753
|
+
"filename": filename,
|
|
1754
|
+
"version": version,
|
|
1755
|
+
"pythonVersion": python_version,
|
|
1756
|
+
"platform": platform_name,
|
|
1757
|
+
"pythonModules": python_modules,
|
|
1758
|
+
"checksum": checksum,
|
|
1759
|
+
"checksumType": checksum_type,
|
|
1760
|
+
"size": file_size,
|
|
1761
|
+
}
|
|
1762
|
+
if sources:
|
|
1763
|
+
body["sources"] = sources
|
|
1764
|
+
|
|
1765
|
+
response = self.post("desktop/installers", **body)
|
|
1766
|
+
response.raise_for_status()
|
|
1767
|
+
|
|
1768
|
+
def update_installer(self, filename, sources):
|
|
1769
|
+
"""Update installer information on server.
|
|
1770
|
+
|
|
1771
|
+
Args:
|
|
1772
|
+
filename (str): Installer filename.
|
|
1773
|
+
sources (list[dict[str, Any]]): List of sources that
|
|
1774
|
+
can be used to download file. Fully replaces existing sources.
|
|
1775
|
+
"""
|
|
1776
|
+
|
|
1777
|
+
response = self.post(
|
|
1778
|
+
"desktop/installers/{}".format(filename),
|
|
1779
|
+
sources=sources
|
|
1780
|
+
)
|
|
1781
|
+
response.raise_for_status()
|
|
1782
|
+
|
|
1783
|
+
def delete_installer(self, filename):
|
|
1784
|
+
"""Delete installer from server.
|
|
1785
|
+
|
|
1786
|
+
Args:
|
|
1787
|
+
filename (str): Installer filename.
|
|
1788
|
+
"""
|
|
1789
|
+
|
|
1790
|
+
response = self.delete("dekstop/installers/{}".format(filename))
|
|
1791
|
+
response.raise_for_status()
|
|
1792
|
+
|
|
1793
|
+
def download_installer(
|
|
1794
|
+
self,
|
|
1795
|
+
filename,
|
|
1796
|
+
dst_filepath,
|
|
1797
|
+
chunk_size=None,
|
|
1798
|
+
progress=None
|
|
1799
|
+
):
|
|
1800
|
+
"""Download installer file from server.
|
|
1801
|
+
|
|
1802
|
+
Args:
|
|
1803
|
+
filename (str): Installer filename.
|
|
1804
|
+
dst_filepath (str): Destination filepath.
|
|
1805
|
+
chunk_size (Optional[int]): Download chunk size.
|
|
1806
|
+
progress (Optional[TransferProgress]): Object that gives ability
|
|
1807
|
+
to track download progress.
|
|
1808
|
+
"""
|
|
1809
|
+
|
|
1810
|
+
self.download_file(
|
|
1811
|
+
"desktop/installers/{}".format(filename),
|
|
1812
|
+
dst_filepath,
|
|
1813
|
+
chunk_size=chunk_size,
|
|
1814
|
+
progress=progress
|
|
1815
|
+
)
|
|
1816
|
+
|
|
1817
|
+
def upload_installer(self, src_filepath, dst_filename, progress=None):
|
|
1818
|
+
"""Upload installer file to server.
|
|
1819
|
+
|
|
1820
|
+
Args:
|
|
1821
|
+
src_filepath (str): Source filepath.
|
|
1822
|
+
dst_filename (str): Destination filename.
|
|
1823
|
+
progress (Optional[TransferProgress]): Object that gives ability
|
|
1824
|
+
to track download progress.
|
|
1825
|
+
"""
|
|
1826
|
+
|
|
1827
|
+
self.upload_file(
|
|
1828
|
+
"desktop/installers/{}".format(dst_filename),
|
|
1829
|
+
src_filepath,
|
|
1830
|
+
progress=progress
|
|
1831
|
+
)
|
|
1832
|
+
|
|
1566
1833
|
def get_dependencies_info(self):
|
|
1567
1834
|
"""Information about dependency packages on server.
|
|
1568
1835
|
|
|
@@ -1581,13 +1848,22 @@ class ServerAPI(object):
|
|
|
1581
1848
|
"productionPackage": str
|
|
1582
1849
|
}
|
|
1583
1850
|
|
|
1851
|
+
Deprecated:
|
|
1852
|
+
Deprecated since server version 0.2.1. Use
|
|
1853
|
+
'get_dependency_packages' instead.
|
|
1854
|
+
|
|
1584
1855
|
Returns:
|
|
1585
1856
|
dict[str, Any]: Information about dependency packages known for
|
|
1586
1857
|
server.
|
|
1587
1858
|
"""
|
|
1588
1859
|
|
|
1589
|
-
|
|
1590
|
-
|
|
1860
|
+
major, minor, patch, _, _ = self.server_version_tuple
|
|
1861
|
+
if major == 0 and (minor < 2 or (minor == 2 and patch < 1)):
|
|
1862
|
+
result = self.get("dependencies")
|
|
1863
|
+
return result.data
|
|
1864
|
+
packages = self.get_dependency_packages()
|
|
1865
|
+
packages["productionPackage"] = None
|
|
1866
|
+
return packages
|
|
1591
1867
|
|
|
1592
1868
|
def update_dependency_info(
|
|
1593
1869
|
self,
|
|
@@ -1604,21 +1880,26 @@ class ServerAPI(object):
|
|
|
1604
1880
|
|
|
1605
1881
|
The endpoint can be used to create or update dependency package.
|
|
1606
1882
|
|
|
1883
|
+
|
|
1884
|
+
Deprecated:
|
|
1885
|
+
Deprecated for server version 0.2.1. Use
|
|
1886
|
+
'create_dependency_pacakge' instead.
|
|
1887
|
+
|
|
1607
1888
|
Args:
|
|
1608
1889
|
name (str): Name of dependency package.
|
|
1609
|
-
platform_name (Literal["windows", "linux", "darwin"]): Platform
|
|
1610
|
-
which is dependency package targeted.
|
|
1890
|
+
platform_name (Literal["windows", "linux", "darwin"]): Platform
|
|
1891
|
+
for which is dependency package targeted.
|
|
1611
1892
|
size (int): Size of dependency package in bytes.
|
|
1612
1893
|
checksum (str): Checksum of archive file where dependencies are.
|
|
1613
1894
|
checksum_algorithm (Optional[str]): Algorithm used to calculate
|
|
1614
1895
|
checksum. By default, is used 'md5' (defined by server).
|
|
1615
|
-
supported_addons (Optional[
|
|
1896
|
+
supported_addons (Optional[dict[str, str]]): Name of addons for
|
|
1616
1897
|
which was the package created.
|
|
1617
1898
|
'{"<addon name>": "<addon version>", ...}'
|
|
1618
|
-
python_modules (Optional[
|
|
1899
|
+
python_modules (Optional[dict[str, str]]): Python modules in
|
|
1619
1900
|
dependencies package.
|
|
1620
1901
|
'{"<module name>": "<module version>", ...}'
|
|
1621
|
-
sources (Optional[
|
|
1902
|
+
sources (Optional[list[dict[str, Any]]]): Information about
|
|
1622
1903
|
sources where dependency package is available.
|
|
1623
1904
|
"""
|
|
1624
1905
|
|
|
@@ -1645,27 +1926,153 @@ class ServerAPI(object):
|
|
|
1645
1926
|
raise ServerError("Failed to create/update dependency")
|
|
1646
1927
|
return response.data
|
|
1647
1928
|
|
|
1929
|
+
def get_dependency_packages(self):
|
|
1930
|
+
"""Information about dependency packages on server.
|
|
1931
|
+
|
|
1932
|
+
To download dependency package, use 'download_dependency_package'
|
|
1933
|
+
method and pass in 'filename'.
|
|
1934
|
+
|
|
1935
|
+
Example data structure:
|
|
1936
|
+
{
|
|
1937
|
+
"packages": [
|
|
1938
|
+
{
|
|
1939
|
+
"filename": str,
|
|
1940
|
+
"platform": str,
|
|
1941
|
+
"checksum": str,
|
|
1942
|
+
"checksumAlgorithm": str,
|
|
1943
|
+
"size": int,
|
|
1944
|
+
"sources": list[dict[str, Any]],
|
|
1945
|
+
"supportedAddons": dict[str, str],
|
|
1946
|
+
"pythonModules": dict[str, str]
|
|
1947
|
+
}
|
|
1948
|
+
]
|
|
1949
|
+
}
|
|
1950
|
+
|
|
1951
|
+
Returns:
|
|
1952
|
+
dict[str, Any]: Information about dependency packages known for
|
|
1953
|
+
server.
|
|
1954
|
+
"""
|
|
1955
|
+
|
|
1956
|
+
result = self.get("desktop/dependency_packages")
|
|
1957
|
+
result.raise_for_status()
|
|
1958
|
+
return result.data
|
|
1959
|
+
|
|
1960
|
+
def create_dependency_package(
|
|
1961
|
+
self,
|
|
1962
|
+
filename,
|
|
1963
|
+
python_modules,
|
|
1964
|
+
source_addons,
|
|
1965
|
+
installer_version,
|
|
1966
|
+
checksum,
|
|
1967
|
+
checksum_algorithm,
|
|
1968
|
+
file_size,
|
|
1969
|
+
sources=None,
|
|
1970
|
+
platform_name=None,
|
|
1971
|
+
):
|
|
1972
|
+
"""Create dependency package on server.
|
|
1973
|
+
|
|
1974
|
+
The package will be created on a server, it is also required to upload
|
|
1975
|
+
the package archive file (using 'upload_dependency_package').
|
|
1976
|
+
|
|
1977
|
+
Args:
|
|
1978
|
+
filename (str): Filename of dependency package.
|
|
1979
|
+
python_modules (dict[str, str]): Python modules in dependency
|
|
1980
|
+
package.
|
|
1981
|
+
'{"<module name>": "<module version>", ...}'
|
|
1982
|
+
source_addons (dict[str, str]): Name of addons for which is
|
|
1983
|
+
dependency package created.
|
|
1984
|
+
'{"<addon name>": "<addon version>", ...}'
|
|
1985
|
+
installer_version (str): Version of installer for which was
|
|
1986
|
+
package created.
|
|
1987
|
+
checksum (str): Checksum of archive file where dependencies are.
|
|
1988
|
+
checksum_algorithm (str): Algorithm used to calculate checksum.
|
|
1989
|
+
file_size (Optional[int]): Size of file.
|
|
1990
|
+
sources (Optional[list[dict[str, Any]]]): Information about
|
|
1991
|
+
sources from where it is possible to get file.
|
|
1992
|
+
platform_name (Optional[str]): Name of platform for which is
|
|
1993
|
+
dependency package targeted. Default value is
|
|
1994
|
+
current platform.
|
|
1995
|
+
"""
|
|
1996
|
+
|
|
1997
|
+
post_body = {
|
|
1998
|
+
"filename": filename,
|
|
1999
|
+
"pythonModules": python_modules,
|
|
2000
|
+
"sourceAddons": source_addons,
|
|
2001
|
+
"installerVersion": installer_version,
|
|
2002
|
+
"checksum": checksum,
|
|
2003
|
+
"checksumAlgorithm": checksum_algorithm,
|
|
2004
|
+
"size": file_size,
|
|
2005
|
+
"platform": platform_name or platform.system().lower(),
|
|
2006
|
+
}
|
|
2007
|
+
if sources:
|
|
2008
|
+
post_body["sources"] = sources
|
|
2009
|
+
|
|
2010
|
+
response = self.post("desktop/dependency_packages", **post_body)
|
|
2011
|
+
response.raise_for_status()
|
|
2012
|
+
|
|
2013
|
+
def update_dependency_package(self, filename, sources):
|
|
2014
|
+
"""Update dependency package metadata on server.
|
|
2015
|
+
|
|
2016
|
+
Args:
|
|
2017
|
+
filename (str): Filename of dependency package.
|
|
2018
|
+
sources (list[dict[str, Any]]): Information about
|
|
2019
|
+
sources from where it is possible to get file. Fully replaces
|
|
2020
|
+
existing sources.
|
|
2021
|
+
"""
|
|
2022
|
+
|
|
2023
|
+
response = self.patch(
|
|
2024
|
+
"desktop/dependency_packages/{}".format(filename),
|
|
2025
|
+
sources=sources
|
|
2026
|
+
)
|
|
2027
|
+
response.raise_for_status()
|
|
2028
|
+
|
|
2029
|
+
def delete_dependency_package(self, filename, platform_name=None):
|
|
2030
|
+
"""Remove dependency package for specific platform.
|
|
2031
|
+
|
|
2032
|
+
Args:
|
|
2033
|
+
filename (str): Filename of dependency package. Or name of package
|
|
2034
|
+
for server version 0.2.0 or lower.
|
|
2035
|
+
platform_name (Optional[str]): Which platform of the package
|
|
2036
|
+
should be removed. Current platform is used if not passed.
|
|
2037
|
+
Deprecated since version 0.2.1
|
|
2038
|
+
"""
|
|
2039
|
+
|
|
2040
|
+
major, minor, patch, _, _ = self.server_version_tuple
|
|
2041
|
+
if major == 0 and (minor < 2 or (minor == 2 and patch < 1)):
|
|
2042
|
+
if platform_name is None:
|
|
2043
|
+
platform_name = platform.system().lower()
|
|
2044
|
+
url = "dependencies/{}/{}".format(filename, platform_name)
|
|
2045
|
+
else:
|
|
2046
|
+
url = "desktop/dependency_packages/{}".format(filename)
|
|
2047
|
+
|
|
2048
|
+
response = self.delete(url)
|
|
2049
|
+
if response.status != 200:
|
|
2050
|
+
raise ServerError("Failed to delete dependency file")
|
|
2051
|
+
return response.data
|
|
2052
|
+
|
|
1648
2053
|
def download_dependency_package(
|
|
1649
2054
|
self,
|
|
1650
|
-
|
|
2055
|
+
src_filename,
|
|
1651
2056
|
dst_directory,
|
|
1652
|
-
|
|
2057
|
+
dst_filename,
|
|
1653
2058
|
platform_name=None,
|
|
1654
2059
|
chunk_size=None,
|
|
1655
2060
|
progress=None,
|
|
1656
2061
|
):
|
|
1657
2062
|
"""Download dependency package from server.
|
|
1658
2063
|
|
|
1659
|
-
This method requires to have authorized token available. The package
|
|
1660
|
-
only downloaded.
|
|
2064
|
+
This method requires to have authorized token available. The package
|
|
2065
|
+
is only downloaded.
|
|
1661
2066
|
|
|
1662
2067
|
Args:
|
|
1663
|
-
|
|
2068
|
+
src_filename (str): Filename of dependency pacakge.
|
|
2069
|
+
For server version 0.2.0 and lower it is name of package
|
|
2070
|
+
to download.
|
|
1664
2071
|
dst_directory (str): Where the file should be downloaded.
|
|
1665
|
-
|
|
2072
|
+
dst_filename (str): Name of destination filename.
|
|
1666
2073
|
platform_name (Optional[str]): Name of platform for which the
|
|
1667
2074
|
dependency package is targeted. Default value is
|
|
1668
|
-
current platform.
|
|
2075
|
+
current platform. Deprecated since server version 0.2.1.
|
|
1669
2076
|
chunk_size (Optional[int]): Download chunk size.
|
|
1670
2077
|
progress (Optional[TransferProgress]): Object that gives ability
|
|
1671
2078
|
to track download progress.
|
|
@@ -1673,12 +2080,18 @@ class ServerAPI(object):
|
|
|
1673
2080
|
Returns:
|
|
1674
2081
|
str: Filepath to downloaded file.
|
|
1675
2082
|
"""
|
|
1676
|
-
if platform_name is None:
|
|
1677
|
-
platform_name = platform.system().lower()
|
|
1678
2083
|
|
|
1679
|
-
|
|
2084
|
+
major, minor, patch, _, _ = self.server_version_tuple
|
|
2085
|
+
if major == 0 and (minor < 2 or (minor == 2 and patch < 1)):
|
|
2086
|
+
if platform_name is None:
|
|
2087
|
+
platform_name = platform.system().lower()
|
|
2088
|
+
url = "dependencies/{}/{}".format(src_filename, platform_name)
|
|
2089
|
+
else:
|
|
2090
|
+
url = "desktop/dependency_packages/{}".format(src_filename)
|
|
2091
|
+
|
|
2092
|
+
package_filepath = os.path.join(dst_directory, dst_filename)
|
|
1680
2093
|
self.download_file(
|
|
1681
|
-
|
|
2094
|
+
url,
|
|
1682
2095
|
package_filepath,
|
|
1683
2096
|
chunk_size=chunk_size,
|
|
1684
2097
|
progress=progress
|
|
@@ -1686,47 +2099,170 @@ class ServerAPI(object):
|
|
|
1686
2099
|
return package_filepath
|
|
1687
2100
|
|
|
1688
2101
|
def upload_dependency_package(
|
|
1689
|
-
self,
|
|
2102
|
+
self, src_filepath, dst_filename, platform_name=None, progress=None
|
|
1690
2103
|
):
|
|
1691
2104
|
"""Upload dependency package to server.
|
|
1692
2105
|
|
|
1693
2106
|
Args:
|
|
1694
|
-
|
|
1695
|
-
|
|
2107
|
+
src_filepath (str): Path to a package file.
|
|
2108
|
+
dst_filename (str): Dependency package filename or name of package
|
|
2109
|
+
for server version 0.2.0 or lower. Must be unique.
|
|
1696
2110
|
platform_name (Optional[str]): For which platform is the
|
|
1697
|
-
package targeted.
|
|
2111
|
+
package targeted. Deprecated since server version 0.2.1.
|
|
1698
2112
|
progress (Optional[TransferProgress]): Object to keep track about
|
|
1699
2113
|
upload state.
|
|
1700
2114
|
"""
|
|
1701
2115
|
|
|
1702
|
-
|
|
1703
|
-
|
|
2116
|
+
major, minor, patch, _, _ = self.server_version_tuple
|
|
2117
|
+
if major == 0 and (minor < 2 or (minor == 2 and patch < 1)):
|
|
2118
|
+
if platform_name is None:
|
|
2119
|
+
platform_name = platform.system().lower()
|
|
2120
|
+
url = "dependencies/{}/{}".format(dst_filename, platform_name)
|
|
2121
|
+
else:
|
|
2122
|
+
url = "desktop/dependency_packages/{}".format(dst_filename)
|
|
1704
2123
|
|
|
1705
|
-
self.upload_file(
|
|
1706
|
-
"dependencies/{}/{}".format(package_name, platform_name),
|
|
1707
|
-
filepath,
|
|
1708
|
-
progress=progress
|
|
1709
|
-
)
|
|
2124
|
+
self.upload_file(url, src_filepath, progress=progress)
|
|
1710
2125
|
|
|
1711
|
-
def
|
|
1712
|
-
"""
|
|
2126
|
+
def create_dependency_package_basename(self, platform_name=None):
|
|
2127
|
+
"""Create basename for dependency package file.
|
|
1713
2128
|
|
|
1714
2129
|
Args:
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
2130
|
+
platform_name (Optional[str]): Name of platform for which the
|
|
2131
|
+
bundle is targeted. Default value is current platform.
|
|
2132
|
+
|
|
2133
|
+
Returns:
|
|
2134
|
+
str: Dependency package name with timestamp and platform.
|
|
1718
2135
|
"""
|
|
1719
2136
|
|
|
1720
2137
|
if platform_name is None:
|
|
1721
2138
|
platform_name = platform.system().lower()
|
|
1722
2139
|
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
)
|
|
1726
|
-
|
|
1727
|
-
|
|
2140
|
+
now_date = datetime.datetime.now()
|
|
2141
|
+
time_stamp = now_date.strftime("%y%m%d%H%M")
|
|
2142
|
+
return "ayon_{}_{}".format(time_stamp, platform_name)
|
|
2143
|
+
|
|
2144
|
+
def get_bundles(self):
|
|
2145
|
+
"""Server bundles with basic information.
|
|
2146
|
+
|
|
2147
|
+
Example output:
|
|
2148
|
+
{
|
|
2149
|
+
"bundles": [
|
|
2150
|
+
{
|
|
2151
|
+
"name": "my_bundle",
|
|
2152
|
+
"createdAt": "2023-06-12T15:37:02.420260",
|
|
2153
|
+
"installerVersion": "1.0.0",
|
|
2154
|
+
"addons": {
|
|
2155
|
+
"core": "1.2.3"
|
|
2156
|
+
},
|
|
2157
|
+
"dependencyPackages": {
|
|
2158
|
+
"windows": "a_windows_package123.zip",
|
|
2159
|
+
"linux": "a_linux_package123.zip",
|
|
2160
|
+
"darwin": "a_mac_package123.zip"
|
|
2161
|
+
},
|
|
2162
|
+
"isProduction": False,
|
|
2163
|
+
"isStaging": False
|
|
2164
|
+
}
|
|
2165
|
+
],
|
|
2166
|
+
"productionBundle": "my_bundle",
|
|
2167
|
+
"stagingBundle": "test_bundle"
|
|
2168
|
+
}
|
|
2169
|
+
|
|
2170
|
+
Returns:
|
|
2171
|
+
dict[str, Any]: Server bundles with basic information.
|
|
2172
|
+
"""
|
|
2173
|
+
|
|
2174
|
+
response = self.get("desktop/bundles")
|
|
2175
|
+
response.raise_for_status()
|
|
1728
2176
|
return response.data
|
|
1729
2177
|
|
|
2178
|
+
def create_bundle(
|
|
2179
|
+
self,
|
|
2180
|
+
name,
|
|
2181
|
+
addon_versions,
|
|
2182
|
+
installer_version,
|
|
2183
|
+
dependency_packages=None,
|
|
2184
|
+
is_production=None,
|
|
2185
|
+
is_staging=None
|
|
2186
|
+
):
|
|
2187
|
+
"""Create bundle on server.
|
|
2188
|
+
|
|
2189
|
+
Bundle cannot be changed once is created. Only isProduction, isStaging
|
|
2190
|
+
and dependency packages can change after creation.
|
|
2191
|
+
|
|
2192
|
+
Args:
|
|
2193
|
+
name (str): Name of bundle.
|
|
2194
|
+
addon_versions (dict[str, str]): Addon versions.
|
|
2195
|
+
installer_version (Union[str, None]): Installer version.
|
|
2196
|
+
dependency_packages (Optional[dict[str, str]]): Dependency
|
|
2197
|
+
package names. Keys are platform names and values are name of
|
|
2198
|
+
packages.
|
|
2199
|
+
is_production (Optional[bool]): Bundle will be marked as
|
|
2200
|
+
production.
|
|
2201
|
+
is_staging (Optional[bool]): Bundle will be marked as staging.
|
|
2202
|
+
"""
|
|
2203
|
+
|
|
2204
|
+
body = {
|
|
2205
|
+
"name": name,
|
|
2206
|
+
"installerVersion": installer_version,
|
|
2207
|
+
"addons": addon_versions,
|
|
2208
|
+
}
|
|
2209
|
+
for key, value in (
|
|
2210
|
+
("dependencyPackages", dependency_packages),
|
|
2211
|
+
("isProduction", is_production),
|
|
2212
|
+
("isStaging", is_staging),
|
|
2213
|
+
):
|
|
2214
|
+
if value is not None:
|
|
2215
|
+
body[key] = value
|
|
2216
|
+
|
|
2217
|
+
response = self.post("desktop/bundles", **body)
|
|
2218
|
+
response.raise_for_status()
|
|
2219
|
+
|
|
2220
|
+
def update_bundle(
|
|
2221
|
+
self,
|
|
2222
|
+
bundle_name,
|
|
2223
|
+
dependency_packages=None,
|
|
2224
|
+
is_production=None,
|
|
2225
|
+
is_staging=None
|
|
2226
|
+
):
|
|
2227
|
+
"""Update bundle on server.
|
|
2228
|
+
|
|
2229
|
+
Dependency packages can be update only for single platform. Others
|
|
2230
|
+
will be left untouched. Use 'None' value to unset dependency package
|
|
2231
|
+
from bundle.
|
|
2232
|
+
|
|
2233
|
+
Args:
|
|
2234
|
+
bundle_name (str): Name of bundle.
|
|
2235
|
+
dependency_packages (Optional[dict[str, str]]): Dependency pacakge
|
|
2236
|
+
names that should be used with the bundle.
|
|
2237
|
+
is_production (Optional[bool]): Bundle will be marked as
|
|
2238
|
+
production.
|
|
2239
|
+
is_staging (Optional[bool]): Bundle will be marked as staging.
|
|
2240
|
+
"""
|
|
2241
|
+
|
|
2242
|
+
body = {
|
|
2243
|
+
key: value
|
|
2244
|
+
for key, value in (
|
|
2245
|
+
("dependencyPackages", dependency_packages),
|
|
2246
|
+
("isProduction", is_production),
|
|
2247
|
+
("isStaging", is_staging),
|
|
2248
|
+
)
|
|
2249
|
+
if value is not None
|
|
2250
|
+
}
|
|
2251
|
+
response = self.patch(
|
|
2252
|
+
"desktop/bundles/{}".format(bundle_name), **body
|
|
2253
|
+
)
|
|
2254
|
+
response.raise_for_status()
|
|
2255
|
+
|
|
2256
|
+
def delete_bundle(self, bundle_name):
|
|
2257
|
+
"""Delete bundle from server.
|
|
2258
|
+
|
|
2259
|
+
Args:
|
|
2260
|
+
bundle_name (str): Name of bundle to delete.
|
|
2261
|
+
"""
|
|
2262
|
+
|
|
2263
|
+
response = self.delete("desktop/bundles/{}".format(bundle_name))
|
|
2264
|
+
response.raise_for_status()
|
|
2265
|
+
|
|
1730
2266
|
# Anatomy presets
|
|
1731
2267
|
def get_project_anatomy_presets(self):
|
|
1732
2268
|
"""Anatomy presets available on server.
|
|
@@ -2150,7 +2686,7 @@ class ServerAPI(object):
|
|
|
2150
2686
|
project_name (str): Name of project.
|
|
2151
2687
|
|
|
2152
2688
|
Returns:
|
|
2153
|
-
Union[
|
|
2689
|
+
Union[dict[str, Any], None]: Project entity data or 'None' if
|
|
2154
2690
|
project was not found.
|
|
2155
2691
|
"""
|
|
2156
2692
|
|
|
@@ -2174,7 +2710,7 @@ class ServerAPI(object):
|
|
|
2174
2710
|
are returned if 'None' is passed.
|
|
2175
2711
|
|
|
2176
2712
|
Returns:
|
|
2177
|
-
Generator[
|
|
2713
|
+
Generator[dict[str, Any]]: Available projects.
|
|
2178
2714
|
"""
|
|
2179
2715
|
|
|
2180
2716
|
for project_name in self.get_project_names(active, library):
|
|
@@ -2235,7 +2771,7 @@ class ServerAPI(object):
|
|
|
2235
2771
|
are returned if 'None' is passed.
|
|
2236
2772
|
|
|
2237
2773
|
Returns:
|
|
2238
|
-
|
|
2774
|
+
list[str]: List of available project names.
|
|
2239
2775
|
"""
|
|
2240
2776
|
|
|
2241
2777
|
query_keys = {}
|
|
@@ -2276,7 +2812,7 @@ class ServerAPI(object):
|
|
|
2276
2812
|
not explicitly set on entity will have 'None' value.
|
|
2277
2813
|
|
|
2278
2814
|
Returns:
|
|
2279
|
-
Generator[
|
|
2815
|
+
Generator[dict[str, Any]]: Queried projects.
|
|
2280
2816
|
"""
|
|
2281
2817
|
|
|
2282
2818
|
if fields is None:
|
|
@@ -2316,7 +2852,7 @@ class ServerAPI(object):
|
|
|
2316
2852
|
not explicitly set on entity will have 'None' value.
|
|
2317
2853
|
|
|
2318
2854
|
Returns:
|
|
2319
|
-
Union[
|
|
2855
|
+
Union[dict[str, Any], None]: Project entity data or None
|
|
2320
2856
|
if project was not found.
|
|
2321
2857
|
"""
|
|
2322
2858
|
|
|
@@ -3112,7 +3648,7 @@ class ServerAPI(object):
|
|
|
3112
3648
|
not explicitly set on entity will have 'None' value.
|
|
3113
3649
|
|
|
3114
3650
|
Returns:
|
|
3115
|
-
Generator[
|
|
3651
|
+
Generator[dict[str, Any]]: Queried version entities.
|
|
3116
3652
|
"""
|
|
3117
3653
|
|
|
3118
3654
|
if not fields:
|
|
@@ -3570,7 +4106,7 @@ class ServerAPI(object):
|
|
|
3570
4106
|
not explicitly set on entity will have 'None' value.
|
|
3571
4107
|
|
|
3572
4108
|
Returns:
|
|
3573
|
-
Generator[
|
|
4109
|
+
Generator[dict[str, Any]]: Queried representation entities.
|
|
3574
4110
|
"""
|
|
3575
4111
|
|
|
3576
4112
|
if not fields:
|
|
@@ -4253,7 +4789,7 @@ class ServerAPI(object):
|
|
|
4253
4789
|
ValueError: When project name already exists.
|
|
4254
4790
|
|
|
4255
4791
|
Returns:
|
|
4256
|
-
|
|
4792
|
+
dict[str, Any]: Created project entity.
|
|
4257
4793
|
"""
|
|
4258
4794
|
|
|
4259
4795
|
if self.get_project(project_name):
|
|
@@ -4286,6 +4822,70 @@ class ServerAPI(object):
|
|
|
4286
4822
|
|
|
4287
4823
|
return self.get_project(project_name)
|
|
4288
4824
|
|
|
4825
|
+
def update_project(
|
|
4826
|
+
self,
|
|
4827
|
+
project_name,
|
|
4828
|
+
library=None,
|
|
4829
|
+
folder_types=None,
|
|
4830
|
+
task_types=None,
|
|
4831
|
+
link_types=None,
|
|
4832
|
+
statuses=None,
|
|
4833
|
+
tags=None,
|
|
4834
|
+
config=None,
|
|
4835
|
+
attrib=None,
|
|
4836
|
+
data=None,
|
|
4837
|
+
active=None,
|
|
4838
|
+
project_code=None,
|
|
4839
|
+
**changes
|
|
4840
|
+
):
|
|
4841
|
+
"""Update project entity on server.
|
|
4842
|
+
|
|
4843
|
+
Args:
|
|
4844
|
+
project_name (str): Name of project.
|
|
4845
|
+
library (Optional[bool]): Change library state.
|
|
4846
|
+
folder_types (Optional[list[dict[str, Any]]]): Folder type
|
|
4847
|
+
definitions.
|
|
4848
|
+
task_types (Optional[list[dict[str, Any]]]): Task type
|
|
4849
|
+
definitions.
|
|
4850
|
+
link_types (Optional[list[dict[str, Any]]]): Link type
|
|
4851
|
+
definitions.
|
|
4852
|
+
statuses (Optional[list[dict[str, Any]]]): Status definitions.
|
|
4853
|
+
tags (Optional[list[dict[str, Any]]]): List of tags available to
|
|
4854
|
+
set on entities.
|
|
4855
|
+
config (Optional[dict[dict[str, Any]]]): Project anatomy config
|
|
4856
|
+
with templates and roots.
|
|
4857
|
+
attrib (Optional[dict[str, Any]]): Project attributes to change.
|
|
4858
|
+
data (Optional[dict[str, Any]]): Custom data of a project. This
|
|
4859
|
+
value will 100% override project data.
|
|
4860
|
+
active (Optional[bool]): Change active state of a project.
|
|
4861
|
+
project_code (Optional[str]): Change project code. Not recommended
|
|
4862
|
+
during production.
|
|
4863
|
+
**changes: Other changed keys based on Rest API documentation.
|
|
4864
|
+
"""
|
|
4865
|
+
|
|
4866
|
+
changes.update({
|
|
4867
|
+
key: value
|
|
4868
|
+
for key, value in (
|
|
4869
|
+
("library", library),
|
|
4870
|
+
("folderTypes", folder_types),
|
|
4871
|
+
("taskTypes", task_types),
|
|
4872
|
+
("linkTypes", link_types),
|
|
4873
|
+
("statuses", statuses),
|
|
4874
|
+
("tags", tags),
|
|
4875
|
+
("config", config),
|
|
4876
|
+
("attrib", attrib),
|
|
4877
|
+
("data", data),
|
|
4878
|
+
("active", active),
|
|
4879
|
+
("code", project_code),
|
|
4880
|
+
)
|
|
4881
|
+
if value is not None
|
|
4882
|
+
})
|
|
4883
|
+
response = self.patch(
|
|
4884
|
+
"projects/{}".format(project_name),
|
|
4885
|
+
**changes
|
|
4886
|
+
)
|
|
4887
|
+
response.raise_for_status()
|
|
4888
|
+
|
|
4289
4889
|
def delete_project(self, project_name):
|
|
4290
4890
|
"""Delete project from server.
|
|
4291
4891
|
|
ayon_api/version.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""Package declaring Python API for Ayon server."""
|
|
2
|
-
__version__ = "0.2.
|
|
2
|
+
__version__ = "0.2.2"
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
ayon_api/__init__.py,sha256=
|
|
2
|
-
ayon_api/_api.py,sha256=
|
|
1
|
+
ayon_api/__init__.py,sha256=RJqmUxlG08JfMyO7AwpIoZeRp2TURt2Qiy4eHd3s2FQ,7328
|
|
2
|
+
ayon_api/_api.py,sha256=XxAKKnsyly_4gt9SC1-ZZUIgtzdRNIZowNEHIjQdgBY,30191
|
|
3
3
|
ayon_api/constants.py,sha256=BRhTb_yX_FaQIzeIIdUGh-fKXhiZJbFA0M_zvi9MKWQ,1755
|
|
4
|
-
ayon_api/entity_hub.py,sha256=
|
|
4
|
+
ayon_api/entity_hub.py,sha256=UH1-aWqftdmZAQDGqsjhpvNwAP6_bTFUk-nC-RIraO4,59757
|
|
5
5
|
ayon_api/events.py,sha256=aJJbAZJ5t0t6x4VQMRfdmOGhIbiRFB0OTUGiKnasFGw,1415
|
|
6
6
|
ayon_api/exceptions.py,sha256=FHGlt6TyKNc0OC8H0zxoNIS4KljPExM2mgDpCh9cYiI,2691
|
|
7
7
|
ayon_api/graphql.py,sha256=4u2pSS85uDsoap0tOkAmi6KCjeKHKClH3Cd7AfY8vGM,25639
|
|
8
8
|
ayon_api/graphql_queries.py,sha256=1f_fAoV1d5rvrlbJ6IPbrcrU56jmrJ-1-ieCW-B5ac8,15583
|
|
9
9
|
ayon_api/operations.py,sha256=55NDgRPDhJ5faU0xUnqC2dktwx5ebJSfHkLmncismKg,19430
|
|
10
|
-
ayon_api/server_api.py,sha256=
|
|
10
|
+
ayon_api/server_api.py,sha256=9Fvp8-XWg81JiqQjhmyj6ECD3b0YRbIZH9sJHTm6N2s,182164
|
|
11
11
|
ayon_api/thumbnails.py,sha256=ofm6pBzGCMShryRUP76-qT9xJPtqRZn1kpoX7kVk_WA,6856
|
|
12
12
|
ayon_api/utils.py,sha256=YhQkEHCho1M0D5oQHz0gl3dad-jw5nWGnvOBtvCxVHM,11714
|
|
13
|
-
ayon_api/version.py,sha256=
|
|
14
|
-
ayon_python_api-0.2.
|
|
15
|
-
ayon_python_api-0.2.
|
|
16
|
-
ayon_python_api-0.2.
|
|
17
|
-
ayon_python_api-0.2.
|
|
18
|
-
ayon_python_api-0.2.
|
|
13
|
+
ayon_api/version.py,sha256=fHHwWLQEHvfwcM-NaNKV7T0r1P4zj0OAyiJ7LD0i298,74
|
|
14
|
+
ayon_python_api-0.2.2.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
15
|
+
ayon_python_api-0.2.2.dist-info/METADATA,sha256=kdPxbr8gk-W3u1jHeahG0xXSlPXYu5EOOre_RcX_hSM,3263
|
|
16
|
+
ayon_python_api-0.2.2.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
|
|
17
|
+
ayon_python_api-0.2.2.dist-info/top_level.txt,sha256=PKrQbX5Cz53_UmSTR_nIySnBkGyHcBTS88SCw9tuVlc,9
|
|
18
|
+
ayon_python_api-0.2.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|