Ayon-Python-Api 0.4.2__tar.gz → 0.5.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-0.4.2 → ayon-python-api-0.5.0}/PKG-INFO +1 -1
- {ayon-python-api-0.4.2 → ayon-python-api-0.5.0}/ayon_api/_api.py +6 -4
- {ayon-python-api-0.4.2 → ayon-python-api-0.5.0}/ayon_api/graphql_queries.py +1 -0
- {ayon-python-api-0.4.2 → ayon-python-api-0.5.0}/ayon_api/server_api.py +77 -35
- {ayon-python-api-0.4.2 → ayon-python-api-0.5.0}/ayon_api/utils.py +37 -12
- {ayon-python-api-0.4.2 → ayon-python-api-0.5.0}/ayon_api/version.py +1 -1
- {ayon-python-api-0.4.2 → ayon-python-api-0.5.0}/ayon_python_api.egg-info/PKG-INFO +1 -1
- {ayon-python-api-0.4.2 → ayon-python-api-0.5.0}/pyproject.toml +1 -1
- {ayon-python-api-0.4.2 → ayon-python-api-0.5.0}/LICENSE +0 -0
- {ayon-python-api-0.4.2 → ayon-python-api-0.5.0}/README.md +0 -0
- {ayon-python-api-0.4.2 → ayon-python-api-0.5.0}/ayon_api/__init__.py +0 -0
- {ayon-python-api-0.4.2 → ayon-python-api-0.5.0}/ayon_api/constants.py +0 -0
- {ayon-python-api-0.4.2 → ayon-python-api-0.5.0}/ayon_api/entity_hub.py +0 -0
- {ayon-python-api-0.4.2 → ayon-python-api-0.5.0}/ayon_api/events.py +0 -0
- {ayon-python-api-0.4.2 → ayon-python-api-0.5.0}/ayon_api/exceptions.py +0 -0
- {ayon-python-api-0.4.2 → ayon-python-api-0.5.0}/ayon_api/graphql.py +0 -0
- {ayon-python-api-0.4.2 → ayon-python-api-0.5.0}/ayon_api/operations.py +0 -0
- {ayon-python-api-0.4.2 → ayon-python-api-0.5.0}/ayon_python_api.egg-info/SOURCES.txt +0 -0
- {ayon-python-api-0.4.2 → ayon-python-api-0.5.0}/ayon_python_api.egg-info/dependency_links.txt +0 -0
- {ayon-python-api-0.4.2 → ayon-python-api-0.5.0}/ayon_python_api.egg-info/requires.txt +0 -0
- {ayon-python-api-0.4.2 → ayon-python-api-0.5.0}/ayon_python_api.egg-info/top_level.txt +0 -0
- {ayon-python-api-0.4.2 → ayon-python-api-0.5.0}/setup.cfg +0 -0
- {ayon-python-api-0.4.2 → ayon-python-api-0.5.0}/setup.py +0 -0
|
@@ -602,12 +602,12 @@ def delete_installer(*args, **kwargs):
|
|
|
602
602
|
|
|
603
603
|
def download_installer(*args, **kwargs):
|
|
604
604
|
con = get_server_api_connection()
|
|
605
|
-
con.download_installer(*args, **kwargs)
|
|
605
|
+
return con.download_installer(*args, **kwargs)
|
|
606
606
|
|
|
607
607
|
|
|
608
608
|
def upload_installer(*args, **kwargs):
|
|
609
609
|
con = get_server_api_connection()
|
|
610
|
-
con.upload_installer(*args, **kwargs)
|
|
610
|
+
return con.upload_installer(*args, **kwargs)
|
|
611
611
|
|
|
612
612
|
|
|
613
613
|
# Dependency packages
|
|
@@ -978,12 +978,14 @@ def delete_project(project_name):
|
|
|
978
978
|
|
|
979
979
|
def get_thumbnail_by_id(project_name, thumbnail_id):
|
|
980
980
|
con = get_server_api_connection()
|
|
981
|
-
con.get_thumbnail_by_id(project_name, thumbnail_id)
|
|
981
|
+
return con.get_thumbnail_by_id(project_name, thumbnail_id)
|
|
982
982
|
|
|
983
983
|
|
|
984
984
|
def get_thumbnail(project_name, entity_type, entity_id, thumbnail_id=None):
|
|
985
985
|
con = get_server_api_connection()
|
|
986
|
-
con.get_thumbnail(
|
|
986
|
+
return con.get_thumbnail(
|
|
987
|
+
project_name, entity_type, entity_id, thumbnail_id
|
|
988
|
+
)
|
|
987
989
|
|
|
988
990
|
|
|
989
991
|
def get_folder_thumbnail(project_name, folder_id, thumbnail_id=None):
|
|
@@ -931,8 +931,8 @@ class ServerAPI(object):
|
|
|
931
931
|
int(re_match.group("major")),
|
|
932
932
|
int(re_match.group("minor")),
|
|
933
933
|
int(re_match.group("patch")),
|
|
934
|
-
re_match.group("prerelease"),
|
|
935
|
-
re_match.group("buildmetadata")
|
|
934
|
+
re_match.group("prerelease") or "",
|
|
935
|
+
re_match.group("buildmetadata") or "",
|
|
936
936
|
)
|
|
937
937
|
return self._server_version_tuple
|
|
938
938
|
|
|
@@ -1133,31 +1133,41 @@ class ServerAPI(object):
|
|
|
1133
1133
|
|
|
1134
1134
|
response = None
|
|
1135
1135
|
new_response = None
|
|
1136
|
-
for
|
|
1136
|
+
for retry_idx in reversed(range(max_retries)):
|
|
1137
1137
|
try:
|
|
1138
1138
|
response = function(url, **kwargs)
|
|
1139
1139
|
break
|
|
1140
1140
|
|
|
1141
1141
|
except ConnectionRefusedError:
|
|
1142
|
+
if retry_idx == 0:
|
|
1143
|
+
self.log.warning(
|
|
1144
|
+
"Connection error happened.", exc_info=True
|
|
1145
|
+
)
|
|
1146
|
+
|
|
1142
1147
|
# Server may be restarting
|
|
1143
1148
|
new_response = RestApiResponse(
|
|
1144
1149
|
None,
|
|
1145
1150
|
{"detail": "Unable to connect the server. Connection refused"}
|
|
1146
1151
|
)
|
|
1152
|
+
|
|
1147
1153
|
except requests.exceptions.Timeout:
|
|
1148
1154
|
# Connection timed out
|
|
1149
1155
|
new_response = RestApiResponse(
|
|
1150
1156
|
None,
|
|
1151
1157
|
{"detail": "Connection timed out."}
|
|
1152
1158
|
)
|
|
1159
|
+
|
|
1153
1160
|
except requests.exceptions.ConnectionError:
|
|
1154
|
-
#
|
|
1155
|
-
|
|
1161
|
+
# Log warning only on last attempt
|
|
1162
|
+
if retry_idx == 0:
|
|
1163
|
+
self.log.warning(
|
|
1164
|
+
"Connection error happened.", exc_info=True
|
|
1165
|
+
)
|
|
1166
|
+
|
|
1156
1167
|
new_response = RestApiResponse(
|
|
1157
1168
|
None,
|
|
1158
1169
|
{"detail": "Unable to connect the server. Connection error"}
|
|
1159
1170
|
)
|
|
1160
|
-
break
|
|
1161
1171
|
|
|
1162
1172
|
time.sleep(0.1)
|
|
1163
1173
|
|
|
@@ -1342,7 +1352,9 @@ class ServerAPI(object):
|
|
|
1342
1352
|
status=None,
|
|
1343
1353
|
description=None,
|
|
1344
1354
|
summary=None,
|
|
1345
|
-
payload=None
|
|
1355
|
+
payload=None,
|
|
1356
|
+
progress=None,
|
|
1357
|
+
retries=None
|
|
1346
1358
|
):
|
|
1347
1359
|
kwargs = {
|
|
1348
1360
|
key: value
|
|
@@ -1353,9 +1365,27 @@ class ServerAPI(object):
|
|
|
1353
1365
|
("description", description),
|
|
1354
1366
|
("summary", summary),
|
|
1355
1367
|
("payload", payload),
|
|
1368
|
+
("progress", progress),
|
|
1369
|
+
("retries", retries),
|
|
1356
1370
|
)
|
|
1357
1371
|
if value is not None
|
|
1358
1372
|
}
|
|
1373
|
+
# 'progress' and 'retries' are available since 0.5.x server version
|
|
1374
|
+
major, minor, _, _, _ = self.server_version_tuple
|
|
1375
|
+
if (major, minor) < (0, 5):
|
|
1376
|
+
args = []
|
|
1377
|
+
if progress is not None:
|
|
1378
|
+
args.append("progress")
|
|
1379
|
+
if retries is not None:
|
|
1380
|
+
args.append("retries")
|
|
1381
|
+
fields = ", ".join("'{}'".format(f) for f in args)
|
|
1382
|
+
ending = "s" if len(args) > 1 else ""
|
|
1383
|
+
raise ValueError((
|
|
1384
|
+
"Your server version '{}' does not support update"
|
|
1385
|
+
" of {} field{} on event. The fields are supported since"
|
|
1386
|
+
" server version '0.5'."
|
|
1387
|
+
).format(self.get_server_version(), fields, ending))
|
|
1388
|
+
|
|
1359
1389
|
response = self.patch(
|
|
1360
1390
|
"events/{}".format(event_id),
|
|
1361
1391
|
**kwargs
|
|
@@ -1427,6 +1457,7 @@ class ServerAPI(object):
|
|
|
1427
1457
|
description=None,
|
|
1428
1458
|
sequential=None,
|
|
1429
1459
|
events_filter=None,
|
|
1460
|
+
max_retries=None,
|
|
1430
1461
|
):
|
|
1431
1462
|
"""Enroll job based on events.
|
|
1432
1463
|
|
|
@@ -1468,8 +1499,12 @@ class ServerAPI(object):
|
|
|
1468
1499
|
in target event.
|
|
1469
1500
|
sequential (Optional[bool]): The source topic must be processed
|
|
1470
1501
|
in sequence.
|
|
1471
|
-
events_filter (Optional[
|
|
1472
|
-
|
|
1502
|
+
events_filter (Optional[dict[str, Any]]): Filtering conditions
|
|
1503
|
+
to filter the source event. For more technical specifications
|
|
1504
|
+
look to server backed 'ayon_server.sqlfilter.Filter'.
|
|
1505
|
+
TODO: Add example of filters.
|
|
1506
|
+
max_retries (Optional[int]): How many times can be event retried.
|
|
1507
|
+
Default value is based on server (3 at the time of this PR).
|
|
1473
1508
|
|
|
1474
1509
|
Returns:
|
|
1475
1510
|
Union[None, dict[str, Any]]: None if there is no event matching
|
|
@@ -1480,6 +1515,7 @@ class ServerAPI(object):
|
|
|
1480
1515
|
"sourceTopic": source_topic,
|
|
1481
1516
|
"targetTopic": target_topic,
|
|
1482
1517
|
"sender": sender,
|
|
1518
|
+
"maxRetries": max_retries,
|
|
1483
1519
|
}
|
|
1484
1520
|
if sequential is not None:
|
|
1485
1521
|
kwargs["sequential"] = sequential
|
|
@@ -2229,6 +2265,34 @@ class ServerAPI(object):
|
|
|
2229
2265
|
response.raise_for_status("Failed to create/update dependency")
|
|
2230
2266
|
return response.data
|
|
2231
2267
|
|
|
2268
|
+
def _get_dependency_package_route(
|
|
2269
|
+
self, filename=None, platform_name=None
|
|
2270
|
+
):
|
|
2271
|
+
major, minor, patch, _, _ = self.server_version_tuple
|
|
2272
|
+
if (major, minor, patch) <= (0, 2, 0):
|
|
2273
|
+
# Backwards compatibility for AYON server 0.2.0 and lower
|
|
2274
|
+
self.log.warning((
|
|
2275
|
+
"Using deprecated dependency package route."
|
|
2276
|
+
" Please update your AYON server to version 0.2.1 or higher."
|
|
2277
|
+
" Backwards compatibility for this route will be removed"
|
|
2278
|
+
" in future releases of ayon-python-api."
|
|
2279
|
+
))
|
|
2280
|
+
if platform_name is None:
|
|
2281
|
+
platform_name = platform.system().lower()
|
|
2282
|
+
base = "dependencies"
|
|
2283
|
+
if not filename:
|
|
2284
|
+
return base
|
|
2285
|
+
return "{}/{}/{}".format(base, filename, platform_name)
|
|
2286
|
+
|
|
2287
|
+
if (major, minor) <= (0, 3):
|
|
2288
|
+
endpoint = "desktop/dependency_packages"
|
|
2289
|
+
else:
|
|
2290
|
+
endpoint = "desktop/dependencyPackages"
|
|
2291
|
+
|
|
2292
|
+
if filename:
|
|
2293
|
+
return "{}/{}".format(endpoint, filename)
|
|
2294
|
+
return endpoint
|
|
2295
|
+
|
|
2232
2296
|
def get_dependency_packages(self):
|
|
2233
2297
|
"""Information about dependency packages on server.
|
|
2234
2298
|
|
|
@@ -2256,33 +2320,11 @@ class ServerAPI(object):
|
|
|
2256
2320
|
server.
|
|
2257
2321
|
"""
|
|
2258
2322
|
|
|
2259
|
-
endpoint =
|
|
2260
|
-
major, minor, _, _, _ = self.server_version_tuple
|
|
2261
|
-
if major == 0 and minor <= 3:
|
|
2262
|
-
endpoint = "desktop/dependency_packages"
|
|
2263
|
-
|
|
2323
|
+
endpoint = self._get_dependency_package_route()
|
|
2264
2324
|
result = self.get(endpoint)
|
|
2265
2325
|
result.raise_for_status()
|
|
2266
2326
|
return result.data
|
|
2267
2327
|
|
|
2268
|
-
def _get_dependency_package_route(
|
|
2269
|
-
self, filename=None, platform_name=None
|
|
2270
|
-
):
|
|
2271
|
-
major, minor, patch, _, _ = self.server_version_tuple
|
|
2272
|
-
if major == 0 and (minor > 2 or (minor == 2 and patch >= 1)):
|
|
2273
|
-
base = "desktop/dependency_packages"
|
|
2274
|
-
if not filename:
|
|
2275
|
-
return base
|
|
2276
|
-
return "{}/{}".format(base, filename)
|
|
2277
|
-
|
|
2278
|
-
# Backwards compatibility for AYON server 0.2.0 and lower
|
|
2279
|
-
if platform_name is None:
|
|
2280
|
-
platform_name = platform.system().lower()
|
|
2281
|
-
base = "dependencies"
|
|
2282
|
-
if not filename:
|
|
2283
|
-
return base
|
|
2284
|
-
return "{}/{}/{}".format(base, filename, platform_name)
|
|
2285
|
-
|
|
2286
2328
|
def create_dependency_package(
|
|
2287
2329
|
self,
|
|
2288
2330
|
filename,
|
|
@@ -4323,9 +4365,6 @@ class ServerAPI(object):
|
|
|
4323
4365
|
fields.remove("attrib")
|
|
4324
4366
|
fields |= self.get_attributes_fields_for_type("version")
|
|
4325
4367
|
|
|
4326
|
-
if active is not None:
|
|
4327
|
-
fields.add("active")
|
|
4328
|
-
|
|
4329
4368
|
# Make sure fields have minimum required fields
|
|
4330
4369
|
fields |= {"id", "version"}
|
|
4331
4370
|
|
|
@@ -4334,6 +4373,9 @@ class ServerAPI(object):
|
|
|
4334
4373
|
use_rest = True
|
|
4335
4374
|
fields = {"id"}
|
|
4336
4375
|
|
|
4376
|
+
if active is not None:
|
|
4377
|
+
fields.add("active")
|
|
4378
|
+
|
|
4337
4379
|
if own_attributes:
|
|
4338
4380
|
fields.add("ownAttrib")
|
|
4339
4381
|
|
|
@@ -263,19 +263,23 @@ def _try_connect_to_server(url, timeout=None):
|
|
|
263
263
|
return True
|
|
264
264
|
|
|
265
265
|
|
|
266
|
-
def login_to_server(url, username, password):
|
|
266
|
+
def login_to_server(url, username, password, timeout=None):
|
|
267
267
|
"""Use login to the server to receive token.
|
|
268
268
|
|
|
269
269
|
Args:
|
|
270
270
|
url (str): Server url.
|
|
271
271
|
username (str): User's username.
|
|
272
272
|
password (str): User's password.
|
|
273
|
+
timeout (Optional[float]): Timeout for request. Value from
|
|
274
|
+
'get_default_timeout' is used if not specified.
|
|
273
275
|
|
|
274
276
|
Returns:
|
|
275
277
|
Union[str, None]: User's token if login was successfull.
|
|
276
278
|
Otherwise 'None'.
|
|
277
279
|
"""
|
|
278
280
|
|
|
281
|
+
if timeout is None:
|
|
282
|
+
timeout = get_default_timeout()
|
|
279
283
|
headers = {"Content-Type": "application/json"}
|
|
280
284
|
response = requests.post(
|
|
281
285
|
"{}/api/auth/login".format(url),
|
|
@@ -283,7 +287,8 @@ def login_to_server(url, username, password):
|
|
|
283
287
|
json={
|
|
284
288
|
"name": username,
|
|
285
289
|
"password": password
|
|
286
|
-
}
|
|
290
|
+
},
|
|
291
|
+
timeout=timeout,
|
|
287
292
|
)
|
|
288
293
|
token = None
|
|
289
294
|
# 200 - success
|
|
@@ -294,44 +299,64 @@ def login_to_server(url, username, password):
|
|
|
294
299
|
return token
|
|
295
300
|
|
|
296
301
|
|
|
297
|
-
def logout_from_server(url, token):
|
|
302
|
+
def logout_from_server(url, token, timeout=None):
|
|
298
303
|
"""Logout from server and throw token away.
|
|
299
304
|
|
|
300
305
|
Args:
|
|
301
306
|
url (str): Url from which should be logged out.
|
|
302
307
|
token (str): Token which should be used to log out.
|
|
308
|
+
timeout (Optional[float]): Timeout for request. Value from
|
|
309
|
+
'get_default_timeout' is used if not specified.
|
|
303
310
|
"""
|
|
304
311
|
|
|
312
|
+
if timeout is None:
|
|
313
|
+
timeout = get_default_timeout()
|
|
305
314
|
headers = {
|
|
306
315
|
"Content-Type": "application/json",
|
|
307
316
|
"Authorization": "Bearer {}".format(token)
|
|
308
317
|
}
|
|
309
318
|
requests.post(
|
|
310
319
|
url + "/api/auth/logout",
|
|
311
|
-
headers=headers
|
|
320
|
+
headers=headers,
|
|
321
|
+
timeout=timeout,
|
|
312
322
|
)
|
|
313
323
|
|
|
314
324
|
|
|
315
|
-
def is_token_valid(url, token):
|
|
325
|
+
def is_token_valid(url, token, timeout=None):
|
|
316
326
|
"""Check if token is valid.
|
|
317
327
|
|
|
328
|
+
Token can be a user token or service api key.
|
|
329
|
+
|
|
318
330
|
Args:
|
|
319
331
|
url (str): Server url.
|
|
320
332
|
token (str): User's token.
|
|
333
|
+
timeout (Optional[float]): Timeout for request. Value from
|
|
334
|
+
'get_default_timeout' is used if not specified.
|
|
321
335
|
|
|
322
336
|
Returns:
|
|
323
337
|
bool: True if token is valid.
|
|
324
338
|
"""
|
|
325
339
|
|
|
326
|
-
|
|
340
|
+
if timeout is None:
|
|
341
|
+
timeout = get_default_timeout()
|
|
342
|
+
|
|
343
|
+
base_headers = {
|
|
327
344
|
"Content-Type": "application/json",
|
|
328
|
-
"Authorization": "Bearer {}".format(token)
|
|
329
345
|
}
|
|
330
|
-
|
|
331
|
-
"{}
|
|
332
|
-
|
|
333
|
-
)
|
|
334
|
-
|
|
346
|
+
for header_value in (
|
|
347
|
+
{"Authorization": "Bearer {}".format(token)},
|
|
348
|
+
{"X-Api-Key": token},
|
|
349
|
+
):
|
|
350
|
+
headers = base_headers.copy()
|
|
351
|
+
headers.update(header_value)
|
|
352
|
+
response = requests.get(
|
|
353
|
+
"{}/api/users/me".format(url),
|
|
354
|
+
headers=headers,
|
|
355
|
+
timeout=timeout,
|
|
356
|
+
)
|
|
357
|
+
if response.status_code == 200:
|
|
358
|
+
return True
|
|
359
|
+
return False
|
|
335
360
|
|
|
336
361
|
|
|
337
362
|
def validate_url(url, timeout=None):
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""Package declaring Python API for Ayon server."""
|
|
2
|
-
__version__ = "0.
|
|
2
|
+
__version__ = "0.5.0"
|
|
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.4.2 → ayon-python-api-0.5.0}/ayon_python_api.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|