sg-python-api 0.1.1__py3-none-any.whl → 0.2.0__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.1.dist-info → sg_python_api-0.2.0.dist-info}/METADATA +21 -24
- sg_python_api-0.2.0.dist-info/RECORD +58 -0
- shotgun_api3/__init__.py +4 -0
- shotgun_api3/_async_client.py +404 -316
- shotgun_api3/_async_driver.py +25 -55
- shotgun_api3/_async_httpx2.py +92 -59
- shotgun_api3/_async_transport.py +38 -3
- shotgun_api3/_capabilities.py +4 -3
- shotgun_api3/_client.py +354 -462
- shotgun_api3/_config.py +245 -120
- shotgun_api3/_connections.py +144 -0
- shotgun_api3/_crud.py +25 -250
- shotgun_api3/_driver.py +29 -54
- shotgun_api3/_execution.py +1 -3
- shotgun_api3/_files.py +215 -123
- shotgun_api3/_methods.py +153 -412
- shotgun_api3/_protocol.py +27 -146
- shotgun_api3/_transport.py +82 -407
- shotgun_api3/_version.py +7 -2
- shotgun_api3/lib/mockgun/__init__.py +20 -7
- shotgun_api3/lib/mockgun/_activity.py +510 -0
- shotgun_api3/lib/mockgun/_async_client.py +196 -0
- shotgun_api3/lib/mockgun/_dates.py +164 -0
- shotgun_api3/lib/mockgun/_errors.py +18 -0
- shotgun_api3/lib/mockgun/_events.py +1031 -0
- shotgun_api3/lib/mockgun/_follows.py +217 -0
- shotgun_api3/lib/mockgun/_handlers.py +558 -0
- shotgun_api3/lib/mockgun/_links.py +440 -0
- shotgun_api3/lib/mockgun/_new_client.py +92 -0
- shotgun_api3/lib/mockgun/_presets.py +492 -0
- shotgun_api3/lib/mockgun/_query.py +2163 -0
- shotgun_api3/lib/mockgun/_retirement.py +368 -0
- shotgun_api3/lib/mockgun/_schema.py +172 -0
- shotgun_api3/lib/mockgun/_schema_writes.py +425 -0
- shotgun_api3/lib/mockgun/_search.py +378 -0
- shotgun_api3/lib/mockgun/_server.py +169 -0
- shotgun_api3/lib/mockgun/_sessions.py +206 -0
- shotgun_api3/lib/mockgun/_site.py +150 -0
- shotgun_api3/lib/mockgun/_site_data.py +584 -0
- shotgun_api3/lib/mockgun/_storage.py +208 -0
- shotgun_api3/lib/mockgun/_store.py +1446 -0
- shotgun_api3/lib/mockgun/_summaries.py +964 -0
- shotgun_api3/lib/mockgun/_sync_client.py +190 -0
- shotgun_api3/lib/mockgun/_threads.py +226 -0
- shotgun_api3/lib/mockgun/_thumbnails.py +146 -0
- shotgun_api3/lib/mockgun/_transport.py +145 -0
- shotgun_api3/lib/mockgun/_uploads.py +417 -0
- shotgun_api3/lib/mockgun/_wire.py +120 -0
- shotgun_api3/lib/mockgun/mockgun.py +14 -0
- shotgun_api3/lib/sgtimezone.py +24 -1
- sg_python_api-0.1.1.dist-info/RECORD +0 -31
- shotgun_api3/_signatures.py +0 -53
- shotgun_api3/lib/mockgun/_async.py +0 -315
- shotgun_api3/lib/mockgun/_mockgun.py +0 -1666
- {sg_python_api-0.1.1.dist-info → sg_python_api-0.2.0.dist-info}/WHEEL +0 -0
- {sg_python_api-0.1.1.dist-info → sg_python_api-0.2.0.dist-info}/licenses/LICENSE +0 -0
shotgun_api3/_client.py
CHANGED
|
@@ -3,16 +3,16 @@
|
|
|
3
3
|
import copy
|
|
4
4
|
import dataclasses
|
|
5
5
|
import datetime as _dt_module
|
|
6
|
-
import inspect
|
|
7
6
|
import os
|
|
8
7
|
import threading
|
|
9
8
|
import urllib.request
|
|
10
|
-
import uuid
|
|
11
9
|
from collections.abc import Callable, Generator, Iterator, Mapping
|
|
12
10
|
from contextlib import ExitStack, contextmanager, suppress
|
|
11
|
+
from functools import partial
|
|
13
12
|
from pathlib import Path
|
|
14
13
|
from typing import (
|
|
15
14
|
Any,
|
|
15
|
+
ClassVar,
|
|
16
16
|
Literal,
|
|
17
17
|
Never,
|
|
18
18
|
TypeAlias,
|
|
@@ -48,7 +48,6 @@ from ._execution import (
|
|
|
48
48
|
release_lease,
|
|
49
49
|
retire_transport,
|
|
50
50
|
)
|
|
51
|
-
from ._signatures import bind_arguments, expose_signature
|
|
52
51
|
from ._transport import (
|
|
53
52
|
SendError,
|
|
54
53
|
StreamingResponse,
|
|
@@ -58,154 +57,12 @@ from ._transport import (
|
|
|
58
57
|
TransportResponse,
|
|
59
58
|
Urllib3Transport,
|
|
60
59
|
)
|
|
61
|
-
from ._version import
|
|
60
|
+
from ._version import COMPATIBILITY_VERSION
|
|
62
61
|
|
|
63
62
|
_ReadinessKey: TypeAlias = tuple[str, int]
|
|
64
63
|
_UploadResult = TypeVar('_UploadResult')
|
|
65
64
|
|
|
66
|
-
__version__ =
|
|
67
|
-
|
|
68
|
-
_CONSTRUCTOR_PARAMETERS = (
|
|
69
|
-
inspect.Parameter('base_url', inspect.Parameter.POSITIONAL_OR_KEYWORD, annotation=str),
|
|
70
|
-
inspect.Parameter(
|
|
71
|
-
'script_name',
|
|
72
|
-
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
73
|
-
default=None,
|
|
74
|
-
annotation=str | None,
|
|
75
|
-
),
|
|
76
|
-
inspect.Parameter(
|
|
77
|
-
'api_key',
|
|
78
|
-
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
79
|
-
default=None,
|
|
80
|
-
annotation=str | None,
|
|
81
|
-
),
|
|
82
|
-
inspect.Parameter(
|
|
83
|
-
'convert_datetimes_to_utc',
|
|
84
|
-
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
85
|
-
default=True,
|
|
86
|
-
annotation=bool,
|
|
87
|
-
),
|
|
88
|
-
inspect.Parameter(
|
|
89
|
-
'http_proxy',
|
|
90
|
-
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
91
|
-
default=None,
|
|
92
|
-
annotation=str | None,
|
|
93
|
-
),
|
|
94
|
-
inspect.Parameter(
|
|
95
|
-
'connect',
|
|
96
|
-
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
97
|
-
default=True,
|
|
98
|
-
annotation=bool,
|
|
99
|
-
),
|
|
100
|
-
inspect.Parameter(
|
|
101
|
-
'ca_certs',
|
|
102
|
-
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
103
|
-
default=None,
|
|
104
|
-
annotation=str | None,
|
|
105
|
-
),
|
|
106
|
-
inspect.Parameter(
|
|
107
|
-
'login',
|
|
108
|
-
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
109
|
-
default=None,
|
|
110
|
-
annotation=str | None,
|
|
111
|
-
),
|
|
112
|
-
inspect.Parameter(
|
|
113
|
-
'password',
|
|
114
|
-
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
115
|
-
default=None,
|
|
116
|
-
annotation=str | None,
|
|
117
|
-
),
|
|
118
|
-
inspect.Parameter(
|
|
119
|
-
'sudo_as_login',
|
|
120
|
-
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
121
|
-
default=None,
|
|
122
|
-
annotation=str | None,
|
|
123
|
-
),
|
|
124
|
-
inspect.Parameter(
|
|
125
|
-
'session_token',
|
|
126
|
-
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
127
|
-
default=None,
|
|
128
|
-
annotation=str | None,
|
|
129
|
-
),
|
|
130
|
-
inspect.Parameter(
|
|
131
|
-
'auth_token',
|
|
132
|
-
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
133
|
-
default=None,
|
|
134
|
-
annotation=str | None,
|
|
135
|
-
),
|
|
136
|
-
)
|
|
137
|
-
_UPLOAD_DOCSTRING = """Upload a file or thumbnail and return its Attachment ID.
|
|
138
|
-
|
|
139
|
-
A successful HTTP response from the legacy form-upload route still
|
|
140
|
-
raises `ShotgunError`; no Attachment ID is established for that
|
|
141
|
-
route. The form request has already been sent when this error is
|
|
142
|
-
raised.
|
|
143
|
-
|
|
144
|
-
Args:
|
|
145
|
-
entity_type: Entity type receiving the upload.
|
|
146
|
-
entity_id: Numeric identifier of the receiving entity.
|
|
147
|
-
path: Existing non-empty file path as text or filesystem-encoded bytes.
|
|
148
|
-
field_name: Optional file field receiving an Attachment.
|
|
149
|
-
display_name: Optional Attachment display name.
|
|
150
|
-
tag_list: Optional comma-delimited Attachment tags.
|
|
151
|
-
created_at: Optional Attachment creation timestamp.
|
|
152
|
-
|
|
153
|
-
Returns:
|
|
154
|
-
Created Attachment ID.
|
|
155
|
-
|
|
156
|
-
Raises:
|
|
157
|
-
TypeError: If arguments do not match the documented signature.
|
|
158
|
-
ShotgunError: If the file or an upload response is invalid, an RPC
|
|
159
|
-
fault or terminal transport failure occurs, or the legacy
|
|
160
|
-
form-upload route succeeds.
|
|
161
|
-
ProtocolError: If an upload endpoint returns an HTTP error.
|
|
162
|
-
ValueError: If authenticated HTTP violates the configured origin policy.
|
|
163
|
-
"""
|
|
164
|
-
_UPLOAD_PARAMETERS = (
|
|
165
|
-
inspect.Parameter('entity_type', inspect.Parameter.POSITIONAL_OR_KEYWORD, annotation=str),
|
|
166
|
-
inspect.Parameter('entity_id', inspect.Parameter.POSITIONAL_OR_KEYWORD, annotation=int),
|
|
167
|
-
inspect.Parameter('path', inspect.Parameter.POSITIONAL_OR_KEYWORD, annotation=str | bytes),
|
|
168
|
-
inspect.Parameter(
|
|
169
|
-
'field_name',
|
|
170
|
-
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
171
|
-
default=None,
|
|
172
|
-
annotation=str | None,
|
|
173
|
-
),
|
|
174
|
-
inspect.Parameter(
|
|
175
|
-
'display_name',
|
|
176
|
-
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
177
|
-
default=None,
|
|
178
|
-
annotation=str | None,
|
|
179
|
-
),
|
|
180
|
-
inspect.Parameter(
|
|
181
|
-
'tag_list',
|
|
182
|
-
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
183
|
-
default=None,
|
|
184
|
-
annotation=str | None,
|
|
185
|
-
),
|
|
186
|
-
inspect.Parameter(
|
|
187
|
-
'created_at',
|
|
188
|
-
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
189
|
-
default=None,
|
|
190
|
-
annotation=_dt_module.datetime | None,
|
|
191
|
-
),
|
|
192
|
-
)
|
|
193
|
-
CONSTRUCTOR_SIGNATURE = inspect.Signature(_CONSTRUCTOR_PARAMETERS, return_annotation=None)
|
|
194
|
-
_METHOD_CONSTRUCTOR_SIGNATURE = inspect.Signature(
|
|
195
|
-
(
|
|
196
|
-
inspect.Parameter('self', inspect.Parameter.POSITIONAL_OR_KEYWORD),
|
|
197
|
-
*_CONSTRUCTOR_PARAMETERS,
|
|
198
|
-
),
|
|
199
|
-
return_annotation=None,
|
|
200
|
-
)
|
|
201
|
-
_METHOD_UPLOAD_SIGNATURE = inspect.Signature(
|
|
202
|
-
(
|
|
203
|
-
inspect.Parameter('self', inspect.Parameter.POSITIONAL_OR_KEYWORD),
|
|
204
|
-
*_UPLOAD_PARAMETERS,
|
|
205
|
-
),
|
|
206
|
-
return_annotation=int,
|
|
207
|
-
)
|
|
208
|
-
_UPLOAD_SIGNATURE = inspect.Signature(_UPLOAD_PARAMETERS, return_annotation=int)
|
|
65
|
+
__version__ = COMPATIBILITY_VERSION
|
|
209
66
|
|
|
210
67
|
|
|
211
68
|
@dataclasses.dataclass(frozen=True)
|
|
@@ -274,13 +131,16 @@ class _DownloadExchange:
|
|
|
274
131
|
transfer = ExceptionCapture()
|
|
275
132
|
try:
|
|
276
133
|
with transfer:
|
|
277
|
-
|
|
134
|
+
with _files.download_destination_io(destination):
|
|
135
|
+
handle = stack.enter_context(_files.download_temporary(destination))
|
|
278
136
|
temporary = Path(handle.name)
|
|
279
137
|
control.consume_into(
|
|
280
138
|
chunks,
|
|
281
|
-
|
|
139
|
+
partial(_files.write_download_chunk, destination, handle),
|
|
282
140
|
total_bytes=total_bytes,
|
|
283
141
|
)
|
|
142
|
+
with _files.download_destination_io(destination):
|
|
143
|
+
handle.flush()
|
|
284
144
|
opened_stack = stack
|
|
285
145
|
stack = None
|
|
286
146
|
opened_cleanup = SuppressedExceptionCapture()
|
|
@@ -290,7 +150,8 @@ class _DownloadExchange:
|
|
|
290
150
|
raise _DownloadCleanupError from None
|
|
291
151
|
if opened_cleanup.exception is not None:
|
|
292
152
|
raise opened_cleanup.exception
|
|
293
|
-
|
|
153
|
+
with _files.download_destination_io(destination):
|
|
154
|
+
temporary.replace(destination)
|
|
294
155
|
finally:
|
|
295
156
|
close_cleanup = SuppressedExceptionCapture()
|
|
296
157
|
unlink_cleanup = SuppressedExceptionCapture()
|
|
@@ -319,12 +180,23 @@ class _DownloadExchange:
|
|
|
319
180
|
return control.consume(chunks, total_bytes=total_bytes)
|
|
320
181
|
return self._write_file(chunks, control, total_bytes)
|
|
321
182
|
|
|
322
|
-
def
|
|
183
|
+
def execute(
|
|
323
184
|
self,
|
|
324
185
|
driver: Driver,
|
|
325
186
|
operation: _protocol.OperationDescriptor,
|
|
326
187
|
) -> bytes | str:
|
|
327
|
-
"""Execute the workflow through the common streaming attempt loop.
|
|
188
|
+
"""Execute the workflow through the common streaming attempt loop.
|
|
189
|
+
|
|
190
|
+
Returns:
|
|
191
|
+
Downloaded bytes, or the destination path for a file download.
|
|
192
|
+
|
|
193
|
+
Raises:
|
|
194
|
+
SendError: If required download cleanup fails.
|
|
195
|
+
TransportError: If the attempt loop cannot complete the transfer.
|
|
196
|
+
ShotgunFileDownloadError: If the response or redirect is invalid,
|
|
197
|
+
or creating, writing, flushing, or publishing the destination
|
|
198
|
+
file fails.
|
|
199
|
+
"""
|
|
328
200
|
try:
|
|
329
201
|
return driver.execute(
|
|
330
202
|
operation,
|
|
@@ -351,16 +223,6 @@ class _InvocationOptions:
|
|
|
351
223
|
auth_spec: _protocol.AuthSpec | None = None
|
|
352
224
|
|
|
353
225
|
|
|
354
|
-
def _bind_upload(
|
|
355
|
-
args: tuple[object, ...],
|
|
356
|
-
kwargs: dict[str, object],
|
|
357
|
-
) -> _files.UploadArguments:
|
|
358
|
-
"""Bind runtime arguments with upload-specific errors."""
|
|
359
|
-
bound = bind_arguments(_UPLOAD_SIGNATURE, args, kwargs, 'Shotgun.upload()')
|
|
360
|
-
arguments = cast('Callable[..., _files.UploadArguments]', _files.UploadArguments)
|
|
361
|
-
return arguments(**bound.arguments)
|
|
362
|
-
|
|
363
|
-
|
|
364
226
|
def _execute_upload_exchange(
|
|
365
227
|
driver: Driver,
|
|
366
228
|
context: RequestContext,
|
|
@@ -376,7 +238,6 @@ def _execute_upload_exchange(
|
|
|
376
238
|
headers=dict(exchange.headers),
|
|
377
239
|
body=exchange.body_factory(),
|
|
378
240
|
timeout=context.timeout,
|
|
379
|
-
token=uuid.uuid4().hex,
|
|
380
241
|
)
|
|
381
242
|
|
|
382
243
|
def consume(
|
|
@@ -402,43 +263,23 @@ def _execute_upload_exchange(
|
|
|
402
263
|
)
|
|
403
264
|
|
|
404
265
|
|
|
405
|
-
def
|
|
406
|
-
"""
|
|
407
|
-
return expose_signature(function, _METHOD_UPLOAD_SIGNATURE, _UPLOAD_DOCSTRING)
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
def bind_constructor(
|
|
411
|
-
args: tuple[object, ...],
|
|
412
|
-
kwargs: dict[str, object],
|
|
413
|
-
client_name: str,
|
|
414
|
-
) -> ConstructorOptions:
|
|
415
|
-
"""Bind constructor arguments with client-specific errors.
|
|
266
|
+
def build_config(options: ConstructorOptions, *, in_process: bool = False) -> Config:
|
|
267
|
+
"""Initialize and validate network-free configuration, auth, and proxy fields.
|
|
416
268
|
|
|
417
269
|
Args:
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
270
|
+
options: Constructor values for the site, authentication, and proxy.
|
|
271
|
+
in_process: Whether requests stay inside this process, allowing
|
|
272
|
+
authentication without the network HTTP origin restriction.
|
|
421
273
|
|
|
422
274
|
Returns:
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
Raises:
|
|
426
|
-
TypeError: If the arguments do not match the public signature.
|
|
427
|
-
"""
|
|
428
|
-
bound = bind_arguments(CONSTRUCTOR_SIGNATURE, args, kwargs, f'{client_name}.__init__()')
|
|
429
|
-
constructor = cast('Callable[..., ConstructorOptions]', ConstructorOptions)
|
|
430
|
-
return constructor(**bound.arguments)
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
def build_config(options: ConstructorOptions) -> Config:
|
|
434
|
-
"""Initialize and validate network-free configuration, auth, and proxy fields.
|
|
275
|
+
A new configuration containing the validated constructor settings.
|
|
435
276
|
|
|
436
277
|
Raises:
|
|
437
278
|
TypeError: If a configuration or proxy value has an unsupported type.
|
|
438
279
|
ValueError: If authentication, site or proxy values, or
|
|
439
280
|
`SHOTGUN_API_RETRY_INTERVAL` are invalid.
|
|
440
281
|
"""
|
|
441
|
-
config = Config()
|
|
282
|
+
config = Config(_in_process=in_process)
|
|
442
283
|
config.set_server_params(options.base_url)
|
|
443
284
|
config.update_fields(
|
|
444
285
|
api_key=options.api_key,
|
|
@@ -457,26 +298,6 @@ def build_config(options: ConstructorOptions) -> Config:
|
|
|
457
298
|
return config
|
|
458
299
|
|
|
459
300
|
|
|
460
|
-
def expose_constructor_signature(function: Callable[..., object]) -> Callable[..., object]:
|
|
461
|
-
"""Expose the documented constructor signature.
|
|
462
|
-
|
|
463
|
-
Args:
|
|
464
|
-
function: Variadic constructor implementation.
|
|
465
|
-
|
|
466
|
-
Returns:
|
|
467
|
-
The same function with its public runtime signature attached.
|
|
468
|
-
"""
|
|
469
|
-
expose_signature(function, _METHOD_CONSTRUCTOR_SIGNATURE, None)
|
|
470
|
-
annotations = {
|
|
471
|
-
name: parameter.annotation
|
|
472
|
-
for name, parameter in CONSTRUCTOR_SIGNATURE.parameters.items()
|
|
473
|
-
if parameter.annotation is not inspect.Parameter.empty
|
|
474
|
-
}
|
|
475
|
-
annotations['return'] = CONSTRUCTOR_SIGNATURE.return_annotation
|
|
476
|
-
object.__setattr__(function, '__annotations__', annotations)
|
|
477
|
-
return function
|
|
478
|
-
|
|
479
|
-
|
|
480
301
|
class Shotgun:
|
|
481
302
|
"""Provide the synchronous Flow Production Tracking API client surface.
|
|
482
303
|
|
|
@@ -490,14 +311,12 @@ class Shotgun:
|
|
|
490
311
|
config: The writable client configuration.
|
|
491
312
|
server_caps: Validated capabilities for the configured origin.
|
|
492
313
|
server_info: Raw validated server metadata.
|
|
314
|
+
transport: Current transport backend, or `None` before connection or
|
|
315
|
+
after retirement.
|
|
493
316
|
"""
|
|
494
317
|
|
|
495
|
-
|
|
318
|
+
_in_process: ClassVar[bool] = False
|
|
496
319
|
|
|
497
|
-
@overload
|
|
498
|
-
def __init__(self, base_url: Never) -> None: ...
|
|
499
|
-
|
|
500
|
-
@overload
|
|
501
320
|
def __init__(
|
|
502
321
|
self,
|
|
503
322
|
base_url: str,
|
|
@@ -512,10 +331,7 @@ class Shotgun:
|
|
|
512
331
|
sudo_as_login: str | None = None,
|
|
513
332
|
session_token: str | None = None,
|
|
514
333
|
auth_token: str | None = None,
|
|
515
|
-
) -> None:
|
|
516
|
-
|
|
517
|
-
@expose_constructor_signature
|
|
518
|
-
def __init__(self, *args: object, **kwargs: object) -> None:
|
|
334
|
+
) -> None:
|
|
519
335
|
"""Initialize a client for one site and authentication mode.
|
|
520
336
|
|
|
521
337
|
Supply exactly one authentication mode: `script_name` with `api_key`,
|
|
@@ -527,30 +343,60 @@ class Shotgun:
|
|
|
527
343
|
`http_proxy` accepts `[user:pass@]host[:port]`, with port 8080 when
|
|
528
344
|
omitted. A truthy `ca_certs` selects a CA bundle; otherwise
|
|
529
345
|
`SHOTGUN_API_CACERTS` is consulted before using system trust roots.
|
|
346
|
+
`SHOTGUN_API_RETRY_INTERVAL` supplies a nonnegative integer retry
|
|
347
|
+
interval in milliseconds, defaulting to 3000.
|
|
530
348
|
|
|
531
349
|
Construction performs server-readiness I/O by default. Supplying
|
|
532
350
|
`auth_token` also performs a session-token exchange during
|
|
533
351
|
construction, even when `connect` is `False`.
|
|
534
352
|
|
|
535
353
|
Args:
|
|
536
|
-
|
|
537
|
-
|
|
354
|
+
base_url: Flow Production Tracking site URL.
|
|
355
|
+
script_name: Script name for script authentication.
|
|
356
|
+
api_key: API key for script authentication.
|
|
357
|
+
convert_datetimes_to_utc: Whether to convert datetime values to
|
|
358
|
+
UTC.
|
|
359
|
+
http_proxy: Optional proxy authority in `[user:pass@]host[:port]`
|
|
360
|
+
form.
|
|
361
|
+
connect: Whether to perform eager readiness during construction.
|
|
362
|
+
ca_certs: Optional certificate-authority bundle path.
|
|
363
|
+
login: Login for human-user authentication.
|
|
364
|
+
password: Password for human-user authentication.
|
|
365
|
+
sudo_as_login: Optional user login for sudo impersonation.
|
|
366
|
+
session_token: Existing session token for authentication.
|
|
367
|
+
auth_token: Optional two-factor authentication token.
|
|
538
368
|
|
|
539
369
|
Raises:
|
|
540
|
-
|
|
541
|
-
|
|
370
|
+
ValueError: If authentication, URL, or proxy values are invalid,
|
|
371
|
+
the configured CA bundle is not a readable file, or
|
|
372
|
+
`SHOTGUN_API_RETRY_INTERVAL` is not a nonnegative integer.
|
|
542
373
|
ShotgunError: If authentication, server metadata, or an RPC result
|
|
543
374
|
is invalid, or a transport attempt fails.
|
|
544
375
|
ProtocolError: If eager readiness or token exchange receives an
|
|
545
376
|
HTTP error.
|
|
546
377
|
"""
|
|
547
|
-
self._initialize(
|
|
378
|
+
self._initialize(
|
|
379
|
+
ConstructorOptions(
|
|
380
|
+
base_url,
|
|
381
|
+
script_name,
|
|
382
|
+
api_key,
|
|
383
|
+
convert_datetimes_to_utc,
|
|
384
|
+
http_proxy,
|
|
385
|
+
connect,
|
|
386
|
+
ca_certs,
|
|
387
|
+
login,
|
|
388
|
+
password,
|
|
389
|
+
sudo_as_login,
|
|
390
|
+
session_token,
|
|
391
|
+
auth_token,
|
|
392
|
+
)
|
|
393
|
+
)
|
|
548
394
|
|
|
549
395
|
@property
|
|
550
396
|
def _connection(self) -> Transport | None:
|
|
551
397
|
"""Return the current private connection compatibility view."""
|
|
552
398
|
with self._transport_lock:
|
|
553
|
-
return self.
|
|
399
|
+
return self.transport
|
|
554
400
|
|
|
555
401
|
def _invoke(
|
|
556
402
|
self,
|
|
@@ -573,12 +419,16 @@ class Shotgun:
|
|
|
573
419
|
return _protocol.transform_inbound(result, context.convert_datetimes_to_utc)
|
|
574
420
|
|
|
575
421
|
def _new_transport(self, context: RequestContext) -> Transport:
|
|
576
|
-
"""Create a transport for one
|
|
422
|
+
"""Create a transport for one generation; mockgun overrides this package-internal hook."""
|
|
423
|
+
if context.in_process:
|
|
424
|
+
raise RuntimeError('an in-process client must supply its own transport')
|
|
577
425
|
return Urllib3Transport(
|
|
578
426
|
ca_certs=self._ca_certs,
|
|
579
427
|
proxy_headers=dict(context.proxy_headers) or None,
|
|
580
428
|
proxy_url=context.proxy_url,
|
|
581
429
|
pool_maxsize=context.pool_maxsize,
|
|
430
|
+
max_connection_idle_secs=context.max_connection_idle_secs,
|
|
431
|
+
tcp_keepalive_timeout_secs=context.tcp_keepalive_timeout_secs,
|
|
582
432
|
)
|
|
583
433
|
|
|
584
434
|
def _publish_capabilities(
|
|
@@ -616,34 +466,39 @@ class Shotgun:
|
|
|
616
466
|
"""Lease the driver and transport for one complete logical operation."""
|
|
617
467
|
close_after_unlock: list[Transport] = []
|
|
618
468
|
with self._transport_lock:
|
|
619
|
-
|
|
469
|
+
decision = _files.choose_driver_lease(
|
|
470
|
+
self._known_transport,
|
|
471
|
+
self.transport,
|
|
472
|
+
self._driver_generation,
|
|
473
|
+
context.transport_generation,
|
|
474
|
+
self._transport_owned,
|
|
475
|
+
)
|
|
476
|
+
if decision.known_changed:
|
|
620
477
|
if self._known_transport is not None:
|
|
621
478
|
retired = retire_transport(
|
|
622
479
|
self._lease_counts, self._retired_transports, self._known_transport
|
|
623
480
|
)
|
|
624
481
|
if retired is not None:
|
|
625
482
|
close_after_unlock.append(retired)
|
|
626
|
-
self._known_transport = self.
|
|
483
|
+
self._known_transport = self.transport
|
|
627
484
|
self._driver = None
|
|
628
485
|
self._driver_generation = None
|
|
629
486
|
self._transport_owned = False
|
|
630
487
|
|
|
631
|
-
transport = self.
|
|
488
|
+
transport = self.transport
|
|
632
489
|
if transport is None:
|
|
633
490
|
transport = self._new_transport(context)
|
|
634
|
-
self.
|
|
491
|
+
self.transport = transport
|
|
635
492
|
self._known_transport = transport
|
|
636
493
|
self._transport_owned = True
|
|
637
|
-
elif
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
self._transport = transport
|
|
646
|
-
self._known_transport = transport
|
|
494
|
+
elif decision.replace_owned_transport:
|
|
495
|
+
retired = retire_transport(self._lease_counts, self._retired_transports, transport)
|
|
496
|
+
if retired is not None:
|
|
497
|
+
close_after_unlock.append(retired)
|
|
498
|
+
transport = self._new_transport(context)
|
|
499
|
+
self.transport = transport
|
|
500
|
+
self._known_transport = transport
|
|
501
|
+
if decision.reset_driver:
|
|
647
502
|
self._driver = None
|
|
648
503
|
|
|
649
504
|
if self._driver is None:
|
|
@@ -801,7 +656,9 @@ class Shotgun:
|
|
|
801
656
|
_files.SHARE_THUMBNAIL,
|
|
802
657
|
fields,
|
|
803
658
|
),
|
|
804
|
-
lambda text, _headers: _files.parse_link_completion(
|
|
659
|
+
lambda text, _headers: _files.parse_link_completion(
|
|
660
|
+
text, operation='share_thumbnail', entities=entities
|
|
661
|
+
),
|
|
805
662
|
)
|
|
806
663
|
|
|
807
664
|
def _thumbnail_source_ready(
|
|
@@ -875,34 +732,12 @@ class Shotgun:
|
|
|
875
732
|
_files.StorageRange(
|
|
876
733
|
length=prepared.file_size,
|
|
877
734
|
offset=0,
|
|
878
|
-
path=prepared.
|
|
735
|
+
path=prepared.path,
|
|
879
736
|
),
|
|
880
737
|
),
|
|
881
738
|
lambda _text, _headers: None,
|
|
882
739
|
)
|
|
883
740
|
|
|
884
|
-
@staticmethod
|
|
885
|
-
def _upload_form(
|
|
886
|
-
driver: Driver,
|
|
887
|
-
context: RequestContext,
|
|
888
|
-
prepared: _files.PreparedUpload,
|
|
889
|
-
) -> Never:
|
|
890
|
-
"""Send the observed form request without guessing a success result."""
|
|
891
|
-
if context.canonical_origin is None:
|
|
892
|
-
raise ValueError('server parameters must be configured before upload I/O')
|
|
893
|
-
exchange = _files.build_form_upload_exchange(
|
|
894
|
-
context.canonical_origin,
|
|
895
|
-
context.user_agent,
|
|
896
|
-
prepared,
|
|
897
|
-
context.auth,
|
|
898
|
-
)
|
|
899
|
-
|
|
900
|
-
def reject_success(_text: str, _headers: Mapping[str, str]) -> Never:
|
|
901
|
-
raise ShotgunError('form upload success response is not established')
|
|
902
|
-
|
|
903
|
-
_execute_upload_exchange(driver, context, exchange, reject_success)
|
|
904
|
-
raise AssertionError('form upload response parser returned')
|
|
905
|
-
|
|
906
741
|
@staticmethod
|
|
907
742
|
def _upload_link(
|
|
908
743
|
driver: Driver,
|
|
@@ -928,7 +763,16 @@ class Shotgun:
|
|
|
928
763
|
_files.LINK_FILE,
|
|
929
764
|
fields,
|
|
930
765
|
),
|
|
931
|
-
lambda text, _headers: _files.parse_link_completion(
|
|
766
|
+
lambda text, _headers: _files.parse_link_completion(
|
|
767
|
+
text,
|
|
768
|
+
operation='upload link',
|
|
769
|
+
entities=[
|
|
770
|
+
{
|
|
771
|
+
'type': prepared.options.arguments.entity_type,
|
|
772
|
+
'id': prepared.options.arguments.entity_id,
|
|
773
|
+
}
|
|
774
|
+
],
|
|
775
|
+
),
|
|
932
776
|
)
|
|
933
777
|
|
|
934
778
|
@staticmethod
|
|
@@ -997,16 +841,8 @@ class Shotgun:
|
|
|
997
841
|
prepared: _files.PreparedUpload,
|
|
998
842
|
) -> int:
|
|
999
843
|
"""Execute one prepared upload through a captured driver lease."""
|
|
1000
|
-
arguments = prepared.options.arguments
|
|
1001
844
|
capabilities = self._ensure_readiness(context, driver)
|
|
1002
|
-
upload_path = _files.
|
|
1003
|
-
capabilities.server_info,
|
|
1004
|
-
arguments.entity_type,
|
|
1005
|
-
arguments.field_name,
|
|
1006
|
-
prepared.file_size,
|
|
1007
|
-
)
|
|
1008
|
-
if upload_path == 'form':
|
|
1009
|
-
return self._upload_form(driver, context, prepared)
|
|
845
|
+
upload_path = _files.choose_prepared_upload_path(capabilities.server_info, prepared)
|
|
1010
846
|
multipart = upload_path == 'multipart'
|
|
1011
847
|
upload_info = self._upload_allocation(driver, context, prepared, multipart)
|
|
1012
848
|
if multipart:
|
|
@@ -1030,7 +866,10 @@ class Shotgun:
|
|
|
1030
866
|
prepared: _files.PreparedUpload,
|
|
1031
867
|
) -> int:
|
|
1032
868
|
"""Execute the exact direct-storage thumbnail workflow."""
|
|
1033
|
-
self._ensure_readiness(context, driver)
|
|
869
|
+
capabilities = self._ensure_readiness(context, driver)
|
|
870
|
+
_files.choose_prepared_upload_path(
|
|
871
|
+
capabilities.server_info, prepared, sharing_thumbnail=True
|
|
872
|
+
)
|
|
1034
873
|
upload_info = self._upload_allocation(driver, context, prepared, multipart=False)
|
|
1035
874
|
self._upload_direct(driver, context, prepared, upload_info)
|
|
1036
875
|
return self._upload_link(driver, context, prepared, upload_info)
|
|
@@ -1057,10 +896,6 @@ class Shotgun:
|
|
|
1057
896
|
result.update({field_name: current.get(field_name) for field_name in thumbnails})
|
|
1058
897
|
return result
|
|
1059
898
|
|
|
1060
|
-
@overload
|
|
1061
|
-
def activity_stream_read(self, entity_type: Never) -> dict[str, object]: ...
|
|
1062
|
-
|
|
1063
|
-
@overload
|
|
1064
899
|
def activity_stream_read(
|
|
1065
900
|
self,
|
|
1066
901
|
entity_type: str,
|
|
@@ -1069,30 +904,30 @@ class Shotgun:
|
|
|
1069
904
|
min_id: int | None = None,
|
|
1070
905
|
max_id: int | None = None,
|
|
1071
906
|
limit: int | None = None,
|
|
1072
|
-
) -> dict[str, object]:
|
|
1073
|
-
|
|
1074
|
-
@_methods.expose_activity_stream_read_signature
|
|
1075
|
-
def activity_stream_read(self, *args: object, **kwargs: object) -> dict[str, object]:
|
|
907
|
+
) -> dict[str, object]:
|
|
1076
908
|
"""Read the activity stream for one entity.
|
|
1077
909
|
|
|
1078
910
|
Args:
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
911
|
+
entity_type: Entity type whose activity stream to read.
|
|
912
|
+
entity_id: Numeric identifier of the entity.
|
|
913
|
+
entity_fields: Optional fields to return for linked entity types.
|
|
914
|
+
min_id: Optional minimum activity identifier.
|
|
915
|
+
max_id: Optional maximum activity identifier.
|
|
916
|
+
limit: Optional maximum number of activity records.
|
|
1083
917
|
|
|
1084
918
|
Returns:
|
|
1085
919
|
Activity stream data returned by the server.
|
|
1086
920
|
|
|
1087
921
|
Raises:
|
|
1088
|
-
TypeError: If arguments do not match the documented signature.
|
|
1089
922
|
ShotgunError: If an RPC fault or terminal transport failure occurs,
|
|
1090
923
|
or if the server result has the wrong type.
|
|
1091
924
|
ProtocolError: If a server request returns an HTTP error.
|
|
1092
925
|
ValueError: If authenticated HTTP violates the configured origin
|
|
1093
926
|
policy.
|
|
1094
927
|
"""
|
|
1095
|
-
options = _methods.
|
|
928
|
+
options = _methods.ActivityStreamReadOptions(
|
|
929
|
+
entity_type, entity_id, entity_fields, min_id, max_id, limit
|
|
930
|
+
)
|
|
1096
931
|
return _crud.require_dictionary_result(
|
|
1097
932
|
self._call(
|
|
1098
933
|
'activity_stream',
|
|
@@ -1178,7 +1013,10 @@ class Shotgun:
|
|
|
1178
1013
|
type, or if the server result is not a list.
|
|
1179
1014
|
ProtocolError: If a server request returns an HTTP error.
|
|
1180
1015
|
ValueError: If authenticated HTTP violates the configured origin
|
|
1181
|
-
policy.
|
|
1016
|
+
policy, or a naive datetime cannot be converted to UTC.
|
|
1017
|
+
OverflowError: If converting an aware datetime to UTC exceeds the
|
|
1018
|
+
supported datetime range.
|
|
1019
|
+
OSError: If the platform cannot resolve a local datetime.
|
|
1182
1020
|
"""
|
|
1183
1021
|
calls = _crud.build_batch_calls(requests)
|
|
1184
1022
|
if not calls:
|
|
@@ -1251,21 +1089,29 @@ class Shotgun:
|
|
|
1251
1089
|
)
|
|
1252
1090
|
|
|
1253
1091
|
def close(self) -> None:
|
|
1254
|
-
"""Retire known and current transports after in-flight work releases them.
|
|
1092
|
+
"""Retire known and current transports after in-flight work releases them.
|
|
1093
|
+
|
|
1094
|
+
Attempt the remaining immediately eligible closes if one fails, then
|
|
1095
|
+
propagate the first failure.
|
|
1096
|
+
|
|
1097
|
+
Raises:
|
|
1098
|
+
Exception: If a transport eligible for immediate cleanup fails to
|
|
1099
|
+
close.
|
|
1100
|
+
"""
|
|
1255
1101
|
close_after_unlock: list[Transport] = []
|
|
1256
1102
|
with self._transport_lock:
|
|
1257
1103
|
advance_transport_generation(self._config)
|
|
1258
|
-
if self._known_transport is not None and self._known_transport is not self.
|
|
1104
|
+
if self._known_transport is not None and self._known_transport is not self.transport:
|
|
1259
1105
|
retired = retire_transport(
|
|
1260
1106
|
self._lease_counts, self._retired_transports, self._known_transport
|
|
1261
1107
|
)
|
|
1262
1108
|
if retired is not None:
|
|
1263
1109
|
close_after_unlock.append(retired)
|
|
1264
|
-
transport = self.
|
|
1110
|
+
transport = self.transport
|
|
1265
1111
|
self._driver = None
|
|
1266
1112
|
self._driver_generation = None
|
|
1267
1113
|
self._known_transport = None
|
|
1268
|
-
self.
|
|
1114
|
+
self.transport = None
|
|
1269
1115
|
self._transport_owned = False
|
|
1270
1116
|
if transport is not None:
|
|
1271
1117
|
retired = retire_transport(self._lease_counts, self._retired_transports, transport)
|
|
@@ -1336,7 +1182,10 @@ class Shotgun:
|
|
|
1336
1182
|
file. A thumbnail failure occurs after the entity is created.
|
|
1337
1183
|
ProtocolError: If a server request returns an HTTP error.
|
|
1338
1184
|
ValueError: If authenticated HTTP violates the configured origin
|
|
1339
|
-
policy.
|
|
1185
|
+
policy, or a naive datetime cannot be converted to UTC.
|
|
1186
|
+
OverflowError: If converting an aware datetime to UTC exceeds the
|
|
1187
|
+
supported datetime range.
|
|
1188
|
+
OSError: If the platform cannot resolve a local datetime.
|
|
1340
1189
|
"""
|
|
1341
1190
|
field_data, thumbnails = _files.split_thumbnail_uploads(data, keep_image_none=False)
|
|
1342
1191
|
params = _crud.build_create_params(entity_type, field_data, return_fields)
|
|
@@ -1404,13 +1253,13 @@ class Shotgun:
|
|
|
1404
1253
|
|
|
1405
1254
|
Raises:
|
|
1406
1255
|
TypeError: If no attachment is given or the reference is a string.
|
|
1407
|
-
ValueError: If an entity dictionary references a different type
|
|
1256
|
+
ValueError: If an entity dictionary references a different type,
|
|
1257
|
+
server settings are incomplete, or authenticated HTTP violates
|
|
1258
|
+
the configured origin security policy.
|
|
1408
1259
|
ShotgunError: If another attachment reference is unsupported or a
|
|
1409
1260
|
setup RPC reports a fault; the fault keeps its specific type.
|
|
1410
1261
|
ShotgunFileDownloadError: If the resolved URL is invalid or setup,
|
|
1411
1262
|
transfer, or destination I/O fails.
|
|
1412
|
-
ValueError: If server settings are incomplete or authenticated HTTP
|
|
1413
|
-
violates the configured origin security policy.
|
|
1414
1263
|
"""
|
|
1415
1264
|
if attachment is False:
|
|
1416
1265
|
if attachment_id is None:
|
|
@@ -1445,7 +1294,7 @@ class Shotgun:
|
|
|
1445
1294
|
headers=headers,
|
|
1446
1295
|
url=url,
|
|
1447
1296
|
)
|
|
1448
|
-
return exchange.
|
|
1297
|
+
return exchange.execute(driver, operation)
|
|
1449
1298
|
except _errors.ShotgunFileDownloadError:
|
|
1450
1299
|
raise
|
|
1451
1300
|
except (TransportError, _errors.ProtocolError, OSError):
|
|
@@ -1460,51 +1309,36 @@ class Shotgun:
|
|
|
1460
1309
|
"""
|
|
1461
1310
|
raise _methods.entity_types_alias_error()
|
|
1462
1311
|
|
|
1463
|
-
@overload
|
|
1464
1312
|
def export_page(
|
|
1465
1313
|
self,
|
|
1466
1314
|
page_id: int,
|
|
1467
|
-
|
|
1468
|
-
/,
|
|
1315
|
+
format: str, # noqa: A002
|
|
1469
1316
|
layout_name: str | None = None,
|
|
1470
|
-
) -> str:
|
|
1471
|
-
|
|
1472
|
-
@overload
|
|
1473
|
-
def export_page(
|
|
1474
|
-
self,
|
|
1475
|
-
page_id: int,
|
|
1476
|
-
**kwargs: Unpack[_methods.ExportPageKeywordArguments],
|
|
1477
|
-
) -> str: ...
|
|
1478
|
-
|
|
1479
|
-
@_methods.expose_export_page_signature
|
|
1480
|
-
def export_page(self, *args: object, **kwargs: object) -> str:
|
|
1317
|
+
) -> str:
|
|
1481
1318
|
"""Export a page using the documented arguments.
|
|
1482
1319
|
|
|
1320
|
+
The Page or its layout must be marked API Exportable in the web UI, or
|
|
1321
|
+
the server rejects the export.
|
|
1322
|
+
|
|
1483
1323
|
Args:
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
signature.
|
|
1324
|
+
page_id: Numeric page identifier.
|
|
1325
|
+
format: Required nonempty export format name.
|
|
1326
|
+
layout_name: Optional layout name, including an empty name.
|
|
1488
1327
|
|
|
1489
1328
|
Returns:
|
|
1490
1329
|
Exported page text returned by the server.
|
|
1491
1330
|
|
|
1492
1331
|
Raises:
|
|
1493
|
-
TypeError: If arguments do not match the documented signature.
|
|
1494
1332
|
ShotgunError: If an RPC fault or terminal transport failure occurs,
|
|
1495
|
-
or if
|
|
1333
|
+
or if `page_id`, `format`, or the server result is invalid.
|
|
1496
1334
|
ProtocolError: If a server request returns an HTTP error.
|
|
1497
1335
|
ValueError: If authenticated HTTP violates the configured origin
|
|
1498
1336
|
policy.
|
|
1499
1337
|
"""
|
|
1500
|
-
options = _methods.
|
|
1338
|
+
options = _methods.ExportPageOptions(page_id, format, layout_name)
|
|
1501
1339
|
params = _methods.build_export_page_params(options)
|
|
1502
1340
|
return _methods.require_string_result(self._call('export_page', params), 'export_page')
|
|
1503
1341
|
|
|
1504
|
-
@overload
|
|
1505
|
-
def find(self, entity_type: Never) -> list[dict[str, object]]: ...
|
|
1506
|
-
|
|
1507
|
-
@overload
|
|
1508
1342
|
def find(
|
|
1509
1343
|
self,
|
|
1510
1344
|
entity_type: str,
|
|
@@ -1517,33 +1351,50 @@ class Shotgun:
|
|
|
1517
1351
|
page: int = 0,
|
|
1518
1352
|
include_archived_projects: bool = True,
|
|
1519
1353
|
additional_filter_presets: object = None,
|
|
1520
|
-
) -> list[dict[str, object]]:
|
|
1521
|
-
|
|
1522
|
-
@_crud.expose_find_signature
|
|
1523
|
-
def find(self, *args: object, **kwargs: object) -> list[dict[str, object]]:
|
|
1354
|
+
) -> list[dict[str, object]]:
|
|
1524
1355
|
"""Find entities matching the supplied filters.
|
|
1525
1356
|
|
|
1526
1357
|
Args:
|
|
1527
|
-
|
|
1528
|
-
|
|
1358
|
+
entity_type: Entity type to find.
|
|
1359
|
+
filters: Filters in list or dict syntax.
|
|
1360
|
+
fields: Optional fields to return; defaults to `id`.
|
|
1361
|
+
order: Optional field and direction sort specifications.
|
|
1362
|
+
filter_operator: `'all'` or `'any'` for list-syntax filters.
|
|
1363
|
+
limit: Maximum entities to return, or `0` for no limit.
|
|
1364
|
+
retired_only: Return retired entities instead of active entities.
|
|
1365
|
+
page: Specific page to return, or `0` to read all pages.
|
|
1366
|
+
include_archived_projects: Include entities from archived projects.
|
|
1367
|
+
additional_filter_presets: Optional server-side filter presets.
|
|
1529
1368
|
|
|
1530
1369
|
Returns:
|
|
1531
1370
|
Matching entities in server order.
|
|
1532
1371
|
|
|
1533
1372
|
Raises:
|
|
1534
|
-
TypeError: If arguments do not match the documented signature.
|
|
1535
1373
|
ShotgunError: If an RPC fault or terminal transport failure occurs,
|
|
1536
|
-
or if filters, paging, ordering, or a server result is
|
|
1374
|
+
or if filters, fields, paging, ordering, or a server result is
|
|
1375
|
+
invalid.
|
|
1537
1376
|
ProtocolError: If a server request returns an HTTP error.
|
|
1538
1377
|
ValueError: If authenticated HTTP violates the configured origin
|
|
1539
|
-
policy.
|
|
1378
|
+
policy, or a naive datetime cannot be converted to UTC.
|
|
1379
|
+
OverflowError: If converting an aware datetime to UTC exceeds the
|
|
1380
|
+
supported datetime range.
|
|
1381
|
+
OSError: If the platform cannot resolve a local datetime.
|
|
1540
1382
|
"""
|
|
1541
|
-
return self._find(
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1383
|
+
return self._find(
|
|
1384
|
+
_crud.FindOptions(
|
|
1385
|
+
entity_type,
|
|
1386
|
+
filters,
|
|
1387
|
+
fields,
|
|
1388
|
+
order,
|
|
1389
|
+
filter_operator,
|
|
1390
|
+
limit,
|
|
1391
|
+
retired_only,
|
|
1392
|
+
page,
|
|
1393
|
+
include_archived_projects,
|
|
1394
|
+
additional_filter_presets,
|
|
1395
|
+
)
|
|
1396
|
+
)
|
|
1545
1397
|
|
|
1546
|
-
@overload
|
|
1547
1398
|
def find_one(
|
|
1548
1399
|
self,
|
|
1549
1400
|
entity_type: str,
|
|
@@ -1554,28 +1405,43 @@ class Shotgun:
|
|
|
1554
1405
|
retired_only: bool = False,
|
|
1555
1406
|
include_archived_projects: bool = True,
|
|
1556
1407
|
additional_filter_presets: object = None,
|
|
1557
|
-
) -> dict[str, object] | None:
|
|
1558
|
-
|
|
1559
|
-
@_crud.expose_find_one_signature
|
|
1560
|
-
def find_one(self, *args: object, **kwargs: object) -> dict[str, object] | None:
|
|
1408
|
+
) -> dict[str, object] | None:
|
|
1561
1409
|
"""Return the first entity matching the supplied filters.
|
|
1562
1410
|
|
|
1563
1411
|
Args:
|
|
1564
|
-
|
|
1565
|
-
|
|
1412
|
+
entity_type: Entity type to find.
|
|
1413
|
+
filters: Filters in list or dict syntax.
|
|
1414
|
+
fields: Optional fields to return; defaults to `id`.
|
|
1415
|
+
order: Optional field and direction sort specifications.
|
|
1416
|
+
filter_operator: `'all'` or `'any'` for list-syntax filters.
|
|
1417
|
+
retired_only: Return a retired entity instead of an active entity.
|
|
1418
|
+
include_archived_projects: Include entities from archived projects.
|
|
1419
|
+
additional_filter_presets: Optional server-side filter presets.
|
|
1566
1420
|
|
|
1567
1421
|
Returns:
|
|
1568
1422
|
The first matching entity, or `None` when no entity matches.
|
|
1569
1423
|
|
|
1570
1424
|
Raises:
|
|
1571
|
-
TypeError: If arguments do not match the documented signature.
|
|
1572
1425
|
ShotgunError: If an RPC fault or terminal transport failure occurs,
|
|
1573
|
-
or if filters, paging, ordering, or a server result is
|
|
1426
|
+
or if filters, fields, paging, ordering, or a server result is
|
|
1427
|
+
invalid.
|
|
1574
1428
|
ProtocolError: If a server request returns an HTTP error.
|
|
1575
1429
|
ValueError: If authenticated HTTP violates the configured origin
|
|
1576
|
-
policy.
|
|
1430
|
+
policy, or a naive datetime cannot be converted to UTC.
|
|
1431
|
+
OverflowError: If converting an aware datetime to UTC exceeds the
|
|
1432
|
+
supported datetime range.
|
|
1433
|
+
OSError: If the platform cannot resolve a local datetime.
|
|
1577
1434
|
"""
|
|
1578
|
-
options = _crud.
|
|
1435
|
+
options = _crud.FindOneOptions(
|
|
1436
|
+
entity_type,
|
|
1437
|
+
filters,
|
|
1438
|
+
fields,
|
|
1439
|
+
order,
|
|
1440
|
+
filter_operator,
|
|
1441
|
+
retired_only,
|
|
1442
|
+
include_archived_projects,
|
|
1443
|
+
additional_filter_presets,
|
|
1444
|
+
)
|
|
1579
1445
|
return _crud.first_result(self._find(_crud.find_options_from_one(options)))
|
|
1580
1446
|
|
|
1581
1447
|
def follow(self, user: dict[str, Any], entity: dict[str, Any]) -> dict[str, object]:
|
|
@@ -1725,16 +1591,20 @@ class Shotgun:
|
|
|
1725
1591
|
def _initialize(self, options: ConstructorOptions) -> None:
|
|
1726
1592
|
"""Initialize client state from validated constructor options."""
|
|
1727
1593
|
self._base_url = options.base_url.rstrip('/')
|
|
1728
|
-
self._ca_certs =
|
|
1594
|
+
self._ca_certs = (
|
|
1595
|
+
options.ca_certs or os.environ.get('SHOTGUN_API_CACERTS') or None
|
|
1596
|
+
if self._in_process
|
|
1597
|
+
else config_module.constructor_ca_certs(options.ca_certs)
|
|
1598
|
+
)
|
|
1729
1599
|
self._client_caps = ClientCapabilities()
|
|
1730
|
-
self._config = build_config(options)
|
|
1600
|
+
self._config = build_config(options, in_process=self._in_process)
|
|
1731
1601
|
|
|
1732
1602
|
self._driver: Driver | None = None
|
|
1733
1603
|
self._driver_generation: int | None = None
|
|
1734
1604
|
self._known_transport: Transport | None = None
|
|
1735
1605
|
self._lease_counts: dict[int, int] = {}
|
|
1736
1606
|
self._retired_transports: dict[int, Transport] = {}
|
|
1737
|
-
self.
|
|
1607
|
+
self.transport: Transport | None = None
|
|
1738
1608
|
self._transport_lock = threading.Lock()
|
|
1739
1609
|
self._transport_owned = False
|
|
1740
1610
|
|
|
@@ -1827,7 +1697,11 @@ class Shotgun:
|
|
|
1827
1697
|
seed_entity_field,
|
|
1828
1698
|
)
|
|
1829
1699
|
return _methods.require_dictionary_list_result(
|
|
1830
|
-
self._call(
|
|
1700
|
+
self._call(
|
|
1701
|
+
'nav_search',
|
|
1702
|
+
params,
|
|
1703
|
+
invocation_options=_InvocationOptions(logical_method_name='nav_search_entity'),
|
|
1704
|
+
),
|
|
1831
1705
|
'nav_search_entity',
|
|
1832
1706
|
)
|
|
1833
1707
|
|
|
@@ -1860,7 +1734,11 @@ class Shotgun:
|
|
|
1860
1734
|
seed_entity_field,
|
|
1861
1735
|
)
|
|
1862
1736
|
return _methods.require_dictionary_list_result(
|
|
1863
|
-
self._call(
|
|
1737
|
+
self._call(
|
|
1738
|
+
'nav_search',
|
|
1739
|
+
params,
|
|
1740
|
+
invocation_options=_InvocationOptions(logical_method_name='nav_search_string'),
|
|
1741
|
+
),
|
|
1864
1742
|
'nav_search_string',
|
|
1865
1743
|
)
|
|
1866
1744
|
|
|
@@ -1887,7 +1765,11 @@ class Shotgun:
|
|
|
1887
1765
|
"""
|
|
1888
1766
|
params = _methods.build_note_thread_read_params(note_id, entity_fields)
|
|
1889
1767
|
return _methods.require_dictionary_list_result(
|
|
1890
|
-
self._call(
|
|
1768
|
+
self._call(
|
|
1769
|
+
'note_thread_contents',
|
|
1770
|
+
params,
|
|
1771
|
+
invocation_options=_InvocationOptions(logical_method_name='note_thread_read'),
|
|
1772
|
+
),
|
|
1891
1773
|
'note_thread_read',
|
|
1892
1774
|
)
|
|
1893
1775
|
|
|
@@ -2000,7 +1882,10 @@ class Shotgun:
|
|
|
2000
1882
|
or if the server result is invalid.
|
|
2001
1883
|
ProtocolError: If a server request returns an HTTP error.
|
|
2002
1884
|
ValueError: If authenticated HTTP violates the configured origin
|
|
2003
|
-
policy.
|
|
1885
|
+
policy, or a naive datetime cannot be converted to UTC.
|
|
1886
|
+
OverflowError: If converting an aware datetime to UTC exceeds the
|
|
1887
|
+
supported datetime range.
|
|
1888
|
+
OSError: If the platform cannot resolve a local datetime.
|
|
2004
1889
|
"""
|
|
2005
1890
|
result = self._call(
|
|
2006
1891
|
'schema_field_create',
|
|
@@ -2096,7 +1981,10 @@ class Shotgun:
|
|
|
2096
1981
|
or if the server result is invalid.
|
|
2097
1982
|
ProtocolError: If a server request returns an HTTP error.
|
|
2098
1983
|
ValueError: If authenticated HTTP violates the configured origin
|
|
2099
|
-
policy.
|
|
1984
|
+
policy, or a naive datetime cannot be converted to UTC.
|
|
1985
|
+
OverflowError: If converting an aware datetime to UTC exceeds the
|
|
1986
|
+
supported datetime range.
|
|
1987
|
+
OSError: If the platform cannot resolve a local datetime.
|
|
2100
1988
|
"""
|
|
2101
1989
|
return _crud.require_boolean_result(
|
|
2102
1990
|
self._call(
|
|
@@ -2185,7 +2073,8 @@ class Shotgun:
|
|
|
2185
2073
|
|
|
2186
2074
|
Supply exactly one of `thumbnail_path` and `source_entity`. A local
|
|
2187
2075
|
thumbnail is uploaded to the first target before it is shared with the
|
|
2188
|
-
remaining targets.
|
|
2076
|
+
remaining targets. A local thumbnail is rejected before any upload
|
|
2077
|
+
request if the server requires legacy form uploads.
|
|
2189
2078
|
|
|
2190
2079
|
Args:
|
|
2191
2080
|
entities: Nonempty list of target entities with `type` and `id`.
|
|
@@ -2202,7 +2091,8 @@ class Shotgun:
|
|
|
2202
2091
|
TypeError: If forwarded arguments do not match the upload signature
|
|
2203
2092
|
or include `field_name`.
|
|
2204
2093
|
ShotgunError: If an RPC fault or terminal transport failure occurs,
|
|
2205
|
-
or if the source selection, entities, or transport fails
|
|
2094
|
+
or if the source selection, entities, or transport fails, or a
|
|
2095
|
+
local upload requires the legacy form route.
|
|
2206
2096
|
ShotgunThumbnailNotReady: If an uploaded source stays transient.
|
|
2207
2097
|
ProtocolError: If an upload endpoint returns an HTTP error.
|
|
2208
2098
|
ValueError: If authenticated HTTP violates the configured origin
|
|
@@ -2214,30 +2104,23 @@ class Shotgun:
|
|
|
2214
2104
|
source_entity,
|
|
2215
2105
|
filmstrip_thumbnail,
|
|
2216
2106
|
)
|
|
2217
|
-
if share.thumbnail_path is not None and 'field_name' in kwargs:
|
|
2218
|
-
raise TypeError("Shotgun.upload() got multiple values for argument 'field_name'")
|
|
2219
2107
|
prepared: _files.PreparedUpload | None = None
|
|
2220
2108
|
if share.thumbnail_path is not None:
|
|
2221
|
-
|
|
2222
|
-
(
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
prepared = _files.prepare_upload(
|
|
2235
|
-
_files.UploadOptions(
|
|
2236
|
-
arguments=arguments,
|
|
2237
|
-
upload_type='Thumbnail',
|
|
2238
|
-
filmstrip=filmstrip_thumbnail,
|
|
2239
|
-
)
|
|
2109
|
+
for keyword in kwargs:
|
|
2110
|
+
if keyword not in ('display_name', 'tag_list', 'created_at'):
|
|
2111
|
+
raise TypeError(
|
|
2112
|
+
f"Shotgun.share_thumbnail() got an unexpected keyword argument '{keyword}'"
|
|
2113
|
+
)
|
|
2114
|
+
arguments = _files.UploadArguments(
|
|
2115
|
+
entity_type=share.source_entity_type,
|
|
2116
|
+
entity_id=share.source_entity_id,
|
|
2117
|
+
path=share.thumbnail_path,
|
|
2118
|
+
field_name=_files.thumbnail_fields(filmstrip_thumbnail)[0],
|
|
2119
|
+
display_name=cast('str | None', kwargs.get('display_name')),
|
|
2120
|
+
tag_list=cast('str | None', kwargs.get('tag_list')),
|
|
2121
|
+
created_at=cast('_dt_module.datetime | None', kwargs.get('created_at')),
|
|
2240
2122
|
)
|
|
2123
|
+
prepared = _files.prepare_upload(_files.upload_options(arguments))
|
|
2241
2124
|
context = config_module.snapshot(self._config)
|
|
2242
2125
|
require_secure_rpc(context, include_auth=True)
|
|
2243
2126
|
with self._driver_lease(context) as driver:
|
|
@@ -2245,9 +2128,7 @@ class Shotgun:
|
|
|
2245
2128
|
attachment_id = self._upload_thumbnail_for(driver, context, prepared)
|
|
2246
2129
|
if len(share.entities) == 1:
|
|
2247
2130
|
return attachment_id
|
|
2248
|
-
field_name
|
|
2249
|
-
'filmstrip_image' if filmstrip_thumbnail else 'image'
|
|
2250
|
-
)
|
|
2131
|
+
field_name = _files.thumbnail_fields(filmstrip_thumbnail)[1]
|
|
2251
2132
|
ready = driver.poll(
|
|
2252
2133
|
lambda: self._thumbnail_source_ready(
|
|
2253
2134
|
driver,
|
|
@@ -2277,10 +2158,6 @@ class Shotgun:
|
|
|
2277
2158
|
filmstrip_thumbnail,
|
|
2278
2159
|
)
|
|
2279
2160
|
|
|
2280
|
-
@overload
|
|
2281
|
-
def summarize(self, entity_type: Never) -> dict[str, object]: ...
|
|
2282
|
-
|
|
2283
|
-
@overload
|
|
2284
2161
|
def summarize(
|
|
2285
2162
|
self,
|
|
2286
2163
|
entity_type: str,
|
|
@@ -2289,29 +2166,39 @@ class Shotgun:
|
|
|
2289
2166
|
filter_operator: str | None = None,
|
|
2290
2167
|
grouping: list[dict[str, Any]] | None = None,
|
|
2291
2168
|
include_archived_projects: bool = True,
|
|
2292
|
-
) -> dict[str, object]:
|
|
2293
|
-
|
|
2294
|
-
@_methods.expose_summarize_signature
|
|
2295
|
-
def summarize(self, *args: object, **kwargs: object) -> dict[str, object]:
|
|
2169
|
+
) -> dict[str, object]:
|
|
2296
2170
|
"""Summarize field data returned by a query.
|
|
2297
2171
|
|
|
2298
2172
|
Args:
|
|
2299
|
-
|
|
2300
|
-
|
|
2173
|
+
entity_type: Entity type to summarize.
|
|
2174
|
+
filters: Filters in list or dict syntax.
|
|
2175
|
+
summary_fields: List of `{'field': ..., 'type': ...}` summaries.
|
|
2176
|
+
filter_operator: `'all'` or `'any'` for list-syntax filters.
|
|
2177
|
+
grouping: Optional grouping specs.
|
|
2178
|
+
include_archived_projects: Include archived projects when `True`.
|
|
2301
2179
|
|
|
2302
2180
|
Returns:
|
|
2303
2181
|
Dict with `summaries` and (when grouped) `groups`.
|
|
2304
2182
|
|
|
2305
2183
|
Raises:
|
|
2306
|
-
TypeError: If arguments do not match the documented signature.
|
|
2307
2184
|
ShotgunError: If an RPC fault or terminal transport failure occurs,
|
|
2308
2185
|
or if `filters`, `summary_fields`, or the server result has the
|
|
2309
2186
|
wrong type.
|
|
2310
2187
|
ProtocolError: If a server request returns an HTTP error.
|
|
2311
2188
|
ValueError: If authenticated HTTP violates the configured origin
|
|
2312
|
-
policy.
|
|
2189
|
+
policy, or a naive datetime cannot be converted to UTC.
|
|
2190
|
+
OverflowError: If converting an aware datetime to UTC exceeds the
|
|
2191
|
+
supported datetime range.
|
|
2192
|
+
OSError: If the platform cannot resolve a local datetime.
|
|
2313
2193
|
"""
|
|
2314
|
-
options = _methods.
|
|
2194
|
+
options = _methods.SummarizeOptions(
|
|
2195
|
+
entity_type,
|
|
2196
|
+
filters,
|
|
2197
|
+
summary_fields,
|
|
2198
|
+
filter_operator,
|
|
2199
|
+
grouping,
|
|
2200
|
+
include_archived_projects,
|
|
2201
|
+
)
|
|
2315
2202
|
params = _methods.build_summarize_params(options)
|
|
2316
2203
|
return _crud.require_dictionary_result(self._call('summarize', params), 'summarize')
|
|
2317
2204
|
|
|
@@ -2322,7 +2209,7 @@ class Shotgun:
|
|
|
2322
2209
|
project_ids: list[int] | None = None,
|
|
2323
2210
|
limit: int | None = None,
|
|
2324
2211
|
) -> dict[str, object]:
|
|
2325
|
-
"""Search entity display names matching `text
|
|
2212
|
+
"""Search entity display names matching `text`.
|
|
2326
2213
|
|
|
2327
2214
|
Args:
|
|
2328
2215
|
text: Text to match.
|
|
@@ -2336,10 +2223,14 @@ class Shotgun:
|
|
|
2336
2223
|
|
|
2337
2224
|
Raises:
|
|
2338
2225
|
ShotgunError: If an RPC fault or terminal transport failure occurs,
|
|
2339
|
-
|
|
2226
|
+
if `entity_types` or the server result is not a dictionary, or
|
|
2227
|
+
if an entity filter is invalid.
|
|
2340
2228
|
ProtocolError: If a server request returns an HTTP error.
|
|
2341
2229
|
ValueError: If authenticated HTTP violates the configured origin
|
|
2342
|
-
policy.
|
|
2230
|
+
policy, or a naive datetime cannot be converted to UTC.
|
|
2231
|
+
OverflowError: If converting an aware datetime to UTC exceeds the
|
|
2232
|
+
supported datetime range.
|
|
2233
|
+
OSError: If the platform cannot resolve a local datetime.
|
|
2343
2234
|
"""
|
|
2344
2235
|
params = _methods.build_text_search_params(
|
|
2345
2236
|
text,
|
|
@@ -2407,7 +2298,10 @@ class Shotgun:
|
|
|
2407
2298
|
nonempty file. A thumbnail failure occurs after the update.
|
|
2408
2299
|
ProtocolError: If a server request returns an HTTP error.
|
|
2409
2300
|
ValueError: If authenticated HTTP violates the configured origin
|
|
2410
|
-
policy.
|
|
2301
|
+
policy, or a naive datetime cannot be converted to UTC.
|
|
2302
|
+
OverflowError: If converting an aware datetime to UTC exceeds the
|
|
2303
|
+
supported datetime range.
|
|
2304
|
+
OSError: If the platform cannot resolve a local datetime.
|
|
2411
2305
|
"""
|
|
2412
2306
|
field_data, thumbnails = _files.split_thumbnail_uploads(data, keep_image_none=True)
|
|
2413
2307
|
params = _crud.build_update_params(
|
|
@@ -2436,7 +2330,8 @@ class Shotgun:
|
|
|
2436
2330
|
user: Optional user entity to attribute the access to.
|
|
2437
2331
|
|
|
2438
2332
|
Raises:
|
|
2439
|
-
ShotgunError: If
|
|
2333
|
+
ShotgunError: If a project or user ID is invalid, or an RPC fault
|
|
2334
|
+
or terminal transport failure occurs.
|
|
2440
2335
|
ProtocolError: If a server request returns an HTTP error.
|
|
2441
2336
|
ValueError: If authenticated HTTP violates the configured origin
|
|
2442
2337
|
policy.
|
|
@@ -2449,10 +2344,6 @@ class Shotgun:
|
|
|
2449
2344
|
),
|
|
2450
2345
|
)
|
|
2451
2346
|
|
|
2452
|
-
@overload
|
|
2453
|
-
def upload(self, entity_type: Never) -> int: ...
|
|
2454
|
-
|
|
2455
|
-
@overload
|
|
2456
2347
|
def upload(
|
|
2457
2348
|
self,
|
|
2458
2349
|
entity_type: str,
|
|
@@ -2462,50 +2353,37 @@ class Shotgun:
|
|
|
2462
2353
|
display_name: str | None = None,
|
|
2463
2354
|
tag_list: str | None = None,
|
|
2464
2355
|
created_at: _dt_module.datetime | None = None,
|
|
2465
|
-
) -> int:
|
|
2466
|
-
|
|
2467
|
-
@_expose_upload_signature
|
|
2468
|
-
def upload(self, *args: object, **kwargs: object) -> int:
|
|
2356
|
+
) -> int:
|
|
2469
2357
|
"""Upload a file or thumbnail and return its Attachment ID.
|
|
2470
2358
|
|
|
2471
|
-
A
|
|
2472
|
-
|
|
2473
|
-
The form request has already been sent when this error is raised.
|
|
2359
|
+
A server requiring legacy form uploads raises `ShotgunError` before any
|
|
2360
|
+
upload request is sent. Server capability reads may occur.
|
|
2474
2361
|
|
|
2475
2362
|
Args:
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2363
|
+
entity_type: Entity type receiving the upload.
|
|
2364
|
+
entity_id: Numeric identifier of the receiving entity.
|
|
2365
|
+
path: Existing non-empty file path as text or filesystem-encoded
|
|
2366
|
+
bytes.
|
|
2367
|
+
field_name: Optional file field receiving an Attachment.
|
|
2368
|
+
display_name: Optional Attachment display name.
|
|
2369
|
+
tag_list: Optional comma-delimited Attachment tags.
|
|
2370
|
+
created_at: Optional Attachment creation timestamp.
|
|
2479
2371
|
|
|
2480
2372
|
Returns:
|
|
2481
2373
|
Created Attachment ID.
|
|
2482
2374
|
|
|
2483
2375
|
Raises:
|
|
2484
|
-
TypeError: If arguments do not match the documented signature.
|
|
2485
2376
|
ShotgunError: If the file or an upload response is invalid, an RPC
|
|
2486
|
-
fault or terminal transport failure occurs, or the
|
|
2487
|
-
form
|
|
2377
|
+
fault or terminal transport failure occurs, or the server
|
|
2378
|
+
requires legacy form uploads.
|
|
2488
2379
|
ProtocolError: If an upload endpoint returns an HTTP error.
|
|
2489
2380
|
ValueError: If authenticated HTTP violates the configured origin
|
|
2490
2381
|
policy.
|
|
2491
2382
|
"""
|
|
2492
|
-
arguments =
|
|
2493
|
-
|
|
2494
|
-
'filmstrip_image',
|
|
2495
|
-
'filmstrip_thumb_image',
|
|
2496
|
-
'image',
|
|
2497
|
-
'thumb_image',
|
|
2498
|
-
}
|
|
2499
|
-
upload_type: Literal['Attachment', 'Thumbnail'] = (
|
|
2500
|
-
'Thumbnail' if arguments.field_name in thumbnail_fields else 'Attachment'
|
|
2501
|
-
)
|
|
2502
|
-
return self._upload(
|
|
2503
|
-
_files.UploadOptions(
|
|
2504
|
-
arguments=arguments,
|
|
2505
|
-
upload_type=upload_type,
|
|
2506
|
-
filmstrip=arguments.field_name in {'filmstrip_image', 'filmstrip_thumb_image'},
|
|
2507
|
-
)
|
|
2383
|
+
arguments = _files.UploadArguments(
|
|
2384
|
+
entity_type, entity_id, path, field_name, display_name, tag_list, created_at
|
|
2508
2385
|
)
|
|
2386
|
+
return self._upload(_files.upload_options(arguments))
|
|
2509
2387
|
|
|
2510
2388
|
def upload_filmstrip_thumbnail(
|
|
2511
2389
|
self,
|
|
@@ -2516,6 +2394,9 @@ class Shotgun:
|
|
|
2516
2394
|
) -> int:
|
|
2517
2395
|
"""Upload a filmstrip thumbnail through `upload`.
|
|
2518
2396
|
|
|
2397
|
+
Servers requiring legacy form uploads are rejected before any upload
|
|
2398
|
+
request is sent.
|
|
2399
|
+
|
|
2519
2400
|
Args:
|
|
2520
2401
|
entity_type: Entity type receiving the thumbnail.
|
|
2521
2402
|
entity_id: Numeric identifier of the receiving entity.
|
|
@@ -2528,7 +2409,8 @@ class Shotgun:
|
|
|
2528
2409
|
Raises:
|
|
2529
2410
|
TypeError: If forwarded arguments do not match `upload`.
|
|
2530
2411
|
ShotgunError: If an RPC fault or terminal transport failure occurs,
|
|
2531
|
-
or if the file, upload response, or transport fails
|
|
2412
|
+
or if the file, upload response, or transport fails, or the
|
|
2413
|
+
server requires legacy form uploads.
|
|
2532
2414
|
ProtocolError: If an upload endpoint returns an HTTP error.
|
|
2533
2415
|
ValueError: If authenticated HTTP violates the configured origin
|
|
2534
2416
|
policy.
|
|
@@ -2550,6 +2432,9 @@ class Shotgun:
|
|
|
2550
2432
|
) -> int:
|
|
2551
2433
|
"""Upload a static thumbnail through `upload`.
|
|
2552
2434
|
|
|
2435
|
+
Servers requiring legacy form uploads are rejected before any upload
|
|
2436
|
+
request is sent.
|
|
2437
|
+
|
|
2553
2438
|
Args:
|
|
2554
2439
|
entity_type: Entity type receiving the thumbnail.
|
|
2555
2440
|
entity_id: Numeric identifier of the receiving entity.
|
|
@@ -2562,7 +2447,8 @@ class Shotgun:
|
|
|
2562
2447
|
Raises:
|
|
2563
2448
|
TypeError: If forwarded arguments do not match `upload`.
|
|
2564
2449
|
ShotgunError: If an RPC fault or terminal transport failure occurs,
|
|
2565
|
-
or if the file, upload response, or transport fails
|
|
2450
|
+
or if the file, upload response, or transport fails, or the
|
|
2451
|
+
server requires legacy form uploads.
|
|
2566
2452
|
ProtocolError: If an upload endpoint returns an HTTP error.
|
|
2567
2453
|
ValueError: If authenticated HTTP violates the configured origin
|
|
2568
2454
|
policy.
|
|
@@ -2578,44 +2464,53 @@ class Shotgun:
|
|
|
2578
2464
|
def user_subscriptions_create(self, users: list[dict[str, Any]]) -> bool:
|
|
2579
2465
|
"""Assign subscriptions to users.
|
|
2580
2466
|
|
|
2467
|
+
The server accepts this call from scripts and from human users with
|
|
2468
|
+
permission to manage subscriptions, such as members of the Admin
|
|
2469
|
+
permission group. It refuses other human users.
|
|
2470
|
+
|
|
2581
2471
|
Args:
|
|
2582
|
-
users: Subscription dictionaries
|
|
2472
|
+
users: Subscription dictionaries with a string or integer
|
|
2473
|
+
`humanUserId`; integers become decimal string keys and booleans
|
|
2474
|
+
are not accepted. Each user may appear only once.
|
|
2475
|
+
`subscription` is `None`, a string, or a list of strings.
|
|
2476
|
+
Lists are copied in order. Other entry keys are ignored.
|
|
2583
2477
|
|
|
2584
2478
|
Returns:
|
|
2585
|
-
|
|
2479
|
+
`True` when every per-user report is `None`, meaning the server
|
|
2480
|
+
reported no problem; `False` when any user has a non-`None` report.
|
|
2586
2481
|
|
|
2587
2482
|
Raises:
|
|
2588
2483
|
ShotgunError: If an RPC fault or terminal transport failure occurs,
|
|
2589
|
-
or if `users`
|
|
2590
|
-
|
|
2484
|
+
or if `users` contains invalid or duplicate entries, or the
|
|
2485
|
+
server result is not a mapping with string keys.
|
|
2591
2486
|
ProtocolError: If a server request returns an HTTP error.
|
|
2592
2487
|
ValueError: If authenticated HTTP violates the configured origin
|
|
2593
2488
|
policy.
|
|
2594
2489
|
"""
|
|
2595
|
-
return
|
|
2490
|
+
return _methods.require_user_subscriptions_create_result(
|
|
2596
2491
|
self._call(
|
|
2597
2492
|
'user_subscriptions_create',
|
|
2598
2493
|
_methods.build_user_subscriptions_create_params(users),
|
|
2599
2494
|
),
|
|
2600
|
-
'user_subscriptions_create',
|
|
2601
2495
|
)
|
|
2602
2496
|
|
|
2603
2497
|
def user_subscriptions_read(self) -> list[dict[str, object]]:
|
|
2604
|
-
"""List
|
|
2498
|
+
"""List user subscriptions in server order.
|
|
2605
2499
|
|
|
2606
2500
|
Returns:
|
|
2607
|
-
|
|
2501
|
+
Subscription entries in server order, each with an unchanged string
|
|
2502
|
+
`humanUserId` and a `subscription` of `None`, a string, or a copied
|
|
2503
|
+
list of strings.
|
|
2608
2504
|
|
|
2609
2505
|
Raises:
|
|
2610
2506
|
ShotgunError: If an RPC fault or terminal transport failure occurs,
|
|
2611
|
-
or if the server result is
|
|
2507
|
+
or if the server result is invalid.
|
|
2612
2508
|
ProtocolError: If a server request returns an HTTP error.
|
|
2613
2509
|
ValueError: If authenticated HTTP violates the configured origin
|
|
2614
2510
|
policy.
|
|
2615
2511
|
"""
|
|
2616
|
-
return _methods.
|
|
2512
|
+
return _methods.require_user_subscriptions_result(
|
|
2617
2513
|
self._call('user_subscriptions_read', None),
|
|
2618
|
-
'user_subscriptions_read',
|
|
2619
2514
|
)
|
|
2620
2515
|
|
|
2621
2516
|
def work_schedule_read(
|
|
@@ -2654,10 +2549,6 @@ class Shotgun:
|
|
|
2654
2549
|
'work_schedule_read',
|
|
2655
2550
|
)
|
|
2656
2551
|
|
|
2657
|
-
@overload
|
|
2658
|
-
def work_schedule_update(self, date: Never) -> dict[str, object]: ...
|
|
2659
|
-
|
|
2660
|
-
@overload
|
|
2661
2552
|
def work_schedule_update(
|
|
2662
2553
|
self,
|
|
2663
2554
|
date: _dt_module.date | str,
|
|
@@ -2666,30 +2557,31 @@ class Shotgun:
|
|
|
2666
2557
|
project: dict[str, Any] | None = None,
|
|
2667
2558
|
user: dict[str, Any] | None = None,
|
|
2668
2559
|
recalculate_field: str | None = None,
|
|
2669
|
-
) -> dict[str, object]:
|
|
2670
|
-
|
|
2671
|
-
@_methods.expose_work_schedule_update_signature
|
|
2672
|
-
def work_schedule_update(self, *args: object, **kwargs: object) -> dict[str, object]:
|
|
2673
|
-
"""Update a work schedule using the documented arguments.
|
|
2560
|
+
) -> dict[str, object]:
|
|
2561
|
+
"""Update a work schedule.
|
|
2674
2562
|
|
|
2675
2563
|
Args:
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2564
|
+
date: Date or exact `YYYY-MM-DD` string to update.
|
|
2565
|
+
working: Whether the date is a working day.
|
|
2566
|
+
description: Optional schedule description.
|
|
2567
|
+
project: Optional project entity restriction.
|
|
2568
|
+
user: Optional user entity restriction.
|
|
2569
|
+
recalculate_field: Optional field to recalculate.
|
|
2680
2570
|
|
|
2681
2571
|
Returns:
|
|
2682
2572
|
Updated work schedule data returned by the server.
|
|
2683
2573
|
|
|
2684
2574
|
Raises:
|
|
2685
|
-
TypeError: If arguments do not match the documented signature.
|
|
2686
2575
|
ShotgunError: If an RPC fault or terminal transport failure occurs,
|
|
2687
|
-
or if
|
|
2576
|
+
or if the date, project/user exclusivity, or server result is
|
|
2577
|
+
invalid.
|
|
2688
2578
|
ProtocolError: If a server request returns an HTTP error.
|
|
2689
2579
|
ValueError: If authenticated HTTP violates the configured origin
|
|
2690
2580
|
policy.
|
|
2691
2581
|
"""
|
|
2692
|
-
options = _methods.
|
|
2582
|
+
options = _methods.WorkScheduleUpdateOptions(
|
|
2583
|
+
date, working, description, project, user, recalculate_field
|
|
2584
|
+
)
|
|
2693
2585
|
params = _methods.build_work_schedule_update_params(options)
|
|
2694
2586
|
return _crud.require_dictionary_result(
|
|
2695
2587
|
self._call('work_schedule_update', params),
|