sg-python-api 0.1.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.0.dist-info/METADATA +177 -0
- sg_python_api-0.1.0.dist-info/RECORD +31 -0
- sg_python_api-0.1.0.dist-info/WHEEL +4 -0
- sg_python_api-0.1.0.dist-info/licenses/LICENSE +21 -0
- shotgun_api3/__init__.py +68 -0
- shotgun_api3/_async_client.py +2906 -0
- shotgun_api3/_async_driver.py +945 -0
- shotgun_api3/_async_httpx2.py +662 -0
- shotgun_api3/_async_transport.py +162 -0
- shotgun_api3/_capabilities.py +165 -0
- shotgun_api3/_client.py +2682 -0
- shotgun_api3/_config.py +1463 -0
- shotgun_api3/_crud.py +916 -0
- shotgun_api3/_driver.py +879 -0
- shotgun_api3/_errors.py +49 -0
- shotgun_api3/_execution.py +273 -0
- shotgun_api3/_files.py +1094 -0
- shotgun_api3/_methods.py +1205 -0
- shotgun_api3/_protocol.py +1347 -0
- shotgun_api3/_sentinel.py +5 -0
- shotgun_api3/_sg_timezone.py +5 -0
- shotgun_api3/_signatures.py +53 -0
- shotgun_api3/_transport.py +901 -0
- shotgun_api3/_version.py +3 -0
- shotgun_api3/lib/__init__.py +1 -0
- shotgun_api3/lib/mockgun/__init__.py +16 -0
- shotgun_api3/lib/mockgun/_async.py +315 -0
- shotgun_api3/lib/mockgun/_mockgun.py +1666 -0
- shotgun_api3/lib/sgtimezone.py +209 -0
- shotgun_api3/py.typed +0 -0
- shotgun_api3/shotgun.py +58 -0
shotgun_api3/_methods.py
ADDED
|
@@ -0,0 +1,1205 @@
|
|
|
1
|
+
"""Shared pure plans for synchronous and asynchronous client methods."""
|
|
2
|
+
|
|
3
|
+
import contextvars
|
|
4
|
+
import dataclasses
|
|
5
|
+
import datetime
|
|
6
|
+
import inspect
|
|
7
|
+
import warnings
|
|
8
|
+
from collections.abc import Callable, Generator
|
|
9
|
+
from contextlib import contextmanager
|
|
10
|
+
from typing import Any, NotRequired, TypedDict, cast
|
|
11
|
+
|
|
12
|
+
from . import _crud, _protocol
|
|
13
|
+
from ._config import CompatibilityWarningCode
|
|
14
|
+
from ._errors import ShotgunError
|
|
15
|
+
from ._signatures import bind_arguments, expose_signature
|
|
16
|
+
|
|
17
|
+
_ACTIVITY_STREAM_READ_DOCSTRING = """Read the activity stream for one entity.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
entity_type: Entity type whose activity stream to read.
|
|
21
|
+
entity_id: Numeric identifier of the entity.
|
|
22
|
+
entity_fields: Optional fields to return for linked entity types.
|
|
23
|
+
min_id: Optional minimum activity identifier.
|
|
24
|
+
max_id: Optional maximum activity identifier.
|
|
25
|
+
limit: Optional maximum number of activity records.
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
Activity stream data returned by the server.
|
|
29
|
+
|
|
30
|
+
Raises:
|
|
31
|
+
TypeError: If arguments do not match the documented signature.
|
|
32
|
+
ShotgunError: If an RPC fault or terminal transport failure
|
|
33
|
+
occurs, or if the server result has the wrong type.
|
|
34
|
+
ProtocolError: If a server request returns an HTTP error.
|
|
35
|
+
ValueError: If authenticated HTTP violates the configured origin policy.
|
|
36
|
+
"""
|
|
37
|
+
_ACTIVITY_STREAM_READ_PARAMETERS = (
|
|
38
|
+
inspect.Parameter('entity_type', inspect.Parameter.POSITIONAL_OR_KEYWORD, annotation=str),
|
|
39
|
+
inspect.Parameter('entity_id', inspect.Parameter.POSITIONAL_OR_KEYWORD, annotation=int),
|
|
40
|
+
inspect.Parameter(
|
|
41
|
+
'entity_fields',
|
|
42
|
+
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
43
|
+
default=None,
|
|
44
|
+
annotation=dict[str, list[str]] | None,
|
|
45
|
+
),
|
|
46
|
+
inspect.Parameter(
|
|
47
|
+
'min_id',
|
|
48
|
+
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
49
|
+
default=None,
|
|
50
|
+
annotation=int | None,
|
|
51
|
+
),
|
|
52
|
+
inspect.Parameter(
|
|
53
|
+
'max_id',
|
|
54
|
+
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
55
|
+
default=None,
|
|
56
|
+
annotation=int | None,
|
|
57
|
+
),
|
|
58
|
+
inspect.Parameter(
|
|
59
|
+
'limit',
|
|
60
|
+
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
61
|
+
default=None,
|
|
62
|
+
annotation=int | None,
|
|
63
|
+
),
|
|
64
|
+
)
|
|
65
|
+
_ACTIVITY_STREAM_READ_SIGNATURE = inspect.Signature(
|
|
66
|
+
_ACTIVITY_STREAM_READ_PARAMETERS,
|
|
67
|
+
return_annotation=dict[str, object],
|
|
68
|
+
)
|
|
69
|
+
_EXPORT_PAGE_DOCSTRING = """Export a page using the documented arguments.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
page_id: Numeric page identifier.
|
|
73
|
+
format: Required nonempty export format name.
|
|
74
|
+
layout_name: Optional layout name, including an empty name.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
Exported page text returned by the server.
|
|
78
|
+
|
|
79
|
+
Raises:
|
|
80
|
+
TypeError: If arguments do not match the documented signature.
|
|
81
|
+
ShotgunError: If an RPC fault or terminal transport failure
|
|
82
|
+
occurs, or if `page_id`, `format`, or the server result is invalid.
|
|
83
|
+
ProtocolError: If a server request returns an HTTP error.
|
|
84
|
+
ValueError: If authenticated HTTP violates the configured origin policy.
|
|
85
|
+
"""
|
|
86
|
+
_EXPORT_PAGE_PARAMETERS = (
|
|
87
|
+
inspect.Parameter('page_id', inspect.Parameter.POSITIONAL_OR_KEYWORD, annotation=int),
|
|
88
|
+
inspect.Parameter('format', inspect.Parameter.POSITIONAL_OR_KEYWORD, annotation=str),
|
|
89
|
+
inspect.Parameter(
|
|
90
|
+
'layout_name',
|
|
91
|
+
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
92
|
+
default=None,
|
|
93
|
+
annotation=str | None,
|
|
94
|
+
),
|
|
95
|
+
)
|
|
96
|
+
_EXPORT_PAGE_SIGNATURE = inspect.Signature(
|
|
97
|
+
_EXPORT_PAGE_PARAMETERS,
|
|
98
|
+
return_annotation=str,
|
|
99
|
+
)
|
|
100
|
+
_METHOD_ACTIVITY_STREAM_READ_SIGNATURE = inspect.Signature(
|
|
101
|
+
(
|
|
102
|
+
inspect.Parameter('self', inspect.Parameter.POSITIONAL_OR_KEYWORD),
|
|
103
|
+
*_ACTIVITY_STREAM_READ_PARAMETERS,
|
|
104
|
+
),
|
|
105
|
+
return_annotation=dict[str, object],
|
|
106
|
+
)
|
|
107
|
+
_METHOD_EXPORT_PAGE_SIGNATURE = inspect.Signature(
|
|
108
|
+
(
|
|
109
|
+
inspect.Parameter('self', inspect.Parameter.POSITIONAL_OR_KEYWORD),
|
|
110
|
+
*_EXPORT_PAGE_PARAMETERS,
|
|
111
|
+
),
|
|
112
|
+
return_annotation=str,
|
|
113
|
+
)
|
|
114
|
+
_PENDING_COMPATIBILITY_WARNINGS = tuple[
|
|
115
|
+
object,
|
|
116
|
+
tuple[CompatibilityWarningCode, ...],
|
|
117
|
+
]
|
|
118
|
+
_SCHEDULE_DATE_LENGTH = 10
|
|
119
|
+
_SUMMARIZE_DOCSTRING = """Summarize field data returned by a query.
|
|
120
|
+
|
|
121
|
+
Args:
|
|
122
|
+
entity_type: Entity type to summarize.
|
|
123
|
+
filters: Filters in list or dict syntax.
|
|
124
|
+
summary_fields: List of `{'field': ..., 'type': ...}` summaries.
|
|
125
|
+
filter_operator: `'all'` or `'any'` for list-syntax filters.
|
|
126
|
+
grouping: Optional grouping specs.
|
|
127
|
+
include_archived_projects: Include archived projects when `True`.
|
|
128
|
+
|
|
129
|
+
Returns:
|
|
130
|
+
Dict with `summaries` and (when grouped) `groups`.
|
|
131
|
+
|
|
132
|
+
Raises:
|
|
133
|
+
TypeError: If arguments do not match the documented signature.
|
|
134
|
+
ShotgunError: If an RPC fault or terminal transport failure
|
|
135
|
+
occurs, or if `filters`, `summary_fields`, or the server result has the
|
|
136
|
+
wrong type.
|
|
137
|
+
ProtocolError: If a server request returns an HTTP error.
|
|
138
|
+
ValueError: If authenticated HTTP violates the configured origin policy.
|
|
139
|
+
"""
|
|
140
|
+
_SUMMARIZE_PARAMETERS = (
|
|
141
|
+
inspect.Parameter('entity_type', inspect.Parameter.POSITIONAL_OR_KEYWORD, annotation=str),
|
|
142
|
+
inspect.Parameter(
|
|
143
|
+
'filters',
|
|
144
|
+
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
145
|
+
annotation=list[Any] | tuple[Any, ...] | dict[str, Any],
|
|
146
|
+
),
|
|
147
|
+
inspect.Parameter(
|
|
148
|
+
'summary_fields',
|
|
149
|
+
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
150
|
+
annotation=list[dict[str, Any]],
|
|
151
|
+
),
|
|
152
|
+
inspect.Parameter(
|
|
153
|
+
'filter_operator',
|
|
154
|
+
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
155
|
+
default=None,
|
|
156
|
+
annotation=str | None,
|
|
157
|
+
),
|
|
158
|
+
inspect.Parameter(
|
|
159
|
+
'grouping',
|
|
160
|
+
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
161
|
+
default=None,
|
|
162
|
+
annotation=list[dict[str, Any]] | None,
|
|
163
|
+
),
|
|
164
|
+
inspect.Parameter(
|
|
165
|
+
'include_archived_projects',
|
|
166
|
+
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
167
|
+
default=True,
|
|
168
|
+
annotation=bool,
|
|
169
|
+
),
|
|
170
|
+
)
|
|
171
|
+
_METHOD_SUMMARIZE_SIGNATURE = inspect.Signature(
|
|
172
|
+
(
|
|
173
|
+
inspect.Parameter('self', inspect.Parameter.POSITIONAL_OR_KEYWORD),
|
|
174
|
+
*_SUMMARIZE_PARAMETERS,
|
|
175
|
+
),
|
|
176
|
+
return_annotation=dict[str, object],
|
|
177
|
+
)
|
|
178
|
+
_SUMMARIZE_SIGNATURE = inspect.Signature(
|
|
179
|
+
_SUMMARIZE_PARAMETERS,
|
|
180
|
+
return_annotation=dict[str, object],
|
|
181
|
+
)
|
|
182
|
+
_WORK_SCHEDULE_UPDATE_DOCSTRING = """Update a work schedule.
|
|
183
|
+
|
|
184
|
+
Args:
|
|
185
|
+
date: Date or exact `YYYY-MM-DD` string to update.
|
|
186
|
+
working: Whether the date is a working day.
|
|
187
|
+
description: Optional schedule description.
|
|
188
|
+
project: Optional project entity restriction.
|
|
189
|
+
user: Optional user entity restriction.
|
|
190
|
+
recalculate_field: Optional field to recalculate.
|
|
191
|
+
|
|
192
|
+
Returns:
|
|
193
|
+
Updated work schedule data returned by the server.
|
|
194
|
+
|
|
195
|
+
Raises:
|
|
196
|
+
TypeError: If arguments do not match the documented signature.
|
|
197
|
+
ShotgunError: If an RPC fault or terminal transport failure
|
|
198
|
+
occurs, or if the date, project/user exclusivity, or server result is
|
|
199
|
+
invalid.
|
|
200
|
+
ProtocolError: If a server request returns an HTTP error.
|
|
201
|
+
ValueError: If authenticated HTTP violates the configured origin policy.
|
|
202
|
+
"""
|
|
203
|
+
_WORK_SCHEDULE_UPDATE_PARAMETERS = (
|
|
204
|
+
inspect.Parameter(
|
|
205
|
+
'date', inspect.Parameter.POSITIONAL_OR_KEYWORD, annotation=datetime.date | str
|
|
206
|
+
),
|
|
207
|
+
inspect.Parameter('working', inspect.Parameter.POSITIONAL_OR_KEYWORD, annotation=bool),
|
|
208
|
+
inspect.Parameter(
|
|
209
|
+
'description',
|
|
210
|
+
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
211
|
+
default=None,
|
|
212
|
+
annotation=str | None,
|
|
213
|
+
),
|
|
214
|
+
inspect.Parameter(
|
|
215
|
+
'project',
|
|
216
|
+
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
217
|
+
default=None,
|
|
218
|
+
annotation=dict[str, Any] | None,
|
|
219
|
+
),
|
|
220
|
+
inspect.Parameter(
|
|
221
|
+
'user',
|
|
222
|
+
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
223
|
+
default=None,
|
|
224
|
+
annotation=dict[str, Any] | None,
|
|
225
|
+
),
|
|
226
|
+
inspect.Parameter(
|
|
227
|
+
'recalculate_field',
|
|
228
|
+
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
229
|
+
default=None,
|
|
230
|
+
annotation=str | None,
|
|
231
|
+
),
|
|
232
|
+
)
|
|
233
|
+
_METHOD_WORK_SCHEDULE_UPDATE_SIGNATURE = inspect.Signature(
|
|
234
|
+
(
|
|
235
|
+
inspect.Parameter('self', inspect.Parameter.POSITIONAL_OR_KEYWORD),
|
|
236
|
+
*_WORK_SCHEDULE_UPDATE_PARAMETERS,
|
|
237
|
+
),
|
|
238
|
+
return_annotation=dict[str, object],
|
|
239
|
+
)
|
|
240
|
+
_WORK_SCHEDULE_UPDATE_SIGNATURE = inspect.Signature(
|
|
241
|
+
_WORK_SCHEDULE_UPDATE_PARAMETERS,
|
|
242
|
+
return_annotation=dict[str, object],
|
|
243
|
+
)
|
|
244
|
+
SCHEMA_ENTITY_READ_WARNINGS: contextvars.ContextVar[_PENDING_COMPATIBILITY_WARNINGS | None] = (
|
|
245
|
+
contextvars.ContextVar('SCHEMA_ENTITY_READ_WARNINGS', default=None)
|
|
246
|
+
)
|
|
247
|
+
SCHEMA_FIELD_READ_WARNINGS: contextvars.ContextVar[_PENDING_COMPATIBILITY_WARNINGS | None] = (
|
|
248
|
+
contextvars.ContextVar('SCHEMA_FIELD_READ_WARNINGS', default=None)
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
@dataclasses.dataclass(frozen=True)
|
|
253
|
+
class _ActivityStreamReadOptions:
|
|
254
|
+
"""Collect exact public activity stream arguments for validation."""
|
|
255
|
+
|
|
256
|
+
entity_type: str
|
|
257
|
+
entity_id: int
|
|
258
|
+
entity_fields: dict[str, list[str]] | None = None
|
|
259
|
+
min_id: int | None = None
|
|
260
|
+
max_id: int | None = None
|
|
261
|
+
limit: int | None = None
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
@dataclasses.dataclass(frozen=True)
|
|
265
|
+
class _AuthenticationPlan:
|
|
266
|
+
"""Carry one human-authentication request and its credentials."""
|
|
267
|
+
|
|
268
|
+
auth_spec: _protocol.AuthSpec
|
|
269
|
+
params: dict[str, object]
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
class ExportPageKeywordArguments(TypedDict):
|
|
273
|
+
"""Describe supported keyword calls to `export_page`.
|
|
274
|
+
|
|
275
|
+
Attributes:
|
|
276
|
+
format: Required nonempty export format.
|
|
277
|
+
layout_name: Optional page layout name.
|
|
278
|
+
"""
|
|
279
|
+
|
|
280
|
+
format: str
|
|
281
|
+
layout_name: NotRequired[str | None]
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
@dataclasses.dataclass(frozen=True)
|
|
285
|
+
class _ExportPageOptions:
|
|
286
|
+
"""Collect exact public export-page arguments for validation."""
|
|
287
|
+
|
|
288
|
+
page_id: int
|
|
289
|
+
format: str
|
|
290
|
+
layout_name: str | None = None
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
@dataclasses.dataclass(frozen=True)
|
|
294
|
+
class _SummarizeOptions:
|
|
295
|
+
"""Collect exact public `summarize` arguments for runtime validation."""
|
|
296
|
+
|
|
297
|
+
entity_type: str
|
|
298
|
+
filters: object
|
|
299
|
+
summary_fields: object
|
|
300
|
+
filter_operator: str | None = None
|
|
301
|
+
grouping: list[dict[str, object]] | None = None
|
|
302
|
+
include_archived_projects: bool = True
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
@dataclasses.dataclass(frozen=True)
|
|
306
|
+
class _WorkScheduleUpdateOptions:
|
|
307
|
+
"""Collect exact public work-schedule update arguments for validation."""
|
|
308
|
+
|
|
309
|
+
date: object
|
|
310
|
+
working: bool
|
|
311
|
+
description: str | None = None
|
|
312
|
+
project: dict[str, object] | None = None
|
|
313
|
+
user: dict[str, object] | None = None
|
|
314
|
+
recalculate_field: str | None = None
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
def _date_str(value: object, argument: str) -> str:
|
|
318
|
+
"""Return an exact schedule date string."""
|
|
319
|
+
if isinstance(value, datetime.datetime):
|
|
320
|
+
raise ShotgunError(f'{argument} must be a date, not a datetime')
|
|
321
|
+
if isinstance(value, datetime.date):
|
|
322
|
+
return f'{value.year:04d}-{value.month:02d}-{value.day:02d}'
|
|
323
|
+
if not isinstance(value, str):
|
|
324
|
+
raise ShotgunError(f'{argument} must be a datetime.date or YYYY-MM-DD string')
|
|
325
|
+
if (
|
|
326
|
+
len(value) != _SCHEDULE_DATE_LENGTH
|
|
327
|
+
or value[4] != '-'
|
|
328
|
+
or value[7] != '-'
|
|
329
|
+
or not value.isascii()
|
|
330
|
+
or not (value[:4] + value[5:7] + value[8:]).isdigit()
|
|
331
|
+
):
|
|
332
|
+
raise ShotgunError(f'{argument} must be YYYY-MM-DD')
|
|
333
|
+
try:
|
|
334
|
+
datetime.date.fromisoformat(value)
|
|
335
|
+
except ValueError:
|
|
336
|
+
raise ShotgunError(f'{argument} must be YYYY-MM-DD') from None
|
|
337
|
+
return value
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
def _entity(value: object) -> object:
|
|
341
|
+
"""Optimize an entity value for client request preparation."""
|
|
342
|
+
return _protocol.optimize_entity(value)
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
def _project_entity(value: object) -> object:
|
|
346
|
+
"""Optimize an optional project entity."""
|
|
347
|
+
return None if value is None else _entity(value)
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
def _property_pairs(properties: dict[str, object]) -> list[dict[str, object]]:
|
|
351
|
+
"""Build schema property entries in caller order."""
|
|
352
|
+
return [{'property_name': name, 'value': value} for name, value in properties.items()]
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
def _reject_project_and_user(
|
|
356
|
+
project: dict[str, object] | None,
|
|
357
|
+
user: dict[str, object] | None,
|
|
358
|
+
) -> None:
|
|
359
|
+
"""Reject simultaneous project and user restrictions."""
|
|
360
|
+
if project is not None and user is not None:
|
|
361
|
+
raise ShotgunError('project and user can only be used exclusively of each other')
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
def _require_nonempty_string(value: object, message: str) -> str:
|
|
365
|
+
"""Validate a nonempty string."""
|
|
366
|
+
if not isinstance(value, str) or not value:
|
|
367
|
+
raise ShotgunError(message)
|
|
368
|
+
return value
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
def bind_activity_stream_read(
|
|
372
|
+
args: tuple[object, ...],
|
|
373
|
+
kwargs: dict[str, object],
|
|
374
|
+
owner_name: str,
|
|
375
|
+
) -> _ActivityStreamReadOptions:
|
|
376
|
+
"""Bind runtime activity-stream arguments.
|
|
377
|
+
|
|
378
|
+
Args:
|
|
379
|
+
args: Positional arguments supplied by the caller.
|
|
380
|
+
kwargs: Keyword arguments supplied by the caller.
|
|
381
|
+
owner_name: Public client class name used in errors.
|
|
382
|
+
|
|
383
|
+
Returns:
|
|
384
|
+
Bound activity-stream options.
|
|
385
|
+
|
|
386
|
+
Raises:
|
|
387
|
+
TypeError: If the arguments do not match the public signature.
|
|
388
|
+
"""
|
|
389
|
+
bound = bind_arguments(
|
|
390
|
+
_ACTIVITY_STREAM_READ_SIGNATURE, args, kwargs, f'{owner_name}.activity_stream_read()'
|
|
391
|
+
)
|
|
392
|
+
options = cast('Callable[..., _ActivityStreamReadOptions]', _ActivityStreamReadOptions)
|
|
393
|
+
return options(**bound.arguments)
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
def bind_export_page(
|
|
397
|
+
args: tuple[object, ...],
|
|
398
|
+
kwargs: dict[str, object],
|
|
399
|
+
owner_name: str,
|
|
400
|
+
) -> _ExportPageOptions:
|
|
401
|
+
"""Bind runtime export-page arguments.
|
|
402
|
+
|
|
403
|
+
Args:
|
|
404
|
+
args: Positional arguments supplied by the caller.
|
|
405
|
+
kwargs: Keyword arguments supplied by the caller.
|
|
406
|
+
owner_name: Public client class name used in errors.
|
|
407
|
+
|
|
408
|
+
Returns:
|
|
409
|
+
Bound export-page options.
|
|
410
|
+
|
|
411
|
+
Raises:
|
|
412
|
+
TypeError: If the arguments do not match the public signature.
|
|
413
|
+
"""
|
|
414
|
+
bound = bind_arguments(_EXPORT_PAGE_SIGNATURE, args, kwargs, f'{owner_name}.export_page()')
|
|
415
|
+
options = cast('Callable[..., _ExportPageOptions]', _ExportPageOptions)
|
|
416
|
+
return options(**bound.arguments)
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
def bind_summarize(
|
|
420
|
+
args: tuple[object, ...],
|
|
421
|
+
kwargs: dict[str, object],
|
|
422
|
+
owner_name: str,
|
|
423
|
+
) -> _SummarizeOptions:
|
|
424
|
+
"""Bind runtime summarize arguments.
|
|
425
|
+
|
|
426
|
+
Args:
|
|
427
|
+
args: Positional arguments supplied by the caller.
|
|
428
|
+
kwargs: Keyword arguments supplied by the caller.
|
|
429
|
+
owner_name: Public client class name used in errors.
|
|
430
|
+
|
|
431
|
+
Returns:
|
|
432
|
+
Bound summarize options.
|
|
433
|
+
|
|
434
|
+
Raises:
|
|
435
|
+
TypeError: If the arguments do not match the public signature.
|
|
436
|
+
"""
|
|
437
|
+
bound = bind_arguments(_SUMMARIZE_SIGNATURE, args, kwargs, f'{owner_name}.summarize()')
|
|
438
|
+
options = cast('Callable[..., _SummarizeOptions]', _SummarizeOptions)
|
|
439
|
+
return options(**bound.arguments)
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
def bind_work_schedule_update(
|
|
443
|
+
args: tuple[object, ...],
|
|
444
|
+
kwargs: dict[str, object],
|
|
445
|
+
owner_name: str,
|
|
446
|
+
) -> _WorkScheduleUpdateOptions:
|
|
447
|
+
"""Bind runtime work-schedule update arguments.
|
|
448
|
+
|
|
449
|
+
Args:
|
|
450
|
+
args: Positional arguments supplied by the caller.
|
|
451
|
+
kwargs: Keyword arguments supplied by the caller.
|
|
452
|
+
owner_name: Public client class name used in errors.
|
|
453
|
+
|
|
454
|
+
Returns:
|
|
455
|
+
Bound schedule-update options.
|
|
456
|
+
|
|
457
|
+
Raises:
|
|
458
|
+
TypeError: If the arguments do not match the public signature.
|
|
459
|
+
"""
|
|
460
|
+
bound = bind_arguments(
|
|
461
|
+
_WORK_SCHEDULE_UPDATE_SIGNATURE, args, kwargs, f'{owner_name}.work_schedule_update()'
|
|
462
|
+
)
|
|
463
|
+
options = cast('Callable[..., _WorkScheduleUpdateOptions]', _WorkScheduleUpdateOptions)
|
|
464
|
+
return options(**bound.arguments)
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
def build_activity_stream_read_params(options: _ActivityStreamReadOptions) -> dict[str, object]:
|
|
468
|
+
"""Build activity-stream parameters.
|
|
469
|
+
|
|
470
|
+
Args:
|
|
471
|
+
options: Bound activity-stream options.
|
|
472
|
+
|
|
473
|
+
Returns:
|
|
474
|
+
RPC parameters copied by the client before dispatch.
|
|
475
|
+
"""
|
|
476
|
+
fields = options.entity_fields
|
|
477
|
+
return {
|
|
478
|
+
'type': options.entity_type,
|
|
479
|
+
'id': options.entity_id,
|
|
480
|
+
'max_id': options.max_id,
|
|
481
|
+
'min_id': options.min_id,
|
|
482
|
+
'limit': options.limit,
|
|
483
|
+
'entity_fields': {} if fields is None else fields,
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
def build_authentication_plan(
|
|
488
|
+
user_login: str,
|
|
489
|
+
user_password: str,
|
|
490
|
+
auth_token: str | None,
|
|
491
|
+
) -> _AuthenticationPlan:
|
|
492
|
+
"""Build one human-authentication operation.
|
|
493
|
+
|
|
494
|
+
Args:
|
|
495
|
+
user_login: Login to authenticate.
|
|
496
|
+
user_password: Password to authenticate.
|
|
497
|
+
auth_token: Optional two-factor token.
|
|
498
|
+
|
|
499
|
+
Returns:
|
|
500
|
+
Request parameters and per-request authentication specification.
|
|
501
|
+
"""
|
|
502
|
+
params = _crud.build_find_plan(
|
|
503
|
+
_crud.prepare_find(
|
|
504
|
+
_crud.FindOptions(
|
|
505
|
+
entity_type='HumanUser',
|
|
506
|
+
filters=[
|
|
507
|
+
['sg_status_list', 'is', 'act'],
|
|
508
|
+
['login', 'is', user_login],
|
|
509
|
+
],
|
|
510
|
+
fields=['id', 'login'],
|
|
511
|
+
order=None,
|
|
512
|
+
filter_operator=None,
|
|
513
|
+
limit=1,
|
|
514
|
+
retired_only=False,
|
|
515
|
+
page=1,
|
|
516
|
+
include_archived_projects=True,
|
|
517
|
+
additional_filter_presets=None,
|
|
518
|
+
)
|
|
519
|
+
),
|
|
520
|
+
1,
|
|
521
|
+
).params
|
|
522
|
+
return _AuthenticationPlan(
|
|
523
|
+
auth_spec=_protocol.AuthSpec(
|
|
524
|
+
script_name=None,
|
|
525
|
+
api_key=None,
|
|
526
|
+
user_login=user_login,
|
|
527
|
+
user_password=user_password,
|
|
528
|
+
session_token=None,
|
|
529
|
+
auth_token=auth_token,
|
|
530
|
+
sudo_as_login=None,
|
|
531
|
+
session_uuid=None,
|
|
532
|
+
extra_auth_params=None,
|
|
533
|
+
),
|
|
534
|
+
params=params,
|
|
535
|
+
)
|
|
536
|
+
|
|
537
|
+
|
|
538
|
+
def build_export_page_params(options: _ExportPageOptions) -> dict[str, object]:
|
|
539
|
+
"""Build validated page-export parameters.
|
|
540
|
+
|
|
541
|
+
Args:
|
|
542
|
+
options: Bound export-page options.
|
|
543
|
+
|
|
544
|
+
Returns:
|
|
545
|
+
RPC parameters copied by the client before dispatch.
|
|
546
|
+
|
|
547
|
+
Raises:
|
|
548
|
+
ShotgunError: If the page identifier or format is invalid.
|
|
549
|
+
"""
|
|
550
|
+
page_id = _crud.require_entity_id(
|
|
551
|
+
options.page_id,
|
|
552
|
+
'export_page page_id must be an integer',
|
|
553
|
+
)
|
|
554
|
+
page_format = _require_nonempty_string(
|
|
555
|
+
options.format,
|
|
556
|
+
'export_page format must be a nonempty string',
|
|
557
|
+
)
|
|
558
|
+
params: dict[str, object] = {'page_id': page_id, 'format': page_format}
|
|
559
|
+
if options.layout_name is not None:
|
|
560
|
+
params['layout_name'] = options.layout_name
|
|
561
|
+
return params
|
|
562
|
+
|
|
563
|
+
|
|
564
|
+
def build_follow_params(user: object, target: object) -> dict[str, object]:
|
|
565
|
+
"""Build follow or unfollow parameters.
|
|
566
|
+
|
|
567
|
+
Args:
|
|
568
|
+
user: User entity.
|
|
569
|
+
target: Target entity.
|
|
570
|
+
|
|
571
|
+
Returns:
|
|
572
|
+
RPC parameters copied by the client before dispatch.
|
|
573
|
+
"""
|
|
574
|
+
return {'user': _entity(user), 'entity': _entity(target)}
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
def build_followers_params(target: object) -> dict[str, object]:
|
|
578
|
+
"""Build follower-query parameters.
|
|
579
|
+
|
|
580
|
+
Args:
|
|
581
|
+
target: Target entity.
|
|
582
|
+
|
|
583
|
+
Returns:
|
|
584
|
+
RPC parameters copied by the client before dispatch.
|
|
585
|
+
"""
|
|
586
|
+
return {'entity': _entity(target)}
|
|
587
|
+
|
|
588
|
+
|
|
589
|
+
def build_following_params(
|
|
590
|
+
user: object,
|
|
591
|
+
project: object,
|
|
592
|
+
entity_type: object,
|
|
593
|
+
) -> dict[str, object]:
|
|
594
|
+
"""Build following-query parameters.
|
|
595
|
+
|
|
596
|
+
Args:
|
|
597
|
+
user: User entity.
|
|
598
|
+
project: Optional project entity.
|
|
599
|
+
entity_type: Optional entity type restriction.
|
|
600
|
+
|
|
601
|
+
Returns:
|
|
602
|
+
RPC parameters copied by the client before dispatch.
|
|
603
|
+
"""
|
|
604
|
+
params: dict[str, object] = {'user': _entity(user)}
|
|
605
|
+
if project is not None:
|
|
606
|
+
params['project'] = _entity(project)
|
|
607
|
+
if entity_type is not None:
|
|
608
|
+
params['entity_type'] = entity_type
|
|
609
|
+
return params
|
|
610
|
+
|
|
611
|
+
|
|
612
|
+
def build_nav_expand_params(
|
|
613
|
+
path: object,
|
|
614
|
+
seed_entity_field: object,
|
|
615
|
+
requested_entity_fields: object,
|
|
616
|
+
) -> dict[str, object]:
|
|
617
|
+
"""Build navigation expansion parameters.
|
|
618
|
+
|
|
619
|
+
Args:
|
|
620
|
+
path: Navigation path.
|
|
621
|
+
seed_entity_field: Optional seed field.
|
|
622
|
+
requested_entity_fields: Optional linked-entity fields.
|
|
623
|
+
|
|
624
|
+
Returns:
|
|
625
|
+
RPC parameters copied by the client before dispatch.
|
|
626
|
+
"""
|
|
627
|
+
fields = requested_entity_fields
|
|
628
|
+
params: dict[str, object] = {'path': path}
|
|
629
|
+
if seed_entity_field is not None:
|
|
630
|
+
params['seed_entity_field'] = seed_entity_field
|
|
631
|
+
if fields is not None:
|
|
632
|
+
params['entity_fields'] = fields
|
|
633
|
+
return params
|
|
634
|
+
|
|
635
|
+
|
|
636
|
+
def build_nav_search_entity_params(
|
|
637
|
+
root_path: object,
|
|
638
|
+
searched_entity: object,
|
|
639
|
+
seed_entity_field: object,
|
|
640
|
+
) -> dict[str, object]:
|
|
641
|
+
"""Build entity navigation-search parameters.
|
|
642
|
+
|
|
643
|
+
Args:
|
|
644
|
+
root_path: Navigation root path.
|
|
645
|
+
searched_entity: Entity to find.
|
|
646
|
+
seed_entity_field: Optional seed field.
|
|
647
|
+
|
|
648
|
+
Returns:
|
|
649
|
+
RPC parameters copied by the client before dispatch.
|
|
650
|
+
"""
|
|
651
|
+
params: dict[str, object] = {
|
|
652
|
+
'root_path': root_path,
|
|
653
|
+
'search_criteria': {'entity': _entity(searched_entity)},
|
|
654
|
+
}
|
|
655
|
+
if seed_entity_field is not None:
|
|
656
|
+
params['seed_entity_field'] = seed_entity_field
|
|
657
|
+
return params
|
|
658
|
+
|
|
659
|
+
|
|
660
|
+
def build_nav_search_string_params(
|
|
661
|
+
root_path: object,
|
|
662
|
+
search_string: object,
|
|
663
|
+
seed_entity_field: object,
|
|
664
|
+
) -> dict[str, object]:
|
|
665
|
+
"""Build string navigation-search parameters.
|
|
666
|
+
|
|
667
|
+
Args:
|
|
668
|
+
root_path: Navigation root path.
|
|
669
|
+
search_string: Search text.
|
|
670
|
+
seed_entity_field: Optional seed field.
|
|
671
|
+
|
|
672
|
+
Returns:
|
|
673
|
+
RPC parameters copied by the client before dispatch.
|
|
674
|
+
"""
|
|
675
|
+
params: dict[str, object] = {
|
|
676
|
+
'root_path': root_path,
|
|
677
|
+
'search_criteria': {'search_string': search_string},
|
|
678
|
+
}
|
|
679
|
+
if seed_entity_field is not None:
|
|
680
|
+
params['seed_entity_field'] = seed_entity_field
|
|
681
|
+
return params
|
|
682
|
+
|
|
683
|
+
|
|
684
|
+
def build_note_thread_read_params(
|
|
685
|
+
note_id: object,
|
|
686
|
+
requested_entity_fields: object,
|
|
687
|
+
) -> dict[str, object]:
|
|
688
|
+
"""Build note-thread parameters.
|
|
689
|
+
|
|
690
|
+
Args:
|
|
691
|
+
note_id: Note identifier.
|
|
692
|
+
requested_entity_fields: Optional linked-entity fields.
|
|
693
|
+
|
|
694
|
+
Returns:
|
|
695
|
+
RPC parameters copied by the client before dispatch.
|
|
696
|
+
"""
|
|
697
|
+
fields = requested_entity_fields
|
|
698
|
+
params: dict[str, object] = {'note_id': note_id}
|
|
699
|
+
if fields is not None:
|
|
700
|
+
params['entity_fields'] = fields
|
|
701
|
+
return params
|
|
702
|
+
|
|
703
|
+
|
|
704
|
+
def build_preferences_read_params(prefs: object) -> dict[str, object]:
|
|
705
|
+
"""Build preference-read parameters.
|
|
706
|
+
|
|
707
|
+
Args:
|
|
708
|
+
prefs: Optional preference names.
|
|
709
|
+
|
|
710
|
+
Returns:
|
|
711
|
+
RPC parameters copied by the client before dispatch.
|
|
712
|
+
"""
|
|
713
|
+
return {'prefs': prefs or []}
|
|
714
|
+
|
|
715
|
+
|
|
716
|
+
def build_schema_entity_read_params(project: object) -> dict[str, object] | None:
|
|
717
|
+
"""Build entity-schema parameters.
|
|
718
|
+
|
|
719
|
+
Args:
|
|
720
|
+
project: Optional project entity.
|
|
721
|
+
|
|
722
|
+
Returns:
|
|
723
|
+
RPC parameters or `None`, copied by the client before dispatch.
|
|
724
|
+
"""
|
|
725
|
+
project_entity = _project_entity(project)
|
|
726
|
+
return {'project': project_entity} if project_entity is not None else None
|
|
727
|
+
|
|
728
|
+
|
|
729
|
+
def build_schema_field_create_params(
|
|
730
|
+
entity_type: object,
|
|
731
|
+
data_type: object,
|
|
732
|
+
display_name: object,
|
|
733
|
+
properties: dict[str, object] | None,
|
|
734
|
+
) -> dict[str, object]:
|
|
735
|
+
"""Build field-creation parameters.
|
|
736
|
+
|
|
737
|
+
Args:
|
|
738
|
+
entity_type: Owning entity type.
|
|
739
|
+
data_type: New field data type.
|
|
740
|
+
display_name: New field display name.
|
|
741
|
+
properties: Optional field properties.
|
|
742
|
+
|
|
743
|
+
Returns:
|
|
744
|
+
RPC parameters copied by the client before dispatch.
|
|
745
|
+
"""
|
|
746
|
+
field_properties = {} if properties is None else properties
|
|
747
|
+
return {
|
|
748
|
+
'type': entity_type,
|
|
749
|
+
'data_type': data_type,
|
|
750
|
+
'properties': [
|
|
751
|
+
{'property_name': 'name', 'value': display_name},
|
|
752
|
+
*_property_pairs(field_properties),
|
|
753
|
+
],
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
|
|
757
|
+
def build_schema_field_delete_params(
|
|
758
|
+
entity_type: object,
|
|
759
|
+
field_name: object,
|
|
760
|
+
) -> dict[str, object]:
|
|
761
|
+
"""Build field-deletion parameters.
|
|
762
|
+
|
|
763
|
+
Args:
|
|
764
|
+
entity_type: Owning entity type.
|
|
765
|
+
field_name: Internal field name.
|
|
766
|
+
|
|
767
|
+
Returns:
|
|
768
|
+
RPC parameters copied by the client before dispatch.
|
|
769
|
+
"""
|
|
770
|
+
return {
|
|
771
|
+
'type': entity_type,
|
|
772
|
+
'field_name': field_name,
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
|
|
776
|
+
def build_schema_field_read_params(
|
|
777
|
+
entity_type: object,
|
|
778
|
+
field_name: object,
|
|
779
|
+
project: object,
|
|
780
|
+
) -> dict[str, object]:
|
|
781
|
+
"""Build field-schema parameters.
|
|
782
|
+
|
|
783
|
+
Args:
|
|
784
|
+
entity_type: Owning entity type.
|
|
785
|
+
field_name: Optional internal field name.
|
|
786
|
+
project: Optional project entity.
|
|
787
|
+
|
|
788
|
+
Returns:
|
|
789
|
+
RPC parameters copied by the client before dispatch.
|
|
790
|
+
"""
|
|
791
|
+
project_entity = _project_entity(project)
|
|
792
|
+
params: dict[str, object] = {'type': entity_type}
|
|
793
|
+
if field_name is not None:
|
|
794
|
+
params['field_name'] = field_name
|
|
795
|
+
if project_entity is not None:
|
|
796
|
+
params['project'] = project_entity
|
|
797
|
+
return params
|
|
798
|
+
|
|
799
|
+
|
|
800
|
+
def build_schema_field_update_params(
|
|
801
|
+
entity_type: object,
|
|
802
|
+
field_name: object,
|
|
803
|
+
properties: dict[str, object],
|
|
804
|
+
project: object,
|
|
805
|
+
) -> dict[str, object]:
|
|
806
|
+
"""Build field-update parameters.
|
|
807
|
+
|
|
808
|
+
Args:
|
|
809
|
+
entity_type: Owning entity type.
|
|
810
|
+
field_name: Internal field name.
|
|
811
|
+
properties: Field properties to update.
|
|
812
|
+
project: Optional project entity.
|
|
813
|
+
|
|
814
|
+
Returns:
|
|
815
|
+
RPC parameters copied by the client before dispatch.
|
|
816
|
+
"""
|
|
817
|
+
project_entity = _project_entity(project)
|
|
818
|
+
params: dict[str, object] = {
|
|
819
|
+
'type': entity_type,
|
|
820
|
+
'field_name': field_name,
|
|
821
|
+
'properties': _property_pairs(properties),
|
|
822
|
+
}
|
|
823
|
+
if project_entity is not None:
|
|
824
|
+
params['project'] = project_entity
|
|
825
|
+
return params
|
|
826
|
+
|
|
827
|
+
|
|
828
|
+
def build_summarize_params(options: _SummarizeOptions) -> dict[str, object]:
|
|
829
|
+
"""Build validated summarize parameters.
|
|
830
|
+
|
|
831
|
+
Args:
|
|
832
|
+
options: Bound summarize options.
|
|
833
|
+
|
|
834
|
+
Returns:
|
|
835
|
+
RPC parameters copied by the client before dispatch.
|
|
836
|
+
|
|
837
|
+
Raises:
|
|
838
|
+
ShotgunError: If filters or summary fields are invalid.
|
|
839
|
+
"""
|
|
840
|
+
raw_filters: object = options.filters
|
|
841
|
+
if not isinstance(raw_filters, (list, tuple, dict)):
|
|
842
|
+
raise ShotgunError('summarize() requires list or dict filters')
|
|
843
|
+
filters = cast(
|
|
844
|
+
'list[object] | tuple[object, ...] | dict[str, object]',
|
|
845
|
+
raw_filters,
|
|
846
|
+
)
|
|
847
|
+
summary_fields = cast(
|
|
848
|
+
'list[dict[str, object]]',
|
|
849
|
+
_crud.require_list(
|
|
850
|
+
options.summary_fields,
|
|
851
|
+
'summarize() requires a list of summary fields',
|
|
852
|
+
),
|
|
853
|
+
)
|
|
854
|
+
params: dict[str, object] = {
|
|
855
|
+
'type': options.entity_type,
|
|
856
|
+
'filters': _protocol.translate_filters(filters, options.filter_operator),
|
|
857
|
+
'summaries': summary_fields,
|
|
858
|
+
}
|
|
859
|
+
if options.grouping is not None:
|
|
860
|
+
params['grouping'] = options.grouping
|
|
861
|
+
if not options.include_archived_projects:
|
|
862
|
+
params['include_archived_projects'] = False
|
|
863
|
+
return params
|
|
864
|
+
|
|
865
|
+
|
|
866
|
+
def build_text_search_params(
|
|
867
|
+
text: str,
|
|
868
|
+
entity_types: object,
|
|
869
|
+
project_ids: object,
|
|
870
|
+
limit: object,
|
|
871
|
+
) -> dict[str, object]:
|
|
872
|
+
"""Build validated text-search parameters.
|
|
873
|
+
|
|
874
|
+
Args:
|
|
875
|
+
text: Search text.
|
|
876
|
+
entity_types: Entity-type filter mapping.
|
|
877
|
+
project_ids: Optional project identifiers.
|
|
878
|
+
limit: Optional maximum result count.
|
|
879
|
+
|
|
880
|
+
Returns:
|
|
881
|
+
RPC parameters copied by the client before dispatch.
|
|
882
|
+
|
|
883
|
+
Raises:
|
|
884
|
+
ShotgunError: If `entity_types` is not a dictionary.
|
|
885
|
+
"""
|
|
886
|
+
validated_entity_types = _crud.require_dictionary(
|
|
887
|
+
entity_types,
|
|
888
|
+
'text_search() entity_types must be a dict',
|
|
889
|
+
)
|
|
890
|
+
translated = {
|
|
891
|
+
entity_type: _protocol.translate_filters(_protocol.require_filter_container(filters))
|
|
892
|
+
for entity_type, filters in validated_entity_types.items()
|
|
893
|
+
}
|
|
894
|
+
return {
|
|
895
|
+
'text': text,
|
|
896
|
+
'entity_types': translated,
|
|
897
|
+
'project_ids': [] if project_ids is None else project_ids,
|
|
898
|
+
'max_results': limit,
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
|
|
902
|
+
def build_update_project_last_accessed_params(
|
|
903
|
+
project: dict[str, object],
|
|
904
|
+
user: dict[str, object] | None,
|
|
905
|
+
) -> dict[str, object]:
|
|
906
|
+
"""Build last-accessed parameters.
|
|
907
|
+
|
|
908
|
+
Args:
|
|
909
|
+
project: Accessed project entity.
|
|
910
|
+
user: Optional attributed user entity.
|
|
911
|
+
|
|
912
|
+
Returns:
|
|
913
|
+
RPC parameters copied by the client before dispatch.
|
|
914
|
+
"""
|
|
915
|
+
params: dict[str, object] = {'project_id': project['id']}
|
|
916
|
+
if user is not None:
|
|
917
|
+
params['user_id'] = user['id']
|
|
918
|
+
return params
|
|
919
|
+
|
|
920
|
+
|
|
921
|
+
def build_user_subscriptions_create_params(users: object) -> dict[str, object]:
|
|
922
|
+
"""Build validated subscription parameters.
|
|
923
|
+
|
|
924
|
+
Args:
|
|
925
|
+
users: User subscription entries.
|
|
926
|
+
|
|
927
|
+
Returns:
|
|
928
|
+
RPC parameters copied by the client before dispatch.
|
|
929
|
+
|
|
930
|
+
Raises:
|
|
931
|
+
ShotgunError: If the entries are invalid.
|
|
932
|
+
"""
|
|
933
|
+
validated = _crud.require_list(
|
|
934
|
+
users,
|
|
935
|
+
'user_subscriptions_create users must be a list',
|
|
936
|
+
)
|
|
937
|
+
message = 'user_subscriptions_create users must contain dictionaries with a user_id key'
|
|
938
|
+
for member in validated:
|
|
939
|
+
if not isinstance(member, dict) or 'user_id' not in member:
|
|
940
|
+
raise ShotgunError(message)
|
|
941
|
+
return {'users': cast('list[dict[str, object]]', validated)}
|
|
942
|
+
|
|
943
|
+
|
|
944
|
+
def build_work_schedule_read_params(
|
|
945
|
+
start_date: object,
|
|
946
|
+
end_date: object,
|
|
947
|
+
project: dict[str, object] | None,
|
|
948
|
+
user: dict[str, object] | None,
|
|
949
|
+
) -> dict[str, object]:
|
|
950
|
+
"""Build validated schedule-read parameters.
|
|
951
|
+
|
|
952
|
+
Args:
|
|
953
|
+
start_date: Inclusive `datetime.date` or exact `YYYY-MM-DD` string;
|
|
954
|
+
`datetime.datetime` is not accepted.
|
|
955
|
+
end_date: Inclusive `datetime.date` or exact `YYYY-MM-DD` string;
|
|
956
|
+
`datetime.datetime` is not accepted.
|
|
957
|
+
project: Optional project restriction.
|
|
958
|
+
user: Optional user restriction.
|
|
959
|
+
|
|
960
|
+
Returns:
|
|
961
|
+
RPC parameters copied by the client before dispatch.
|
|
962
|
+
|
|
963
|
+
Raises:
|
|
964
|
+
ShotgunError: If dates or restrictions are invalid.
|
|
965
|
+
"""
|
|
966
|
+
params: dict[str, object] = {
|
|
967
|
+
'start_date': _date_str(start_date, 'start_date'),
|
|
968
|
+
'end_date': _date_str(end_date, 'end_date'),
|
|
969
|
+
}
|
|
970
|
+
if project is not None:
|
|
971
|
+
params['project'] = _entity(project)
|
|
972
|
+
if user is not None:
|
|
973
|
+
params['user'] = _entity(user)
|
|
974
|
+
return params
|
|
975
|
+
|
|
976
|
+
|
|
977
|
+
def build_work_schedule_update_params(
|
|
978
|
+
options: _WorkScheduleUpdateOptions,
|
|
979
|
+
) -> dict[str, object]:
|
|
980
|
+
"""Build validated schedule-update parameters.
|
|
981
|
+
|
|
982
|
+
Args:
|
|
983
|
+
options: Bound schedule-update options. The date must be a
|
|
984
|
+
`datetime.date` or exact `YYYY-MM-DD` string, not a
|
|
985
|
+
`datetime.datetime`. Project and user restrictions are mutually
|
|
986
|
+
exclusive.
|
|
987
|
+
|
|
988
|
+
Returns:
|
|
989
|
+
RPC parameters copied by the client before dispatch.
|
|
990
|
+
|
|
991
|
+
Raises:
|
|
992
|
+
ShotgunError: If the date is invalid or both restrictions are supplied.
|
|
993
|
+
"""
|
|
994
|
+
_reject_project_and_user(options.project, options.user)
|
|
995
|
+
params: dict[str, object] = {
|
|
996
|
+
'date': _date_str(options.date, 'date'),
|
|
997
|
+
'working': options.working,
|
|
998
|
+
}
|
|
999
|
+
if options.description is not None:
|
|
1000
|
+
params['description'] = options.description
|
|
1001
|
+
if options.project is not None:
|
|
1002
|
+
params['project'] = _entity(options.project)
|
|
1003
|
+
if options.user is not None:
|
|
1004
|
+
params['user'] = _entity(options.user)
|
|
1005
|
+
if options.recalculate_field is not None:
|
|
1006
|
+
params['recalculate_field'] = options.recalculate_field
|
|
1007
|
+
return params
|
|
1008
|
+
|
|
1009
|
+
|
|
1010
|
+
def consume_compatibility_warnings(
|
|
1011
|
+
warning_context: contextvars.ContextVar[_PENDING_COMPATIBILITY_WARNINGS | None],
|
|
1012
|
+
owner: object,
|
|
1013
|
+
) -> tuple[CompatibilityWarningCode, ...]:
|
|
1014
|
+
"""Consume operation-local compatibility warnings exactly once.
|
|
1015
|
+
|
|
1016
|
+
Args:
|
|
1017
|
+
warning_context: Context-local warning state.
|
|
1018
|
+
owner: Client instance expected to own the warning.
|
|
1019
|
+
|
|
1020
|
+
Returns:
|
|
1021
|
+
Compatibility warning codes for the target call.
|
|
1022
|
+
"""
|
|
1023
|
+
pending = warning_context.get()
|
|
1024
|
+
if pending is None or pending[0] is not owner:
|
|
1025
|
+
return ()
|
|
1026
|
+
warning_context.set(None)
|
|
1027
|
+
return pending[1]
|
|
1028
|
+
|
|
1029
|
+
|
|
1030
|
+
@contextmanager
|
|
1031
|
+
def entity_types_alias(owner: object) -> Generator[None, None, None]:
|
|
1032
|
+
"""Scope the deprecated `entity_types` compatibility notice.
|
|
1033
|
+
|
|
1034
|
+
Args:
|
|
1035
|
+
owner: Client instance invoking the alias.
|
|
1036
|
+
|
|
1037
|
+
Yields:
|
|
1038
|
+
Control while the public target method consumes the warning.
|
|
1039
|
+
"""
|
|
1040
|
+
token = SCHEMA_ENTITY_READ_WARNINGS.set(
|
|
1041
|
+
(owner, ('deprecated-entity-types-alias',)),
|
|
1042
|
+
)
|
|
1043
|
+
try:
|
|
1044
|
+
yield
|
|
1045
|
+
finally:
|
|
1046
|
+
SCHEMA_ENTITY_READ_WARNINGS.reset(token)
|
|
1047
|
+
|
|
1048
|
+
|
|
1049
|
+
def expose_activity_stream_read_signature(
|
|
1050
|
+
function: Callable[..., object],
|
|
1051
|
+
) -> Callable[..., object]:
|
|
1052
|
+
"""Expose the documented activity-stream signature.
|
|
1053
|
+
|
|
1054
|
+
Args:
|
|
1055
|
+
function: Variadic implementation.
|
|
1056
|
+
|
|
1057
|
+
Returns:
|
|
1058
|
+
The implementation with public reflection metadata.
|
|
1059
|
+
"""
|
|
1060
|
+
return expose_signature(
|
|
1061
|
+
function, _METHOD_ACTIVITY_STREAM_READ_SIGNATURE, _ACTIVITY_STREAM_READ_DOCSTRING
|
|
1062
|
+
)
|
|
1063
|
+
|
|
1064
|
+
|
|
1065
|
+
def expose_export_page_signature(
|
|
1066
|
+
function: Callable[..., object],
|
|
1067
|
+
) -> Callable[..., object]:
|
|
1068
|
+
"""Expose the documented page-export signature.
|
|
1069
|
+
|
|
1070
|
+
Args:
|
|
1071
|
+
function: Variadic implementation.
|
|
1072
|
+
|
|
1073
|
+
Returns:
|
|
1074
|
+
The implementation with public reflection metadata.
|
|
1075
|
+
"""
|
|
1076
|
+
return expose_signature(function, _METHOD_EXPORT_PAGE_SIGNATURE, _EXPORT_PAGE_DOCSTRING)
|
|
1077
|
+
|
|
1078
|
+
|
|
1079
|
+
def expose_summarize_signature(
|
|
1080
|
+
function: Callable[..., object],
|
|
1081
|
+
) -> Callable[..., object]:
|
|
1082
|
+
"""Expose the documented summarize signature.
|
|
1083
|
+
|
|
1084
|
+
Args:
|
|
1085
|
+
function: Variadic implementation.
|
|
1086
|
+
|
|
1087
|
+
Returns:
|
|
1088
|
+
The implementation with public reflection metadata.
|
|
1089
|
+
"""
|
|
1090
|
+
return expose_signature(function, _METHOD_SUMMARIZE_SIGNATURE, _SUMMARIZE_DOCSTRING)
|
|
1091
|
+
|
|
1092
|
+
|
|
1093
|
+
def expose_work_schedule_update_signature(
|
|
1094
|
+
function: Callable[..., object],
|
|
1095
|
+
) -> Callable[..., object]:
|
|
1096
|
+
"""Expose the documented schedule-update signature.
|
|
1097
|
+
|
|
1098
|
+
Args:
|
|
1099
|
+
function: Variadic implementation.
|
|
1100
|
+
|
|
1101
|
+
Returns:
|
|
1102
|
+
The implementation with public reflection metadata.
|
|
1103
|
+
"""
|
|
1104
|
+
return expose_signature(
|
|
1105
|
+
function, _METHOD_WORK_SCHEDULE_UPDATE_SIGNATURE, _WORK_SCHEDULE_UPDATE_DOCSTRING
|
|
1106
|
+
)
|
|
1107
|
+
|
|
1108
|
+
|
|
1109
|
+
def require_dictionary_list_result(
|
|
1110
|
+
value: object,
|
|
1111
|
+
method_name: str,
|
|
1112
|
+
) -> list[dict[str, object]]:
|
|
1113
|
+
"""Validate a list of dictionary RPC results.
|
|
1114
|
+
|
|
1115
|
+
Args:
|
|
1116
|
+
value: Raw RPC result.
|
|
1117
|
+
method_name: Public method name used in errors.
|
|
1118
|
+
|
|
1119
|
+
Returns:
|
|
1120
|
+
Validated dictionary list.
|
|
1121
|
+
|
|
1122
|
+
Raises:
|
|
1123
|
+
ShotgunError: If the result is invalid.
|
|
1124
|
+
"""
|
|
1125
|
+
result = _crud.require_list_result(value, method_name)
|
|
1126
|
+
if any(not isinstance(member, dict) for member in result):
|
|
1127
|
+
raise ShotgunError(f'{method_name} returned a non-dictionary member')
|
|
1128
|
+
return cast('list[dict[str, object]]', result)
|
|
1129
|
+
|
|
1130
|
+
|
|
1131
|
+
def require_human_authentication_result(value: object) -> dict[str, object] | None:
|
|
1132
|
+
"""Validate and select the first human-authentication result.
|
|
1133
|
+
|
|
1134
|
+
Args:
|
|
1135
|
+
value: Raw read result.
|
|
1136
|
+
|
|
1137
|
+
Returns:
|
|
1138
|
+
First matching user or `None`.
|
|
1139
|
+
|
|
1140
|
+
Raises:
|
|
1141
|
+
ShotgunError: If the result is invalid.
|
|
1142
|
+
"""
|
|
1143
|
+
result = _crud.require_dictionary_result(value, 'authenticate_human_user')
|
|
1144
|
+
entities = _crud.require_list(
|
|
1145
|
+
result.get('entities', []),
|
|
1146
|
+
'authenticate_human_user did not return an entities list',
|
|
1147
|
+
)
|
|
1148
|
+
if any(not isinstance(member, dict) for member in entities):
|
|
1149
|
+
raise ShotgunError('authenticate_human_user returned a non-dictionary entity')
|
|
1150
|
+
return cast('dict[str, object]', entities[0]) if entities else None
|
|
1151
|
+
|
|
1152
|
+
|
|
1153
|
+
def require_string_result(value: object, method_name: str) -> str:
|
|
1154
|
+
"""Validate a string RPC result.
|
|
1155
|
+
|
|
1156
|
+
Args:
|
|
1157
|
+
value: Raw RPC result.
|
|
1158
|
+
method_name: Public method name used in errors.
|
|
1159
|
+
|
|
1160
|
+
Returns:
|
|
1161
|
+
Validated string.
|
|
1162
|
+
|
|
1163
|
+
Raises:
|
|
1164
|
+
ShotgunError: If the result is not a string.
|
|
1165
|
+
"""
|
|
1166
|
+
if not isinstance(value, str):
|
|
1167
|
+
raise ShotgunError(f'{method_name} did not return a string')
|
|
1168
|
+
return value
|
|
1169
|
+
|
|
1170
|
+
|
|
1171
|
+
@contextmanager
|
|
1172
|
+
def schema_alias(owner: object) -> Generator[None, None, None]:
|
|
1173
|
+
"""Scope the deprecated `schema` compatibility notice.
|
|
1174
|
+
|
|
1175
|
+
Args:
|
|
1176
|
+
owner: Client instance invoking the alias.
|
|
1177
|
+
|
|
1178
|
+
Yields:
|
|
1179
|
+
Control while the public target method consumes the warning.
|
|
1180
|
+
"""
|
|
1181
|
+
token = SCHEMA_FIELD_READ_WARNINGS.set(
|
|
1182
|
+
(owner, ('deprecated-schema-alias',)),
|
|
1183
|
+
)
|
|
1184
|
+
try:
|
|
1185
|
+
yield
|
|
1186
|
+
finally:
|
|
1187
|
+
SCHEMA_FIELD_READ_WARNINGS.reset(token)
|
|
1188
|
+
|
|
1189
|
+
|
|
1190
|
+
def warn_entity_types_alias() -> None:
|
|
1191
|
+
"""Warn at the caller of the deprecated `entity_types` method."""
|
|
1192
|
+
warnings.warn(
|
|
1193
|
+
'entity_types() is deprecated; use schema_entity_read()',
|
|
1194
|
+
DeprecationWarning,
|
|
1195
|
+
stacklevel=3,
|
|
1196
|
+
)
|
|
1197
|
+
|
|
1198
|
+
|
|
1199
|
+
def warn_schema_alias() -> None:
|
|
1200
|
+
"""Warn at the caller of the deprecated `schema` method."""
|
|
1201
|
+
warnings.warn(
|
|
1202
|
+
'schema() is deprecated; use schema_field_read()',
|
|
1203
|
+
DeprecationWarning,
|
|
1204
|
+
stacklevel=3,
|
|
1205
|
+
)
|