ayon-python-api 1.2.10__tar.gz → 1.2.12__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-1.2.10 → ayon_python_api-1.2.12}/PKG-INFO +1 -1
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/__init__.py +6 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/_api.py +138 -1
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/_api_helpers/bundles_addons.py +20 -3
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/_api_helpers/dependency_packages.py +2 -2
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/_api_helpers/installers.py +2 -2
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/_api_helpers/thumbnails.py +4 -4
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/server_api.py +216 -36
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/utils.py +28 -11
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/version.py +1 -1
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_python_api.egg-info/PKG-INFO +1 -1
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/pyproject.toml +3 -3
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/LICENSE +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/README.md +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/_api_helpers/__init__.py +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/_api_helpers/actions.py +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/_api_helpers/activities.py +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/_api_helpers/attributes.py +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/_api_helpers/base.py +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/_api_helpers/events.py +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/_api_helpers/folders.py +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/_api_helpers/links.py +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/_api_helpers/lists.py +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/_api_helpers/products.py +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/_api_helpers/projects.py +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/_api_helpers/representations.py +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/_api_helpers/secrets.py +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/_api_helpers/tasks.py +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/_api_helpers/versions.py +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/_api_helpers/workfiles.py +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/constants.py +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/entity_hub.py +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/events.py +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/exceptions.py +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/graphql.py +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/graphql_queries.py +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/operations.py +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/typing.py +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_python_api.egg-info/SOURCES.txt +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_python_api.egg-info/dependency_links.txt +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_python_api.egg-info/requires.txt +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_python_api.egg-info/top_level.txt +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/setup.cfg +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/setup.py +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/tests/test_entity_hub.py +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/tests/test_folder_hierarchy.py +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/tests/test_get_events.py +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/tests/test_graphql_queries.py +0 -0
- {ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/tests/test_server.py +0 -0
|
@@ -70,8 +70,11 @@ from ._api import (
|
|
|
70
70
|
delete,
|
|
71
71
|
download_file_to_stream,
|
|
72
72
|
download_file,
|
|
73
|
+
upload_project_file,
|
|
74
|
+
upload_project_file_from_stream,
|
|
73
75
|
download_project_file,
|
|
74
76
|
download_project_file_to_stream,
|
|
77
|
+
delete_project_file,
|
|
75
78
|
upload_file_from_stream,
|
|
76
79
|
upload_file,
|
|
77
80
|
upload_reviewable,
|
|
@@ -351,8 +354,11 @@ __all__ = (
|
|
|
351
354
|
"delete",
|
|
352
355
|
"download_file_to_stream",
|
|
353
356
|
"download_file",
|
|
357
|
+
"upload_project_file",
|
|
358
|
+
"upload_project_file_from_stream",
|
|
354
359
|
"download_project_file",
|
|
355
360
|
"download_project_file_to_stream",
|
|
361
|
+
"delete_project_file",
|
|
356
362
|
"upload_file_from_stream",
|
|
357
363
|
"upload_file",
|
|
358
364
|
"upload_reviewable",
|
|
@@ -993,6 +993,99 @@ def download_file(
|
|
|
993
993
|
)
|
|
994
994
|
|
|
995
995
|
|
|
996
|
+
def upload_project_file(
|
|
997
|
+
project_name: str,
|
|
998
|
+
filepath: str,
|
|
999
|
+
*,
|
|
1000
|
+
content_type: Optional[str] = None,
|
|
1001
|
+
filename: Optional[str] = None,
|
|
1002
|
+
file_id: Optional[str] = None,
|
|
1003
|
+
activity_id: Optional[str] = None,
|
|
1004
|
+
chunk_size: Optional[int] = None,
|
|
1005
|
+
progress: Optional[TransferProgress] = None,
|
|
1006
|
+
) -> requests.Response:
|
|
1007
|
+
"""Upload project file from a filepath.
|
|
1008
|
+
|
|
1009
|
+
Project files are usually binary files, such as images, videos,
|
|
1010
|
+
or other media files that can be accessed via api endpoint
|
|
1011
|
+
'{server url}/api/projects/{project_name}/files/{file_id}'.
|
|
1012
|
+
|
|
1013
|
+
Args:
|
|
1014
|
+
project_name (str): Project name.
|
|
1015
|
+
filepath (str): Path where file will be downloaded.
|
|
1016
|
+
content_type (Optional[str]): MIME type of file.
|
|
1017
|
+
filename (Optional[str]): Server filename, filename from filepath
|
|
1018
|
+
is used if not passed.
|
|
1019
|
+
file_id (Optional[str]): File id.
|
|
1020
|
+
activity_id (Optional[str]): To which activity is file related.
|
|
1021
|
+
chunk_size (Optional[int]): Size of chunks that are received
|
|
1022
|
+
in single loop.
|
|
1023
|
+
progress (Optional[TransferProgress]): Object that gives ability
|
|
1024
|
+
to track download progress.
|
|
1025
|
+
|
|
1026
|
+
Returns:
|
|
1027
|
+
requests.Response: Requests response.
|
|
1028
|
+
|
|
1029
|
+
"""
|
|
1030
|
+
con = get_server_api_connection()
|
|
1031
|
+
return con.upload_project_file(
|
|
1032
|
+
project_name=project_name,
|
|
1033
|
+
filepath=filepath,
|
|
1034
|
+
content_type=content_type,
|
|
1035
|
+
filename=filename,
|
|
1036
|
+
file_id=file_id,
|
|
1037
|
+
activity_id=activity_id,
|
|
1038
|
+
chunk_size=chunk_size,
|
|
1039
|
+
progress=progress,
|
|
1040
|
+
)
|
|
1041
|
+
|
|
1042
|
+
|
|
1043
|
+
def upload_project_file_from_stream(
|
|
1044
|
+
project_name: str,
|
|
1045
|
+
stream: StreamType,
|
|
1046
|
+
filename: str,
|
|
1047
|
+
*,
|
|
1048
|
+
content_type: Optional[str] = None,
|
|
1049
|
+
file_id: Optional[str] = None,
|
|
1050
|
+
activity_id: Optional[str] = None,
|
|
1051
|
+
chunk_size: Optional[int] = None,
|
|
1052
|
+
progress: Optional[TransferProgress] = None,
|
|
1053
|
+
) -> requests.Response:
|
|
1054
|
+
"""Upload project file from a filepath.
|
|
1055
|
+
|
|
1056
|
+
Project files are usually binary files, such as images, videos,
|
|
1057
|
+
or other media files that can be accessed via api endpoint
|
|
1058
|
+
'{server url}/api/projects/{project_name}/files/{file_id}'.
|
|
1059
|
+
|
|
1060
|
+
Args:
|
|
1061
|
+
project_name (str): Project name.
|
|
1062
|
+
stream (StreamType): Stream used as source for upload.
|
|
1063
|
+
filename (str): Name of file on server.
|
|
1064
|
+
content_type (Optional[str]): MIME type of file.
|
|
1065
|
+
file_id (Optional[str]): File id.
|
|
1066
|
+
activity_id (Optional[str]): To which activity is file related.
|
|
1067
|
+
chunk_size (Optional[int]): Size of chunks that are received
|
|
1068
|
+
in single loop.
|
|
1069
|
+
progress (Optional[TransferProgress]): Object that gives ability
|
|
1070
|
+
to track download progress.
|
|
1071
|
+
|
|
1072
|
+
Returns:
|
|
1073
|
+
requests.Response: Requests response.
|
|
1074
|
+
|
|
1075
|
+
"""
|
|
1076
|
+
con = get_server_api_connection()
|
|
1077
|
+
return con.upload_project_file_from_stream(
|
|
1078
|
+
project_name=project_name,
|
|
1079
|
+
stream=stream,
|
|
1080
|
+
filename=filename,
|
|
1081
|
+
content_type=content_type,
|
|
1082
|
+
file_id=file_id,
|
|
1083
|
+
activity_id=activity_id,
|
|
1084
|
+
chunk_size=chunk_size,
|
|
1085
|
+
progress=progress,
|
|
1086
|
+
)
|
|
1087
|
+
|
|
1088
|
+
|
|
996
1089
|
def download_project_file(
|
|
997
1090
|
project_name: str,
|
|
998
1091
|
file_id: str,
|
|
@@ -1067,11 +1160,27 @@ def download_project_file_to_stream(
|
|
|
1067
1160
|
)
|
|
1068
1161
|
|
|
1069
1162
|
|
|
1163
|
+
def delete_project_file(
|
|
1164
|
+
project_name: str,
|
|
1165
|
+
file_id: str,
|
|
1166
|
+
) -> None:
|
|
1167
|
+
"""Delete project file.
|
|
1168
|
+
"""
|
|
1169
|
+
con = get_server_api_connection()
|
|
1170
|
+
return con.delete_project_file(
|
|
1171
|
+
project_name=project_name,
|
|
1172
|
+
file_id=file_id,
|
|
1173
|
+
)
|
|
1174
|
+
|
|
1175
|
+
|
|
1070
1176
|
def upload_file_from_stream(
|
|
1071
1177
|
endpoint: str,
|
|
1072
1178
|
stream: StreamType,
|
|
1073
1179
|
progress: Optional[TransferProgress] = None,
|
|
1074
1180
|
request_type: Optional[RequestType] = None,
|
|
1181
|
+
*,
|
|
1182
|
+
content_type: Optional[str] = None,
|
|
1183
|
+
filename: Optional[str] = None,
|
|
1075
1184
|
**kwargs,
|
|
1076
1185
|
) -> requests.Response:
|
|
1077
1186
|
"""Upload file to server from bytes.
|
|
@@ -1087,6 +1196,8 @@ def upload_file_from_stream(
|
|
|
1087
1196
|
to track upload progress.
|
|
1088
1197
|
request_type (Optional[RequestType]): Type of request that will
|
|
1089
1198
|
be used to upload file.
|
|
1199
|
+
content_type (Optional[str]): MIME type of the file.
|
|
1200
|
+
filename (Optional[str]): Filename of file on server.
|
|
1090
1201
|
**kwargs (Any): Additional arguments that will be passed
|
|
1091
1202
|
to request function.
|
|
1092
1203
|
|
|
@@ -1100,6 +1211,8 @@ def upload_file_from_stream(
|
|
|
1100
1211
|
stream=stream,
|
|
1101
1212
|
progress=progress,
|
|
1102
1213
|
request_type=request_type,
|
|
1214
|
+
content_type=content_type,
|
|
1215
|
+
filename=filename,
|
|
1103
1216
|
**kwargs,
|
|
1104
1217
|
)
|
|
1105
1218
|
|
|
@@ -1109,6 +1222,9 @@ def upload_file(
|
|
|
1109
1222
|
filepath: str,
|
|
1110
1223
|
progress: Optional[TransferProgress] = None,
|
|
1111
1224
|
request_type: Optional[RequestType] = None,
|
|
1225
|
+
*,
|
|
1226
|
+
content_type: Optional[str] = None,
|
|
1227
|
+
filename: Optional[str] = None,
|
|
1112
1228
|
**kwargs,
|
|
1113
1229
|
) -> requests.Response:
|
|
1114
1230
|
"""Upload file to server.
|
|
@@ -1124,6 +1240,8 @@ def upload_file(
|
|
|
1124
1240
|
to track upload progress.
|
|
1125
1241
|
request_type (Optional[RequestType]): Type of request that will
|
|
1126
1242
|
be used to upload file.
|
|
1243
|
+
content_type (Optional[str]): MIME type of the file.
|
|
1244
|
+
filename (Optional[str]): Filename of file on server.
|
|
1127
1245
|
**kwargs (Any): Additional arguments that will be passed
|
|
1128
1246
|
to request function.
|
|
1129
1247
|
|
|
@@ -1137,6 +1255,8 @@ def upload_file(
|
|
|
1137
1255
|
filepath=filepath,
|
|
1138
1256
|
progress=progress,
|
|
1139
1257
|
request_type=request_type,
|
|
1258
|
+
content_type=content_type,
|
|
1259
|
+
filename=filename,
|
|
1140
1260
|
**kwargs,
|
|
1141
1261
|
)
|
|
1142
1262
|
|
|
@@ -2889,6 +3009,7 @@ def get_addon_site_settings(
|
|
|
2889
3009
|
def get_bundle_settings(
|
|
2890
3010
|
bundle_name: Optional[str] = None,
|
|
2891
3011
|
project_name: Optional[str] = None,
|
|
3012
|
+
project_bundle_name: Optional[str] = None,
|
|
2892
3013
|
variant: Optional[str] = None,
|
|
2893
3014
|
site_id: Optional[str] = None,
|
|
2894
3015
|
use_site: bool = True,
|
|
@@ -2928,6 +3049,7 @@ def get_bundle_settings(
|
|
|
2928
3049
|
return con.get_bundle_settings(
|
|
2929
3050
|
bundle_name=bundle_name,
|
|
2930
3051
|
project_name=project_name,
|
|
3052
|
+
project_bundle_name=project_bundle_name,
|
|
2931
3053
|
variant=variant,
|
|
2932
3054
|
site_id=site_id,
|
|
2933
3055
|
use_site=use_site,
|
|
@@ -2936,6 +3058,7 @@ def get_bundle_settings(
|
|
|
2936
3058
|
|
|
2937
3059
|
def get_addons_studio_settings(
|
|
2938
3060
|
bundle_name: Optional[str] = None,
|
|
3061
|
+
project_bundle_name: Optional[str] = None,
|
|
2939
3062
|
variant: Optional[str] = None,
|
|
2940
3063
|
site_id: Optional[str] = None,
|
|
2941
3064
|
use_site: bool = True,
|
|
@@ -2951,6 +3074,8 @@ def get_addons_studio_settings(
|
|
|
2951
3074
|
Args:
|
|
2952
3075
|
bundle_name (Optional[str]): Name of bundle for which should be
|
|
2953
3076
|
settings received.
|
|
3077
|
+
project_bundle_name (Optional[str]): Project bundle name for
|
|
3078
|
+
which should be settings received.
|
|
2954
3079
|
variant (Optional[Literal['production', 'staging']]): Name of
|
|
2955
3080
|
settings variant. Used 'default_settings_variant' by default.
|
|
2956
3081
|
site_id (Optional[str]): Site id for which want to receive
|
|
@@ -2968,6 +3093,7 @@ def get_addons_studio_settings(
|
|
|
2968
3093
|
con = get_server_api_connection()
|
|
2969
3094
|
return con.get_addons_studio_settings(
|
|
2970
3095
|
bundle_name=bundle_name,
|
|
3096
|
+
project_bundle_name=project_bundle_name,
|
|
2971
3097
|
variant=variant,
|
|
2972
3098
|
site_id=site_id,
|
|
2973
3099
|
use_site=use_site,
|
|
@@ -2978,6 +3104,7 @@ def get_addons_studio_settings(
|
|
|
2978
3104
|
def get_addons_project_settings(
|
|
2979
3105
|
project_name: str,
|
|
2980
3106
|
bundle_name: Optional[str] = None,
|
|
3107
|
+
project_bundle_name: Optional[str] = None,
|
|
2981
3108
|
variant: Optional[str] = None,
|
|
2982
3109
|
site_id: Optional[str] = None,
|
|
2983
3110
|
use_site: bool = True,
|
|
@@ -3009,6 +3136,8 @@ def get_addons_project_settings(
|
|
|
3009
3136
|
received.
|
|
3010
3137
|
bundle_name (Optional[str]): Name of bundle for which should be
|
|
3011
3138
|
settings received.
|
|
3139
|
+
project_bundle_name (Optional[str]): Project bundle name for which
|
|
3140
|
+
should be settings received.
|
|
3012
3141
|
variant (Optional[Literal['production', 'staging']]): Name of
|
|
3013
3142
|
settings variant. Used 'default_settings_variant' by default.
|
|
3014
3143
|
site_id (Optional[str]): Site id for which want to receive
|
|
@@ -3028,6 +3157,7 @@ def get_addons_project_settings(
|
|
|
3028
3157
|
return con.get_addons_project_settings(
|
|
3029
3158
|
project_name=project_name,
|
|
3030
3159
|
bundle_name=bundle_name,
|
|
3160
|
+
project_bundle_name=project_bundle_name,
|
|
3031
3161
|
variant=variant,
|
|
3032
3162
|
site_id=site_id,
|
|
3033
3163
|
use_site=use_site,
|
|
@@ -3037,6 +3167,7 @@ def get_addons_project_settings(
|
|
|
3037
3167
|
|
|
3038
3168
|
def get_addons_settings(
|
|
3039
3169
|
bundle_name: Optional[str] = None,
|
|
3170
|
+
project_bundle_name: Optional[str] = None,
|
|
3040
3171
|
project_name: Optional[str] = None,
|
|
3041
3172
|
variant: Optional[str] = None,
|
|
3042
3173
|
site_id: Optional[str] = None,
|
|
@@ -3056,6 +3187,8 @@ def get_addons_settings(
|
|
|
3056
3187
|
Args:
|
|
3057
3188
|
bundle_name (Optional[str]): Name of bundle for which should be
|
|
3058
3189
|
settings received.
|
|
3190
|
+
project_bundle_name (Optional[str]): Name of project bundle
|
|
3191
|
+
for which should be settings received.
|
|
3059
3192
|
project_name (Optional[str]): Name of project for which should be
|
|
3060
3193
|
settings received.
|
|
3061
3194
|
variant (Optional[Literal['production', 'staging']]): Name of
|
|
@@ -3072,6 +3205,7 @@ def get_addons_settings(
|
|
|
3072
3205
|
con = get_server_api_connection()
|
|
3073
3206
|
return con.get_addons_settings(
|
|
3074
3207
|
bundle_name=bundle_name,
|
|
3208
|
+
project_bundle_name=project_bundle_name,
|
|
3075
3209
|
project_name=project_name,
|
|
3076
3210
|
variant=variant,
|
|
3077
3211
|
site_id=site_id,
|
|
@@ -6887,6 +7021,7 @@ def create_link(
|
|
|
6887
7021
|
output_id: str,
|
|
6888
7022
|
output_type: str,
|
|
6889
7023
|
link_name: Optional[str] = None,
|
|
7024
|
+
data: Optional[dict[str, Any]] = None,
|
|
6890
7025
|
) -> CreateLinkData:
|
|
6891
7026
|
"""Create link between 2 entities.
|
|
6892
7027
|
|
|
@@ -6906,7 +7041,8 @@ def create_link(
|
|
|
6906
7041
|
output_id (str): Output entity id.
|
|
6907
7042
|
output_type (str): Entity type of output entity.
|
|
6908
7043
|
link_name (Optional[str]): Name of link.
|
|
6909
|
-
|
|
7044
|
+
data (Optional[dict[str, Any]]): Additional data to be stored
|
|
7045
|
+
with the link.
|
|
6910
7046
|
|
|
6911
7047
|
Returns:
|
|
6912
7048
|
CreateLinkData: Information about link.
|
|
@@ -6924,6 +7060,7 @@ def create_link(
|
|
|
6924
7060
|
output_id=output_id,
|
|
6925
7061
|
output_type=output_type,
|
|
6926
7062
|
link_name=link_name,
|
|
7063
|
+
data=data,
|
|
6927
7064
|
)
|
|
6928
7065
|
|
|
6929
7066
|
|
|
@@ -398,7 +398,7 @@ class BundlesAddonsAPI(BaseServerAPI):
|
|
|
398
398
|
|
|
399
399
|
"""
|
|
400
400
|
response = self.upload_file(
|
|
401
|
-
"addons/install",
|
|
401
|
+
"api/addons/install",
|
|
402
402
|
src_filepath,
|
|
403
403
|
progress=progress,
|
|
404
404
|
request_type=RequestTypes.post,
|
|
@@ -448,9 +448,11 @@ class BundlesAddonsAPI(BaseServerAPI):
|
|
|
448
448
|
"private",
|
|
449
449
|
filename
|
|
450
450
|
)
|
|
451
|
-
url = f"{self.get_base_url()}/{endpoint}"
|
|
452
451
|
self.download_file(
|
|
453
|
-
|
|
452
|
+
endpoint,
|
|
453
|
+
dst_filepath,
|
|
454
|
+
chunk_size=chunk_size,
|
|
455
|
+
progress=progress,
|
|
454
456
|
)
|
|
455
457
|
return dst_filepath
|
|
456
458
|
|
|
@@ -669,6 +671,7 @@ class BundlesAddonsAPI(BaseServerAPI):
|
|
|
669
671
|
self,
|
|
670
672
|
bundle_name: Optional[str] = None,
|
|
671
673
|
project_name: Optional[str] = None,
|
|
674
|
+
project_bundle_name: Optional[str] = None,
|
|
672
675
|
variant: Optional[str] = None,
|
|
673
676
|
site_id: Optional[str] = None,
|
|
674
677
|
use_site: bool = True,
|
|
@@ -712,6 +715,7 @@ class BundlesAddonsAPI(BaseServerAPI):
|
|
|
712
715
|
query = prepare_query_string({
|
|
713
716
|
"project_name": project_name or None,
|
|
714
717
|
"bundle_name": bundle_name or None,
|
|
718
|
+
"project_bundle_name": project_bundle_name or None,
|
|
715
719
|
"variant": variant or self.get_default_settings_variant() or None,
|
|
716
720
|
"site_id": site_id,
|
|
717
721
|
})
|
|
@@ -722,6 +726,7 @@ class BundlesAddonsAPI(BaseServerAPI):
|
|
|
722
726
|
def get_addons_studio_settings(
|
|
723
727
|
self,
|
|
724
728
|
bundle_name: Optional[str] = None,
|
|
729
|
+
project_bundle_name: Optional[str] = None,
|
|
725
730
|
variant: Optional[str] = None,
|
|
726
731
|
site_id: Optional[str] = None,
|
|
727
732
|
use_site: bool = True,
|
|
@@ -737,6 +742,8 @@ class BundlesAddonsAPI(BaseServerAPI):
|
|
|
737
742
|
Args:
|
|
738
743
|
bundle_name (Optional[str]): Name of bundle for which should be
|
|
739
744
|
settings received.
|
|
745
|
+
project_bundle_name (Optional[str]): Project bundle name for
|
|
746
|
+
which should be settings received.
|
|
740
747
|
variant (Optional[Literal['production', 'staging']]): Name of
|
|
741
748
|
settings variant. Used 'default_settings_variant' by default.
|
|
742
749
|
site_id (Optional[str]): Site id for which want to receive
|
|
@@ -753,6 +760,7 @@ class BundlesAddonsAPI(BaseServerAPI):
|
|
|
753
760
|
"""
|
|
754
761
|
output = self.get_bundle_settings(
|
|
755
762
|
bundle_name=bundle_name,
|
|
763
|
+
project_bundle_name=project_bundle_name,
|
|
756
764
|
variant=variant,
|
|
757
765
|
site_id=site_id,
|
|
758
766
|
use_site=use_site
|
|
@@ -768,6 +776,7 @@ class BundlesAddonsAPI(BaseServerAPI):
|
|
|
768
776
|
self,
|
|
769
777
|
project_name: str,
|
|
770
778
|
bundle_name: Optional[str] = None,
|
|
779
|
+
project_bundle_name: Optional[str] = None,
|
|
771
780
|
variant: Optional[str] = None,
|
|
772
781
|
site_id: Optional[str] = None,
|
|
773
782
|
use_site: bool = True,
|
|
@@ -799,6 +808,8 @@ class BundlesAddonsAPI(BaseServerAPI):
|
|
|
799
808
|
received.
|
|
800
809
|
bundle_name (Optional[str]): Name of bundle for which should be
|
|
801
810
|
settings received.
|
|
811
|
+
project_bundle_name (Optional[str]): Project bundle name for which
|
|
812
|
+
should be settings received.
|
|
802
813
|
variant (Optional[Literal['production', 'staging']]): Name of
|
|
803
814
|
settings variant. Used 'default_settings_variant' by default.
|
|
804
815
|
site_id (Optional[str]): Site id for which want to receive
|
|
@@ -820,6 +831,7 @@ class BundlesAddonsAPI(BaseServerAPI):
|
|
|
820
831
|
output = self.get_bundle_settings(
|
|
821
832
|
project_name=project_name,
|
|
822
833
|
bundle_name=bundle_name,
|
|
834
|
+
project_bundle_name=project_bundle_name,
|
|
823
835
|
variant=variant,
|
|
824
836
|
site_id=site_id,
|
|
825
837
|
use_site=use_site
|
|
@@ -834,6 +846,7 @@ class BundlesAddonsAPI(BaseServerAPI):
|
|
|
834
846
|
def get_addons_settings(
|
|
835
847
|
self,
|
|
836
848
|
bundle_name: Optional[str] = None,
|
|
849
|
+
project_bundle_name: Optional[str] = None,
|
|
837
850
|
project_name: Optional[str] = None,
|
|
838
851
|
variant: Optional[str] = None,
|
|
839
852
|
site_id: Optional[str] = None,
|
|
@@ -853,6 +866,8 @@ class BundlesAddonsAPI(BaseServerAPI):
|
|
|
853
866
|
Args:
|
|
854
867
|
bundle_name (Optional[str]): Name of bundle for which should be
|
|
855
868
|
settings received.
|
|
869
|
+
project_bundle_name (Optional[str]): Name of project bundle
|
|
870
|
+
for which should be settings received.
|
|
856
871
|
project_name (Optional[str]): Name of project for which should be
|
|
857
872
|
settings received.
|
|
858
873
|
variant (Optional[Literal['production', 'staging']]): Name of
|
|
@@ -869,6 +884,7 @@ class BundlesAddonsAPI(BaseServerAPI):
|
|
|
869
884
|
if project_name is None:
|
|
870
885
|
return self.get_addons_studio_settings(
|
|
871
886
|
bundle_name=bundle_name,
|
|
887
|
+
project_bundle_name=project_bundle_name,
|
|
872
888
|
variant=variant,
|
|
873
889
|
site_id=site_id,
|
|
874
890
|
use_site=use_site,
|
|
@@ -878,6 +894,7 @@ class BundlesAddonsAPI(BaseServerAPI):
|
|
|
878
894
|
return self.get_addons_project_settings(
|
|
879
895
|
project_name=project_name,
|
|
880
896
|
bundle_name=bundle_name,
|
|
897
|
+
project_bundle_name=project_bundle_name,
|
|
881
898
|
variant=variant,
|
|
882
899
|
site_id=site_id,
|
|
883
900
|
use_site=use_site,
|
{ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_api/_api_helpers/dependency_packages.py
RENAMED
|
@@ -189,7 +189,7 @@ class DependencyPackagesAPI(BaseServerAPI):
|
|
|
189
189
|
route = self._get_dependency_package_route(src_filename)
|
|
190
190
|
package_filepath = os.path.join(dst_directory, dst_filename)
|
|
191
191
|
self.download_file(
|
|
192
|
-
route,
|
|
192
|
+
f"api/{route}",
|
|
193
193
|
package_filepath,
|
|
194
194
|
chunk_size=chunk_size,
|
|
195
195
|
progress=progress
|
|
@@ -225,7 +225,7 @@ class DependencyPackagesAPI(BaseServerAPI):
|
|
|
225
225
|
)
|
|
226
226
|
|
|
227
227
|
route = self._get_dependency_package_route(dst_filename)
|
|
228
|
-
self.upload_file(route, src_filepath, progress=progress)
|
|
228
|
+
self.upload_file(f"api/{route}", src_filepath, progress=progress)
|
|
229
229
|
|
|
230
230
|
def _get_dependency_package_route(
|
|
231
231
|
self, filename: Optional[str] = None
|
|
@@ -143,7 +143,7 @@ class InstallersAPI(BaseServerAPI):
|
|
|
143
143
|
|
|
144
144
|
"""
|
|
145
145
|
return self.download_file(
|
|
146
|
-
f"desktop/installers/{filename}",
|
|
146
|
+
f"api/desktop/installers/{filename}",
|
|
147
147
|
dst_filepath,
|
|
148
148
|
chunk_size=chunk_size,
|
|
149
149
|
progress=progress
|
|
@@ -168,7 +168,7 @@ class InstallersAPI(BaseServerAPI):
|
|
|
168
168
|
|
|
169
169
|
"""
|
|
170
170
|
return self.upload_file(
|
|
171
|
-
f"desktop/installers/{dst_filename}",
|
|
171
|
+
f"api/desktop/installers/{dst_filename}",
|
|
172
172
|
src_filepath,
|
|
173
173
|
progress=progress
|
|
174
174
|
)
|
|
@@ -256,7 +256,7 @@ class ThumbnailsAPI(BaseServerAPI):
|
|
|
256
256
|
|
|
257
257
|
mime_type = get_media_mime_type(src_filepath)
|
|
258
258
|
response = self.upload_file(
|
|
259
|
-
f"projects/{project_name}/thumbnails",
|
|
259
|
+
f"api/projects/{project_name}/thumbnails",
|
|
260
260
|
src_filepath,
|
|
261
261
|
request_type=RequestTypes.post,
|
|
262
262
|
headers={"Content-Type": mime_type},
|
|
@@ -295,7 +295,7 @@ class ThumbnailsAPI(BaseServerAPI):
|
|
|
295
295
|
|
|
296
296
|
mime_type = get_media_mime_type_for_stream(stream)
|
|
297
297
|
response = self.upload_file_from_stream(
|
|
298
|
-
f"projects/{project_name}/thumbnails",
|
|
298
|
+
f"api/projects/{project_name}/thumbnails",
|
|
299
299
|
stream,
|
|
300
300
|
request_type=RequestTypes.post,
|
|
301
301
|
headers={"Content-Type": mime_type},
|
|
@@ -325,7 +325,7 @@ class ThumbnailsAPI(BaseServerAPI):
|
|
|
325
325
|
|
|
326
326
|
mime_type = get_media_mime_type(src_filepath)
|
|
327
327
|
response = self.upload_file(
|
|
328
|
-
f"projects/{project_name}/thumbnails/{thumbnail_id}",
|
|
328
|
+
f"api/projects/{project_name}/thumbnails/{thumbnail_id}",
|
|
329
329
|
src_filepath,
|
|
330
330
|
request_type=RequestTypes.put,
|
|
331
331
|
headers={"Content-Type": mime_type},
|
|
@@ -351,7 +351,7 @@ class ThumbnailsAPI(BaseServerAPI):
|
|
|
351
351
|
"""
|
|
352
352
|
mime_type = get_media_mime_type_for_stream(stream)
|
|
353
353
|
response = self.upload_file_from_stream(
|
|
354
|
-
f"projects/{project_name}/thumbnails/{thumbnail_id}",
|
|
354
|
+
f"api/projects/{project_name}/thumbnails/{thumbnail_id}",
|
|
355
355
|
stream,
|
|
356
356
|
request_type=RequestTypes.put,
|
|
357
357
|
headers={"Content-Type": mime_type},
|
|
@@ -62,6 +62,7 @@ from .utils import (
|
|
|
62
62
|
get_default_site_id,
|
|
63
63
|
NOT_SET,
|
|
64
64
|
get_media_mime_type,
|
|
65
|
+
get_media_mime_type_for_stream,
|
|
65
66
|
get_machine_name,
|
|
66
67
|
fill_own_attribs,
|
|
67
68
|
)
|
|
@@ -1352,7 +1353,7 @@ class ServerAPI(
|
|
|
1352
1353
|
|
|
1353
1354
|
def _download_file_to_stream(
|
|
1354
1355
|
self,
|
|
1355
|
-
|
|
1356
|
+
endpoint: str,
|
|
1356
1357
|
stream: StreamType,
|
|
1357
1358
|
chunk_size: int,
|
|
1358
1359
|
progress: TransferProgress,
|
|
@@ -1367,7 +1368,11 @@ class ServerAPI(
|
|
|
1367
1368
|
else:
|
|
1368
1369
|
get_func = self._session_functions_mapping[RequestTypes.get]
|
|
1369
1370
|
|
|
1371
|
+
url = self._endpoint_to_url(endpoint, use_rest=False)
|
|
1372
|
+
progress.set_source_url(url)
|
|
1373
|
+
|
|
1370
1374
|
retries = self.get_default_max_retries()
|
|
1375
|
+
api_prepended = False
|
|
1371
1376
|
for attempt in range(retries):
|
|
1372
1377
|
# Continue in download
|
|
1373
1378
|
offset = progress.get_transferred_size()
|
|
@@ -1376,6 +1381,18 @@ class ServerAPI(
|
|
|
1376
1381
|
|
|
1377
1382
|
try:
|
|
1378
1383
|
with get_func(url, **kwargs) as response:
|
|
1384
|
+
# Auto-fix missing 'api/'
|
|
1385
|
+
if response.status_code == 405 and not api_prepended:
|
|
1386
|
+
api_prepended = True
|
|
1387
|
+
if (
|
|
1388
|
+
not endpoint.startswith(self._base_url)
|
|
1389
|
+
and not endpoint.startswith("api/")
|
|
1390
|
+
):
|
|
1391
|
+
url = self._endpoint_to_url(
|
|
1392
|
+
endpoint, use_rest=True
|
|
1393
|
+
)
|
|
1394
|
+
progress.set_destination_url(url)
|
|
1395
|
+
continue
|
|
1379
1396
|
response.raise_for_status()
|
|
1380
1397
|
if progress.get_content_size() is None:
|
|
1381
1398
|
progress.set_content_size(
|
|
@@ -1395,6 +1412,12 @@ class ServerAPI(
|
|
|
1395
1412
|
raise
|
|
1396
1413
|
progress.next_attempt()
|
|
1397
1414
|
|
|
1415
|
+
if api_prepended:
|
|
1416
|
+
self.log.warning(
|
|
1417
|
+
f"Auto-fixed endpoint '{endpoint}' -> 'api/{endpoint}'."
|
|
1418
|
+
" Please fix the endpoint passed to the function."
|
|
1419
|
+
)
|
|
1420
|
+
|
|
1398
1421
|
def download_file_to_stream(
|
|
1399
1422
|
self,
|
|
1400
1423
|
endpoint: str,
|
|
@@ -1427,17 +1450,14 @@ class ServerAPI(
|
|
|
1427
1450
|
if not chunk_size:
|
|
1428
1451
|
chunk_size = self.default_download_chunk_size
|
|
1429
1452
|
|
|
1430
|
-
url = self._endpoint_to_url(endpoint, use_rest=False)
|
|
1431
|
-
|
|
1432
1453
|
if progress is None:
|
|
1433
1454
|
progress = TransferProgress()
|
|
1434
1455
|
|
|
1435
|
-
progress.set_source_url(url)
|
|
1436
1456
|
progress.set_started()
|
|
1437
1457
|
|
|
1438
1458
|
try:
|
|
1439
1459
|
self._download_file_to_stream(
|
|
1440
|
-
|
|
1460
|
+
endpoint, stream, chunk_size, progress
|
|
1441
1461
|
)
|
|
1442
1462
|
|
|
1443
1463
|
except Exception as exc:
|
|
@@ -1498,6 +1518,117 @@ class ServerAPI(
|
|
|
1498
1518
|
|
|
1499
1519
|
return progress
|
|
1500
1520
|
|
|
1521
|
+
def upload_project_file(
|
|
1522
|
+
self,
|
|
1523
|
+
project_name: str,
|
|
1524
|
+
filepath: str,
|
|
1525
|
+
*,
|
|
1526
|
+
content_type: Optional[str] = None,
|
|
1527
|
+
filename: Optional[str] = None,
|
|
1528
|
+
file_id: Optional[str] = None,
|
|
1529
|
+
activity_id: Optional[str] = None,
|
|
1530
|
+
chunk_size: Optional[int] = None,
|
|
1531
|
+
progress: Optional[TransferProgress] = None,
|
|
1532
|
+
) -> requests.Response:
|
|
1533
|
+
"""Upload project file from a filepath.
|
|
1534
|
+
|
|
1535
|
+
Project files are usually binary files, such as images, videos,
|
|
1536
|
+
or other media files that can be accessed via api endpoint
|
|
1537
|
+
'{server url}/api/projects/{project_name}/files/{file_id}'.
|
|
1538
|
+
|
|
1539
|
+
Args:
|
|
1540
|
+
project_name (str): Project name.
|
|
1541
|
+
filepath (str): Path where file will be downloaded.
|
|
1542
|
+
content_type (Optional[str]): MIME type of file.
|
|
1543
|
+
filename (Optional[str]): Server filename, filename from filepath
|
|
1544
|
+
is used if not passed.
|
|
1545
|
+
file_id (Optional[str]): File id.
|
|
1546
|
+
activity_id (Optional[str]): To which activity is file related.
|
|
1547
|
+
chunk_size (Optional[int]): Size of chunks that are received
|
|
1548
|
+
in single loop.
|
|
1549
|
+
progress (Optional[TransferProgress]): Object that gives ability
|
|
1550
|
+
to track download progress.
|
|
1551
|
+
|
|
1552
|
+
Returns:
|
|
1553
|
+
requests.Response: Requests response.
|
|
1554
|
+
|
|
1555
|
+
"""
|
|
1556
|
+
if not filename:
|
|
1557
|
+
filename = os.path.basename(filepath)
|
|
1558
|
+
|
|
1559
|
+
if not content_type:
|
|
1560
|
+
content_type = get_media_mime_type(filepath)
|
|
1561
|
+
if not content_type:
|
|
1562
|
+
content_type = "application/octet-stream"
|
|
1563
|
+
|
|
1564
|
+
query = prepare_query_string({
|
|
1565
|
+
"x_file_id": file_id,
|
|
1566
|
+
"x_activity_id": activity_id,
|
|
1567
|
+
})
|
|
1568
|
+
return self.upload_file(
|
|
1569
|
+
f"api/projects/{project_name}/files{query}",
|
|
1570
|
+
filepath,
|
|
1571
|
+
content_type=content_type,
|
|
1572
|
+
filename=filename,
|
|
1573
|
+
chunk_size=chunk_size,
|
|
1574
|
+
progress=progress,
|
|
1575
|
+
request_type=RequestTypes.post,
|
|
1576
|
+
)
|
|
1577
|
+
|
|
1578
|
+
def upload_project_file_from_stream(
|
|
1579
|
+
self,
|
|
1580
|
+
project_name: str,
|
|
1581
|
+
stream: StreamType,
|
|
1582
|
+
filename: str,
|
|
1583
|
+
*,
|
|
1584
|
+
content_type: Optional[str] = None,
|
|
1585
|
+
file_id: Optional[str] = None,
|
|
1586
|
+
activity_id: Optional[str] = None,
|
|
1587
|
+
chunk_size: Optional[int] = None,
|
|
1588
|
+
progress: Optional[TransferProgress] = None,
|
|
1589
|
+
) -> requests.Response:
|
|
1590
|
+
"""Upload project file from a filepath.
|
|
1591
|
+
|
|
1592
|
+
Project files are usually binary files, such as images, videos,
|
|
1593
|
+
or other media files that can be accessed via api endpoint
|
|
1594
|
+
'{server url}/api/projects/{project_name}/files/{file_id}'.
|
|
1595
|
+
|
|
1596
|
+
Args:
|
|
1597
|
+
project_name (str): Project name.
|
|
1598
|
+
stream (StreamType): Stream used as source for upload.
|
|
1599
|
+
filename (str): Name of file on server.
|
|
1600
|
+
content_type (Optional[str]): MIME type of file.
|
|
1601
|
+
file_id (Optional[str]): File id.
|
|
1602
|
+
activity_id (Optional[str]): To which activity is file related.
|
|
1603
|
+
chunk_size (Optional[int]): Size of chunks that are received
|
|
1604
|
+
in single loop.
|
|
1605
|
+
progress (Optional[TransferProgress]): Object that gives ability
|
|
1606
|
+
to track download progress.
|
|
1607
|
+
|
|
1608
|
+
Returns:
|
|
1609
|
+
requests.Response: Requests response.
|
|
1610
|
+
|
|
1611
|
+
"""
|
|
1612
|
+
if not content_type:
|
|
1613
|
+
stream.seek(0)
|
|
1614
|
+
content_type = get_media_mime_type_for_stream(stream)
|
|
1615
|
+
if not content_type:
|
|
1616
|
+
content_type = "application/octet-stream"
|
|
1617
|
+
|
|
1618
|
+
query = prepare_query_string({
|
|
1619
|
+
"x_file_id": file_id,
|
|
1620
|
+
"x_activity_id": activity_id,
|
|
1621
|
+
})
|
|
1622
|
+
return self.upload_file_from_stream(
|
|
1623
|
+
f"api/projects/{project_name}/files{query}",
|
|
1624
|
+
stream,
|
|
1625
|
+
content_type=content_type,
|
|
1626
|
+
filename=filename,
|
|
1627
|
+
chunk_size=chunk_size,
|
|
1628
|
+
progress=progress,
|
|
1629
|
+
request_type=RequestTypes.post,
|
|
1630
|
+
)
|
|
1631
|
+
|
|
1501
1632
|
def download_project_file(
|
|
1502
1633
|
self,
|
|
1503
1634
|
project_name: str,
|
|
@@ -1568,6 +1699,11 @@ class ServerAPI(
|
|
|
1568
1699
|
progress=progress,
|
|
1569
1700
|
)
|
|
1570
1701
|
|
|
1702
|
+
def delete_project_file(self, project_name: str, file_id: str) -> None:
|
|
1703
|
+
"""Delete project file."""
|
|
1704
|
+
response = self.delete(f"projects/{project_name}/files/{file_id}")
|
|
1705
|
+
response.raise_for_status()
|
|
1706
|
+
|
|
1571
1707
|
@staticmethod
|
|
1572
1708
|
def _upload_chunks_iter(
|
|
1573
1709
|
file_stream: StreamType,
|
|
@@ -1585,13 +1721,7 @@ class ServerAPI(
|
|
|
1585
1721
|
bytes: Chunk of file.
|
|
1586
1722
|
|
|
1587
1723
|
"""
|
|
1588
|
-
# Get size of file
|
|
1589
|
-
file_stream.seek(0, io.SEEK_END)
|
|
1590
|
-
size = file_stream.tell()
|
|
1591
1724
|
file_stream.seek(0)
|
|
1592
|
-
# Set content size to progress object
|
|
1593
|
-
progress.set_content_size(size)
|
|
1594
|
-
|
|
1595
1725
|
while True:
|
|
1596
1726
|
chunk = file_stream.read(chunk_size)
|
|
1597
1727
|
if not chunk:
|
|
@@ -1601,17 +1731,20 @@ class ServerAPI(
|
|
|
1601
1731
|
|
|
1602
1732
|
def _upload_file(
|
|
1603
1733
|
self,
|
|
1604
|
-
|
|
1734
|
+
endpoint: str,
|
|
1605
1735
|
stream: StreamType,
|
|
1606
1736
|
progress: TransferProgress,
|
|
1607
1737
|
request_type: Optional[RequestType] = None,
|
|
1608
1738
|
chunk_size: Optional[int] = None,
|
|
1739
|
+
*,
|
|
1740
|
+
content_type: Optional[str] = None,
|
|
1741
|
+
filename: Optional[str] = None,
|
|
1609
1742
|
**kwargs
|
|
1610
1743
|
) -> requests.Response:
|
|
1611
1744
|
"""Upload file to server.
|
|
1612
1745
|
|
|
1613
1746
|
Args:
|
|
1614
|
-
|
|
1747
|
+
endpoint (str): Endpoint used to upload.
|
|
1615
1748
|
stream (StreamType): File stream.
|
|
1616
1749
|
progress (TransferProgress): Object that gives ability to track
|
|
1617
1750
|
progress.
|
|
@@ -1629,11 +1762,18 @@ class ServerAPI(
|
|
|
1629
1762
|
if request_type is None:
|
|
1630
1763
|
request_type = RequestTypes.put
|
|
1631
1764
|
|
|
1765
|
+
endpoint = endpoint.lstrip("/")
|
|
1766
|
+
url = self._endpoint_to_url(endpoint, use_rest=False)
|
|
1767
|
+
progress.set_destination_url(url)
|
|
1768
|
+
|
|
1769
|
+
headers = kwargs.setdefault("headers", {})
|
|
1770
|
+
headers_keys_by_low_key = {key.lower(): key for key in headers}
|
|
1632
1771
|
if self._session is None:
|
|
1633
|
-
headers = kwargs.setdefault("headers", {})
|
|
1634
1772
|
for key, value in self.get_headers().items():
|
|
1635
|
-
|
|
1773
|
+
orig_key = headers_keys_by_low_key.get(key)
|
|
1774
|
+
if not orig_key:
|
|
1636
1775
|
headers[key] = value
|
|
1776
|
+
|
|
1637
1777
|
post_func = self._base_functions_mapping[request_type]
|
|
1638
1778
|
else:
|
|
1639
1779
|
post_func = self._session_functions_mapping[request_type]
|
|
@@ -1641,8 +1781,27 @@ class ServerAPI(
|
|
|
1641
1781
|
if not chunk_size:
|
|
1642
1782
|
chunk_size = self.default_upload_chunk_size
|
|
1643
1783
|
|
|
1784
|
+
for key, value in (
|
|
1785
|
+
("x-file-name", filename),
|
|
1786
|
+
("Content-Type", content_type),
|
|
1787
|
+
):
|
|
1788
|
+
if not value:
|
|
1789
|
+
continue
|
|
1790
|
+
orig_key = headers_keys_by_low_key.get(key.lower())
|
|
1791
|
+
if orig_key:
|
|
1792
|
+
headers.pop(orig_key)
|
|
1793
|
+
headers[key] = value
|
|
1794
|
+
|
|
1644
1795
|
retries = self.get_default_max_retries()
|
|
1645
1796
|
response = None
|
|
1797
|
+
|
|
1798
|
+
# Get size of file
|
|
1799
|
+
stream.seek(0, io.SEEK_END)
|
|
1800
|
+
size = stream.tell()
|
|
1801
|
+
# Set content size to progress object
|
|
1802
|
+
progress.set_content_size(size)
|
|
1803
|
+
|
|
1804
|
+
api_prepended = False
|
|
1646
1805
|
for attempt in range(retries):
|
|
1647
1806
|
try:
|
|
1648
1807
|
response = post_func(
|
|
@@ -1652,6 +1811,16 @@ class ServerAPI(
|
|
|
1652
1811
|
),
|
|
1653
1812
|
**kwargs
|
|
1654
1813
|
)
|
|
1814
|
+
# Auto-fix missing 'api/'
|
|
1815
|
+
if response.status_code == 405 and not api_prepended:
|
|
1816
|
+
api_prepended = True
|
|
1817
|
+
if (
|
|
1818
|
+
not endpoint.startswith(self._base_url)
|
|
1819
|
+
and not endpoint.startswith("api/")
|
|
1820
|
+
):
|
|
1821
|
+
url = self._endpoint_to_url(endpoint, use_rest=True)
|
|
1822
|
+
progress.set_destination_url(url)
|
|
1823
|
+
continue
|
|
1655
1824
|
break
|
|
1656
1825
|
|
|
1657
1826
|
except (
|
|
@@ -1664,6 +1833,11 @@ class ServerAPI(
|
|
|
1664
1833
|
progress.reset_transferred()
|
|
1665
1834
|
|
|
1666
1835
|
response.raise_for_status()
|
|
1836
|
+
if api_prepended:
|
|
1837
|
+
self.log.warning(
|
|
1838
|
+
f"Auto-fixed endpoint '{endpoint}' -> 'api/{endpoint}'."
|
|
1839
|
+
" Please fix the endpoint passed to the function."
|
|
1840
|
+
)
|
|
1667
1841
|
return response
|
|
1668
1842
|
|
|
1669
1843
|
def upload_file_from_stream(
|
|
@@ -1672,6 +1846,9 @@ class ServerAPI(
|
|
|
1672
1846
|
stream: StreamType,
|
|
1673
1847
|
progress: Optional[TransferProgress] = None,
|
|
1674
1848
|
request_type: Optional[RequestType] = None,
|
|
1849
|
+
*,
|
|
1850
|
+
content_type: Optional[str] = None,
|
|
1851
|
+
filename: Optional[str] = None,
|
|
1675
1852
|
**kwargs
|
|
1676
1853
|
) -> requests.Response:
|
|
1677
1854
|
"""Upload file to server from bytes.
|
|
@@ -1687,6 +1864,8 @@ class ServerAPI(
|
|
|
1687
1864
|
to track upload progress.
|
|
1688
1865
|
request_type (Optional[RequestType]): Type of request that will
|
|
1689
1866
|
be used to upload file.
|
|
1867
|
+
content_type (Optional[str]): MIME type of the file.
|
|
1868
|
+
filename (Optional[str]): Filename of file on server.
|
|
1690
1869
|
**kwargs (Any): Additional arguments that will be passed
|
|
1691
1870
|
to request function.
|
|
1692
1871
|
|
|
@@ -1694,19 +1873,22 @@ class ServerAPI(
|
|
|
1694
1873
|
requests.Response: Response object
|
|
1695
1874
|
|
|
1696
1875
|
"""
|
|
1697
|
-
url = self._endpoint_to_url(endpoint)
|
|
1698
|
-
|
|
1699
1876
|
# Create dummy object so the function does not have to check
|
|
1700
1877
|
# 'progress' variable everywhere
|
|
1701
1878
|
if progress is None:
|
|
1702
1879
|
progress = TransferProgress()
|
|
1703
1880
|
|
|
1704
|
-
progress.set_destination_url(url)
|
|
1705
1881
|
progress.set_started()
|
|
1706
1882
|
|
|
1707
1883
|
try:
|
|
1708
1884
|
return self._upload_file(
|
|
1709
|
-
|
|
1885
|
+
endpoint,
|
|
1886
|
+
stream,
|
|
1887
|
+
progress,
|
|
1888
|
+
request_type,
|
|
1889
|
+
content_type=content_type,
|
|
1890
|
+
filename=filename,
|
|
1891
|
+
**kwargs
|
|
1710
1892
|
)
|
|
1711
1893
|
|
|
1712
1894
|
except Exception as exc:
|
|
@@ -1722,6 +1904,9 @@ class ServerAPI(
|
|
|
1722
1904
|
filepath: str,
|
|
1723
1905
|
progress: Optional[TransferProgress] = None,
|
|
1724
1906
|
request_type: Optional[RequestType] = None,
|
|
1907
|
+
*,
|
|
1908
|
+
content_type: Optional[str] = None,
|
|
1909
|
+
filename: Optional[str] = None,
|
|
1725
1910
|
**kwargs
|
|
1726
1911
|
) -> requests.Response:
|
|
1727
1912
|
"""Upload file to server.
|
|
@@ -1737,6 +1922,8 @@ class ServerAPI(
|
|
|
1737
1922
|
to track upload progress.
|
|
1738
1923
|
request_type (Optional[RequestType]): Type of request that will
|
|
1739
1924
|
be used to upload file.
|
|
1925
|
+
content_type (Optional[str]): MIME type of the file.
|
|
1926
|
+
filename (Optional[str]): Filename of file on server.
|
|
1740
1927
|
**kwargs (Any): Additional arguments that will be passed
|
|
1741
1928
|
to request function.
|
|
1742
1929
|
|
|
@@ -1751,7 +1938,13 @@ class ServerAPI(
|
|
|
1751
1938
|
|
|
1752
1939
|
with open(filepath, "rb") as stream:
|
|
1753
1940
|
return self.upload_file_from_stream(
|
|
1754
|
-
endpoint,
|
|
1941
|
+
endpoint,
|
|
1942
|
+
stream,
|
|
1943
|
+
progress,
|
|
1944
|
+
request_type,
|
|
1945
|
+
content_type=content_type,
|
|
1946
|
+
filename=filename,
|
|
1947
|
+
**kwargs
|
|
1755
1948
|
)
|
|
1756
1949
|
|
|
1757
1950
|
def upload_reviewable(
|
|
@@ -1792,34 +1985,21 @@ class ServerAPI(
|
|
|
1792
1985
|
f"Could not determine MIME type of file '{filepath}'"
|
|
1793
1986
|
)
|
|
1794
1987
|
|
|
1795
|
-
if headers is None:
|
|
1796
|
-
headers = self.get_headers(content_type)
|
|
1797
|
-
else:
|
|
1798
|
-
# Make sure content-type is filled with file content type
|
|
1799
|
-
content_type_key = next(
|
|
1800
|
-
(
|
|
1801
|
-
key
|
|
1802
|
-
for key in headers
|
|
1803
|
-
if key.lower() == "content-type"
|
|
1804
|
-
),
|
|
1805
|
-
"Content-Type"
|
|
1806
|
-
)
|
|
1807
|
-
headers[content_type_key] = content_type
|
|
1808
|
-
|
|
1809
1988
|
# Fill original filename if not explicitly defined
|
|
1810
1989
|
if not filename:
|
|
1811
1990
|
filename = os.path.basename(filepath)
|
|
1812
|
-
headers["x-file-name"] = filename
|
|
1813
1991
|
|
|
1814
1992
|
query = prepare_query_string({"label": label or None})
|
|
1815
1993
|
endpoint = (
|
|
1816
|
-
f"/projects/{project_name}"
|
|
1994
|
+
f"api/projects/{project_name}"
|
|
1817
1995
|
f"/versions/{version_id}/reviewables{query}"
|
|
1818
1996
|
)
|
|
1819
1997
|
return self.upload_file(
|
|
1820
1998
|
endpoint,
|
|
1821
1999
|
filepath,
|
|
1822
2000
|
progress=progress,
|
|
2001
|
+
content_type=content_type,
|
|
2002
|
+
filename=filename,
|
|
1823
2003
|
headers=headers,
|
|
1824
2004
|
request_type=RequestTypes.post,
|
|
1825
2005
|
**kwargs
|
|
@@ -1118,12 +1118,12 @@ def _get_media_mime_type_for_content_base(content: bytes) -> Optional[str]:
|
|
|
1118
1118
|
content_len = len(content)
|
|
1119
1119
|
# Pre-validation (largest definition check)
|
|
1120
1120
|
# - hopefully there cannot be media defined in less than 12 bytes
|
|
1121
|
-
if content_len <
|
|
1121
|
+
if content_len < 4:
|
|
1122
1122
|
return None
|
|
1123
1123
|
|
|
1124
|
-
#
|
|
1125
|
-
if content[4
|
|
1126
|
-
return
|
|
1124
|
+
# PDF
|
|
1125
|
+
if content[0:4] == b"%PDF":
|
|
1126
|
+
return "application/pdf"
|
|
1127
1127
|
|
|
1128
1128
|
# BMP
|
|
1129
1129
|
if content[0:2] == b"BM":
|
|
@@ -1162,6 +1162,14 @@ def _get_media_mime_type_for_content_base(content: bytes) -> Optional[str]:
|
|
|
1162
1162
|
# with this header
|
|
1163
1163
|
if content[0:4] == b"\x00\x00\x01\x00":
|
|
1164
1164
|
return "image/x-icon"
|
|
1165
|
+
|
|
1166
|
+
if content_len < 8:
|
|
1167
|
+
return None
|
|
1168
|
+
|
|
1169
|
+
# FTYP
|
|
1170
|
+
if content[4:8] == b"ftyp":
|
|
1171
|
+
return _get_media_mime_type_from_ftyp(content)
|
|
1172
|
+
|
|
1165
1173
|
return None
|
|
1166
1174
|
|
|
1167
1175
|
|
|
@@ -1172,23 +1180,32 @@ def _get_svg_mime_type(content: bytes) -> Optional[str]:
|
|
|
1172
1180
|
return None
|
|
1173
1181
|
|
|
1174
1182
|
|
|
1183
|
+
def _get_json_mime_type(content: bytes) -> Optional[str]:
|
|
1184
|
+
# json
|
|
1185
|
+
try:
|
|
1186
|
+
json.loads(content.decode("utf-8"))
|
|
1187
|
+
return "application/json"
|
|
1188
|
+
except (UnicodeDecodeError, ValueError):
|
|
1189
|
+
pass
|
|
1190
|
+
return None
|
|
1191
|
+
|
|
1192
|
+
|
|
1175
1193
|
def get_media_mime_type_for_content(content: bytes) -> Optional[str]:
|
|
1176
1194
|
mime_type = _get_media_mime_type_for_content_base(content)
|
|
1177
1195
|
if mime_type is not None:
|
|
1178
1196
|
return mime_type
|
|
1179
|
-
return _get_svg_mime_type(content)
|
|
1197
|
+
return _get_svg_mime_type(content) or _get_json_mime_type(content)
|
|
1180
1198
|
|
|
1181
1199
|
|
|
1182
1200
|
def get_media_mime_type_for_stream(stream: StreamType) -> Optional[str]:
|
|
1183
1201
|
# Read only 12 bytes to determine mime type
|
|
1184
1202
|
content = stream.read(12)
|
|
1185
|
-
if len(content) < 12:
|
|
1186
|
-
return None
|
|
1187
1203
|
mime_type = _get_media_mime_type_for_content_base(content)
|
|
1188
|
-
if mime_type is None:
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1204
|
+
if mime_type is not None:
|
|
1205
|
+
return mime_type
|
|
1206
|
+
|
|
1207
|
+
content += stream.read()
|
|
1208
|
+
return _get_svg_mime_type(content) or _get_json_mime_type(content)
|
|
1192
1209
|
|
|
1193
1210
|
|
|
1194
1211
|
def get_media_mime_type(filepath: str) -> Optional[str]:
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""Package declaring Python API for AYON server."""
|
|
2
|
-
__version__ = "1.2.
|
|
2
|
+
__version__ = "1.2.12"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "ayon_python_api"
|
|
3
|
-
version = "1.2.
|
|
3
|
+
version = "1.2.12"
|
|
4
4
|
description = "AYON Python API"
|
|
5
5
|
license = {file = "LICENSE"}
|
|
6
6
|
readme = {file = "README.md", content-type = "text/markdown"}
|
|
@@ -28,7 +28,7 @@ build-backend = "poetry.core.masonry.api"
|
|
|
28
28
|
|
|
29
29
|
[tool.poetry]
|
|
30
30
|
name = "ayon_python_api"
|
|
31
|
-
version = "1.2.
|
|
31
|
+
version = "1.2.12"
|
|
32
32
|
description = "AYON Python API"
|
|
33
33
|
authors = [
|
|
34
34
|
"ynput.io <info@ynput.io>"
|
|
@@ -49,4 +49,4 @@ mock = "*"
|
|
|
49
49
|
sphinx-autoapi = "*"
|
|
50
50
|
revitron-sphinx-theme = { git = "https://github.com/revitron/revitron-sphinx-theme.git", branch = "master" }
|
|
51
51
|
pytest = "^6.2.5"
|
|
52
|
-
pydocstyle = "^6.3.0"
|
|
52
|
+
pydocstyle = "^6.3.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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ayon_python_api-1.2.10 → ayon_python_api-1.2.12}/ayon_python_api.egg-info/dependency_links.txt
RENAMED
|
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
|