Ayon-Python-Api 0.5.2__tar.gz → 0.5.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.5.2 → ayon-python-api-0.5.3}/PKG-INFO +1 -1
- {ayon-python-api-0.5.2 → ayon-python-api-0.5.3}/ayon_api/_api.py +1 -1
- {ayon-python-api-0.5.2 → ayon-python-api-0.5.3}/ayon_api/constants.py +11 -0
- {ayon-python-api-0.5.2 → ayon-python-api-0.5.3}/ayon_api/entity_hub.py +5 -2
- {ayon-python-api-0.5.2 → ayon-python-api-0.5.3}/ayon_api/server_api.py +83 -15
- {ayon-python-api-0.5.2 → ayon-python-api-0.5.3}/ayon_api/utils.py +25 -1
- {ayon-python-api-0.5.2 → ayon-python-api-0.5.3}/ayon_api/version.py +1 -1
- {ayon-python-api-0.5.2 → ayon-python-api-0.5.3}/ayon_python_api.egg-info/PKG-INFO +1 -1
- {ayon-python-api-0.5.2 → ayon-python-api-0.5.3}/pyproject.toml +1 -1
- {ayon-python-api-0.5.2 → ayon-python-api-0.5.3}/LICENSE +0 -0
- {ayon-python-api-0.5.2 → ayon-python-api-0.5.3}/README.md +0 -0
- {ayon-python-api-0.5.2 → ayon-python-api-0.5.3}/ayon_api/__init__.py +0 -0
- {ayon-python-api-0.5.2 → ayon-python-api-0.5.3}/ayon_api/events.py +0 -0
- {ayon-python-api-0.5.2 → ayon-python-api-0.5.3}/ayon_api/exceptions.py +0 -0
- {ayon-python-api-0.5.2 → ayon-python-api-0.5.3}/ayon_api/graphql.py +0 -0
- {ayon-python-api-0.5.2 → ayon-python-api-0.5.3}/ayon_api/graphql_queries.py +0 -0
- {ayon-python-api-0.5.2 → ayon-python-api-0.5.3}/ayon_api/operations.py +0 -0
- {ayon-python-api-0.5.2 → ayon-python-api-0.5.3}/ayon_python_api.egg-info/SOURCES.txt +0 -0
- {ayon-python-api-0.5.2 → ayon-python-api-0.5.3}/ayon_python_api.egg-info/dependency_links.txt +0 -0
- {ayon-python-api-0.5.2 → ayon-python-api-0.5.3}/ayon_python_api.egg-info/requires.txt +0 -0
- {ayon-python-api-0.5.2 → ayon-python-api-0.5.3}/ayon_python_api.egg-info/top_level.txt +0 -0
- {ayon-python-api-0.5.2 → ayon-python-api-0.5.3}/setup.cfg +0 -0
- {ayon-python-api-0.5.2 → ayon-python-api-0.5.3}/setup.py +0 -0
|
@@ -3,6 +3,10 @@ SERVER_URL_ENV_KEY = "AYON_SERVER_URL"
|
|
|
3
3
|
SERVER_API_ENV_KEY = "AYON_API_KEY"
|
|
4
4
|
SERVER_TIMEOUT_ENV_KEY = "AYON_SERVER_TIMEOUT"
|
|
5
5
|
SERVER_RETRIES_ENV_KEY = "AYON_SERVER_RETRIES"
|
|
6
|
+
# Default variant used for settings
|
|
7
|
+
DEFAULT_VARIANT_ENV_KEY = "AYON_DEFAULT_SETTINGS_VARIANT"
|
|
8
|
+
# Default site id used for connection
|
|
9
|
+
SITE_ID_ENV_KEY = "AYON_SITE_ID"
|
|
6
10
|
|
|
7
11
|
# Backwards compatibility
|
|
8
12
|
SERVER_TOKEN_ENV_KEY = SERVER_API_ENV_KEY
|
|
@@ -40,6 +44,7 @@ DEFAULT_PROJECT_FIELDS = {
|
|
|
40
44
|
"code",
|
|
41
45
|
"config",
|
|
42
46
|
"createdAt",
|
|
47
|
+
"data",
|
|
43
48
|
}
|
|
44
49
|
|
|
45
50
|
# --- Folders ---
|
|
@@ -52,6 +57,7 @@ DEFAULT_FOLDER_FIELDS = {
|
|
|
52
57
|
"parentId",
|
|
53
58
|
"active",
|
|
54
59
|
"thumbnailId",
|
|
60
|
+
"data",
|
|
55
61
|
}
|
|
56
62
|
|
|
57
63
|
# --- Tasks ---
|
|
@@ -63,6 +69,7 @@ DEFAULT_TASK_FIELDS = {
|
|
|
63
69
|
"folderId",
|
|
64
70
|
"active",
|
|
65
71
|
"assignees",
|
|
72
|
+
"data",
|
|
66
73
|
}
|
|
67
74
|
|
|
68
75
|
# --- Products ---
|
|
@@ -72,6 +79,7 @@ DEFAULT_PRODUCT_FIELDS = {
|
|
|
72
79
|
"folderId",
|
|
73
80
|
"active",
|
|
74
81
|
"productType",
|
|
82
|
+
"data",
|
|
75
83
|
}
|
|
76
84
|
|
|
77
85
|
# --- Versions ---
|
|
@@ -86,6 +94,7 @@ DEFAULT_VERSION_FIELDS = {
|
|
|
86
94
|
"thumbnailId",
|
|
87
95
|
"createdAt",
|
|
88
96
|
"updatedAt",
|
|
97
|
+
"data",
|
|
89
98
|
}
|
|
90
99
|
|
|
91
100
|
# --- Representations ---
|
|
@@ -96,6 +105,7 @@ DEFAULT_REPRESENTATION_FIELDS = {
|
|
|
96
105
|
"createdAt",
|
|
97
106
|
"active",
|
|
98
107
|
"versionId",
|
|
108
|
+
"data",
|
|
99
109
|
}
|
|
100
110
|
|
|
101
111
|
REPRESENTATION_FILES_FIELDS = {
|
|
@@ -119,6 +129,7 @@ DEFAULT_WORKFILE_INFO_FIELDS = {
|
|
|
119
129
|
"thumbnailId",
|
|
120
130
|
"updatedAt",
|
|
121
131
|
"updatedBy",
|
|
132
|
+
"data",
|
|
122
133
|
}
|
|
123
134
|
|
|
124
135
|
DEFAULT_EVENT_FIELDS = {
|
|
@@ -36,15 +36,18 @@ class EntityHub(object):
|
|
|
36
36
|
"""
|
|
37
37
|
|
|
38
38
|
def __init__(
|
|
39
|
-
self, project_name, connection=None, allow_data_changes=
|
|
39
|
+
self, project_name, connection=None, allow_data_changes=None
|
|
40
40
|
):
|
|
41
41
|
if not connection:
|
|
42
42
|
connection = get_server_api_connection()
|
|
43
|
-
major, minor,
|
|
43
|
+
major, minor, patch, _, _ = connection.server_version_tuple
|
|
44
44
|
path_start_with_slash = True
|
|
45
45
|
if (major, minor) < (0, 6):
|
|
46
46
|
path_start_with_slash = False
|
|
47
47
|
|
|
48
|
+
if allow_data_changes is None:
|
|
49
|
+
allow_data_changes = connection.graphql_allows_data_in_query
|
|
50
|
+
|
|
48
51
|
self._connection = connection
|
|
49
52
|
self._path_start_with_slash = path_start_with_slash
|
|
50
53
|
|
|
@@ -9,6 +9,9 @@ import platform
|
|
|
9
9
|
import copy
|
|
10
10
|
import uuid
|
|
11
11
|
from contextlib import contextmanager
|
|
12
|
+
|
|
13
|
+
import six
|
|
14
|
+
|
|
12
15
|
try:
|
|
13
16
|
from http import HTTPStatus
|
|
14
17
|
except ImportError:
|
|
@@ -27,7 +30,6 @@ except ImportError:
|
|
|
27
30
|
from json import JSONDecodeError as RequestsJSONDecodeError
|
|
28
31
|
|
|
29
32
|
from .constants import (
|
|
30
|
-
SERVER_TIMEOUT_ENV_KEY,
|
|
31
33
|
SERVER_RETRIES_ENV_KEY,
|
|
32
34
|
DEFAULT_PRODUCT_TYPE_FIELDS,
|
|
33
35
|
DEFAULT_PROJECT_FIELDS,
|
|
@@ -76,8 +78,11 @@ from .utils import (
|
|
|
76
78
|
create_dependency_package_basename,
|
|
77
79
|
ThumbnailContent,
|
|
78
80
|
get_default_timeout,
|
|
81
|
+
get_default_settings_variant,
|
|
82
|
+
get_default_site_id,
|
|
79
83
|
)
|
|
80
84
|
|
|
85
|
+
_PLACEHOLDER = object()
|
|
81
86
|
PatternType = type(re.compile(""))
|
|
82
87
|
JSONDecodeError = getattr(json, "JSONDecodeError", ValueError)
|
|
83
88
|
# This should be collected from server schema
|
|
@@ -363,7 +368,7 @@ class ServerAPI(object):
|
|
|
363
368
|
self,
|
|
364
369
|
base_url,
|
|
365
370
|
token=None,
|
|
366
|
-
site_id=
|
|
371
|
+
site_id=_PLACEHOLDER,
|
|
367
372
|
client_version=None,
|
|
368
373
|
default_settings_variant=None,
|
|
369
374
|
sender=None,
|
|
@@ -382,11 +387,14 @@ class ServerAPI(object):
|
|
|
382
387
|
self._graphql_url = "{}/graphql".format(base_url)
|
|
383
388
|
self._log = None
|
|
384
389
|
self._access_token = token
|
|
390
|
+
# Allow to have 'site_id' to 'None'
|
|
391
|
+
if site_id is _PLACEHOLDER:
|
|
392
|
+
site_id = get_default_site_id()
|
|
385
393
|
self._site_id = site_id
|
|
386
394
|
self._client_version = client_version
|
|
387
395
|
self._default_settings_variant = (
|
|
388
396
|
default_settings_variant
|
|
389
|
-
or
|
|
397
|
+
or get_default_settings_variant()
|
|
390
398
|
)
|
|
391
399
|
self._sender = sender
|
|
392
400
|
|
|
@@ -416,6 +424,8 @@ class ServerAPI(object):
|
|
|
416
424
|
self._server_version = None
|
|
417
425
|
self._server_version_tuple = None
|
|
418
426
|
|
|
427
|
+
self._graphql_allows_data_in_query = None
|
|
428
|
+
|
|
419
429
|
self._session = None
|
|
420
430
|
|
|
421
431
|
self._base_functions_mapping = {
|
|
@@ -941,6 +951,26 @@ class ServerAPI(object):
|
|
|
941
951
|
server_version = property(get_server_version)
|
|
942
952
|
server_version_tuple = property(get_server_version_tuple)
|
|
943
953
|
|
|
954
|
+
@property
|
|
955
|
+
def graphql_allows_data_in_query(self):
|
|
956
|
+
"""GraphlQl query can support 'data' field.
|
|
957
|
+
|
|
958
|
+
This applies only to project hierarchy entities 'project', 'folder',
|
|
959
|
+
'task', 'product', 'version' and 'representation'. Others like 'user'
|
|
960
|
+
still require to use rest api to access 'data'.
|
|
961
|
+
|
|
962
|
+
Returns:
|
|
963
|
+
bool: True if server supports 'data' field in GraphQl query.
|
|
964
|
+
"""
|
|
965
|
+
|
|
966
|
+
if self._graphql_allows_data_in_query is None:
|
|
967
|
+
major, minor, patch, _, _ = self.server_version_tuple
|
|
968
|
+
graphql_allows_data_in_query = True
|
|
969
|
+
if (major, minor, patch) < (0, 5, 5):
|
|
970
|
+
graphql_allows_data_in_query = False
|
|
971
|
+
self._graphql_allows_data_in_query = graphql_allows_data_in_query
|
|
972
|
+
return self._graphql_allows_data_in_query
|
|
973
|
+
|
|
944
974
|
def _get_user_info(self):
|
|
945
975
|
if self._access_token is None:
|
|
946
976
|
return None
|
|
@@ -1883,31 +1913,45 @@ class ServerAPI(object):
|
|
|
1883
1913
|
return set(DEFAULT_EVENT_FIELDS)
|
|
1884
1914
|
|
|
1885
1915
|
if entity_type == "project":
|
|
1886
|
-
entity_type_defaults = DEFAULT_PROJECT_FIELDS
|
|
1916
|
+
entity_type_defaults = set(DEFAULT_PROJECT_FIELDS)
|
|
1917
|
+
if not self.graphql_allows_data_in_query:
|
|
1918
|
+
entity_type_defaults.discard("data")
|
|
1887
1919
|
|
|
1888
1920
|
elif entity_type == "folder":
|
|
1889
|
-
entity_type_defaults = DEFAULT_FOLDER_FIELDS
|
|
1921
|
+
entity_type_defaults = set(DEFAULT_FOLDER_FIELDS)
|
|
1922
|
+
if not self.graphql_allows_data_in_query:
|
|
1923
|
+
entity_type_defaults.discard("data")
|
|
1890
1924
|
|
|
1891
1925
|
elif entity_type == "task":
|
|
1892
|
-
entity_type_defaults = DEFAULT_TASK_FIELDS
|
|
1926
|
+
entity_type_defaults = set(DEFAULT_TASK_FIELDS)
|
|
1927
|
+
if not self.graphql_allows_data_in_query:
|
|
1928
|
+
entity_type_defaults.discard("data")
|
|
1893
1929
|
|
|
1894
1930
|
elif entity_type == "product":
|
|
1895
|
-
entity_type_defaults = DEFAULT_PRODUCT_FIELDS
|
|
1931
|
+
entity_type_defaults = set(DEFAULT_PRODUCT_FIELDS)
|
|
1932
|
+
if not self.graphql_allows_data_in_query:
|
|
1933
|
+
entity_type_defaults.discard("data")
|
|
1896
1934
|
|
|
1897
1935
|
elif entity_type == "version":
|
|
1898
|
-
entity_type_defaults = DEFAULT_VERSION_FIELDS
|
|
1936
|
+
entity_type_defaults = set(DEFAULT_VERSION_FIELDS)
|
|
1937
|
+
if not self.graphql_allows_data_in_query:
|
|
1938
|
+
entity_type_defaults.discard("data")
|
|
1899
1939
|
|
|
1900
1940
|
elif entity_type == "representation":
|
|
1901
1941
|
entity_type_defaults = (
|
|
1902
1942
|
DEFAULT_REPRESENTATION_FIELDS
|
|
1903
1943
|
| REPRESENTATION_FILES_FIELDS
|
|
1904
1944
|
)
|
|
1945
|
+
if not self.graphql_allows_data_in_query:
|
|
1946
|
+
entity_type_defaults.discard("data")
|
|
1905
1947
|
|
|
1906
1948
|
elif entity_type == "productType":
|
|
1907
|
-
entity_type_defaults = DEFAULT_PRODUCT_TYPE_FIELDS
|
|
1949
|
+
entity_type_defaults = set(DEFAULT_PRODUCT_TYPE_FIELDS)
|
|
1908
1950
|
|
|
1909
1951
|
elif entity_type == "workfile":
|
|
1910
|
-
entity_type_defaults = DEFAULT_WORKFILE_INFO_FIELDS
|
|
1952
|
+
entity_type_defaults = set(DEFAULT_WORKFILE_INFO_FIELDS)
|
|
1953
|
+
if not self.graphql_allows_data_in_query:
|
|
1954
|
+
entity_type_defaults.discard("data")
|
|
1911
1955
|
|
|
1912
1956
|
elif entity_type == "user":
|
|
1913
1957
|
entity_type_defaults = set(DEFAULT_USER_FIELDS)
|
|
@@ -3659,7 +3703,7 @@ class ServerAPI(object):
|
|
|
3659
3703
|
fields |= self.get_attributes_fields_for_type("folder")
|
|
3660
3704
|
|
|
3661
3705
|
use_rest = False
|
|
3662
|
-
if "data" in fields:
|
|
3706
|
+
if "data" in fields and not self.graphql_allows_data_in_query:
|
|
3663
3707
|
use_rest = True
|
|
3664
3708
|
fields = {"id"}
|
|
3665
3709
|
|
|
@@ -3680,6 +3724,8 @@ class ServerAPI(object):
|
|
|
3680
3724
|
|
|
3681
3725
|
if use_rest:
|
|
3682
3726
|
folder = self.get_rest_folder(project_name, folder["id"])
|
|
3727
|
+
else:
|
|
3728
|
+
self._convert_entity_data(folder)
|
|
3683
3729
|
|
|
3684
3730
|
if own_attributes:
|
|
3685
3731
|
fill_own_attribs(folder)
|
|
@@ -3897,7 +3943,7 @@ class ServerAPI(object):
|
|
|
3897
3943
|
fields |= self.get_attributes_fields_for_type("task")
|
|
3898
3944
|
|
|
3899
3945
|
use_rest = False
|
|
3900
|
-
if "data" in fields:
|
|
3946
|
+
if "data" in fields and not self.graphql_allows_data_in_query:
|
|
3901
3947
|
use_rest = True
|
|
3902
3948
|
fields = {"id"}
|
|
3903
3949
|
|
|
@@ -3918,6 +3964,8 @@ class ServerAPI(object):
|
|
|
3918
3964
|
|
|
3919
3965
|
if use_rest:
|
|
3920
3966
|
task = self.get_rest_task(project_name, task["id"])
|
|
3967
|
+
else:
|
|
3968
|
+
self._convert_entity_data(task)
|
|
3921
3969
|
|
|
3922
3970
|
if own_attributes:
|
|
3923
3971
|
fill_own_attribs(task)
|
|
@@ -3998,6 +4046,8 @@ class ServerAPI(object):
|
|
|
3998
4046
|
|
|
3999
4047
|
if use_rest:
|
|
4000
4048
|
product = self.get_rest_product(project_name, product["id"])
|
|
4049
|
+
else:
|
|
4050
|
+
self._convert_entity_data(product)
|
|
4001
4051
|
|
|
4002
4052
|
if own_attributes:
|
|
4003
4053
|
fill_own_attribs(product)
|
|
@@ -4104,7 +4154,7 @@ class ServerAPI(object):
|
|
|
4104
4154
|
fields = self.get_default_fields_for_type("product")
|
|
4105
4155
|
|
|
4106
4156
|
use_rest = False
|
|
4107
|
-
if "data" in fields:
|
|
4157
|
+
if "data" in fields and not self.graphql_allows_data_in_query:
|
|
4108
4158
|
use_rest = True
|
|
4109
4159
|
fields = {"id"}
|
|
4110
4160
|
|
|
@@ -4372,7 +4422,7 @@ class ServerAPI(object):
|
|
|
4372
4422
|
fields |= {"id", "version"}
|
|
4373
4423
|
|
|
4374
4424
|
use_rest = False
|
|
4375
|
-
if "data" in fields:
|
|
4425
|
+
if "data" in fields and not self.graphql_allows_data_in_query:
|
|
4376
4426
|
use_rest = True
|
|
4377
4427
|
fields = {"id"}
|
|
4378
4428
|
|
|
@@ -4452,6 +4502,8 @@ class ServerAPI(object):
|
|
|
4452
4502
|
version = self.get_rest_version(
|
|
4453
4503
|
project_name, version["id"]
|
|
4454
4504
|
)
|
|
4505
|
+
else:
|
|
4506
|
+
self._convert_entity_data(version)
|
|
4455
4507
|
|
|
4456
4508
|
if own_attributes:
|
|
4457
4509
|
fill_own_attribs(version)
|
|
@@ -4831,7 +4883,7 @@ class ServerAPI(object):
|
|
|
4831
4883
|
fields |= self.get_attributes_fields_for_type("representation")
|
|
4832
4884
|
|
|
4833
4885
|
use_rest = False
|
|
4834
|
-
if "data" in fields:
|
|
4886
|
+
if "data" in fields and not self.graphql_allows_data_in_query:
|
|
4835
4887
|
use_rest = True
|
|
4836
4888
|
fields = {"id"}
|
|
4837
4889
|
|
|
@@ -4894,6 +4946,8 @@ class ServerAPI(object):
|
|
|
4894
4946
|
repre = self.get_rest_representation(
|
|
4895
4947
|
project_name, repre["id"]
|
|
4896
4948
|
)
|
|
4949
|
+
else:
|
|
4950
|
+
self._convert_entity_data(repre)
|
|
4897
4951
|
|
|
4898
4952
|
if "context" in repre:
|
|
4899
4953
|
orig_context = repre["context"]
|
|
@@ -5013,6 +5067,10 @@ class ServerAPI(object):
|
|
|
5013
5067
|
version = repre.pop("version")
|
|
5014
5068
|
product = version.pop("product")
|
|
5015
5069
|
folder = product.pop("folder")
|
|
5070
|
+
self._convert_entity_data(repre)
|
|
5071
|
+
self._convert_entity_data(version)
|
|
5072
|
+
self._convert_entity_data(product)
|
|
5073
|
+
self._convert_entity_data(folder)
|
|
5016
5074
|
output[repre_id] = RepresentationParents(
|
|
5017
5075
|
version, product, folder, project
|
|
5018
5076
|
)
|
|
@@ -6323,3 +6381,13 @@ class ServerAPI(object):
|
|
|
6323
6381
|
op_result["detail"],
|
|
6324
6382
|
))
|
|
6325
6383
|
return op_results
|
|
6384
|
+
|
|
6385
|
+
def _convert_entity_data(self, entity):
|
|
6386
|
+
if not entity:
|
|
6387
|
+
return
|
|
6388
|
+
entity_data = entity.get("data")
|
|
6389
|
+
if (
|
|
6390
|
+
entity_data is not None
|
|
6391
|
+
and isinstance(entity_data, six.string_types)
|
|
6392
|
+
):
|
|
6393
|
+
entity["data"] = json.loads(entity_data)
|
|
@@ -16,7 +16,11 @@ except ImportError:
|
|
|
16
16
|
import requests
|
|
17
17
|
import unidecode
|
|
18
18
|
|
|
19
|
-
from .constants import
|
|
19
|
+
from .constants import (
|
|
20
|
+
SERVER_TIMEOUT_ENV_KEY,
|
|
21
|
+
DEFAULT_VARIANT_ENV_KEY,
|
|
22
|
+
SITE_ID_ENV_KEY,
|
|
23
|
+
)
|
|
20
24
|
from .exceptions import UrlError
|
|
21
25
|
|
|
22
26
|
REMOVED_VALUE = object()
|
|
@@ -46,6 +50,26 @@ def get_default_timeout():
|
|
|
46
50
|
return 10.0
|
|
47
51
|
|
|
48
52
|
|
|
53
|
+
def get_default_settings_variant():
|
|
54
|
+
"""Default settings variant.
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
str: Settings variant from environment variable or 'production'.
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
return os.environ.get(DEFAULT_VARIANT_ENV_KEY) or "production"
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def get_default_site_id():
|
|
64
|
+
"""Site id used for server connection.
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
Union[str, None]: Site id from environment variable or None.
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
return os.environ.get(SITE_ID_ENV_KEY)
|
|
71
|
+
|
|
72
|
+
|
|
49
73
|
class ThumbnailContent:
|
|
50
74
|
"""Wrapper for thumbnail content.
|
|
51
75
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""Package declaring Python API for Ayon server."""
|
|
2
|
-
__version__ = "0.5.
|
|
2
|
+
__version__ = "0.5.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
|
{ayon-python-api-0.5.2 → ayon-python-api-0.5.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
|