ayon-python-api 1.2.23__py3-none-any.whl → 1.2.24__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/_api.py +4 -0
- ayon_api/_api_helpers/dependency_packages.py +6 -0
- ayon_api/graphql.py +38 -34
- ayon_api/server_api.py +38 -9
- ayon_api/utils.py +2 -2
- ayon_api/version.py +1 -1
- {ayon_python_api-1.2.23.dist-info → ayon_python_api-1.2.24.dist-info}/METADATA +1 -1
- {ayon_python_api-1.2.23.dist-info → ayon_python_api-1.2.24.dist-info}/RECORD +11 -11
- {ayon_python_api-1.2.23.dist-info → ayon_python_api-1.2.24.dist-info}/WHEEL +0 -0
- {ayon_python_api-1.2.23.dist-info → ayon_python_api-1.2.24.dist-info}/licenses/LICENSE +0 -0
- {ayon_python_api-1.2.23.dist-info → ayon_python_api-1.2.24.dist-info}/top_level.txt +0 -0
ayon_api/_api.py
CHANGED
|
@@ -1943,6 +1943,7 @@ def create_dependency_package(
|
|
|
1943
1943
|
checksum: str,
|
|
1944
1944
|
checksum_algorithm: str,
|
|
1945
1945
|
file_size: int,
|
|
1946
|
+
python_version: str | None = None,
|
|
1946
1947
|
sources: Optional[list[dict[str, Any]]] = None,
|
|
1947
1948
|
platform_name: Optional[str] = None,
|
|
1948
1949
|
) -> None:
|
|
@@ -1968,6 +1969,8 @@ def create_dependency_package(
|
|
|
1968
1969
|
checksum (str): Checksum of archive file where dependencies are.
|
|
1969
1970
|
checksum_algorithm (str): Algorithm used to calculate checksum.
|
|
1970
1971
|
file_size (Optional[int]): Size of file.
|
|
1972
|
+
python_version (str | None): Python version for which
|
|
1973
|
+
is dependency package created.
|
|
1971
1974
|
sources (Optional[list[dict[str, Any]]]): Information about
|
|
1972
1975
|
sources from where it is possible to get file.
|
|
1973
1976
|
platform_name (Optional[str]): Name of platform for which is
|
|
@@ -1984,6 +1987,7 @@ def create_dependency_package(
|
|
|
1984
1987
|
checksum=checksum,
|
|
1985
1988
|
checksum_algorithm=checksum_algorithm,
|
|
1986
1989
|
file_size=file_size,
|
|
1990
|
+
python_version=python_version,
|
|
1987
1991
|
sources=sources,
|
|
1988
1992
|
platform_name=platform_name,
|
|
1989
1993
|
)
|
|
@@ -57,6 +57,7 @@ class DependencyPackagesAPI(BaseServerAPI):
|
|
|
57
57
|
checksum: str,
|
|
58
58
|
checksum_algorithm: str,
|
|
59
59
|
file_size: int,
|
|
60
|
+
python_version: str | None = None,
|
|
60
61
|
sources: Optional[list[dict[str, Any]]] = None,
|
|
61
62
|
platform_name: Optional[str] = None,
|
|
62
63
|
) -> None:
|
|
@@ -82,6 +83,8 @@ class DependencyPackagesAPI(BaseServerAPI):
|
|
|
82
83
|
checksum (str): Checksum of archive file where dependencies are.
|
|
83
84
|
checksum_algorithm (str): Algorithm used to calculate checksum.
|
|
84
85
|
file_size (Optional[int]): Size of file.
|
|
86
|
+
python_version (str | None): Python version for which
|
|
87
|
+
is dependency package created.
|
|
85
88
|
sources (Optional[list[dict[str, Any]]]): Information about
|
|
86
89
|
sources from where it is possible to get file.
|
|
87
90
|
platform_name (Optional[str]): Name of platform for which is
|
|
@@ -99,6 +102,9 @@ class DependencyPackagesAPI(BaseServerAPI):
|
|
|
99
102
|
"size": file_size,
|
|
100
103
|
"platform": platform_name or platform.system().lower(),
|
|
101
104
|
}
|
|
105
|
+
if python_version:
|
|
106
|
+
post_body["pythonVersion"] = python_version
|
|
107
|
+
|
|
102
108
|
if sources:
|
|
103
109
|
post_body["sources"] = sources
|
|
104
110
|
|
ayon_api/graphql.py
CHANGED
|
@@ -353,6 +353,25 @@ class GraphQlQuery:
|
|
|
353
353
|
for child in self._children:
|
|
354
354
|
child.parse_result(data, output, progress_data)
|
|
355
355
|
|
|
356
|
+
def _query_data(self, con: ServerAPI) -> dict[str, Any]:
|
|
357
|
+
"""Send single query to server and return 'data' of the response."""
|
|
358
|
+
query_str = self.calculate_query()
|
|
359
|
+
variables = self.get_variables_values()
|
|
360
|
+
response = con.query_graphql(query_str, variables)
|
|
361
|
+
if response.errors:
|
|
362
|
+
raise GraphQlQueryFailed(response.errors, query_str, variables)
|
|
363
|
+
|
|
364
|
+
data = response.data.get("data")
|
|
365
|
+
if data is None:
|
|
366
|
+
# Parsing 'None' would not change pagination state and the same
|
|
367
|
+
# query would be sent again in an infinite loop.
|
|
368
|
+
raise GraphQlQueryError(
|
|
369
|
+
f"GraphQl query '{self._name}' response does not contain"
|
|
370
|
+
f" 'data'. Response: {str(response.data)[:1000]}"
|
|
371
|
+
f"\nQuery:\n{query_str}\nVariables: {variables}"
|
|
372
|
+
)
|
|
373
|
+
return data
|
|
374
|
+
|
|
356
375
|
def query(self, con: ServerAPI) -> dict[str, Any]:
|
|
357
376
|
"""Do a query from server.
|
|
358
377
|
|
|
@@ -366,15 +385,8 @@ class GraphQlQuery:
|
|
|
366
385
|
progress_data = {}
|
|
367
386
|
output = {}
|
|
368
387
|
while self.need_query:
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
response = con.query_graphql(
|
|
372
|
-
query_str,
|
|
373
|
-
variables
|
|
374
|
-
)
|
|
375
|
-
if response.errors:
|
|
376
|
-
raise GraphQlQueryFailed(response.errors, query_str, variables)
|
|
377
|
-
self.parse_result(response.data["data"], output, progress_data)
|
|
388
|
+
data = self._query_data(con)
|
|
389
|
+
self.parse_result(data, output, progress_data)
|
|
378
390
|
|
|
379
391
|
return output
|
|
380
392
|
|
|
@@ -394,30 +406,16 @@ class GraphQlQuery:
|
|
|
394
406
|
if self.has_multiple_edge_fields:
|
|
395
407
|
output = {}
|
|
396
408
|
while self.need_query:
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
response = con.query_graphql(query_str, variables)
|
|
401
|
-
if response.errors:
|
|
402
|
-
raise GraphQlQueryFailed(
|
|
403
|
-
response.errors, query_str, variables
|
|
404
|
-
)
|
|
405
|
-
self.parse_result(response.data["data"], output, progress_data)
|
|
409
|
+
data = self._query_data(con)
|
|
410
|
+
self.parse_result(data, output, progress_data)
|
|
406
411
|
|
|
407
412
|
yield output
|
|
408
413
|
|
|
409
414
|
else:
|
|
410
415
|
while self.need_query:
|
|
411
416
|
output = {}
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
response = con.query_graphql(query_str, variables)
|
|
415
|
-
if response.errors:
|
|
416
|
-
raise GraphQlQueryFailed(
|
|
417
|
-
response.errors, query_str, variables
|
|
418
|
-
)
|
|
419
|
-
|
|
420
|
-
self.parse_result(response.data["data"], output, progress_data)
|
|
417
|
+
data = self._query_data(con)
|
|
418
|
+
self.parse_result(data, output, progress_data)
|
|
421
419
|
|
|
422
420
|
yield output
|
|
423
421
|
|
|
@@ -903,11 +901,13 @@ class GraphQlQueryEdgeField(BaseGraphQlQueryField):
|
|
|
903
901
|
progress_data[cursor_key] = nodes_by_cursor
|
|
904
902
|
|
|
905
903
|
page_info = value["pageInfo"]
|
|
904
|
+
# Continue from the last received edge for both orders. Server
|
|
905
|
+
# returns edges of 'last' page from the newest item, so
|
|
906
|
+
# 'startCursor' would move the cursor back only by one item.
|
|
907
|
+
new_cursor = page_info["endCursor"]
|
|
906
908
|
if self._order == SortOrder.ascending:
|
|
907
|
-
new_cursor = page_info["endCursor"]
|
|
908
909
|
self._need_query = page_info["hasNextPage"]
|
|
909
910
|
else:
|
|
910
|
-
new_cursor = page_info["startCursor"]
|
|
911
911
|
self._need_query = page_info["hasPreviousPage"]
|
|
912
912
|
|
|
913
913
|
edges = value["edges"]
|
|
@@ -943,6 +943,14 @@ class GraphQlQueryEdgeField(BaseGraphQlQueryField):
|
|
|
943
943
|
change_cursor = False
|
|
944
944
|
|
|
945
945
|
if change_cursor and self._need_query:
|
|
946
|
+
if new_cursor is None:
|
|
947
|
+
# Without cursor the pagination would start from beginning
|
|
948
|
+
raise GraphQlQueryError(
|
|
949
|
+
f"Field '{self.path}' reported another page without"
|
|
950
|
+
" a cursor. Stopped pagination after"
|
|
951
|
+
f" {self._fetched_counter} items."
|
|
952
|
+
)
|
|
953
|
+
|
|
946
954
|
if new_cursor == self._cursor:
|
|
947
955
|
raise GraphQlQueryError(
|
|
948
956
|
"Cursor didn't change during pagination."
|
|
@@ -1016,11 +1024,7 @@ class GraphQlQueryEdgeField(BaseGraphQlQueryField):
|
|
|
1016
1024
|
# Add page information
|
|
1017
1025
|
output.append(edges_offset + "pageInfo {")
|
|
1018
1026
|
for page_key in (
|
|
1019
|
-
|
|
1020
|
-
"endCursor"
|
|
1021
|
-
if self._order == SortOrder.ascending
|
|
1022
|
-
else "startCursor"
|
|
1023
|
-
),
|
|
1027
|
+
"endCursor",
|
|
1024
1028
|
(
|
|
1025
1029
|
"hasNextPage"
|
|
1026
1030
|
if self._order == SortOrder.ascending
|
ayon_api/server_api.py
CHANGED
|
@@ -1489,6 +1489,8 @@ class ServerAPI(
|
|
|
1489
1489
|
response = self.raw_get(
|
|
1490
1490
|
"info",
|
|
1491
1491
|
handle_invalid_token=False,
|
|
1492
|
+
verify=self.ssl_verify,
|
|
1493
|
+
cert=self.cert
|
|
1492
1494
|
)
|
|
1493
1495
|
response.raise_for_status()
|
|
1494
1496
|
return response.data
|
|
@@ -1519,7 +1521,7 @@ class ServerAPI(
|
|
|
1519
1521
|
**kwargs
|
|
1520
1522
|
) -> RestApiResponse:
|
|
1521
1523
|
kwargs.setdefault("timeout", self.timeout)
|
|
1522
|
-
max_retries = kwargs.
|
|
1524
|
+
max_retries = kwargs.pop("max_retries", self.max_retries)
|
|
1523
1525
|
if max_retries < 1:
|
|
1524
1526
|
max_retries = 1
|
|
1525
1527
|
|
|
@@ -1558,6 +1560,7 @@ class ServerAPI(
|
|
|
1558
1560
|
response = None
|
|
1559
1561
|
new_response = None
|
|
1560
1562
|
for retry_idx in reversed(range(max_retries)):
|
|
1563
|
+
new_response = None
|
|
1561
1564
|
try:
|
|
1562
1565
|
response = function(url, **kwargs)
|
|
1563
1566
|
|
|
@@ -1658,7 +1661,7 @@ class ServerAPI(
|
|
|
1658
1661
|
url = self._endpoint_to_url(endpoint, use_rest=False)
|
|
1659
1662
|
progress.set_source_url(url)
|
|
1660
1663
|
|
|
1661
|
-
retries = self.
|
|
1664
|
+
retries = max(self.max_retries, 1)
|
|
1662
1665
|
api_prepended = False
|
|
1663
1666
|
for attempt in range(retries):
|
|
1664
1667
|
# Continue in download
|
|
@@ -1684,6 +1687,14 @@ class ServerAPI(
|
|
|
1684
1687
|
progress.set_destination_url(url)
|
|
1685
1688
|
continue
|
|
1686
1689
|
response.raise_for_status()
|
|
1690
|
+
if offset > 0 and response.status_code != 206:
|
|
1691
|
+
# Server ignored 'Range' and sends whole file again,
|
|
1692
|
+
# already downloaded content must be discarded
|
|
1693
|
+
stream.seek(0)
|
|
1694
|
+
stream.truncate()
|
|
1695
|
+
progress.reset_transferred()
|
|
1696
|
+
headers.pop("Range", None)
|
|
1697
|
+
|
|
1687
1698
|
if progress.get_content_size() is None:
|
|
1688
1699
|
progress.set_content_size(
|
|
1689
1700
|
response.headers["Content-length"]
|
|
@@ -1692,11 +1703,21 @@ class ServerAPI(
|
|
|
1692
1703
|
for chunk in response.iter_content(chunk_size=chunk_size):
|
|
1693
1704
|
stream.write(chunk)
|
|
1694
1705
|
progress.add_transferred_chunk(len(chunk))
|
|
1706
|
+
|
|
1707
|
+
content_size = progress.get_content_size()
|
|
1708
|
+
transferred = progress.get_transferred_size()
|
|
1709
|
+
if content_size is not None and transferred != content_size:
|
|
1710
|
+
# Connection was closed before all content was received
|
|
1711
|
+
raise requests.exceptions.ConnectionError(
|
|
1712
|
+
f"Downloaded {transferred} out of {content_size}"
|
|
1713
|
+
f" bytes from '{url}'."
|
|
1714
|
+
)
|
|
1695
1715
|
break
|
|
1696
1716
|
|
|
1697
1717
|
except (
|
|
1698
1718
|
requests.exceptions.Timeout,
|
|
1699
1719
|
requests.exceptions.ConnectionError,
|
|
1720
|
+
requests.exceptions.ChunkedEncodingError,
|
|
1700
1721
|
):
|
|
1701
1722
|
if attempt == retries - 1:
|
|
1702
1723
|
raise
|
|
@@ -2093,7 +2114,7 @@ class ServerAPI(
|
|
|
2093
2114
|
headers.pop(orig_key)
|
|
2094
2115
|
headers[key] = value
|
|
2095
2116
|
|
|
2096
|
-
retries = self.
|
|
2117
|
+
retries = max(self.max_retries, 1)
|
|
2097
2118
|
response = None
|
|
2098
2119
|
|
|
2099
2120
|
# Get size of file
|
|
@@ -2676,24 +2697,32 @@ class ServerAPI(
|
|
|
2676
2697
|
if result.get("success"):
|
|
2677
2698
|
return None
|
|
2678
2699
|
|
|
2679
|
-
|
|
2680
|
-
|
|
2700
|
+
self.log.warning(
|
|
2701
|
+
"Operations failed. Server response:\n%s",
|
|
2702
|
+
json.dumps(result, indent=4, default=str),
|
|
2703
|
+
)
|
|
2704
|
+
for op_result in result.get("operations") or []:
|
|
2681
2705
|
if op_result["success"]:
|
|
2682
2706
|
continue
|
|
2683
2707
|
|
|
2684
2708
|
operation_id = op_result["id"]
|
|
2685
2709
|
operation = next(
|
|
2686
|
-
op
|
|
2687
|
-
|
|
2688
|
-
if op["id"] == operation_id
|
|
2710
|
+
(op for op in operations_body if op["id"] == operation_id),
|
|
2711
|
+
op_result,
|
|
2689
2712
|
)
|
|
2690
2713
|
detail = op_result["detail"]
|
|
2691
2714
|
raise FailedOperations(
|
|
2692
2715
|
f"Operation \"{operation_id}\" failed with data:"
|
|
2693
|
-
f"\n{json.dumps(operation, indent=4)}"
|
|
2716
|
+
f"\n{json.dumps(operation, indent=4, default=str)}"
|
|
2694
2717
|
f"\nDetail: {detail}."
|
|
2695
2718
|
)
|
|
2696
2719
|
|
|
2720
|
+
# Server did not report which operation failed
|
|
2721
|
+
raise FailedOperations(
|
|
2722
|
+
"Operations failed. Server response:"
|
|
2723
|
+
f"\n{json.dumps(result, indent=4, default=str)}"
|
|
2724
|
+
)
|
|
2725
|
+
|
|
2697
2726
|
def _prepare_fields(
|
|
2698
2727
|
self,
|
|
2699
2728
|
entity_type: str,
|
ayon_api/utils.py
CHANGED
|
@@ -955,7 +955,7 @@ class TransferProgress:
|
|
|
955
955
|
"""
|
|
956
956
|
return self._content_size
|
|
957
957
|
|
|
958
|
-
def set_content_size(self, content_size: int) -> None:
|
|
958
|
+
def set_content_size(self, content_size: int | str) -> None:
|
|
959
959
|
"""Set content size in bytes.
|
|
960
960
|
|
|
961
961
|
Args:
|
|
@@ -967,7 +967,7 @@ class TransferProgress:
|
|
|
967
967
|
"""
|
|
968
968
|
if self._content_size is not None:
|
|
969
969
|
raise ValueError("Content size was set more then once")
|
|
970
|
-
self._content_size = content_size
|
|
970
|
+
self._content_size = int(content_size)
|
|
971
971
|
|
|
972
972
|
def get_started(self) -> bool:
|
|
973
973
|
"""Transfer was started.
|
ayon_api/version.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""Package declaring Python API for AYON server."""
|
|
2
|
-
__version__ = "1.2.
|
|
2
|
+
__version__ = "1.2.24"
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
ayon_api/__init__.py,sha256=_54OHR1kxUb07F9ck43MsOX_aTqN97G2itxSgqlENjo,16313
|
|
2
|
-
ayon_api/_api.py,sha256=
|
|
2
|
+
ayon_api/_api.py,sha256=EGHH53Kzt9JWGRIMzcLN48_QYaaIQoz7ozQNndSqJyo,262271
|
|
3
3
|
ayon_api/constants.py,sha256=wnBse4dsk9zoeJOkayya3cFiGu00EXfebMNTioUclh0,4113
|
|
4
4
|
ayon_api/entity_hub.py,sha256=MaMl2zbiPDbQNwaSlDV65NOCscPQqgLzIrfAqAq5LxU,119854
|
|
5
5
|
ayon_api/events.py,sha256=RQ_ct_GTb3KbZ6QWBkYn5m-ZUc6NJDAFFsoy2P_w3dQ,1370
|
|
6
6
|
ayon_api/exceptions.py,sha256=9inI-TkAGMKuhF84O3FwikW2esgmCdPIeRhbj2ithQU,3692
|
|
7
|
-
ayon_api/graphql.py,sha256=
|
|
7
|
+
ayon_api/graphql.py,sha256=I6_PQTxGkgPxLl7e0BKy4V7htV5Z8yw9OvXG9FDj1dU,31037
|
|
8
8
|
ayon_api/graphql_queries.py,sha256=atupD5oe9t6WCyHy3YSY_0_uR8_c4ysb7d8SxbfZAvk,26455
|
|
9
9
|
ayon_api/operations.py,sha256=Cqm9GjqO_9S55dLZ07GIZVlCuCKQ7_fX2MfhPJvKt2A,56235
|
|
10
|
-
ayon_api/server_api.py,sha256=
|
|
10
|
+
ayon_api/server_api.py,sha256=Hu1z1OZItqOxglycGDh44nVHsZwePPzv1Vq_uTU7hM8,90780
|
|
11
11
|
ayon_api/typing.py,sha256=p2jNqGoh1m9_IUS0Dfr8sMoqjt60UycAkLuSbYtLY14,12286
|
|
12
|
-
ayon_api/utils.py,sha256=
|
|
13
|
-
ayon_api/version.py,sha256=
|
|
12
|
+
ayon_api/utils.py,sha256=DHQXzByX4m2F_9MDaL1WaI__u0f22bonDPOchIq7lno,36388
|
|
13
|
+
ayon_api/version.py,sha256=iyZ9soTd1NAp6X8Qui-VR3zSWsWs7VJi2viiasWmmzg,75
|
|
14
14
|
ayon_api/_api_helpers/__init__.py,sha256=15wxNshWe1htzZhFnwTTflBfQ3tYJzTe6-0hrEUCQbw,1076
|
|
15
15
|
ayon_api/_api_helpers/actions.py,sha256=OBRAEJSVnhGP0xf8ktQL3M7Ubz64nDmn957qZehaRQ0,10578
|
|
16
16
|
ayon_api/_api_helpers/activities.py,sha256=3U-0JA_F9-FlR9Tv6JPZZ2cpo6YegXQG4yNDB0wuhF8,14029
|
|
17
17
|
ayon_api/_api_helpers/attributes.py,sha256=ur9FsMWWY1K1Paw966srRj-z4EDx3nCVDLdLm9Yxn44,6949
|
|
18
18
|
ayon_api/_api_helpers/base.py,sha256=I5ejQN-WNxjmsWLBcGVTnMB834T8ZzEWcezyQ6Q4Hl8,4582
|
|
19
19
|
ayon_api/_api_helpers/bundles_addons.py,sha256=_AvquS0GZuUiGbCapRYu3vb_5Pp835HlbNfg9ipD3VU,31087
|
|
20
|
-
ayon_api/_api_helpers/dependency_packages.py,sha256=
|
|
20
|
+
ayon_api/_api_helpers/dependency_packages.py,sha256=_ADSpLDcWlsuqUppQNfMVHC_DDnZeDFvUFunP2PWx3A,8451
|
|
21
21
|
ayon_api/_api_helpers/events.py,sha256=j89YfsYXox_wIvMkiyxr3l2dzkA8x-JOgGy6p-7-ndU,17229
|
|
22
22
|
ayon_api/_api_helpers/folders.py,sha256=AvRx5r2V0luERFZ2Z6EOSIRh3Pe_OmLwR-HrrVrrVms,22279
|
|
23
23
|
ayon_api/_api_helpers/installers.py,sha256=Q45sg6rfKUht6g4bSPHHYFj8mDo_EAm9ahg9Zk3pSUs,5552
|
|
@@ -31,8 +31,8 @@ ayon_api/_api_helpers/tasks.py,sha256=gW8QbC2V7fNQeirViKyQVugnxfnYkQGGxiv3btYRn3
|
|
|
31
31
|
ayon_api/_api_helpers/thumbnails.py,sha256=2mQWU4cSY98J18ImYYt_5CRpm7DyOCO2wCmcLXwtdhk,12281
|
|
32
32
|
ayon_api/_api_helpers/versions.py,sha256=c9ebZdM9i3J24B4bs2BRRoH937JWvRTWlJ3cFRscdug,22413
|
|
33
33
|
ayon_api/_api_helpers/workfiles.py,sha256=8ksjCZ5xn7nEAKX792PeIwFNF5flslQwzbcHnJZwcu8,17679
|
|
34
|
-
ayon_python_api-1.2.
|
|
35
|
-
ayon_python_api-1.2.
|
|
36
|
-
ayon_python_api-1.2.
|
|
37
|
-
ayon_python_api-1.2.
|
|
38
|
-
ayon_python_api-1.2.
|
|
34
|
+
ayon_python_api-1.2.24.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
35
|
+
ayon_python_api-1.2.24.dist-info/METADATA,sha256=rt7sHv_R3L4FSUGsm7bL3oSGO2GtYL4P4Fm_M9IJp6E,16266
|
|
36
|
+
ayon_python_api-1.2.24.dist-info/WHEEL,sha256=SmOxYU7pzNKBqASvQJ7DjX3XGUF92lrGhMb3R6_iiqI,91
|
|
37
|
+
ayon_python_api-1.2.24.dist-info/top_level.txt,sha256=PKrQbX5Cz53_UmSTR_nIySnBkGyHcBTS88SCw9tuVlc,9
|
|
38
|
+
ayon_python_api-1.2.24.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|