Ayon-Python-Api 0.3.1__tar.gz → 0.3.3__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-0.3.1 → ayon-python-api-0.3.3}/PKG-INFO +1 -1
- {ayon-python-api-0.3.1 → ayon-python-api-0.3.3}/ayon_api/__init__.py +9 -0
- {ayon-python-api-0.3.1 → ayon-python-api-0.3.3}/ayon_api/_api.py +30 -34
- {ayon-python-api-0.3.1 → ayon-python-api-0.3.3}/ayon_api/server_api.py +196 -35
- {ayon-python-api-0.3.1 → ayon-python-api-0.3.3}/ayon_api/utils.py +151 -8
- {ayon-python-api-0.3.1 → ayon-python-api-0.3.3}/ayon_api/version.py +1 -1
- {ayon-python-api-0.3.1 → ayon-python-api-0.3.3}/ayon_python_api.egg-info/PKG-INFO +1 -1
- {ayon-python-api-0.3.1 → ayon-python-api-0.3.3}/pyproject.toml +1 -1
- {ayon-python-api-0.3.1 → ayon-python-api-0.3.3}/LICENSE +0 -0
- {ayon-python-api-0.3.1 → ayon-python-api-0.3.3}/README.md +0 -0
- {ayon-python-api-0.3.1 → ayon-python-api-0.3.3}/ayon_api/constants.py +0 -0
- {ayon-python-api-0.3.1 → ayon-python-api-0.3.3}/ayon_api/entity_hub.py +0 -0
- {ayon-python-api-0.3.1 → ayon-python-api-0.3.3}/ayon_api/events.py +0 -0
- {ayon-python-api-0.3.1 → ayon-python-api-0.3.3}/ayon_api/exceptions.py +0 -0
- {ayon-python-api-0.3.1 → ayon-python-api-0.3.3}/ayon_api/graphql.py +0 -0
- {ayon-python-api-0.3.1 → ayon-python-api-0.3.3}/ayon_api/graphql_queries.py +0 -0
- {ayon-python-api-0.3.1 → ayon-python-api-0.3.3}/ayon_api/operations.py +0 -0
- {ayon-python-api-0.3.1 → ayon-python-api-0.3.3}/ayon_api/thumbnails.py +0 -0
- {ayon-python-api-0.3.1 → ayon-python-api-0.3.3}/ayon_python_api.egg-info/SOURCES.txt +0 -0
- {ayon-python-api-0.3.1 → ayon-python-api-0.3.3}/ayon_python_api.egg-info/dependency_links.txt +0 -0
- {ayon-python-api-0.3.1 → ayon-python-api-0.3.3}/ayon_python_api.egg-info/requires.txt +0 -0
- {ayon-python-api-0.3.1 → ayon-python-api-0.3.3}/ayon_python_api.egg-info/top_level.txt +0 -0
- {ayon-python-api-0.3.1 → ayon-python-api-0.3.3}/setup.cfg +0 -0
- {ayon-python-api-0.3.1 → ayon-python-api-0.3.3}/setup.py +0 -0
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
from .version import __version__
|
|
1
2
|
from .utils import (
|
|
2
3
|
TransferProgress,
|
|
3
4
|
slugify_string,
|
|
5
|
+
create_dependency_package_basename,
|
|
4
6
|
)
|
|
5
7
|
from .server_api import (
|
|
6
8
|
ServerAPI,
|
|
@@ -76,6 +78,8 @@ from ._api import (
|
|
|
76
78
|
download_dependency_package,
|
|
77
79
|
upload_dependency_package,
|
|
78
80
|
|
|
81
|
+
upload_addon_zip,
|
|
82
|
+
|
|
79
83
|
get_bundles,
|
|
80
84
|
create_bundle,
|
|
81
85
|
update_bundle,
|
|
@@ -183,8 +187,11 @@ from ._api import (
|
|
|
183
187
|
|
|
184
188
|
|
|
185
189
|
__all__ = (
|
|
190
|
+
"__version__",
|
|
191
|
+
|
|
186
192
|
"TransferProgress",
|
|
187
193
|
"slugify_string",
|
|
194
|
+
"create_dependency_package_basename",
|
|
188
195
|
|
|
189
196
|
"ServerAPI",
|
|
190
197
|
|
|
@@ -257,6 +264,8 @@ __all__ = (
|
|
|
257
264
|
"download_dependency_package",
|
|
258
265
|
"upload_dependency_package",
|
|
259
266
|
|
|
267
|
+
"upload_addon_zip",
|
|
268
|
+
|
|
260
269
|
"get_bundles",
|
|
261
270
|
"create_bundle",
|
|
262
271
|
"update_bundle",
|
|
@@ -25,12 +25,29 @@ class GlobalServerAPI(ServerAPI):
|
|
|
25
25
|
but that can be filled afterwards with calling 'login' method.
|
|
26
26
|
"""
|
|
27
27
|
|
|
28
|
-
def __init__(
|
|
28
|
+
def __init__(
|
|
29
|
+
self,
|
|
30
|
+
site_id=None,
|
|
31
|
+
client_version=None,
|
|
32
|
+
default_settings_variant=None,
|
|
33
|
+
ssl_verify=None,
|
|
34
|
+
cert=None,
|
|
35
|
+
):
|
|
29
36
|
url = self.get_url()
|
|
30
37
|
token = self.get_token()
|
|
31
38
|
|
|
32
|
-
super(GlobalServerAPI, self).__init__(
|
|
33
|
-
|
|
39
|
+
super(GlobalServerAPI, self).__init__(
|
|
40
|
+
url,
|
|
41
|
+
token,
|
|
42
|
+
site_id,
|
|
43
|
+
client_version,
|
|
44
|
+
default_settings_variant,
|
|
45
|
+
ssl_verify,
|
|
46
|
+
cert,
|
|
47
|
+
# We want to make sure that server and api key validation
|
|
48
|
+
# happens all the time in 'GlobalServerAPI'.
|
|
49
|
+
create_session=False,
|
|
50
|
+
)
|
|
34
51
|
self.validate_server_availability()
|
|
35
52
|
self.create_session()
|
|
36
53
|
|
|
@@ -129,17 +146,6 @@ class ServiceContext:
|
|
|
129
146
|
addon_version = None
|
|
130
147
|
service_name = None
|
|
131
148
|
|
|
132
|
-
@staticmethod
|
|
133
|
-
def get_value_from_envs(env_keys, value=None):
|
|
134
|
-
if value:
|
|
135
|
-
return value
|
|
136
|
-
|
|
137
|
-
for env_key in env_keys:
|
|
138
|
-
value = os.environ.get(env_key)
|
|
139
|
-
if value:
|
|
140
|
-
break
|
|
141
|
-
return value
|
|
142
|
-
|
|
143
149
|
@classmethod
|
|
144
150
|
def init_service(
|
|
145
151
|
cls,
|
|
@@ -150,14 +156,8 @@ class ServiceContext:
|
|
|
150
156
|
service_name=None,
|
|
151
157
|
connect=True
|
|
152
158
|
):
|
|
153
|
-
token =
|
|
154
|
-
|
|
155
|
-
token
|
|
156
|
-
)
|
|
157
|
-
server_url = cls.get_value_from_envs(
|
|
158
|
-
("AY_SERVER_URL", "AYON_SERVER_URL"),
|
|
159
|
-
server_url
|
|
160
|
-
)
|
|
159
|
+
token = token or os.environ.get("AYON_API_KEY")
|
|
160
|
+
server_url = server_url or os.environ.get("AYON_SERVER_URL")
|
|
161
161
|
if not server_url:
|
|
162
162
|
raise FailedServiceInit("URL to server is not set")
|
|
163
163
|
|
|
@@ -166,18 +166,9 @@ class ServiceContext:
|
|
|
166
166
|
"Token to server {} is not set".format(server_url)
|
|
167
167
|
)
|
|
168
168
|
|
|
169
|
-
addon_name =
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
)
|
|
173
|
-
addon_version = cls.get_value_from_envs(
|
|
174
|
-
("AY_ADDON_VERSION", "AYON_ADDON_VERSION"),
|
|
175
|
-
addon_version
|
|
176
|
-
)
|
|
177
|
-
service_name = cls.get_value_from_envs(
|
|
178
|
-
("AY_SERVICE_NAME", "AYON_SERVICE_NAME"),
|
|
179
|
-
service_name
|
|
180
|
-
)
|
|
169
|
+
addon_name = addon_name or os.environ.get("AYON_ADDON_NAME")
|
|
170
|
+
addon_version = addon_version or os.environ.get("AYON_ADDON_VERSION")
|
|
171
|
+
service_name = service_name or os.environ.get("AYON_SERVICE_NAME")
|
|
181
172
|
|
|
182
173
|
cls.token = token
|
|
183
174
|
cls.server_url = server_url
|
|
@@ -618,6 +609,11 @@ def delete_dependency_package(*args, **kwargs):
|
|
|
618
609
|
return con.delete_dependency_package(*args, **kwargs)
|
|
619
610
|
|
|
620
611
|
|
|
612
|
+
def upload_addon_zip(*args, **kwargs):
|
|
613
|
+
con = get_server_api_connection()
|
|
614
|
+
return con.upload_addon_zip(*args, **kwargs)
|
|
615
|
+
|
|
616
|
+
|
|
621
617
|
def get_project_anatomy_presets(*args, **kwargs):
|
|
622
618
|
con = get_server_api_connection()
|
|
623
619
|
return con.get_project_anatomy_presets(*args, **kwargs)
|
|
@@ -4,7 +4,6 @@ import io
|
|
|
4
4
|
import json
|
|
5
5
|
import logging
|
|
6
6
|
import collections
|
|
7
|
-
import datetime
|
|
8
7
|
import platform
|
|
9
8
|
import copy
|
|
10
9
|
import uuid
|
|
@@ -61,6 +60,7 @@ from .utils import (
|
|
|
61
60
|
entity_data_json_default,
|
|
62
61
|
failed_json_default,
|
|
63
62
|
TransferProgress,
|
|
63
|
+
create_dependency_package_basename,
|
|
64
64
|
)
|
|
65
65
|
|
|
66
66
|
PatternType = type(re.compile(""))
|
|
@@ -114,6 +114,10 @@ class RestApiResponse(object):
|
|
|
114
114
|
self.status = status_code
|
|
115
115
|
self._data = data
|
|
116
116
|
|
|
117
|
+
@property
|
|
118
|
+
def text(self):
|
|
119
|
+
return self._response.text
|
|
120
|
+
|
|
117
121
|
@property
|
|
118
122
|
def orig_response(self):
|
|
119
123
|
return self._response
|
|
@@ -150,11 +154,13 @@ class RestApiResponse(object):
|
|
|
150
154
|
def status_code(self):
|
|
151
155
|
return self.status
|
|
152
156
|
|
|
153
|
-
def raise_for_status(self):
|
|
157
|
+
def raise_for_status(self, message=None):
|
|
154
158
|
try:
|
|
155
159
|
self._response.raise_for_status()
|
|
156
160
|
except requests.exceptions.HTTPError as exc:
|
|
157
|
-
|
|
161
|
+
if message is None:
|
|
162
|
+
message = str(exc)
|
|
163
|
+
raise HTTPRequestError(message, exc.response)
|
|
158
164
|
|
|
159
165
|
def __enter__(self, *args, **kwargs):
|
|
160
166
|
return self._response.__enter__(*args, **kwargs)
|
|
@@ -318,6 +324,8 @@ class ServerAPI(object):
|
|
|
318
324
|
available then 'True' is used.
|
|
319
325
|
cert (Optional[str]): Path to certificate file. Looks for env
|
|
320
326
|
variable value 'AYON_CERT_FILE' by default.
|
|
327
|
+
create_session (Optional[bool]): Create session for connection if
|
|
328
|
+
token is available. Default is True.
|
|
321
329
|
"""
|
|
322
330
|
|
|
323
331
|
def __init__(
|
|
@@ -329,6 +337,7 @@ class ServerAPI(object):
|
|
|
329
337
|
default_settings_variant=None,
|
|
330
338
|
ssl_verify=None,
|
|
331
339
|
cert=None,
|
|
340
|
+
create_session=True,
|
|
332
341
|
):
|
|
333
342
|
if not base_url:
|
|
334
343
|
raise ValueError("Invalid server URL {}".format(str(base_url)))
|
|
@@ -360,6 +369,7 @@ class ServerAPI(object):
|
|
|
360
369
|
|
|
361
370
|
self._access_token_is_service = None
|
|
362
371
|
self._token_is_valid = None
|
|
372
|
+
self._token_validation_started = False
|
|
363
373
|
self._server_available = None
|
|
364
374
|
self._server_version = None
|
|
365
375
|
self._server_version_tuple = None
|
|
@@ -382,6 +392,11 @@ class ServerAPI(object):
|
|
|
382
392
|
self._as_user_stack = _AsUserStack()
|
|
383
393
|
self._thumbnail_cache = ThumbnailCache(True)
|
|
384
394
|
|
|
395
|
+
# Create session
|
|
396
|
+
if self._access_token and create_session:
|
|
397
|
+
self.validate_server_availability()
|
|
398
|
+
self.create_session()
|
|
399
|
+
|
|
385
400
|
@property
|
|
386
401
|
def log(self):
|
|
387
402
|
if self._log is None:
|
|
@@ -645,6 +660,7 @@ class ServerAPI(object):
|
|
|
645
660
|
|
|
646
661
|
def validate_token(self):
|
|
647
662
|
try:
|
|
663
|
+
self._token_validation_started = True
|
|
648
664
|
# TODO add other possible validations
|
|
649
665
|
# - existence of 'user' key in info
|
|
650
666
|
# - validate that 'site_id' is in 'sites' in info
|
|
@@ -654,6 +670,9 @@ class ServerAPI(object):
|
|
|
654
670
|
|
|
655
671
|
except UnauthorizedError:
|
|
656
672
|
self._token_is_valid = False
|
|
673
|
+
|
|
674
|
+
finally:
|
|
675
|
+
self._token_validation_started = False
|
|
657
676
|
return self._token_is_valid
|
|
658
677
|
|
|
659
678
|
def set_token(self, token):
|
|
@@ -666,8 +685,25 @@ class ServerAPI(object):
|
|
|
666
685
|
self._token_is_valid = None
|
|
667
686
|
self.close_session()
|
|
668
687
|
|
|
669
|
-
def create_session(self):
|
|
688
|
+
def create_session(self, ignore_existing=True, force=False):
|
|
689
|
+
"""Create a connection session.
|
|
690
|
+
|
|
691
|
+
Session helps to keep connection with server without
|
|
692
|
+
need to reconnect on each call.
|
|
693
|
+
|
|
694
|
+
Args:
|
|
695
|
+
ignore_existing (bool): If session already exists,
|
|
696
|
+
ignore creation.
|
|
697
|
+
force (bool): If session already exists, close it and
|
|
698
|
+
create new.
|
|
699
|
+
"""
|
|
700
|
+
|
|
701
|
+
if force and self._session is not None:
|
|
702
|
+
self.close_session()
|
|
703
|
+
|
|
670
704
|
if self._session is not None:
|
|
705
|
+
if ignore_existing:
|
|
706
|
+
return
|
|
671
707
|
raise ValueError("Session is already created.")
|
|
672
708
|
|
|
673
709
|
self._as_user_stack.clear()
|
|
@@ -834,7 +870,19 @@ class ServerAPI(object):
|
|
|
834
870
|
self._access_token)
|
|
835
871
|
return headers
|
|
836
872
|
|
|
837
|
-
def login(self, username, password):
|
|
873
|
+
def login(self, username, password, create_session=True):
|
|
874
|
+
"""Login to server.
|
|
875
|
+
|
|
876
|
+
Args:
|
|
877
|
+
username (str): Username.
|
|
878
|
+
password (str): Password.
|
|
879
|
+
create_session (Optional[bool]): Create session after login.
|
|
880
|
+
Default: True.
|
|
881
|
+
|
|
882
|
+
Raises:
|
|
883
|
+
AuthenticationError: Login failed.
|
|
884
|
+
"""
|
|
885
|
+
|
|
838
886
|
if self.has_valid_token:
|
|
839
887
|
try:
|
|
840
888
|
user_info = self.get_user()
|
|
@@ -844,7 +892,8 @@ class ServerAPI(object):
|
|
|
844
892
|
current_username = user_info.get("name")
|
|
845
893
|
if current_username == username:
|
|
846
894
|
self.close_session()
|
|
847
|
-
|
|
895
|
+
if create_session:
|
|
896
|
+
self.create_session()
|
|
848
897
|
return
|
|
849
898
|
|
|
850
899
|
self.reset_token()
|
|
@@ -868,7 +917,9 @@ class ServerAPI(object):
|
|
|
868
917
|
|
|
869
918
|
if not self.has_valid_token:
|
|
870
919
|
raise AuthenticationError("Invalid credentials")
|
|
871
|
-
|
|
920
|
+
|
|
921
|
+
if create_session:
|
|
922
|
+
self.create_session()
|
|
872
923
|
|
|
873
924
|
def logout(self, soft=False):
|
|
874
925
|
if self._access_token:
|
|
@@ -881,6 +932,15 @@ class ServerAPI(object):
|
|
|
881
932
|
|
|
882
933
|
def _do_rest_request(self, function, url, **kwargs):
|
|
883
934
|
if self._session is None:
|
|
935
|
+
# Validate token if was not yet validated
|
|
936
|
+
# - ignore validation if we're in middle of
|
|
937
|
+
# validation
|
|
938
|
+
if (
|
|
939
|
+
self._token_is_valid is None
|
|
940
|
+
and not self._token_validation_started
|
|
941
|
+
):
|
|
942
|
+
self.validate_token()
|
|
943
|
+
|
|
884
944
|
if "headers" not in kwargs:
|
|
885
945
|
kwargs["headers"] = self.get_headers()
|
|
886
946
|
|
|
@@ -1303,13 +1363,15 @@ class ServerAPI(object):
|
|
|
1303
1363
|
progress.set_transfer_done()
|
|
1304
1364
|
return progress
|
|
1305
1365
|
|
|
1306
|
-
def _upload_file(self, url, filepath, progress):
|
|
1366
|
+
def _upload_file(self, url, filepath, progress, request_type=None):
|
|
1367
|
+
if request_type is None:
|
|
1368
|
+
request_type = RequestTypes.put
|
|
1307
1369
|
kwargs = {}
|
|
1308
1370
|
if self._session is None:
|
|
1309
1371
|
kwargs["headers"] = self.get_headers()
|
|
1310
|
-
post_func = self._base_functions_mapping[
|
|
1372
|
+
post_func = self._base_functions_mapping[request_type]
|
|
1311
1373
|
else:
|
|
1312
|
-
post_func = self._session_functions_mapping[
|
|
1374
|
+
post_func = self._session_functions_mapping[request_type]
|
|
1313
1375
|
|
|
1314
1376
|
with open(filepath, "rb") as stream:
|
|
1315
1377
|
stream.seek(0, io.SEEK_END)
|
|
@@ -1319,8 +1381,11 @@ class ServerAPI(object):
|
|
|
1319
1381
|
response = post_func(url, data=stream, **kwargs)
|
|
1320
1382
|
response.raise_for_status()
|
|
1321
1383
|
progress.set_transferred_size(size)
|
|
1384
|
+
return response
|
|
1322
1385
|
|
|
1323
|
-
def upload_file(
|
|
1386
|
+
def upload_file(
|
|
1387
|
+
self, endpoint, filepath, progress=None, request_type=None
|
|
1388
|
+
):
|
|
1324
1389
|
"""Upload file to server.
|
|
1325
1390
|
|
|
1326
1391
|
Todos:
|
|
@@ -1331,6 +1396,11 @@ class ServerAPI(object):
|
|
|
1331
1396
|
filepath (str): Source filepath.
|
|
1332
1397
|
progress (Optional[TransferProgress]): Object that gives ability
|
|
1333
1398
|
to track upload progress.
|
|
1399
|
+
request_type (Optional[RequestType]): Type of request that will
|
|
1400
|
+
be used to upload file.
|
|
1401
|
+
|
|
1402
|
+
Returns:
|
|
1403
|
+
requests.Response: Response object.
|
|
1334
1404
|
"""
|
|
1335
1405
|
|
|
1336
1406
|
if endpoint.startswith(self._base_url):
|
|
@@ -1349,7 +1419,7 @@ class ServerAPI(object):
|
|
|
1349
1419
|
progress.set_started()
|
|
1350
1420
|
|
|
1351
1421
|
try:
|
|
1352
|
-
self._upload_file(url, filepath, progress)
|
|
1422
|
+
return self._upload_file(url, filepath, progress, request_type)
|
|
1353
1423
|
|
|
1354
1424
|
except Exception as exc:
|
|
1355
1425
|
progress.set_failed(str(exc))
|
|
@@ -1486,13 +1556,11 @@ class ServerAPI(object):
|
|
|
1486
1556
|
"""
|
|
1487
1557
|
|
|
1488
1558
|
response = self.delete("attributes/{}".format(attribute_name))
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
"Attribute \"{}\" was not created/updated. {}".format(
|
|
1493
|
-
attribute_name, response.detail
|
|
1494
|
-
)
|
|
1559
|
+
response.raise_for_status(
|
|
1560
|
+
"Attribute \"{}\" was not created/updated. {}".format(
|
|
1561
|
+
attribute_name, response.detail
|
|
1495
1562
|
)
|
|
1563
|
+
)
|
|
1496
1564
|
|
|
1497
1565
|
self.reset_attributes_schema()
|
|
1498
1566
|
|
|
@@ -1629,7 +1697,7 @@ class ServerAPI(object):
|
|
|
1629
1697
|
Args:
|
|
1630
1698
|
addon_name (str): Name of addon.
|
|
1631
1699
|
addon_version (str): Version of addon.
|
|
1632
|
-
subpaths (
|
|
1700
|
+
*subpaths (str): Any amount of subpaths that are added to
|
|
1633
1701
|
addon url.
|
|
1634
1702
|
|
|
1635
1703
|
Returns:
|
|
@@ -1732,8 +1800,9 @@ class ServerAPI(object):
|
|
|
1732
1800
|
python_version,
|
|
1733
1801
|
platform_name,
|
|
1734
1802
|
python_modules,
|
|
1803
|
+
runtime_python_modules,
|
|
1735
1804
|
checksum,
|
|
1736
|
-
|
|
1805
|
+
checksum_algorithm,
|
|
1737
1806
|
file_size,
|
|
1738
1807
|
sources=None,
|
|
1739
1808
|
):
|
|
@@ -1742,6 +1811,10 @@ class ServerAPI(object):
|
|
|
1742
1811
|
This step will create only metadata. Make sure to upload installer
|
|
1743
1812
|
to the server using 'upload_installer' method.
|
|
1744
1813
|
|
|
1814
|
+
Runtime python modules are modules that are required to run AYON
|
|
1815
|
+
desktop application, but are not added to PYTHONPATH for any
|
|
1816
|
+
subprocess.
|
|
1817
|
+
|
|
1745
1818
|
Args:
|
|
1746
1819
|
filename (str): Installer filename.
|
|
1747
1820
|
version (str): Version of installer.
|
|
@@ -1749,8 +1822,10 @@ class ServerAPI(object):
|
|
|
1749
1822
|
platform_name (str): Name of platform.
|
|
1750
1823
|
python_modules (dict[str, str]): Python modules that are available
|
|
1751
1824
|
in installer.
|
|
1825
|
+
runtime_python_modules (dict[str, str]): Runtime python modules
|
|
1826
|
+
that are available in installer.
|
|
1752
1827
|
checksum (str): Installer file checksum.
|
|
1753
|
-
|
|
1828
|
+
checksum_algorithm (str): Type of checksum used to create checksum.
|
|
1754
1829
|
file_size (int): File size.
|
|
1755
1830
|
sources (Optional[list[dict[str, Any]]]): List of sources that
|
|
1756
1831
|
can be used to download file.
|
|
@@ -1762,8 +1837,9 @@ class ServerAPI(object):
|
|
|
1762
1837
|
"pythonVersion": python_version,
|
|
1763
1838
|
"platform": platform_name,
|
|
1764
1839
|
"pythonModules": python_modules,
|
|
1840
|
+
"runtimePythonModules": runtime_python_modules,
|
|
1765
1841
|
"checksum": checksum,
|
|
1766
|
-
"
|
|
1842
|
+
"checksumAlgorithm": checksum_algorithm,
|
|
1767
1843
|
"size": file_size,
|
|
1768
1844
|
}
|
|
1769
1845
|
if sources:
|
|
@@ -1781,7 +1857,7 @@ class ServerAPI(object):
|
|
|
1781
1857
|
can be used to download file. Fully replaces existing sources.
|
|
1782
1858
|
"""
|
|
1783
1859
|
|
|
1784
|
-
response = self.
|
|
1860
|
+
response = self.patch(
|
|
1785
1861
|
"desktop/installers/{}".format(filename),
|
|
1786
1862
|
sources=sources
|
|
1787
1863
|
)
|
|
@@ -1794,7 +1870,7 @@ class ServerAPI(object):
|
|
|
1794
1870
|
filename (str): Installer filename.
|
|
1795
1871
|
"""
|
|
1796
1872
|
|
|
1797
|
-
response = self.delete("
|
|
1873
|
+
response = self.delete("desktop/installers/{}".format(filename))
|
|
1798
1874
|
response.raise_for_status()
|
|
1799
1875
|
|
|
1800
1876
|
def download_installer(
|
|
@@ -1829,9 +1905,12 @@ class ServerAPI(object):
|
|
|
1829
1905
|
dst_filename (str): Destination filename.
|
|
1830
1906
|
progress (Optional[TransferProgress]): Object that gives ability
|
|
1831
1907
|
to track download progress.
|
|
1908
|
+
|
|
1909
|
+
Returns:
|
|
1910
|
+
requests.Response: Response object.
|
|
1832
1911
|
"""
|
|
1833
1912
|
|
|
1834
|
-
self.upload_file(
|
|
1913
|
+
return self.upload_file(
|
|
1835
1914
|
"desktop/installers/{}".format(dst_filename),
|
|
1836
1915
|
src_filepath,
|
|
1837
1916
|
progress=progress
|
|
@@ -1929,8 +2008,7 @@ class ServerAPI(object):
|
|
|
1929
2008
|
checksum=checksum,
|
|
1930
2009
|
**kwargs
|
|
1931
2010
|
)
|
|
1932
|
-
|
|
1933
|
-
raise ServerError("Failed to create/update dependency")
|
|
2011
|
+
response.raise_for_status("Failed to create/update dependency")
|
|
1934
2012
|
return response.data
|
|
1935
2013
|
|
|
1936
2014
|
def get_dependency_packages(self):
|
|
@@ -2065,8 +2143,7 @@ class ServerAPI(object):
|
|
|
2065
2143
|
|
|
2066
2144
|
route = self._get_dependency_package_route(filename, platform_name)
|
|
2067
2145
|
response = self.delete(route)
|
|
2068
|
-
|
|
2069
|
-
raise ServerError("Failed to delete dependency file")
|
|
2146
|
+
response.raise_for_status("Failed to delete dependency file")
|
|
2070
2147
|
return response.data
|
|
2071
2148
|
|
|
2072
2149
|
def download_dependency_package(
|
|
@@ -2131,6 +2208,10 @@ class ServerAPI(object):
|
|
|
2131
2208
|
def create_dependency_package_basename(self, platform_name=None):
|
|
2132
2209
|
"""Create basename for dependency package file.
|
|
2133
2210
|
|
|
2211
|
+
Deprecated:
|
|
2212
|
+
Use 'create_dependency_package_basename' from `ayon_api` or
|
|
2213
|
+
`ayon_api.utils` instead.
|
|
2214
|
+
|
|
2134
2215
|
Args:
|
|
2135
2216
|
platform_name (Optional[str]): Name of platform for which the
|
|
2136
2217
|
bundle is targeted. Default value is current platform.
|
|
@@ -2139,12 +2220,34 @@ class ServerAPI(object):
|
|
|
2139
2220
|
str: Dependency package name with timestamp and platform.
|
|
2140
2221
|
"""
|
|
2141
2222
|
|
|
2142
|
-
|
|
2143
|
-
|
|
2223
|
+
return create_dependency_package_basename(platform_name)
|
|
2224
|
+
|
|
2225
|
+
def upload_addon_zip(self, src_filepath, progress=None):
|
|
2226
|
+
"""Upload addon zip file to server.
|
|
2227
|
+
|
|
2228
|
+
File is validated on server. If it is valid, it is installed. It will
|
|
2229
|
+
create an event job which can be tracked (tracking part is not
|
|
2230
|
+
implemented yet).
|
|
2144
2231
|
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2232
|
+
Example output:
|
|
2233
|
+
{'eventId': 'a1bfbdee27c611eea7580242ac120003'}
|
|
2234
|
+
|
|
2235
|
+
Args:
|
|
2236
|
+
src_filepath (str): Path to a zip file.
|
|
2237
|
+
progress (Optional[TransferProgress]): Object to keep track about
|
|
2238
|
+
upload state.
|
|
2239
|
+
|
|
2240
|
+
Returns:
|
|
2241
|
+
dict[str, Any]: Response data from server.
|
|
2242
|
+
"""
|
|
2243
|
+
|
|
2244
|
+
response = self.upload_file(
|
|
2245
|
+
"addons/install",
|
|
2246
|
+
src_filepath,
|
|
2247
|
+
progress=progress,
|
|
2248
|
+
request_type=RequestTypes.post,
|
|
2249
|
+
)
|
|
2250
|
+
return response.json()
|
|
2148
2251
|
|
|
2149
2252
|
def _get_bundles_route(self):
|
|
2150
2253
|
major, minor, patch, _, _ = self.server_version_tuple
|
|
@@ -3035,6 +3138,65 @@ class ServerAPI(object):
|
|
|
3035
3138
|
fill_own_attribs(project)
|
|
3036
3139
|
return project
|
|
3037
3140
|
|
|
3141
|
+
def get_folders_hierarchy(
|
|
3142
|
+
self,
|
|
3143
|
+
project_name,
|
|
3144
|
+
search_string=None,
|
|
3145
|
+
folder_types=None
|
|
3146
|
+
):
|
|
3147
|
+
"""Get project hierarchy.
|
|
3148
|
+
|
|
3149
|
+
All folders in project in hierarchy data structure.
|
|
3150
|
+
|
|
3151
|
+
Example output:
|
|
3152
|
+
{
|
|
3153
|
+
"hierarchy": [
|
|
3154
|
+
{
|
|
3155
|
+
"id": "...",
|
|
3156
|
+
"name": "...",
|
|
3157
|
+
"label": "...",
|
|
3158
|
+
"status": "...",
|
|
3159
|
+
"folderType": "...",
|
|
3160
|
+
"hasTasks": False,
|
|
3161
|
+
"taskNames": [],
|
|
3162
|
+
"parents": [],
|
|
3163
|
+
"parentId": None,
|
|
3164
|
+
"children": [...children folders...]
|
|
3165
|
+
},
|
|
3166
|
+
...
|
|
3167
|
+
]
|
|
3168
|
+
}
|
|
3169
|
+
|
|
3170
|
+
Args:
|
|
3171
|
+
project_name (str): Project where to look for folders.
|
|
3172
|
+
search_string (Optional[str]): Search string to filter folders.
|
|
3173
|
+
folder_types (Optional[Iterable[str]]): Folder types to filter.
|
|
3174
|
+
|
|
3175
|
+
Returns:
|
|
3176
|
+
dict[str, Any]: Response data from server.
|
|
3177
|
+
"""
|
|
3178
|
+
|
|
3179
|
+
if folder_types:
|
|
3180
|
+
folder_types = ",".join(folder_types)
|
|
3181
|
+
|
|
3182
|
+
query_fields = [
|
|
3183
|
+
"{}={}".format(key, value)
|
|
3184
|
+
for key, value in (
|
|
3185
|
+
("search", search_string),
|
|
3186
|
+
("types", folder_types),
|
|
3187
|
+
)
|
|
3188
|
+
if value
|
|
3189
|
+
]
|
|
3190
|
+
query = ""
|
|
3191
|
+
if query_fields:
|
|
3192
|
+
query = "?{}".format(",".join(query_fields))
|
|
3193
|
+
|
|
3194
|
+
response = self.get(
|
|
3195
|
+
"projects/{}/hierarchy{}".format(project_name, query)
|
|
3196
|
+
)
|
|
3197
|
+
response.raise_for_status()
|
|
3198
|
+
return response.data
|
|
3199
|
+
|
|
3038
3200
|
def get_folders(
|
|
3039
3201
|
self,
|
|
3040
3202
|
project_name,
|
|
@@ -3606,7 +3768,6 @@ class ServerAPI(object):
|
|
|
3606
3768
|
if filtered_product is not None:
|
|
3607
3769
|
yield filtered_product
|
|
3608
3770
|
|
|
3609
|
-
|
|
3610
3771
|
def get_product_by_id(
|
|
3611
3772
|
self,
|
|
3612
3773
|
project_name,
|
|
@@ -2,6 +2,7 @@ import re
|
|
|
2
2
|
import datetime
|
|
3
3
|
import uuid
|
|
4
4
|
import string
|
|
5
|
+
import platform
|
|
5
6
|
import collections
|
|
6
7
|
try:
|
|
7
8
|
# Python 3
|
|
@@ -358,7 +359,7 @@ class TransferProgress:
|
|
|
358
359
|
def __init__(self):
|
|
359
360
|
self._started = False
|
|
360
361
|
self._transfer_done = False
|
|
361
|
-
self.
|
|
362
|
+
self._transferred = 0
|
|
362
363
|
self._content_size = None
|
|
363
364
|
|
|
364
365
|
self._failed = False
|
|
@@ -368,25 +369,66 @@ class TransferProgress:
|
|
|
368
369
|
self._destination_url = "N/A"
|
|
369
370
|
|
|
370
371
|
def get_content_size(self):
|
|
372
|
+
"""Content size in bytes.
|
|
373
|
+
|
|
374
|
+
Returns:
|
|
375
|
+
Union[int, None]: Content size in bytes or None
|
|
376
|
+
if is unknown.
|
|
377
|
+
"""
|
|
378
|
+
|
|
371
379
|
return self._content_size
|
|
372
380
|
|
|
373
381
|
def set_content_size(self, content_size):
|
|
382
|
+
"""Set content size in bytes.
|
|
383
|
+
|
|
384
|
+
Args:
|
|
385
|
+
content_size (int): Content size in bytes.
|
|
386
|
+
|
|
387
|
+
Raises:
|
|
388
|
+
ValueError: If content size was already set.
|
|
389
|
+
"""
|
|
390
|
+
|
|
374
391
|
if self._content_size is not None:
|
|
375
392
|
raise ValueError("Content size was set more then once")
|
|
376
393
|
self._content_size = content_size
|
|
377
394
|
|
|
378
395
|
def get_started(self):
|
|
396
|
+
"""Transfer was started.
|
|
397
|
+
|
|
398
|
+
Returns:
|
|
399
|
+
bool: True if transfer started.
|
|
400
|
+
"""
|
|
401
|
+
|
|
379
402
|
return self._started
|
|
380
403
|
|
|
381
404
|
def set_started(self):
|
|
405
|
+
"""Mark that transfer started.
|
|
406
|
+
|
|
407
|
+
Raises:
|
|
408
|
+
ValueError: If transfer was already started.
|
|
409
|
+
"""
|
|
410
|
+
|
|
382
411
|
if self._started:
|
|
383
412
|
raise ValueError("Progress already started")
|
|
384
413
|
self._started = True
|
|
385
414
|
|
|
386
415
|
def get_transfer_done(self):
|
|
416
|
+
"""Transfer finished.
|
|
417
|
+
|
|
418
|
+
Returns:
|
|
419
|
+
bool: Transfer finished.
|
|
420
|
+
"""
|
|
421
|
+
|
|
387
422
|
return self._transfer_done
|
|
388
423
|
|
|
389
424
|
def set_transfer_done(self):
|
|
425
|
+
"""Mark progress as transfer finished.
|
|
426
|
+
|
|
427
|
+
Raises:
|
|
428
|
+
ValueError: If progress was already marked as done
|
|
429
|
+
or wasn't started yet.
|
|
430
|
+
"""
|
|
431
|
+
|
|
390
432
|
if self._transfer_done:
|
|
391
433
|
raise ValueError("Progress was already marked as done")
|
|
392
434
|
if not self._started:
|
|
@@ -394,41 +436,117 @@ class TransferProgress:
|
|
|
394
436
|
self._transfer_done = True
|
|
395
437
|
|
|
396
438
|
def get_failed(self):
|
|
439
|
+
"""Transfer failed.
|
|
440
|
+
|
|
441
|
+
Returns:
|
|
442
|
+
bool: True if transfer failed.
|
|
443
|
+
"""
|
|
444
|
+
|
|
397
445
|
return self._failed
|
|
398
446
|
|
|
399
447
|
def get_fail_reason(self):
|
|
448
|
+
"""Get reason why transfer failed.
|
|
449
|
+
|
|
450
|
+
Returns:
|
|
451
|
+
Union[str, None]: Reason why transfer
|
|
452
|
+
failed or None.
|
|
453
|
+
"""
|
|
454
|
+
|
|
400
455
|
return self._fail_reason
|
|
401
456
|
|
|
402
457
|
def set_failed(self, reason):
|
|
458
|
+
"""Mark progress as failed.
|
|
459
|
+
|
|
460
|
+
Args:
|
|
461
|
+
reason (str): Reason why transfer failed.
|
|
462
|
+
"""
|
|
463
|
+
|
|
403
464
|
self._fail_reason = reason
|
|
404
465
|
self._failed = True
|
|
405
466
|
|
|
406
467
|
def get_transferred_size(self):
|
|
407
|
-
|
|
468
|
+
"""Already transferred size in bytes.
|
|
469
|
+
|
|
470
|
+
Returns:
|
|
471
|
+
int: Already transferred size in bytes.
|
|
472
|
+
"""
|
|
473
|
+
|
|
474
|
+
return self._transferred
|
|
408
475
|
|
|
409
|
-
def set_transferred_size(self,
|
|
410
|
-
|
|
476
|
+
def set_transferred_size(self, transferred):
|
|
477
|
+
"""Set already transferred size in bytes.
|
|
478
|
+
|
|
479
|
+
Args:
|
|
480
|
+
transferred (int): Already transferred size in bytes.
|
|
481
|
+
"""
|
|
482
|
+
|
|
483
|
+
self._transferred = transferred
|
|
411
484
|
|
|
412
485
|
def add_transferred_chunk(self, chunk_size):
|
|
413
|
-
|
|
486
|
+
"""Add transferred chunk size in bytes.
|
|
487
|
+
|
|
488
|
+
Args:
|
|
489
|
+
chunk_size (int): Add transferred chunk size
|
|
490
|
+
in bytes.
|
|
491
|
+
"""
|
|
492
|
+
|
|
493
|
+
self._transferred += chunk_size
|
|
414
494
|
|
|
415
495
|
def get_source_url(self):
|
|
496
|
+
"""Source url from where transfer happens.
|
|
497
|
+
|
|
498
|
+
Note:
|
|
499
|
+
Consider this as title. Must be set using
|
|
500
|
+
'set_source_url' or 'N/A' will be returned.
|
|
501
|
+
|
|
502
|
+
Returns:
|
|
503
|
+
str: Source url from where transfer happens.
|
|
504
|
+
"""
|
|
505
|
+
|
|
416
506
|
return self._source_url
|
|
417
507
|
|
|
418
508
|
def set_source_url(self, url):
|
|
509
|
+
"""Set source url from where transfer happens.
|
|
510
|
+
|
|
511
|
+
Args:
|
|
512
|
+
url (str): Source url from where transfer happens.
|
|
513
|
+
"""
|
|
514
|
+
|
|
419
515
|
self._source_url = url
|
|
420
516
|
|
|
421
517
|
def get_destination_url(self):
|
|
518
|
+
"""Destination url where transfer happens.
|
|
519
|
+
|
|
520
|
+
Note:
|
|
521
|
+
Consider this as title. Must be set using
|
|
522
|
+
'set_source_url' or 'N/A' will be returned.
|
|
523
|
+
|
|
524
|
+
Returns:
|
|
525
|
+
str: Destination url where transfer happens.
|
|
526
|
+
"""
|
|
527
|
+
|
|
422
528
|
return self._destination_url
|
|
423
529
|
|
|
424
530
|
def set_destination_url(self, url):
|
|
531
|
+
"""Set destination url where transfer happens.
|
|
532
|
+
|
|
533
|
+
Args:
|
|
534
|
+
url (str): Destination url where transfer happens.
|
|
535
|
+
"""
|
|
536
|
+
|
|
425
537
|
self._destination_url = url
|
|
426
538
|
|
|
427
539
|
@property
|
|
428
540
|
def is_running(self):
|
|
541
|
+
"""Check if transfer is running.
|
|
542
|
+
|
|
543
|
+
Returns:
|
|
544
|
+
bool: True if transfer is running.
|
|
545
|
+
"""
|
|
546
|
+
|
|
429
547
|
if (
|
|
430
548
|
not self.started
|
|
431
|
-
or self.
|
|
549
|
+
or self.transfer_done
|
|
432
550
|
or self.failed
|
|
433
551
|
):
|
|
434
552
|
return False
|
|
@@ -436,9 +554,16 @@ class TransferProgress:
|
|
|
436
554
|
|
|
437
555
|
@property
|
|
438
556
|
def transfer_progress(self):
|
|
557
|
+
"""Get transfer progress in percents.
|
|
558
|
+
|
|
559
|
+
Returns:
|
|
560
|
+
Union[float, None]: Transfer progress in percents or 'None'
|
|
561
|
+
if content size is unknown.
|
|
562
|
+
"""
|
|
563
|
+
|
|
439
564
|
if self._content_size is None:
|
|
440
565
|
return None
|
|
441
|
-
return (self.
|
|
566
|
+
return (self._transferred * 100.0) / float(self._content_size)
|
|
442
567
|
|
|
443
568
|
content_size = property(get_content_size, set_content_size)
|
|
444
569
|
started = property(get_started)
|
|
@@ -447,5 +572,23 @@ class TransferProgress:
|
|
|
447
572
|
fail_reason = property(get_fail_reason)
|
|
448
573
|
source_url = property(get_source_url, set_source_url)
|
|
449
574
|
destination_url = property(get_destination_url, set_destination_url)
|
|
450
|
-
content_size = property(get_content_size, set_content_size)
|
|
451
575
|
transferred_size = property(get_transferred_size, set_transferred_size)
|
|
576
|
+
|
|
577
|
+
|
|
578
|
+
def create_dependency_package_basename(platform_name=None):
|
|
579
|
+
"""Create basename for dependency package file.
|
|
580
|
+
|
|
581
|
+
Args:
|
|
582
|
+
platform_name (Optional[str]): Name of platform for which the
|
|
583
|
+
bundle is targeted. Default value is current platform.
|
|
584
|
+
|
|
585
|
+
Returns:
|
|
586
|
+
str: Dependency package name with timestamp and platform.
|
|
587
|
+
"""
|
|
588
|
+
|
|
589
|
+
if platform_name is None:
|
|
590
|
+
platform_name = platform.system().lower()
|
|
591
|
+
|
|
592
|
+
now_date = datetime.datetime.now()
|
|
593
|
+
time_stamp = now_date.strftime("%y%m%d%H%M")
|
|
594
|
+
return "ayon_{}_{}".format(time_stamp, platform_name)
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""Package declaring Python API for Ayon server."""
|
|
2
|
-
__version__ = "0.3.
|
|
2
|
+
__version__ = "0.3.3"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ayon-python-api-0.3.1 → ayon-python-api-0.3.3}/ayon_python_api.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|