Ayon-Python-Api 0.1.7__tar.gz → 0.1.9__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.1.7/ayon_python_api.egg-info → ayon-python-api-0.1.9}/PKG-INFO +1 -1
- {ayon-python-api-0.1.7 → ayon-python-api-0.1.9}/ayon_api/__init__.py +25 -0
- {ayon-python-api-0.1.7 → ayon-python-api-0.1.9}/ayon_api/exceptions.py +4 -0
- {ayon-python-api-0.1.7 → ayon-python-api-0.1.9}/ayon_api/server.py +220 -87
- {ayon-python-api-0.1.7 → ayon-python-api-0.1.9}/ayon_api/server_api.py +172 -0
- {ayon-python-api-0.1.7 → ayon-python-api-0.1.9}/ayon_api/utils.py +76 -17
- {ayon-python-api-0.1.7 → ayon-python-api-0.1.9}/ayon_api/version.py +1 -1
- {ayon-python-api-0.1.7 → ayon-python-api-0.1.9/ayon_python_api.egg-info}/PKG-INFO +1 -1
- ayon-python-api-0.1.9/ayon_python_api.egg-info/dependency_links.txt +1 -0
- ayon-python-api-0.1.9/ayon_python_api.egg-info/requires.txt +4 -0
- {ayon-python-api-0.1.7 → ayon-python-api-0.1.9}/pyproject.toml +3 -2
- {ayon-python-api-0.1.7 → ayon-python-api-0.1.9}/setup.py +2 -3
- ayon-python-api-0.1.7/ayon_python_api.egg-info/dependency_links.txt +0 -1
- ayon-python-api-0.1.7/ayon_python_api.egg-info/requires.txt +0 -2
- {ayon-python-api-0.1.7 → ayon-python-api-0.1.9}/LICENSE +0 -0
- {ayon-python-api-0.1.7 → ayon-python-api-0.1.9}/README.md +0 -0
- {ayon-python-api-0.1.7 → ayon-python-api-0.1.9}/ayon_api/constants.py +0 -0
- {ayon-python-api-0.1.7 → ayon-python-api-0.1.9}/ayon_api/entity_hub.py +0 -0
- {ayon-python-api-0.1.7 → ayon-python-api-0.1.9}/ayon_api/events.py +0 -0
- {ayon-python-api-0.1.7 → ayon-python-api-0.1.9}/ayon_api/graphql.py +0 -0
- {ayon-python-api-0.1.7 → ayon-python-api-0.1.9}/ayon_api/graphql_queries.py +0 -0
- {ayon-python-api-0.1.7 → ayon-python-api-0.1.9}/ayon_api/operations.py +0 -0
- {ayon-python-api-0.1.7 → ayon-python-api-0.1.9}/ayon_api/thumbnails.py +0 -0
- {ayon-python-api-0.1.7 → ayon-python-api-0.1.9}/ayon_python_api.egg-info/SOURCES.txt +0 -0
- {ayon-python-api-0.1.7 → ayon-python-api-0.1.9}/ayon_python_api.egg-info/top_level.txt +0 -0
- {ayon-python-api-0.1.7 → ayon-python-api-0.1.9}/setup.cfg +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from .utils import (
|
|
2
2
|
TransferProgress,
|
|
3
|
+
slugify_string,
|
|
3
4
|
)
|
|
4
5
|
from .server import (
|
|
5
6
|
ServerAPIBase,
|
|
@@ -7,7 +8,14 @@ from .server import (
|
|
|
7
8
|
|
|
8
9
|
from .server_api import (
|
|
9
10
|
ServerAPI,
|
|
11
|
+
ServiceContext,
|
|
10
12
|
|
|
13
|
+
init_service,
|
|
14
|
+
|
|
15
|
+
is_connection_created,
|
|
16
|
+
close_connection,
|
|
17
|
+
change_token,
|
|
18
|
+
set_environments,
|
|
11
19
|
get_server_api_connection,
|
|
12
20
|
|
|
13
21
|
get_base_url,
|
|
@@ -25,6 +33,11 @@ from .server_api import (
|
|
|
25
33
|
patch,
|
|
26
34
|
delete,
|
|
27
35
|
|
|
36
|
+
get_event,
|
|
37
|
+
dispatch_event,
|
|
38
|
+
update_event,
|
|
39
|
+
enroll_event_job,
|
|
40
|
+
|
|
28
41
|
download_file,
|
|
29
42
|
upload_file,
|
|
30
43
|
|
|
@@ -99,11 +112,18 @@ from .server_api import (
|
|
|
99
112
|
|
|
100
113
|
__all__ = (
|
|
101
114
|
"TransferProgress",
|
|
115
|
+
"slugify_string",
|
|
102
116
|
|
|
103
117
|
"ServerAPIBase",
|
|
104
118
|
|
|
105
119
|
"ServerAPI",
|
|
120
|
+
"ServiceContext",
|
|
121
|
+
"init_service",
|
|
106
122
|
|
|
123
|
+
"is_connection_created",
|
|
124
|
+
"close_connection",
|
|
125
|
+
"change_token",
|
|
126
|
+
"set_environments",
|
|
107
127
|
"get_server_api_connection",
|
|
108
128
|
|
|
109
129
|
"get_base_url",
|
|
@@ -121,6 +141,11 @@ __all__ = (
|
|
|
121
141
|
"patch",
|
|
122
142
|
"delete",
|
|
123
143
|
|
|
144
|
+
"get_event",
|
|
145
|
+
"dispatch_event",
|
|
146
|
+
"update_event",
|
|
147
|
+
"enroll_event_job",
|
|
148
|
+
|
|
124
149
|
"download_file",
|
|
125
150
|
"upload_file",
|
|
126
151
|
|
|
@@ -75,13 +75,32 @@ class RequestTypes:
|
|
|
75
75
|
class RestApiResponse(object):
|
|
76
76
|
"""API Response."""
|
|
77
77
|
|
|
78
|
-
def __init__(self,
|
|
79
|
-
if
|
|
80
|
-
|
|
78
|
+
def __init__(self, response, data=None):
|
|
79
|
+
if response is None:
|
|
80
|
+
status_code = 500
|
|
81
|
+
else:
|
|
82
|
+
status_code = response.status_code
|
|
83
|
+
self._response = response
|
|
81
84
|
self.status = status_code
|
|
82
|
-
self.
|
|
83
|
-
|
|
84
|
-
|
|
85
|
+
self._data = data
|
|
86
|
+
|
|
87
|
+
@property
|
|
88
|
+
def orig_response(self):
|
|
89
|
+
return self._response
|
|
90
|
+
|
|
91
|
+
@property
|
|
92
|
+
def headers(self):
|
|
93
|
+
return self._response.headers
|
|
94
|
+
|
|
95
|
+
@property
|
|
96
|
+
def data(self):
|
|
97
|
+
if self._data is None:
|
|
98
|
+
self._data = self._response.json()
|
|
99
|
+
return self._data
|
|
100
|
+
|
|
101
|
+
@property
|
|
102
|
+
def content(self):
|
|
103
|
+
return self._response.content
|
|
85
104
|
|
|
86
105
|
@property
|
|
87
106
|
def content_type(self):
|
|
@@ -95,6 +114,12 @@ class RestApiResponse(object):
|
|
|
95
114
|
def status_code(self):
|
|
96
115
|
return self.status
|
|
97
116
|
|
|
117
|
+
def raise_for_status(self):
|
|
118
|
+
self._response.raise_for_status()
|
|
119
|
+
|
|
120
|
+
def __enter__(self, *args, **kwargs):
|
|
121
|
+
return self._response.__enter__(*args, **kwargs)
|
|
122
|
+
|
|
98
123
|
def __contains__(self, key):
|
|
99
124
|
return key in self.data
|
|
100
125
|
|
|
@@ -448,26 +473,22 @@ class ServerAPIBase(object):
|
|
|
448
473
|
|
|
449
474
|
except ConnectionRefusedError:
|
|
450
475
|
new_response = RestApiResponse(
|
|
451
|
-
|
|
476
|
+
None,
|
|
452
477
|
{"detail": "Unable to connect the server. Connection refused"}
|
|
453
478
|
)
|
|
454
479
|
except requests.exceptions.ConnectionError:
|
|
455
480
|
new_response = RestApiResponse(
|
|
456
|
-
|
|
481
|
+
None,
|
|
457
482
|
{"detail": "Unable to connect the server. Connection error"}
|
|
458
483
|
)
|
|
459
484
|
else:
|
|
460
485
|
content_type = response.headers.get("Content-Type")
|
|
461
486
|
if content_type == "application/json":
|
|
462
487
|
try:
|
|
463
|
-
new_response = RestApiResponse(
|
|
464
|
-
response.status_code,
|
|
465
|
-
response.json(),
|
|
466
|
-
headers=response.headers,
|
|
467
|
-
)
|
|
488
|
+
new_response = RestApiResponse(response)
|
|
468
489
|
except JSONDecodeError:
|
|
469
490
|
new_response = RestApiResponse(
|
|
470
|
-
|
|
491
|
+
None,
|
|
471
492
|
{
|
|
472
493
|
"detail": "The response is not a JSON: {}".format(
|
|
473
494
|
response.text)
|
|
@@ -475,17 +496,10 @@ class ServerAPIBase(object):
|
|
|
475
496
|
)
|
|
476
497
|
|
|
477
498
|
elif content_type in ("image/jpeg", "image/png"):
|
|
478
|
-
new_response = RestApiResponse(
|
|
479
|
-
response.status_code,
|
|
480
|
-
headers=response.headers,
|
|
481
|
-
content=response.content
|
|
482
|
-
)
|
|
499
|
+
new_response = RestApiResponse(response)
|
|
483
500
|
|
|
484
501
|
else:
|
|
485
|
-
new_response = RestApiResponse(
|
|
486
|
-
response.status_code,
|
|
487
|
-
headers=response.headers,
|
|
488
|
-
)
|
|
502
|
+
new_response = RestApiResponse(response)
|
|
489
503
|
|
|
490
504
|
self.log.debug("Response {}".format(str(new_response)))
|
|
491
505
|
return new_response
|
|
@@ -555,6 +569,119 @@ class ServerAPIBase(object):
|
|
|
555
569
|
def delete(self, entrypoint, **kwargs):
|
|
556
570
|
return self.raw_delete(entrypoint, params=kwargs)
|
|
557
571
|
|
|
572
|
+
def get_event(self, event_id):
|
|
573
|
+
"""Receive full event data by id.
|
|
574
|
+
|
|
575
|
+
Events received using event server do not contain full information. To
|
|
576
|
+
get the full event information is required to receive it explicitly.
|
|
577
|
+
|
|
578
|
+
Args:
|
|
579
|
+
event_id (str): Id of event.
|
|
580
|
+
|
|
581
|
+
Returns:
|
|
582
|
+
Dict[str, Any]: Full event data.
|
|
583
|
+
"""
|
|
584
|
+
|
|
585
|
+
response = self.get("events/{}".format(event_id))
|
|
586
|
+
response.raise_for_status()
|
|
587
|
+
return response.data
|
|
588
|
+
|
|
589
|
+
def update_event(
|
|
590
|
+
self,
|
|
591
|
+
event_id,
|
|
592
|
+
sender=None,
|
|
593
|
+
project_name=None,
|
|
594
|
+
status=None,
|
|
595
|
+
description=None,
|
|
596
|
+
summary=None,
|
|
597
|
+
payload=None
|
|
598
|
+
):
|
|
599
|
+
kwargs = {}
|
|
600
|
+
for key, value in (
|
|
601
|
+
("sender", sender),
|
|
602
|
+
("projectName", project_name),
|
|
603
|
+
("status", status),
|
|
604
|
+
("description", description),
|
|
605
|
+
("summary", summary),
|
|
606
|
+
("payload", payload),
|
|
607
|
+
):
|
|
608
|
+
if value is not None:
|
|
609
|
+
kwargs[key] = value
|
|
610
|
+
response = self.patch(
|
|
611
|
+
"events/{}".format(event_id),
|
|
612
|
+
**kwargs
|
|
613
|
+
)
|
|
614
|
+
response.raise_for_status()
|
|
615
|
+
|
|
616
|
+
def dispatch_event(
|
|
617
|
+
self,
|
|
618
|
+
topic,
|
|
619
|
+
sender=None,
|
|
620
|
+
event_hash=None,
|
|
621
|
+
project_name=None,
|
|
622
|
+
username=None,
|
|
623
|
+
dependencies=None,
|
|
624
|
+
description=None,
|
|
625
|
+
summary=None,
|
|
626
|
+
payload=None,
|
|
627
|
+
finished=True,
|
|
628
|
+
store=True,
|
|
629
|
+
):
|
|
630
|
+
if summary is None:
|
|
631
|
+
summary = {}
|
|
632
|
+
if payload is None:
|
|
633
|
+
payload = {}
|
|
634
|
+
event_data = {
|
|
635
|
+
"topic": topic,
|
|
636
|
+
"sender": sender,
|
|
637
|
+
"hash": event_hash,
|
|
638
|
+
"project": project_name,
|
|
639
|
+
"user": username,
|
|
640
|
+
"dependencies": dependencies,
|
|
641
|
+
"description": description,
|
|
642
|
+
"summary": summary,
|
|
643
|
+
"payload": payload,
|
|
644
|
+
"finished": finished,
|
|
645
|
+
"store": store,
|
|
646
|
+
}
|
|
647
|
+
if self.post("events", **event_data):
|
|
648
|
+
self.log.debug("Dispatched event {}".format(topic))
|
|
649
|
+
return True
|
|
650
|
+
self.log.error("Unable to dispatch event {}".format(topic))
|
|
651
|
+
return False
|
|
652
|
+
|
|
653
|
+
def enroll_event_job(
|
|
654
|
+
self,
|
|
655
|
+
source_topic,
|
|
656
|
+
target_topic,
|
|
657
|
+
sender,
|
|
658
|
+
description=None,
|
|
659
|
+
sequential=None
|
|
660
|
+
):
|
|
661
|
+
"""Enroll job based on events.
|
|
662
|
+
|
|
663
|
+
Args:
|
|
664
|
+
source_topic (str): Topic
|
|
665
|
+
"""
|
|
666
|
+
|
|
667
|
+
kwargs = {
|
|
668
|
+
"sourceTopic": source_topic,
|
|
669
|
+
"targetTopic": target_topic,
|
|
670
|
+
"sender": sender,
|
|
671
|
+
}
|
|
672
|
+
if sequential is not None:
|
|
673
|
+
kwargs["sequential"] = sequential
|
|
674
|
+
if description is not None:
|
|
675
|
+
kwargs["description"] = description
|
|
676
|
+
response = self.post("enroll", **kwargs)
|
|
677
|
+
if response.status_code == 204:
|
|
678
|
+
return None
|
|
679
|
+
elif response.status_code >= 400:
|
|
680
|
+
self.log.error(response.text)
|
|
681
|
+
return None
|
|
682
|
+
|
|
683
|
+
return response.data
|
|
684
|
+
|
|
558
685
|
def _download_file(self, url, filepath, chunk_size, progress):
|
|
559
686
|
dst_directory = os.path.dirname(filepath)
|
|
560
687
|
if not os.path.exists(dst_directory):
|
|
@@ -573,7 +700,7 @@ class ServerAPIBase(object):
|
|
|
573
700
|
progress.set_content_size(response.headers["Content-length"])
|
|
574
701
|
for chunk in response.iter_content(chunk_size=chunk_size):
|
|
575
702
|
f_stream.write(chunk)
|
|
576
|
-
progress.
|
|
703
|
+
progress.add_transferred_chunk(len(chunk))
|
|
577
704
|
|
|
578
705
|
def download_file(self, endpoint, filepath, chunk_size=None, progress=None):
|
|
579
706
|
"""Download file from AYON server.
|
|
@@ -618,7 +745,7 @@ class ServerAPIBase(object):
|
|
|
618
745
|
raise
|
|
619
746
|
|
|
620
747
|
finally:
|
|
621
|
-
progress.
|
|
748
|
+
progress.set_transfer_done()
|
|
622
749
|
|
|
623
750
|
def _upload_file(self, url, filepath, progress):
|
|
624
751
|
kwargs = {}
|
|
@@ -635,7 +762,7 @@ class ServerAPIBase(object):
|
|
|
635
762
|
progress.set_content_size(size)
|
|
636
763
|
response = post_func(url, data=stream, **kwargs)
|
|
637
764
|
response.raise_for_status()
|
|
638
|
-
progress.
|
|
765
|
+
progress.set_transferred_size(size)
|
|
639
766
|
|
|
640
767
|
def upload_file(self, endpoint, filepath, progress=None):
|
|
641
768
|
"""Upload file to server.
|
|
@@ -673,7 +800,7 @@ class ServerAPIBase(object):
|
|
|
673
800
|
raise
|
|
674
801
|
|
|
675
802
|
finally:
|
|
676
|
-
progress.
|
|
803
|
+
progress.set_transfer_done()
|
|
677
804
|
|
|
678
805
|
def trigger_server_restart(self):
|
|
679
806
|
result = self.post("system/restart")
|
|
@@ -889,8 +1016,7 @@ class ServerAPIBase(object):
|
|
|
889
1016
|
if details:
|
|
890
1017
|
endpoint += "?details=1"
|
|
891
1018
|
response = self.get(endpoint)
|
|
892
|
-
|
|
893
|
-
raise ServerError(response.text)
|
|
1019
|
+
response.raise_for_status()
|
|
894
1020
|
return response.data
|
|
895
1021
|
|
|
896
1022
|
def download_addon_private_file(
|
|
@@ -1106,8 +1232,7 @@ class ServerAPIBase(object):
|
|
|
1106
1232
|
result = self.get(
|
|
1107
1233
|
"addons/{}/{}/settings".format(addon_name, addon_version)
|
|
1108
1234
|
)
|
|
1109
|
-
|
|
1110
|
-
raise ServerError(result.text)
|
|
1235
|
+
result.raise_for_status()
|
|
1111
1236
|
return result.data
|
|
1112
1237
|
|
|
1113
1238
|
def get_addon_project_settings(
|
|
@@ -1118,8 +1243,7 @@ class ServerAPIBase(object):
|
|
|
1118
1243
|
addon_name, addon_version, project_name
|
|
1119
1244
|
)
|
|
1120
1245
|
)
|
|
1121
|
-
|
|
1122
|
-
raise ServerError(result.text)
|
|
1246
|
+
result.raise_for_status()
|
|
1123
1247
|
return result.data
|
|
1124
1248
|
|
|
1125
1249
|
def get_addon_settings(self, addon_name, addon_version, project_name=None):
|
|
@@ -1160,7 +1284,7 @@ class ServerAPIBase(object):
|
|
|
1160
1284
|
returned if 'None' is passed.
|
|
1161
1285
|
|
|
1162
1286
|
Returns:
|
|
1163
|
-
|
|
1287
|
+
Generator[Dict[str, Any]]: Available projects.
|
|
1164
1288
|
"""
|
|
1165
1289
|
|
|
1166
1290
|
for project_name in self.get_project_names(active, library):
|
|
@@ -1223,8 +1347,7 @@ class ServerAPIBase(object):
|
|
|
1223
1347
|
]))
|
|
1224
1348
|
|
|
1225
1349
|
response = self.get("projects{}".format(query), **query_keys)
|
|
1226
|
-
|
|
1227
|
-
response.status
|
|
1350
|
+
response.raise_for_status()
|
|
1228
1351
|
data = response.data
|
|
1229
1352
|
project_names = []
|
|
1230
1353
|
if data:
|
|
@@ -1248,7 +1371,7 @@ class ServerAPIBase(object):
|
|
|
1248
1371
|
on entity will have 'None' value.
|
|
1249
1372
|
|
|
1250
1373
|
Returns:
|
|
1251
|
-
|
|
1374
|
+
Generator[Dict[str, Any]]: Queried projects.
|
|
1252
1375
|
"""
|
|
1253
1376
|
|
|
1254
1377
|
if fields is None:
|
|
@@ -1357,11 +1480,11 @@ class ServerAPIBase(object):
|
|
|
1357
1480
|
if 'None' is passed.
|
|
1358
1481
|
|
|
1359
1482
|
Returns:
|
|
1360
|
-
|
|
1483
|
+
Generator[dict[str, Any]]: Queried folder entities.
|
|
1361
1484
|
"""
|
|
1362
1485
|
|
|
1363
1486
|
if not project_name:
|
|
1364
|
-
return
|
|
1487
|
+
return
|
|
1365
1488
|
|
|
1366
1489
|
filters = {
|
|
1367
1490
|
"projectName": project_name
|
|
@@ -1369,25 +1492,25 @@ class ServerAPIBase(object):
|
|
|
1369
1492
|
if folder_ids is not None:
|
|
1370
1493
|
folder_ids = set(folder_ids)
|
|
1371
1494
|
if not folder_ids:
|
|
1372
|
-
return
|
|
1495
|
+
return
|
|
1373
1496
|
filters["folderIds"] = list(folder_ids)
|
|
1374
1497
|
|
|
1375
1498
|
if folder_paths is not None:
|
|
1376
1499
|
folder_paths = set(folder_paths)
|
|
1377
1500
|
if not folder_paths:
|
|
1378
|
-
return
|
|
1501
|
+
return
|
|
1379
1502
|
filters["folderPaths"] = list(folder_paths)
|
|
1380
1503
|
|
|
1381
1504
|
if folder_names is not None:
|
|
1382
1505
|
folder_names = set(folder_names)
|
|
1383
1506
|
if not folder_names:
|
|
1384
|
-
return
|
|
1507
|
+
return
|
|
1385
1508
|
filters["folderNames"] = list(folder_names)
|
|
1386
1509
|
|
|
1387
1510
|
if parent_ids is not None:
|
|
1388
1511
|
parent_ids = set(parent_ids)
|
|
1389
1512
|
if not parent_ids:
|
|
1390
|
-
return
|
|
1513
|
+
return
|
|
1391
1514
|
if None in parent_ids:
|
|
1392
1515
|
# Replace 'None' with '"root"' which is used during GraphQl
|
|
1393
1516
|
# query for parent ids filter for folders without folder
|
|
@@ -1448,7 +1571,7 @@ class ServerAPIBase(object):
|
|
|
1448
1571
|
own_attributes=False
|
|
1449
1572
|
):
|
|
1450
1573
|
if not project_name:
|
|
1451
|
-
return
|
|
1574
|
+
return
|
|
1452
1575
|
|
|
1453
1576
|
filters = {
|
|
1454
1577
|
"projectName": project_name
|
|
@@ -1457,25 +1580,25 @@ class ServerAPIBase(object):
|
|
|
1457
1580
|
if task_ids is not None:
|
|
1458
1581
|
task_ids = set(task_ids)
|
|
1459
1582
|
if not task_ids:
|
|
1460
|
-
return
|
|
1583
|
+
return
|
|
1461
1584
|
filters["taskIds"] = list(task_ids)
|
|
1462
1585
|
|
|
1463
1586
|
if task_names is not None:
|
|
1464
1587
|
task_names = set(task_names)
|
|
1465
1588
|
if not task_names:
|
|
1466
|
-
return
|
|
1589
|
+
return
|
|
1467
1590
|
filters["taskNames"] = list(task_names)
|
|
1468
1591
|
|
|
1469
1592
|
if task_types is not None:
|
|
1470
1593
|
task_types = set(task_types)
|
|
1471
1594
|
if not task_types:
|
|
1472
|
-
return
|
|
1595
|
+
return
|
|
1473
1596
|
filters["taskTypes"] = list(task_types)
|
|
1474
1597
|
|
|
1475
1598
|
if folder_ids is not None:
|
|
1476
1599
|
folder_ids = set(folder_ids)
|
|
1477
1600
|
if not folder_ids:
|
|
1478
|
-
return
|
|
1601
|
+
return
|
|
1479
1602
|
filters["folderIds"] = list(folder_ids)
|
|
1480
1603
|
|
|
1481
1604
|
if not fields:
|
|
@@ -1633,6 +1756,20 @@ class ServerAPIBase(object):
|
|
|
1633
1756
|
for folder in folders
|
|
1634
1757
|
}
|
|
1635
1758
|
|
|
1759
|
+
def _filter_subset(
|
|
1760
|
+
self, project_name, subset, active, own_attributes, use_rest
|
|
1761
|
+
):
|
|
1762
|
+
if active is not None and subset["active"] is not active:
|
|
1763
|
+
return None
|
|
1764
|
+
|
|
1765
|
+
if use_rest:
|
|
1766
|
+
subset = self.get_rest_subset(project_name, subset["id"])
|
|
1767
|
+
|
|
1768
|
+
if own_attributes:
|
|
1769
|
+
fill_own_attribs(subset)
|
|
1770
|
+
|
|
1771
|
+
return subset
|
|
1772
|
+
|
|
1636
1773
|
def get_subsets(
|
|
1637
1774
|
self,
|
|
1638
1775
|
project_name,
|
|
@@ -1645,24 +1782,24 @@ class ServerAPIBase(object):
|
|
|
1645
1782
|
own_attributes=False
|
|
1646
1783
|
):
|
|
1647
1784
|
if not project_name:
|
|
1648
|
-
return
|
|
1785
|
+
return
|
|
1649
1786
|
|
|
1650
1787
|
if subset_ids is not None:
|
|
1651
1788
|
subset_ids = set(subset_ids)
|
|
1652
1789
|
if not subset_ids:
|
|
1653
|
-
return
|
|
1790
|
+
return
|
|
1654
1791
|
|
|
1655
1792
|
filter_subset_names = None
|
|
1656
1793
|
if subset_names is not None:
|
|
1657
1794
|
filter_subset_names = set(subset_names)
|
|
1658
1795
|
if not filter_subset_names:
|
|
1659
|
-
return
|
|
1796
|
+
return
|
|
1660
1797
|
|
|
1661
1798
|
filter_folder_ids = None
|
|
1662
1799
|
if folder_ids is not None:
|
|
1663
1800
|
filter_folder_ids = set(folder_ids)
|
|
1664
1801
|
if not filter_folder_ids:
|
|
1665
|
-
return
|
|
1802
|
+
return
|
|
1666
1803
|
|
|
1667
1804
|
# This will disable 'folder_ids' and 'subset_names' filters
|
|
1668
1805
|
# - maybe could be enhanced in future?
|
|
@@ -1676,7 +1813,7 @@ class ServerAPIBase(object):
|
|
|
1676
1813
|
filter_subset_names |= set(names)
|
|
1677
1814
|
|
|
1678
1815
|
if not filter_subset_names or not filter_folder_ids:
|
|
1679
|
-
return
|
|
1816
|
+
return
|
|
1680
1817
|
|
|
1681
1818
|
# Convert fields and add minimum required fields
|
|
1682
1819
|
if fields:
|
|
@@ -1720,35 +1857,30 @@ class ServerAPIBase(object):
|
|
|
1720
1857
|
parsed_data = query.query(self)
|
|
1721
1858
|
|
|
1722
1859
|
subsets = parsed_data.get("project", {}).get("subsets", [])
|
|
1723
|
-
if active is not None or own_attributes:
|
|
1724
|
-
_subsets = []
|
|
1725
|
-
for subset in subsets:
|
|
1726
|
-
if active is not None and subset["active"] is not active:
|
|
1727
|
-
continue
|
|
1728
|
-
|
|
1729
|
-
if use_rest:
|
|
1730
|
-
subset = self.get_rest_subset(project_name, subset["id"])
|
|
1731
|
-
|
|
1732
|
-
if own_attributes:
|
|
1733
|
-
fill_own_attribs(subset)
|
|
1734
|
-
_subsets.append(subset)
|
|
1735
|
-
subsets = _subsets
|
|
1736
|
-
|
|
1737
1860
|
# Filter subsets by 'names_by_folder_ids'
|
|
1738
1861
|
if names_by_folder_ids:
|
|
1739
1862
|
subsets_by_folder_id = collections.defaultdict(list)
|
|
1740
1863
|
for subset in subsets:
|
|
1741
|
-
|
|
1742
|
-
|
|
1864
|
+
filtered_subset = self._filter_subset(
|
|
1865
|
+
project_name, subset, active, own_attributes, use_rest
|
|
1866
|
+
)
|
|
1867
|
+
if filtered_subset is not None:
|
|
1868
|
+
folder_id = filtered_subset["folderId"]
|
|
1869
|
+
subsets_by_folder_id[folder_id].append(filtered_subset)
|
|
1743
1870
|
|
|
1744
|
-
filtered_subsets = []
|
|
1745
1871
|
for folder_id, names in names_by_folder_ids.items():
|
|
1746
1872
|
for folder_subset in subsets_by_folder_id[folder_id]:
|
|
1747
1873
|
if folder_subset["name"] in names:
|
|
1748
|
-
|
|
1749
|
-
|
|
1874
|
+
yield folder_subset
|
|
1875
|
+
|
|
1876
|
+
else:
|
|
1877
|
+
for subset in subsets:
|
|
1878
|
+
filtered_subset = self._filter_subset(
|
|
1879
|
+
project_name, subset, active, own_attributes, use_rest
|
|
1880
|
+
)
|
|
1881
|
+
if filtered_subset is not None:
|
|
1882
|
+
yield filtered_subset
|
|
1750
1883
|
|
|
1751
|
-
return list(subsets)
|
|
1752
1884
|
|
|
1753
1885
|
def get_subset_by_id(
|
|
1754
1886
|
self,
|
|
@@ -1845,7 +1977,7 @@ class ServerAPIBase(object):
|
|
|
1845
1977
|
if 'None' is passed.
|
|
1846
1978
|
|
|
1847
1979
|
Returns:
|
|
1848
|
-
|
|
1980
|
+
Generator[Dict[str, Any]]: Queried version entities.
|
|
1849
1981
|
"""
|
|
1850
1982
|
|
|
1851
1983
|
if not fields:
|
|
@@ -1872,24 +2004,24 @@ class ServerAPIBase(object):
|
|
|
1872
2004
|
if version_ids is not None:
|
|
1873
2005
|
version_ids = set(version_ids)
|
|
1874
2006
|
if not version_ids:
|
|
1875
|
-
return
|
|
2007
|
+
return
|
|
1876
2008
|
filters["versionIds"] = list(version_ids)
|
|
1877
2009
|
|
|
1878
2010
|
if subset_ids is not None:
|
|
1879
2011
|
subset_ids = set(subset_ids)
|
|
1880
2012
|
if not subset_ids:
|
|
1881
|
-
return
|
|
2013
|
+
return
|
|
1882
2014
|
filters["subsetIds"] = list(subset_ids)
|
|
1883
2015
|
|
|
1884
2016
|
# TODO versions can't be used as fitler at this moment!
|
|
1885
2017
|
if versions is not None:
|
|
1886
2018
|
versions = set(versions)
|
|
1887
2019
|
if not versions:
|
|
1888
|
-
return
|
|
2020
|
+
return
|
|
1889
2021
|
filters["versions"] = list(versions)
|
|
1890
2022
|
|
|
1891
2023
|
if not hero and not standard:
|
|
1892
|
-
return
|
|
2024
|
+
return
|
|
1893
2025
|
|
|
1894
2026
|
queries = []
|
|
1895
2027
|
# Add filters based on 'hero' and 'standard'
|
|
@@ -2158,7 +2290,7 @@ class ServerAPIBase(object):
|
|
|
2158
2290
|
passed.
|
|
2159
2291
|
|
|
2160
2292
|
Returns:
|
|
2161
|
-
|
|
2293
|
+
Generator[Dict[str, Any]]: Queried representation entities.
|
|
2162
2294
|
"""
|
|
2163
2295
|
|
|
2164
2296
|
if not fields:
|
|
@@ -2183,7 +2315,7 @@ class ServerAPIBase(object):
|
|
|
2183
2315
|
if representation_ids is not None:
|
|
2184
2316
|
representation_ids = set(representation_ids)
|
|
2185
2317
|
if not representation_ids:
|
|
2186
|
-
return
|
|
2318
|
+
return
|
|
2187
2319
|
filters["representationIds"] = list(representation_ids)
|
|
2188
2320
|
|
|
2189
2321
|
version_ids_filter = None
|
|
@@ -2196,18 +2328,18 @@ class ServerAPIBase(object):
|
|
|
2196
2328
|
representaion_names_filter |= set(names)
|
|
2197
2329
|
|
|
2198
2330
|
if not version_ids_filter or not representaion_names_filter:
|
|
2199
|
-
return
|
|
2331
|
+
return
|
|
2200
2332
|
|
|
2201
2333
|
else:
|
|
2202
2334
|
if representation_names is not None:
|
|
2203
2335
|
representaion_names_filter = set(representation_names)
|
|
2204
2336
|
if not representaion_names_filter:
|
|
2205
|
-
return
|
|
2337
|
+
return
|
|
2206
2338
|
|
|
2207
2339
|
if version_ids is not None:
|
|
2208
2340
|
version_ids_filter = set(version_ids)
|
|
2209
2341
|
if not version_ids_filter:
|
|
2210
|
-
return
|
|
2342
|
+
return
|
|
2211
2343
|
|
|
2212
2344
|
if version_ids_filter:
|
|
2213
2345
|
filters["versionIds"] = list(version_ids_filter)
|
|
@@ -2332,19 +2464,19 @@ class ServerAPIBase(object):
|
|
|
2332
2464
|
if task_ids is not None:
|
|
2333
2465
|
task_ids = set(task_ids)
|
|
2334
2466
|
if not task_ids:
|
|
2335
|
-
return
|
|
2467
|
+
return
|
|
2336
2468
|
filters["taskIds"] = list(task_ids)
|
|
2337
2469
|
|
|
2338
2470
|
if paths is not None:
|
|
2339
2471
|
paths = set(paths)
|
|
2340
2472
|
if not paths:
|
|
2341
|
-
return
|
|
2473
|
+
return
|
|
2342
2474
|
filters["paths"] = list(paths)
|
|
2343
2475
|
|
|
2344
2476
|
if workfile_ids is not None:
|
|
2345
2477
|
workfile_ids = set(workfile_ids)
|
|
2346
2478
|
if not workfile_ids:
|
|
2347
|
-
return
|
|
2479
|
+
return
|
|
2348
2480
|
filters["workfileIds"] = list(workfile_ids)
|
|
2349
2481
|
|
|
2350
2482
|
if not fields:
|
|
@@ -2722,4 +2854,5 @@ class ServerAPIBase(object):
|
|
|
2722
2854
|
operation_id,
|
|
2723
2855
|
json.dumps(body_by_id[operation_id], indent=4),
|
|
2724
2856
|
op_result["error"],
|
|
2725
|
-
))
|
|
2857
|
+
))
|
|
2858
|
+
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import os
|
|
2
|
+
import socket
|
|
3
|
+
|
|
2
4
|
from .constants import (
|
|
3
5
|
SERVER_URL_ENV_KEY,
|
|
4
6
|
SERVER_TOKEN_ENV_KEY,
|
|
5
7
|
)
|
|
6
8
|
from .server import ServerAPIBase
|
|
9
|
+
from .exceptions import FailedServiceInit
|
|
7
10
|
|
|
8
11
|
|
|
9
12
|
class ServerAPI(ServerAPIBase):
|
|
@@ -65,6 +68,27 @@ class GlobalContext:
|
|
|
65
68
|
|
|
66
69
|
_connection = None
|
|
67
70
|
|
|
71
|
+
@classmethod
|
|
72
|
+
def is_connection_created(cls):
|
|
73
|
+
return cls._connection is not None
|
|
74
|
+
|
|
75
|
+
@classmethod
|
|
76
|
+
def change_token(cls, url, token):
|
|
77
|
+
ServerAPI.set_environments(url, token)
|
|
78
|
+
if cls._connection is None:
|
|
79
|
+
return
|
|
80
|
+
|
|
81
|
+
if cls._connection.get_base_url() == url:
|
|
82
|
+
cls._connection.set_token(token)
|
|
83
|
+
else:
|
|
84
|
+
cls.close_connection()
|
|
85
|
+
|
|
86
|
+
@classmethod
|
|
87
|
+
def close_connection(cls):
|
|
88
|
+
if cls._connection is not None:
|
|
89
|
+
cls._connection.close_session()
|
|
90
|
+
cls._connection = None
|
|
91
|
+
|
|
68
92
|
@classmethod
|
|
69
93
|
def get_server_api_connection(cls):
|
|
70
94
|
if cls._connection is None:
|
|
@@ -72,6 +96,134 @@ class GlobalContext:
|
|
|
72
96
|
return cls._connection
|
|
73
97
|
|
|
74
98
|
|
|
99
|
+
class ServiceContext:
|
|
100
|
+
"""Helper for services running under server.
|
|
101
|
+
|
|
102
|
+
When service is running from server the process receives information about
|
|
103
|
+
connection from environment variables. This class helps to initialize the
|
|
104
|
+
values without knowing environment variables (that may change over time).
|
|
105
|
+
|
|
106
|
+
All what must be done is to call 'init_service' function/method. The
|
|
107
|
+
arguments are for cases when the service is running in specific environment
|
|
108
|
+
and their values are e.g. loaded from private file or for testing purposes.
|
|
109
|
+
"""
|
|
110
|
+
|
|
111
|
+
token = None
|
|
112
|
+
server_url = None
|
|
113
|
+
addon_name = None
|
|
114
|
+
addon_version = None
|
|
115
|
+
service_name = None
|
|
116
|
+
|
|
117
|
+
@staticmethod
|
|
118
|
+
def get_value_from_envs(env_keys, value=None):
|
|
119
|
+
if value:
|
|
120
|
+
return value
|
|
121
|
+
|
|
122
|
+
for env_key in env_keys:
|
|
123
|
+
value = os.environ.get(env_key)
|
|
124
|
+
if value:
|
|
125
|
+
break
|
|
126
|
+
return value
|
|
127
|
+
|
|
128
|
+
@classmethod
|
|
129
|
+
def init_service(
|
|
130
|
+
cls,
|
|
131
|
+
token=None,
|
|
132
|
+
server_url=None,
|
|
133
|
+
addon_name=None,
|
|
134
|
+
addon_version=None,
|
|
135
|
+
service_name=None,
|
|
136
|
+
connect=True
|
|
137
|
+
):
|
|
138
|
+
token = cls.get_value_from_envs(
|
|
139
|
+
("AY_API_KEY", "AYON_TOKEN"),
|
|
140
|
+
token
|
|
141
|
+
)
|
|
142
|
+
server_url = cls.get_value_from_envs(
|
|
143
|
+
("AY_SERVER_URL", "AYON_SERVER_URL"),
|
|
144
|
+
server_url
|
|
145
|
+
)
|
|
146
|
+
if not server_url:
|
|
147
|
+
raise FailedServiceInit("URL to server is not set")
|
|
148
|
+
|
|
149
|
+
if not token:
|
|
150
|
+
raise FailedServiceInit(
|
|
151
|
+
"Token to server {} is not set".format(server_url)
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
addon_name = cls.get_value_from_envs(
|
|
155
|
+
("AY_ADDON_NAME", "AYON_ADDON_NAME"),
|
|
156
|
+
addon_name
|
|
157
|
+
)
|
|
158
|
+
addon_version = cls.get_value_from_envs(
|
|
159
|
+
("AY_ADDON_VERSION", "AYON_ADDON_VERSION"),
|
|
160
|
+
addon_version
|
|
161
|
+
)
|
|
162
|
+
service_name = cls.get_value_from_envs(
|
|
163
|
+
("AY_SERVICE_NAME", "AYON_SERVICE_NAME"),
|
|
164
|
+
service_name
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
cls.token = token
|
|
168
|
+
cls.server_url = server_url
|
|
169
|
+
cls.addon_name = addon_name
|
|
170
|
+
cls.addon_version = addon_version
|
|
171
|
+
cls.service_name = service_name or socket.gethostname()
|
|
172
|
+
|
|
173
|
+
# Make sure required environments for ServerAPI are set
|
|
174
|
+
ServerAPI.set_environments(cls.server_url, cls.token)
|
|
175
|
+
|
|
176
|
+
if connect:
|
|
177
|
+
print("Connecting to server \"{}\"".format(server_url))
|
|
178
|
+
con = GlobalContext.get_server_api_connection()
|
|
179
|
+
user = con.get_user()
|
|
180
|
+
print("Logged in as user \"{}\"".format(user["name"]))
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def init_service(*args, **kwargs):
|
|
184
|
+
ServiceContext.init_service(*args, **kwargs)
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def is_connection_created():
|
|
188
|
+
"""Is global connection created.
|
|
189
|
+
|
|
190
|
+
Returns:
|
|
191
|
+
bool: True if connection was connected.
|
|
192
|
+
"""
|
|
193
|
+
|
|
194
|
+
return GlobalContext.is_connection_created()
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def close_connection():
|
|
198
|
+
"""Close global connection if is connected."""
|
|
199
|
+
|
|
200
|
+
GlobalContext.close_connection()
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def change_token(url, token):
|
|
204
|
+
"""Change connection token for url.
|
|
205
|
+
|
|
206
|
+
This function can be also used to change url.
|
|
207
|
+
|
|
208
|
+
Args:
|
|
209
|
+
url (str): Server url.
|
|
210
|
+
token (str): API key token.
|
|
211
|
+
"""
|
|
212
|
+
|
|
213
|
+
GlobalContext.change_token(url, token)
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def set_environments(url, token):
|
|
217
|
+
"""Set global environments for global connection.
|
|
218
|
+
|
|
219
|
+
Args:
|
|
220
|
+
url (Union[str, None]): Url to server or None to unset environments.
|
|
221
|
+
token (Union[str, None]): API key token to be used for connection.
|
|
222
|
+
"""
|
|
223
|
+
|
|
224
|
+
ServerAPI.set_environments(url, token)
|
|
225
|
+
|
|
226
|
+
|
|
75
227
|
def get_server_api_connection():
|
|
76
228
|
"""Access to global scope object of ServerAPI.
|
|
77
229
|
|
|
@@ -145,6 +297,26 @@ def delete(*args, **kwargs):
|
|
|
145
297
|
return con.delete(*args, **kwargs)
|
|
146
298
|
|
|
147
299
|
|
|
300
|
+
def get_event(*args, **kwargs):
|
|
301
|
+
con = get_server_api_connection()
|
|
302
|
+
return con.get_event(*args, **kwargs)
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
def dispatch_event(*args, **kwargs):
|
|
306
|
+
con = get_server_api_connection()
|
|
307
|
+
return con.dispatch_event(*args, **kwargs)
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
def update_event(*args, **kwargs):
|
|
311
|
+
con = get_server_api_connection()
|
|
312
|
+
return con.update_event(*args, **kwargs)
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
def enroll_event_job(*args, **kwargs):
|
|
316
|
+
con = get_server_api_connection()
|
|
317
|
+
return con.enroll_event_job(*args, **kwargs)
|
|
318
|
+
|
|
319
|
+
|
|
148
320
|
def download_file(*args, **kwargs):
|
|
149
321
|
con = get_server_api_connection()
|
|
150
322
|
return con.download_file(*args, **kwargs)
|
|
@@ -1,15 +1,21 @@
|
|
|
1
|
+
import re
|
|
1
2
|
import datetime
|
|
2
3
|
import uuid
|
|
4
|
+
import string
|
|
3
5
|
try:
|
|
4
6
|
from urlparse import urlparse
|
|
5
7
|
except ImportError:
|
|
6
8
|
from urllib.parse import urlparse
|
|
7
9
|
|
|
8
10
|
import requests
|
|
11
|
+
import unidecode
|
|
12
|
+
|
|
9
13
|
|
|
10
14
|
from .exceptions import UrlError
|
|
11
15
|
|
|
12
16
|
REMOVED_VALUE = object()
|
|
17
|
+
SLUGIFY_WHITELIST = string.ascii_letters + string.digits
|
|
18
|
+
SLUGIFY_SEP_WHITELIST = " ,./\\;:!|*^#@~+-_="
|
|
13
19
|
|
|
14
20
|
|
|
15
21
|
def create_entity_id():
|
|
@@ -47,6 +53,59 @@ def entity_data_json_default(value):
|
|
|
47
53
|
)
|
|
48
54
|
|
|
49
55
|
|
|
56
|
+
def slugify_string(
|
|
57
|
+
input_string,
|
|
58
|
+
separator="_",
|
|
59
|
+
slug_whitelist=SLUGIFY_WHITELIST,
|
|
60
|
+
split_chars=SLUGIFY_SEP_WHITELIST,
|
|
61
|
+
min_length=1,
|
|
62
|
+
lower=False,
|
|
63
|
+
make_set=False,
|
|
64
|
+
):
|
|
65
|
+
"""Slugify a text string.
|
|
66
|
+
|
|
67
|
+
This function removes transliterates input string to ASCII, removes
|
|
68
|
+
special characters and use join resulting elements using
|
|
69
|
+
specified separator.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
input_string (str): Input string to slugify
|
|
73
|
+
separator (str): A string used to separate returned elements
|
|
74
|
+
(default: "_")
|
|
75
|
+
slug_whitelist (str): Characters allowed in the output
|
|
76
|
+
(default: ascii letters, digits and the separator)
|
|
77
|
+
split_chars (str): Set of characters used for word splitting
|
|
78
|
+
(there is a sane default)
|
|
79
|
+
lower (bool): Convert to lower-case (default: False)
|
|
80
|
+
make_set (bool): Return "set" object instead of string.
|
|
81
|
+
min_length (int): Minimal length of an element (word).
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
Union[str, Set[str]]: Based on 'make_set' value returns slugified
|
|
85
|
+
string.
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
tmp_string = unidecode.unidecode(input_string)
|
|
89
|
+
if lower:
|
|
90
|
+
tmp_string = tmp_string.lower()
|
|
91
|
+
|
|
92
|
+
parts = [
|
|
93
|
+
# Remove all characters that are not in whitelist
|
|
94
|
+
re.sub("[^{}]".format(re.escape(slug_whitelist)), "", part)
|
|
95
|
+
# Split text into part by split characters
|
|
96
|
+
for part in re.split("[{}]".format(re.escape(split_chars)), tmp_string)
|
|
97
|
+
]
|
|
98
|
+
# Filter text parts by length
|
|
99
|
+
filtered_parts = [
|
|
100
|
+
part
|
|
101
|
+
for part in parts
|
|
102
|
+
if len(part) >= min_length
|
|
103
|
+
]
|
|
104
|
+
if make_set:
|
|
105
|
+
return set(filtered_parts)
|
|
106
|
+
return separator.join(filtered_parts)
|
|
107
|
+
|
|
108
|
+
|
|
50
109
|
def failed_json_default(value):
|
|
51
110
|
return "< Failed value {} > {}".format(type(value), str(value))
|
|
52
111
|
|
|
@@ -272,8 +331,8 @@ class TransferProgress:
|
|
|
272
331
|
|
|
273
332
|
def __init__(self):
|
|
274
333
|
self._started = False
|
|
275
|
-
self.
|
|
276
|
-
self.
|
|
334
|
+
self._transfer_done = False
|
|
335
|
+
self._transfered = 0
|
|
277
336
|
self._content_size = None
|
|
278
337
|
|
|
279
338
|
self._failed = False
|
|
@@ -298,15 +357,15 @@ class TransferProgress:
|
|
|
298
357
|
raise ValueError("Progress already started")
|
|
299
358
|
self._started = True
|
|
300
359
|
|
|
301
|
-
def
|
|
302
|
-
return self.
|
|
360
|
+
def get_transfer_done(self):
|
|
361
|
+
return self._transfer_done
|
|
303
362
|
|
|
304
|
-
def
|
|
305
|
-
if self.
|
|
363
|
+
def set_transfer_done(self):
|
|
364
|
+
if self._transfer_done:
|
|
306
365
|
raise ValueError("Progress was already marked as done")
|
|
307
366
|
if not self._started:
|
|
308
367
|
raise ValueError("Progress didn't start yet")
|
|
309
|
-
self.
|
|
368
|
+
self._transfer_done = True
|
|
310
369
|
|
|
311
370
|
def get_failed(self):
|
|
312
371
|
return self._failed
|
|
@@ -318,14 +377,14 @@ class TransferProgress:
|
|
|
318
377
|
self._fail_reason = reason
|
|
319
378
|
self._failed = True
|
|
320
379
|
|
|
321
|
-
def
|
|
322
|
-
return self.
|
|
380
|
+
def get_transferred_size(self):
|
|
381
|
+
return self._transfered
|
|
323
382
|
|
|
324
|
-
def
|
|
325
|
-
self.
|
|
383
|
+
def set_transferred_size(self, transfered):
|
|
384
|
+
self._transfered = transfered
|
|
326
385
|
|
|
327
|
-
def
|
|
328
|
-
self.
|
|
386
|
+
def add_transferred_chunk(self, chunk_size):
|
|
387
|
+
self._transfered += chunk_size
|
|
329
388
|
|
|
330
389
|
def get_source_url(self):
|
|
331
390
|
return self._source_url
|
|
@@ -350,17 +409,17 @@ class TransferProgress:
|
|
|
350
409
|
return True
|
|
351
410
|
|
|
352
411
|
@property
|
|
353
|
-
def
|
|
412
|
+
def transfer_progress(self):
|
|
354
413
|
if self._content_size is None:
|
|
355
414
|
return None
|
|
356
|
-
return (self.
|
|
415
|
+
return (self._transfered * 100.0) / float(self._content_size)
|
|
357
416
|
|
|
358
417
|
content_size = property(get_content_size, set_content_size)
|
|
359
418
|
started = property(get_started)
|
|
360
|
-
|
|
419
|
+
transfer_done = property(get_transfer_done)
|
|
361
420
|
failed = property(get_failed)
|
|
362
421
|
fail_reason = property(get_fail_reason)
|
|
363
422
|
source_url = property(get_source_url, set_source_url)
|
|
364
423
|
destination_url = property(get_destination_url, set_destination_url)
|
|
365
424
|
content_size = property(get_content_size, set_content_size)
|
|
366
|
-
|
|
425
|
+
transferred_size = property(get_transferred_size, set_transferred_size)
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""Package declaring Python API for Ayon server."""
|
|
2
|
-
__version__ = "0.1.
|
|
2
|
+
__version__ = "0.1.9"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "ayon_api"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.9"
|
|
4
4
|
description = "Python api for AYON server"
|
|
5
5
|
authors = ["ynput.io <info@ynput.io>"]
|
|
6
6
|
|
|
7
7
|
[tool.poetry.dependencies]
|
|
8
8
|
requests = "^2.28.1"
|
|
9
9
|
six = "^1.15"
|
|
10
|
-
|
|
10
|
+
Unidecode = "^1.3"
|
|
11
|
+
appdirs = "^1.4"
|
|
11
12
|
|
|
12
13
|
[tool.poetry.dev-dependencies]
|
|
13
14
|
pytest = "^5.2"
|
|
@@ -30,9 +30,8 @@ setup(
|
|
|
30
30
|
install_requires=[
|
|
31
31
|
"requests >= 2.27.1",
|
|
32
32
|
"six >= 1.15",
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
"appdirs @ git+https://github.com/ActiveState/appdirs.git@master"
|
|
33
|
+
"Unidecode >= 1.3.6",
|
|
34
|
+
"appdirs >=1, <2",
|
|
36
35
|
],
|
|
37
36
|
keywords=["AYON", "ynput", "OpenPype", "vfx"],
|
|
38
37
|
)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
appdirs @ git+https://github.com/ActiveState/appdirs.git@master
|
|
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
|
|
File without changes
|