sg-python-api 0.1.0__py3-none-any.whl → 0.1.2__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.
- {sg_python_api-0.1.0.dist-info → sg_python_api-0.1.2.dist-info}/METADATA +15 -28
- {sg_python_api-0.1.0.dist-info → sg_python_api-0.1.2.dist-info}/RECORD +13 -13
- shotgun_api3/_async_client.py +151 -108
- shotgun_api3/_async_driver.py +2 -14
- shotgun_api3/_client.py +152 -119
- shotgun_api3/_config.py +2 -10
- shotgun_api3/_driver.py +4 -18
- shotgun_api3/_files.py +66 -107
- shotgun_api3/_methods.py +104 -80
- shotgun_api3/_protocol.py +0 -93
- shotgun_api3/_version.py +1 -1
- {sg_python_api-0.1.0.dist-info → sg_python_api-0.1.2.dist-info}/WHEEL +0 -0
- {sg_python_api-0.1.0.dist-info → sg_python_api-0.1.2.dist-info}/licenses/LICENSE +0 -0
shotgun_api3/_async_driver.py
CHANGED
|
@@ -15,7 +15,6 @@ from typing import Protocol, TypeVar, cast
|
|
|
15
15
|
from . import _protocol, _transport
|
|
16
16
|
from ._async_transport import AsyncTransport
|
|
17
17
|
from ._config import (
|
|
18
|
-
CompatibilityWarningCode,
|
|
19
18
|
EventRoute,
|
|
20
19
|
ObserverCallback,
|
|
21
20
|
Outcome,
|
|
@@ -200,14 +199,11 @@ class AsyncExecutionOptions:
|
|
|
200
199
|
"""Control async executor transport choreography.
|
|
201
200
|
|
|
202
201
|
Attributes:
|
|
203
|
-
compatibility_warning_codes: Compatibility warnings emitted before
|
|
204
|
-
attempts.
|
|
205
202
|
logical_method_name: Optional observer-facing operation name.
|
|
206
203
|
redirect_factory: Optional request factory for redirect responses.
|
|
207
204
|
streaming: Whether the response body is consumed as a stream.
|
|
208
205
|
"""
|
|
209
206
|
|
|
210
|
-
compatibility_warning_codes: tuple[CompatibilityWarningCode, ...] = ()
|
|
211
207
|
logical_method_name: str | None = None
|
|
212
208
|
redirect_factory: Callable[['AsyncLiveResponse'], TransportRequest] | None = None
|
|
213
209
|
streaming: bool = False
|
|
@@ -486,10 +482,7 @@ class AsyncDriver:
|
|
|
486
482
|
consumption, or cleanup fails.
|
|
487
483
|
"""
|
|
488
484
|
execution_options = options or AsyncExecutionOptions()
|
|
489
|
-
for event in compatibility_warning_events(
|
|
490
|
-
execution_options.compatibility_warning_codes,
|
|
491
|
-
context.timeout,
|
|
492
|
-
):
|
|
485
|
+
for event in compatibility_warning_events(context.timeout):
|
|
493
486
|
notify_observer(context.on_compatibility_warning, event)
|
|
494
487
|
route = event_route(operation)
|
|
495
488
|
self._transport.checkout()
|
|
@@ -590,7 +583,6 @@ class AsyncDriver:
|
|
|
590
583
|
params: object,
|
|
591
584
|
context: RequestContext,
|
|
592
585
|
include_auth: bool = True,
|
|
593
|
-
compatibility_warning_codes: tuple[CompatibilityWarningCode, ...] = (),
|
|
594
586
|
*,
|
|
595
587
|
_logical_method_name: str | None = None,
|
|
596
588
|
) -> object:
|
|
@@ -601,7 +593,6 @@ class AsyncDriver:
|
|
|
601
593
|
params: Normalized method parameters.
|
|
602
594
|
context: Immutable operation configuration.
|
|
603
595
|
include_auth: Whether to include captured authentication.
|
|
604
|
-
compatibility_warning_codes: Sanitized compatibility notices.
|
|
605
596
|
_logical_method_name: Optional logical operation name when it
|
|
606
597
|
differs from the wire method.
|
|
607
598
|
|
|
@@ -615,10 +606,7 @@ class AsyncDriver:
|
|
|
615
606
|
consumption, or cleanup fails.
|
|
616
607
|
"""
|
|
617
608
|
normalized_params = copy.deepcopy(params)
|
|
618
|
-
options = AsyncExecutionOptions(
|
|
619
|
-
compatibility_warning_codes=compatibility_warning_codes,
|
|
620
|
-
logical_method_name=_logical_method_name,
|
|
621
|
-
)
|
|
609
|
+
options = AsyncExecutionOptions(logical_method_name=_logical_method_name)
|
|
622
610
|
return await self._execute_rpc(
|
|
623
611
|
method_name,
|
|
624
612
|
normalized_params,
|
shotgun_api3/_client.py
CHANGED
|
@@ -26,7 +26,6 @@ from . import _config as config_module
|
|
|
26
26
|
from . import _crud, _errors, _files, _methods, _protocol, _transport
|
|
27
27
|
from ._capabilities import ClientCapabilities, ServerCapabilities
|
|
28
28
|
from ._config import (
|
|
29
|
-
CompatibilityWarningCode,
|
|
30
29
|
Config,
|
|
31
30
|
RequestContext,
|
|
32
31
|
advance_transport_generation,
|
|
@@ -137,10 +136,8 @@ _CONSTRUCTOR_PARAMETERS = (
|
|
|
137
136
|
)
|
|
138
137
|
_UPLOAD_DOCSTRING = """Upload a file or thumbnail and return its Attachment ID.
|
|
139
138
|
|
|
140
|
-
A
|
|
141
|
-
|
|
142
|
-
route. The form request has already been sent when this error is
|
|
143
|
-
raised.
|
|
139
|
+
A server requiring legacy form uploads raises `ShotgunError` before
|
|
140
|
+
any upload request is sent. Server capability reads may occur.
|
|
144
141
|
|
|
145
142
|
Args:
|
|
146
143
|
entity_type: Entity type receiving the upload.
|
|
@@ -157,8 +154,8 @@ Returns:
|
|
|
157
154
|
Raises:
|
|
158
155
|
TypeError: If arguments do not match the documented signature.
|
|
159
156
|
ShotgunError: If the file or an upload response is invalid, an RPC
|
|
160
|
-
fault or terminal transport failure occurs, or the
|
|
161
|
-
form
|
|
157
|
+
fault or terminal transport failure occurs, or the server
|
|
158
|
+
requires legacy form uploads.
|
|
162
159
|
ProtocolError: If an upload endpoint returns an HTTP error.
|
|
163
160
|
ValueError: If authenticated HTTP violates the configured origin policy.
|
|
164
161
|
"""
|
|
@@ -348,7 +345,6 @@ class _InvocationOptions:
|
|
|
348
345
|
"""Collect non-payload controls for one client invocation."""
|
|
349
346
|
|
|
350
347
|
include_auth: bool = True
|
|
351
|
-
compatibility_warning_codes: tuple[CompatibilityWarningCode, ...] = ()
|
|
352
348
|
logical_method_name: str | None = None
|
|
353
349
|
auth_spec: _protocol.AuthSpec | None = None
|
|
354
350
|
|
|
@@ -570,7 +566,6 @@ class Shotgun:
|
|
|
570
566
|
outbound,
|
|
571
567
|
context,
|
|
572
568
|
include_auth=options.include_auth,
|
|
573
|
-
compatibility_warning_codes=options.compatibility_warning_codes,
|
|
574
569
|
_logical_method_name=options.logical_method_name,
|
|
575
570
|
)
|
|
576
571
|
return _protocol.transform_inbound(result, context.convert_datetimes_to_utc)
|
|
@@ -884,28 +879,6 @@ class Shotgun:
|
|
|
884
879
|
lambda _text, _headers: None,
|
|
885
880
|
)
|
|
886
881
|
|
|
887
|
-
@staticmethod
|
|
888
|
-
def _upload_form(
|
|
889
|
-
driver: Driver,
|
|
890
|
-
context: RequestContext,
|
|
891
|
-
prepared: _files.PreparedUpload,
|
|
892
|
-
) -> Never:
|
|
893
|
-
"""Send the observed form request without guessing a success result."""
|
|
894
|
-
if context.canonical_origin is None:
|
|
895
|
-
raise ValueError('server parameters must be configured before upload I/O')
|
|
896
|
-
exchange = _files.build_form_upload_exchange(
|
|
897
|
-
context.canonical_origin,
|
|
898
|
-
context.user_agent,
|
|
899
|
-
prepared,
|
|
900
|
-
context.auth,
|
|
901
|
-
)
|
|
902
|
-
|
|
903
|
-
def reject_success(_text: str, _headers: Mapping[str, str]) -> Never:
|
|
904
|
-
raise ShotgunError('form upload success response is not established')
|
|
905
|
-
|
|
906
|
-
_execute_upload_exchange(driver, context, exchange, reject_success)
|
|
907
|
-
raise AssertionError('form upload response parser returned')
|
|
908
|
-
|
|
909
882
|
@staticmethod
|
|
910
883
|
def _upload_link(
|
|
911
884
|
driver: Driver,
|
|
@@ -1002,14 +975,14 @@ class Shotgun:
|
|
|
1002
975
|
"""Execute one prepared upload through a captured driver lease."""
|
|
1003
976
|
arguments = prepared.options.arguments
|
|
1004
977
|
capabilities = self._ensure_readiness(context, driver)
|
|
1005
|
-
upload_path = _files.
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
978
|
+
upload_path = _files.require_supported_upload_path(
|
|
979
|
+
_files.choose_upload_path(
|
|
980
|
+
capabilities.server_info,
|
|
981
|
+
arguments.entity_type,
|
|
982
|
+
arguments.field_name,
|
|
983
|
+
prepared.file_size,
|
|
984
|
+
)
|
|
1010
985
|
)
|
|
1011
|
-
if upload_path == 'form':
|
|
1012
|
-
return self._upload_form(driver, context, prepared)
|
|
1013
986
|
multipart = upload_path == 'multipart'
|
|
1014
987
|
upload_info = self._upload_allocation(driver, context, prepared, multipart)
|
|
1015
988
|
if multipart:
|
|
@@ -1033,11 +1006,42 @@ class Shotgun:
|
|
|
1033
1006
|
prepared: _files.PreparedUpload,
|
|
1034
1007
|
) -> int:
|
|
1035
1008
|
"""Execute the exact direct-storage thumbnail workflow."""
|
|
1036
|
-
self._ensure_readiness(context, driver)
|
|
1009
|
+
capabilities = self._ensure_readiness(context, driver)
|
|
1010
|
+
arguments = prepared.options.arguments
|
|
1011
|
+
_files.require_supported_upload_path(
|
|
1012
|
+
_files.choose_upload_path(
|
|
1013
|
+
capabilities.server_info,
|
|
1014
|
+
arguments.entity_type,
|
|
1015
|
+
arguments.field_name,
|
|
1016
|
+
prepared.file_size,
|
|
1017
|
+
)
|
|
1018
|
+
)
|
|
1037
1019
|
upload_info = self._upload_allocation(driver, context, prepared, multipart=False)
|
|
1038
1020
|
self._upload_direct(driver, context, prepared, upload_info)
|
|
1039
1021
|
return self._upload_link(driver, context, prepared, upload_info)
|
|
1040
1022
|
|
|
1023
|
+
def _upload_thumbnails_after_write(
|
|
1024
|
+
self,
|
|
1025
|
+
entity_type: str,
|
|
1026
|
+
entity_id: int,
|
|
1027
|
+
thumbnails: dict[str, object],
|
|
1028
|
+
result: dict[str, object],
|
|
1029
|
+
) -> dict[str, object]:
|
|
1030
|
+
"""Upload separated thumbnail paths and merge their current field values."""
|
|
1031
|
+
if not thumbnails:
|
|
1032
|
+
return result
|
|
1033
|
+
for field_name, path in thumbnails.items():
|
|
1034
|
+
upload = (
|
|
1035
|
+
self.upload_filmstrip_thumbnail
|
|
1036
|
+
if field_name == 'filmstrip_image'
|
|
1037
|
+
else self.upload_thumbnail
|
|
1038
|
+
)
|
|
1039
|
+
upload(entity_type, entity_id, cast('str', path))
|
|
1040
|
+
current = self.find_one(entity_type, [['id', 'is', entity_id]], list(thumbnails))
|
|
1041
|
+
if current is not None:
|
|
1042
|
+
result.update({field_name: current.get(field_name) for field_name in thumbnails})
|
|
1043
|
+
return result
|
|
1044
|
+
|
|
1041
1045
|
@overload
|
|
1042
1046
|
def activity_stream_read(self, entity_type: Never) -> dict[str, object]: ...
|
|
1043
1047
|
|
|
@@ -1298,6 +1302,10 @@ class Shotgun:
|
|
|
1298
1302
|
) -> dict[str, object]:
|
|
1299
1303
|
"""Create an entity with the supplied field values.
|
|
1300
1304
|
|
|
1305
|
+
Non-empty `image` and `filmstrip_image` values are file paths. They are
|
|
1306
|
+
uploaded as thumbnails after the entity is created, and the result
|
|
1307
|
+
includes their current field values.
|
|
1308
|
+
|
|
1301
1309
|
Args:
|
|
1302
1310
|
entity_type: Entity type to create.
|
|
1303
1311
|
data: Field values for the new entity.
|
|
@@ -1308,14 +1316,20 @@ class Shotgun:
|
|
|
1308
1316
|
|
|
1309
1317
|
Raises:
|
|
1310
1318
|
ShotgunError: If an RPC fault or terminal transport failure occurs,
|
|
1311
|
-
|
|
1312
|
-
result is invalid
|
|
1319
|
+
if `data`, its field names, `return_fields`, or the server
|
|
1320
|
+
result is invalid, or if a thumbnail path is not a nonempty
|
|
1321
|
+
file. A thumbnail failure occurs after the entity is created.
|
|
1313
1322
|
ProtocolError: If a server request returns an HTTP error.
|
|
1314
1323
|
ValueError: If authenticated HTTP violates the configured origin
|
|
1315
1324
|
policy.
|
|
1316
1325
|
"""
|
|
1317
|
-
|
|
1318
|
-
|
|
1326
|
+
field_data, thumbnails = _files.split_thumbnail_uploads(data, keep_image_none=False)
|
|
1327
|
+
params = _crud.build_create_params(entity_type, field_data, return_fields)
|
|
1328
|
+
result = _crud.require_dictionary_result(self._call('create', params), 'create')
|
|
1329
|
+
if not thumbnails:
|
|
1330
|
+
return result
|
|
1331
|
+
entity_id = _crud.require_entity_id(result.get('id'), 'create did not return an entity id')
|
|
1332
|
+
return self._upload_thumbnails_after_write(entity_type, entity_id, thumbnails, result)
|
|
1319
1333
|
|
|
1320
1334
|
def delete(self, entity_type: str, entity_id: int) -> bool:
|
|
1321
1335
|
"""Retire an entity.
|
|
@@ -1422,6 +1436,15 @@ class Shotgun:
|
|
|
1422
1436
|
except (TransportError, _errors.ProtocolError, OSError):
|
|
1423
1437
|
raise _errors.ShotgunFileDownloadError('attachment download failed') from None
|
|
1424
1438
|
|
|
1439
|
+
def entity_types(self) -> Never:
|
|
1440
|
+
"""Reject the deprecated alias of `schema_entity_read()` without I/O.
|
|
1441
|
+
|
|
1442
|
+
Raises:
|
|
1443
|
+
ShotgunError: Always, naming `schema_entity_read()` as the
|
|
1444
|
+
replacement.
|
|
1445
|
+
"""
|
|
1446
|
+
raise _methods.entity_types_alias_error()
|
|
1447
|
+
|
|
1425
1448
|
@overload
|
|
1426
1449
|
def export_page(
|
|
1427
1450
|
self,
|
|
@@ -1442,6 +1465,9 @@ class Shotgun:
|
|
|
1442
1465
|
def export_page(self, *args: object, **kwargs: object) -> str:
|
|
1443
1466
|
"""Export a page using the documented arguments.
|
|
1444
1467
|
|
|
1468
|
+
The Page or its layout must be marked API Exportable in the web UI, or
|
|
1469
|
+
the server rejects the export.
|
|
1470
|
+
|
|
1445
1471
|
Args:
|
|
1446
1472
|
*args: Positional values from the documented `export_page`
|
|
1447
1473
|
signature.
|
|
@@ -1789,7 +1815,11 @@ class Shotgun:
|
|
|
1789
1815
|
seed_entity_field,
|
|
1790
1816
|
)
|
|
1791
1817
|
return _methods.require_dictionary_list_result(
|
|
1792
|
-
self._call(
|
|
1818
|
+
self._call(
|
|
1819
|
+
'nav_search',
|
|
1820
|
+
params,
|
|
1821
|
+
invocation_options=_InvocationOptions(logical_method_name='nav_search_entity'),
|
|
1822
|
+
),
|
|
1793
1823
|
'nav_search_entity',
|
|
1794
1824
|
)
|
|
1795
1825
|
|
|
@@ -1822,7 +1852,11 @@ class Shotgun:
|
|
|
1822
1852
|
seed_entity_field,
|
|
1823
1853
|
)
|
|
1824
1854
|
return _methods.require_dictionary_list_result(
|
|
1825
|
-
self._call(
|
|
1855
|
+
self._call(
|
|
1856
|
+
'nav_search',
|
|
1857
|
+
params,
|
|
1858
|
+
invocation_options=_InvocationOptions(logical_method_name='nav_search_string'),
|
|
1859
|
+
),
|
|
1826
1860
|
'nav_search_string',
|
|
1827
1861
|
)
|
|
1828
1862
|
|
|
@@ -1849,7 +1883,11 @@ class Shotgun:
|
|
|
1849
1883
|
"""
|
|
1850
1884
|
params = _methods.build_note_thread_read_params(note_id, entity_fields)
|
|
1851
1885
|
return _methods.require_dictionary_list_result(
|
|
1852
|
-
self._call(
|
|
1886
|
+
self._call(
|
|
1887
|
+
'note_thread_contents',
|
|
1888
|
+
params,
|
|
1889
|
+
invocation_options=_InvocationOptions(logical_method_name='note_thread_read'),
|
|
1890
|
+
),
|
|
1853
1891
|
'note_thread_read',
|
|
1854
1892
|
)
|
|
1855
1893
|
|
|
@@ -1900,6 +1938,18 @@ class Shotgun:
|
|
|
1900
1938
|
'revive',
|
|
1901
1939
|
)
|
|
1902
1940
|
|
|
1941
|
+
def schema(self, entity_type: str) -> Never:
|
|
1942
|
+
"""Reject the deprecated alias of `schema_field_read()` without I/O.
|
|
1943
|
+
|
|
1944
|
+
Args:
|
|
1945
|
+
entity_type: Entity type named in the replacement suggestion.
|
|
1946
|
+
|
|
1947
|
+
Raises:
|
|
1948
|
+
ShotgunError: Always, naming the equivalent `schema_field_read()`
|
|
1949
|
+
call.
|
|
1950
|
+
"""
|
|
1951
|
+
raise _methods.schema_alias_error(entity_type)
|
|
1952
|
+
|
|
1903
1953
|
def schema_entity_read(
|
|
1904
1954
|
self,
|
|
1905
1955
|
project_entity: dict[str, Any] | None = None,
|
|
@@ -1923,33 +1973,10 @@ class Shotgun:
|
|
|
1923
1973
|
self._call(
|
|
1924
1974
|
'schema_entity_read',
|
|
1925
1975
|
_methods.build_schema_entity_read_params(project_entity),
|
|
1926
|
-
_InvocationOptions(
|
|
1927
|
-
compatibility_warning_codes=_methods.consume_compatibility_warnings(
|
|
1928
|
-
_methods.SCHEMA_ENTITY_READ_WARNINGS,
|
|
1929
|
-
self,
|
|
1930
|
-
),
|
|
1931
|
-
),
|
|
1932
1976
|
),
|
|
1933
1977
|
'schema_entity_read',
|
|
1934
1978
|
)
|
|
1935
1979
|
|
|
1936
|
-
def entity_types(self) -> dict[str, object]:
|
|
1937
|
-
"""Return entity schema through the deprecated alias.
|
|
1938
|
-
|
|
1939
|
-
Returns:
|
|
1940
|
-
Entity-type schema data returned by the server.
|
|
1941
|
-
|
|
1942
|
-
Raises:
|
|
1943
|
-
ShotgunError: If an RPC fault or terminal transport failure occurs,
|
|
1944
|
-
or if the server result is not a dictionary.
|
|
1945
|
-
ProtocolError: If a server request returns an HTTP error.
|
|
1946
|
-
ValueError: If authenticated HTTP violates the configured origin
|
|
1947
|
-
policy.
|
|
1948
|
-
"""
|
|
1949
|
-
_methods.warn_entity_types_alias()
|
|
1950
|
-
with _methods.entity_types_alias(self):
|
|
1951
|
-
return self.schema_entity_read()
|
|
1952
|
-
|
|
1953
1980
|
def schema_field_create(
|
|
1954
1981
|
self,
|
|
1955
1982
|
entity_type: str,
|
|
@@ -2042,36 +2069,10 @@ class Shotgun:
|
|
|
2042
2069
|
field_name,
|
|
2043
2070
|
project_entity,
|
|
2044
2071
|
),
|
|
2045
|
-
_InvocationOptions(
|
|
2046
|
-
compatibility_warning_codes=_methods.consume_compatibility_warnings(
|
|
2047
|
-
_methods.SCHEMA_FIELD_READ_WARNINGS,
|
|
2048
|
-
self,
|
|
2049
|
-
),
|
|
2050
|
-
),
|
|
2051
2072
|
),
|
|
2052
2073
|
'schema_field_read',
|
|
2053
2074
|
)
|
|
2054
2075
|
|
|
2055
|
-
def schema(self, entity_type: str) -> dict[str, object]:
|
|
2056
|
-
"""Return field schema through the deprecated alias.
|
|
2057
|
-
|
|
2058
|
-
Args:
|
|
2059
|
-
entity_type: Entity type whose fields to return.
|
|
2060
|
-
|
|
2061
|
-
Returns:
|
|
2062
|
-
Field schema data returned by the server.
|
|
2063
|
-
|
|
2064
|
-
Raises:
|
|
2065
|
-
ShotgunError: If an RPC fault or terminal transport failure occurs,
|
|
2066
|
-
or if the server result is invalid.
|
|
2067
|
-
ProtocolError: If a server request returns an HTTP error.
|
|
2068
|
-
ValueError: If authenticated HTTP violates the configured origin
|
|
2069
|
-
policy.
|
|
2070
|
-
"""
|
|
2071
|
-
_methods.warn_schema_alias()
|
|
2072
|
-
with _methods.schema_alias(self):
|
|
2073
|
-
return self.schema_field_read(entity_type)
|
|
2074
|
-
|
|
2075
2076
|
def schema_field_update(
|
|
2076
2077
|
self,
|
|
2077
2078
|
entity_type: str,
|
|
@@ -2184,7 +2185,8 @@ class Shotgun:
|
|
|
2184
2185
|
|
|
2185
2186
|
Supply exactly one of `thumbnail_path` and `source_entity`. A local
|
|
2186
2187
|
thumbnail is uploaded to the first target before it is shared with the
|
|
2187
|
-
remaining targets.
|
|
2188
|
+
remaining targets. A local thumbnail is rejected before any upload
|
|
2189
|
+
request if the server requires legacy form uploads.
|
|
2188
2190
|
|
|
2189
2191
|
Args:
|
|
2190
2192
|
entities: Nonempty list of target entities with `type` and `id`.
|
|
@@ -2201,7 +2203,8 @@ class Shotgun:
|
|
|
2201
2203
|
TypeError: If forwarded arguments do not match the upload signature
|
|
2202
2204
|
or include `field_name`.
|
|
2203
2205
|
ShotgunError: If an RPC fault or terminal transport failure occurs,
|
|
2204
|
-
or if the source selection, entities, or transport fails
|
|
2206
|
+
or if the source selection, entities, or transport fails, or a
|
|
2207
|
+
local upload requires the legacy form route.
|
|
2205
2208
|
ShotgunThumbnailNotReady: If an uploaded source stays transient.
|
|
2206
2209
|
ProtocolError: If an upload endpoint returns an HTTP error.
|
|
2207
2210
|
ValueError: If authenticated HTTP violates the configured origin
|
|
@@ -2384,6 +2387,12 @@ class Shotgun:
|
|
|
2384
2387
|
) -> dict[str, object]:
|
|
2385
2388
|
"""Update fields on an existing entity.
|
|
2386
2389
|
|
|
2390
|
+
Non-empty `image` and `filmstrip_image` values are file paths. They are
|
|
2391
|
+
uploaded as thumbnails after the other fields are updated, and the
|
|
2392
|
+
result includes their current field values. An `image` of `None` clears
|
|
2393
|
+
both thumbnails. When no other fields remain, no update request is sent
|
|
2394
|
+
and the result contains only `id` and `type`.
|
|
2395
|
+
|
|
2387
2396
|
Args:
|
|
2388
2397
|
entity_type: Entity type to update.
|
|
2389
2398
|
entity_id: Numeric entity identifier.
|
|
@@ -2395,19 +2404,27 @@ class Shotgun:
|
|
|
2395
2404
|
|
|
2396
2405
|
Raises:
|
|
2397
2406
|
ShotgunError: If an RPC fault or terminal transport failure occurs,
|
|
2398
|
-
|
|
2399
|
-
|
|
2407
|
+
if `data`, its field names, `multi_entity_update_modes`, or the
|
|
2408
|
+
server result is invalid, or if a thumbnail path is not a
|
|
2409
|
+
nonempty file. A thumbnail failure occurs after the update.
|
|
2400
2410
|
ProtocolError: If a server request returns an HTTP error.
|
|
2401
2411
|
ValueError: If authenticated HTTP violates the configured origin
|
|
2402
2412
|
policy.
|
|
2403
2413
|
"""
|
|
2414
|
+
field_data, thumbnails = _files.split_thumbnail_uploads(data, keep_image_none=True)
|
|
2404
2415
|
params = _crud.build_update_params(
|
|
2405
2416
|
entity_type,
|
|
2406
2417
|
entity_id,
|
|
2407
|
-
|
|
2418
|
+
field_data,
|
|
2408
2419
|
multi_entity_update_modes,
|
|
2409
2420
|
)
|
|
2410
|
-
|
|
2421
|
+
result: dict[str, object] = {'id': entity_id, 'type': entity_type}
|
|
2422
|
+
if params['fields']:
|
|
2423
|
+
result = _crud.require_dictionary_result(
|
|
2424
|
+
self._call('update', params),
|
|
2425
|
+
'update',
|
|
2426
|
+
)
|
|
2427
|
+
return self._upload_thumbnails_after_write(entity_type, entity_id, thumbnails, result)
|
|
2411
2428
|
|
|
2412
2429
|
def update_project_last_accessed(
|
|
2413
2430
|
self,
|
|
@@ -2453,9 +2470,8 @@ class Shotgun:
|
|
|
2453
2470
|
def upload(self, *args: object, **kwargs: object) -> int:
|
|
2454
2471
|
"""Upload a file or thumbnail and return its Attachment ID.
|
|
2455
2472
|
|
|
2456
|
-
A
|
|
2457
|
-
|
|
2458
|
-
The form request has already been sent when this error is raised.
|
|
2473
|
+
A server requiring legacy form uploads raises `ShotgunError` before any
|
|
2474
|
+
upload request is sent. Server capability reads may occur.
|
|
2459
2475
|
|
|
2460
2476
|
Args:
|
|
2461
2477
|
*args: Positional arguments from the documented upload signature;
|
|
@@ -2468,8 +2484,8 @@ class Shotgun:
|
|
|
2468
2484
|
Raises:
|
|
2469
2485
|
TypeError: If arguments do not match the documented signature.
|
|
2470
2486
|
ShotgunError: If the file or an upload response is invalid, an RPC
|
|
2471
|
-
fault or terminal transport failure occurs, or the
|
|
2472
|
-
form
|
|
2487
|
+
fault or terminal transport failure occurs, or the server
|
|
2488
|
+
requires legacy form uploads.
|
|
2473
2489
|
ProtocolError: If an upload endpoint returns an HTTP error.
|
|
2474
2490
|
ValueError: If authenticated HTTP violates the configured origin
|
|
2475
2491
|
policy.
|
|
@@ -2501,6 +2517,9 @@ class Shotgun:
|
|
|
2501
2517
|
) -> int:
|
|
2502
2518
|
"""Upload a filmstrip thumbnail through `upload`.
|
|
2503
2519
|
|
|
2520
|
+
Servers requiring legacy form uploads are rejected before any upload
|
|
2521
|
+
request is sent.
|
|
2522
|
+
|
|
2504
2523
|
Args:
|
|
2505
2524
|
entity_type: Entity type receiving the thumbnail.
|
|
2506
2525
|
entity_id: Numeric identifier of the receiving entity.
|
|
@@ -2513,7 +2532,8 @@ class Shotgun:
|
|
|
2513
2532
|
Raises:
|
|
2514
2533
|
TypeError: If forwarded arguments do not match `upload`.
|
|
2515
2534
|
ShotgunError: If an RPC fault or terminal transport failure occurs,
|
|
2516
|
-
or if the file, upload response, or transport fails
|
|
2535
|
+
or if the file, upload response, or transport fails, or the
|
|
2536
|
+
server requires legacy form uploads.
|
|
2517
2537
|
ProtocolError: If an upload endpoint returns an HTTP error.
|
|
2518
2538
|
ValueError: If authenticated HTTP violates the configured origin
|
|
2519
2539
|
policy.
|
|
@@ -2535,6 +2555,9 @@ class Shotgun:
|
|
|
2535
2555
|
) -> int:
|
|
2536
2556
|
"""Upload a static thumbnail through `upload`.
|
|
2537
2557
|
|
|
2558
|
+
Servers requiring legacy form uploads are rejected before any upload
|
|
2559
|
+
request is sent.
|
|
2560
|
+
|
|
2538
2561
|
Args:
|
|
2539
2562
|
entity_type: Entity type receiving the thumbnail.
|
|
2540
2563
|
entity_id: Numeric identifier of the receiving entity.
|
|
@@ -2547,7 +2570,8 @@ class Shotgun:
|
|
|
2547
2570
|
Raises:
|
|
2548
2571
|
TypeError: If forwarded arguments do not match `upload`.
|
|
2549
2572
|
ShotgunError: If an RPC fault or terminal transport failure occurs,
|
|
2550
|
-
or if the file, upload response, or transport fails
|
|
2573
|
+
or if the file, upload response, or transport fails, or the
|
|
2574
|
+
server requires legacy form uploads.
|
|
2551
2575
|
ProtocolError: If an upload endpoint returns an HTTP error.
|
|
2552
2576
|
ValueError: If authenticated HTTP violates the configured origin
|
|
2553
2577
|
policy.
|
|
@@ -2563,44 +2587,53 @@ class Shotgun:
|
|
|
2563
2587
|
def user_subscriptions_create(self, users: list[dict[str, Any]]) -> bool:
|
|
2564
2588
|
"""Assign subscriptions to users.
|
|
2565
2589
|
|
|
2590
|
+
The server accepts this call from scripts and from human users with
|
|
2591
|
+
permission to manage subscriptions, such as members of the Admin
|
|
2592
|
+
permission group. It refuses other human users.
|
|
2593
|
+
|
|
2566
2594
|
Args:
|
|
2567
|
-
users: Subscription dictionaries
|
|
2595
|
+
users: Subscription dictionaries with a string or integer
|
|
2596
|
+
`humanUserId`; integers become decimal string keys and booleans
|
|
2597
|
+
are not accepted. Each user may appear only once.
|
|
2598
|
+
`subscription` is `None`, a string, or a list of strings.
|
|
2599
|
+
Lists are copied in order. Other entry keys are ignored.
|
|
2568
2600
|
|
|
2569
2601
|
Returns:
|
|
2570
|
-
|
|
2602
|
+
`True` when every per-user report is `None`, meaning the server
|
|
2603
|
+
reported no problem; `False` when any user has a non-`None` report.
|
|
2571
2604
|
|
|
2572
2605
|
Raises:
|
|
2573
2606
|
ShotgunError: If an RPC fault or terminal transport failure occurs,
|
|
2574
|
-
or if `users`
|
|
2575
|
-
|
|
2607
|
+
or if `users` contains invalid or duplicate entries, or the
|
|
2608
|
+
server result is not a mapping with string keys.
|
|
2576
2609
|
ProtocolError: If a server request returns an HTTP error.
|
|
2577
2610
|
ValueError: If authenticated HTTP violates the configured origin
|
|
2578
2611
|
policy.
|
|
2579
2612
|
"""
|
|
2580
|
-
return
|
|
2613
|
+
return _methods.require_user_subscriptions_create_result(
|
|
2581
2614
|
self._call(
|
|
2582
2615
|
'user_subscriptions_create',
|
|
2583
2616
|
_methods.build_user_subscriptions_create_params(users),
|
|
2584
2617
|
),
|
|
2585
|
-
'user_subscriptions_create',
|
|
2586
2618
|
)
|
|
2587
2619
|
|
|
2588
2620
|
def user_subscriptions_read(self) -> list[dict[str, object]]:
|
|
2589
|
-
"""List
|
|
2621
|
+
"""List user subscriptions in server order.
|
|
2590
2622
|
|
|
2591
2623
|
Returns:
|
|
2592
|
-
|
|
2624
|
+
Subscription entries in server order, each with an unchanged string
|
|
2625
|
+
`humanUserId` and a `subscription` of `None`, a string, or a copied
|
|
2626
|
+
list of strings.
|
|
2593
2627
|
|
|
2594
2628
|
Raises:
|
|
2595
2629
|
ShotgunError: If an RPC fault or terminal transport failure occurs,
|
|
2596
|
-
or if the server result is
|
|
2630
|
+
or if the server result is invalid.
|
|
2597
2631
|
ProtocolError: If a server request returns an HTTP error.
|
|
2598
2632
|
ValueError: If authenticated HTTP violates the configured origin
|
|
2599
2633
|
policy.
|
|
2600
2634
|
"""
|
|
2601
|
-
return _methods.
|
|
2635
|
+
return _methods.require_user_subscriptions_result(
|
|
2602
2636
|
self._call('user_subscriptions_read', None),
|
|
2603
|
-
'user_subscriptions_read',
|
|
2604
2637
|
)
|
|
2605
2638
|
|
|
2606
2639
|
def work_schedule_read(
|
shotgun_api3/_config.py
CHANGED
|
@@ -21,11 +21,7 @@ from ._sentinel import Unset as _Unset
|
|
|
21
21
|
from ._transport import TimeoutConfig
|
|
22
22
|
from ._version import PACKAGE_VERSION
|
|
23
23
|
|
|
24
|
-
CompatibilityWarningCode: TypeAlias = Literal[
|
|
25
|
-
'deprecated-entity-types-alias',
|
|
26
|
-
'deprecated-schema-alias',
|
|
27
|
-
'legacy-infinite-timeout',
|
|
28
|
-
]
|
|
24
|
+
CompatibilityWarningCode: TypeAlias = Literal['legacy-infinite-timeout']
|
|
29
25
|
EventRoute: TypeAlias = Literal[
|
|
30
26
|
'allocation',
|
|
31
27
|
'download',
|
|
@@ -85,8 +81,6 @@ _ORIGIN_FIELDS = frozenset({'api_path', 'scheme', 'server'})
|
|
|
85
81
|
_ORIGIN_STRING_FIELDS = frozenset({'scheme', 'server'})
|
|
86
82
|
_UNSET: Final = _Unset()
|
|
87
83
|
_WARNING_MESSAGES: Mapping[CompatibilityWarningCode, str] = {
|
|
88
|
-
'deprecated-entity-types-alias': 'The entity_types alias is deprecated.',
|
|
89
|
-
'deprecated-schema-alias': 'The schema alias is deprecated.',
|
|
90
84
|
'legacy-infinite-timeout': 'Explicit None timeout enables legacy infinite waits.',
|
|
91
85
|
}
|
|
92
86
|
_PUBLIC_FIELDS = frozenset(
|
|
@@ -1021,19 +1015,17 @@ def auth_spec(config: Config) -> _protocol.AuthSpec:
|
|
|
1021
1015
|
|
|
1022
1016
|
|
|
1023
1017
|
def compatibility_warning_events(
|
|
1024
|
-
warning_codes: tuple[CompatibilityWarningCode, ...],
|
|
1025
1018
|
timeout: TimeoutConfig,
|
|
1026
1019
|
) -> tuple[CompatibilityWarningEvent, ...]:
|
|
1027
1020
|
"""Build fixed-message compatibility warnings for one operation.
|
|
1028
1021
|
|
|
1029
1022
|
Args:
|
|
1030
|
-
warning_codes: Sanitized compatibility notices from the client.
|
|
1031
1023
|
timeout: Captured operation timeout semantics.
|
|
1032
1024
|
|
|
1033
1025
|
Returns:
|
|
1034
1026
|
Immutable compatibility-warning events in publication order.
|
|
1035
1027
|
"""
|
|
1036
|
-
codes =
|
|
1028
|
+
codes: list[CompatibilityWarningCode] = []
|
|
1037
1029
|
if timeout.connect is None and timeout.read is None:
|
|
1038
1030
|
codes.append('legacy-infinite-timeout')
|
|
1039
1031
|
return tuple(
|