sg-python-api 0.1.2__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.
Files changed (56) hide show
  1. {sg_python_api-0.1.2.dist-info → sg_python_api-0.2.0.dist-info}/METADATA +21 -24
  2. sg_python_api-0.2.0.dist-info/RECORD +58 -0
  3. shotgun_api3/__init__.py +4 -0
  4. shotgun_api3/_async_client.py +347 -281
  5. shotgun_api3/_async_driver.py +25 -55
  6. shotgun_api3/_async_httpx2.py +92 -59
  7. shotgun_api3/_async_transport.py +38 -3
  8. shotgun_api3/_capabilities.py +4 -3
  9. shotgun_api3/_client.py +296 -422
  10. shotgun_api3/_config.py +245 -120
  11. shotgun_api3/_connections.py +144 -0
  12. shotgun_api3/_crud.py +25 -250
  13. shotgun_api3/_driver.py +29 -54
  14. shotgun_api3/_execution.py +1 -3
  15. shotgun_api3/_files.py +193 -21
  16. shotgun_api3/_methods.py +59 -411
  17. shotgun_api3/_protocol.py +27 -53
  18. shotgun_api3/_transport.py +82 -407
  19. shotgun_api3/_version.py +7 -2
  20. shotgun_api3/lib/mockgun/__init__.py +20 -7
  21. shotgun_api3/lib/mockgun/_activity.py +510 -0
  22. shotgun_api3/lib/mockgun/_async_client.py +196 -0
  23. shotgun_api3/lib/mockgun/_dates.py +164 -0
  24. shotgun_api3/lib/mockgun/_errors.py +18 -0
  25. shotgun_api3/lib/mockgun/_events.py +1031 -0
  26. shotgun_api3/lib/mockgun/_follows.py +217 -0
  27. shotgun_api3/lib/mockgun/_handlers.py +558 -0
  28. shotgun_api3/lib/mockgun/_links.py +440 -0
  29. shotgun_api3/lib/mockgun/_new_client.py +92 -0
  30. shotgun_api3/lib/mockgun/_presets.py +492 -0
  31. shotgun_api3/lib/mockgun/_query.py +2163 -0
  32. shotgun_api3/lib/mockgun/_retirement.py +368 -0
  33. shotgun_api3/lib/mockgun/_schema.py +172 -0
  34. shotgun_api3/lib/mockgun/_schema_writes.py +425 -0
  35. shotgun_api3/lib/mockgun/_search.py +378 -0
  36. shotgun_api3/lib/mockgun/_server.py +169 -0
  37. shotgun_api3/lib/mockgun/_sessions.py +206 -0
  38. shotgun_api3/lib/mockgun/_site.py +150 -0
  39. shotgun_api3/lib/mockgun/_site_data.py +584 -0
  40. shotgun_api3/lib/mockgun/_storage.py +208 -0
  41. shotgun_api3/lib/mockgun/_store.py +1446 -0
  42. shotgun_api3/lib/mockgun/_summaries.py +964 -0
  43. shotgun_api3/lib/mockgun/_sync_client.py +190 -0
  44. shotgun_api3/lib/mockgun/_threads.py +226 -0
  45. shotgun_api3/lib/mockgun/_thumbnails.py +146 -0
  46. shotgun_api3/lib/mockgun/_transport.py +145 -0
  47. shotgun_api3/lib/mockgun/_uploads.py +417 -0
  48. shotgun_api3/lib/mockgun/_wire.py +120 -0
  49. shotgun_api3/lib/mockgun/mockgun.py +14 -0
  50. shotgun_api3/lib/sgtimezone.py +24 -1
  51. sg_python_api-0.1.2.dist-info/RECORD +0 -31
  52. shotgun_api3/_signatures.py +0 -53
  53. shotgun_api3/lib/mockgun/_async.py +0 -315
  54. shotgun_api3/lib/mockgun/_mockgun.py +0 -1666
  55. {sg_python_api-0.1.2.dist-info → sg_python_api-0.2.0.dist-info}/WHEEL +0 -0
  56. {sg_python_api-0.1.2.dist-info → sg_python_api-0.2.0.dist-info}/licenses/LICENSE +0 -0
shotgun_api3/_protocol.py CHANGED
@@ -16,7 +16,6 @@ from typing import Final, Literal, TypeAlias, TypeGuard, TypeVar, cast, overload
16
16
  from . import _errors
17
17
  from ._sg_timezone import SG_TIMEZONE
18
18
  from ._transport import (
19
- AbortedError,
20
19
  ConnectError,
21
20
  ProxyError,
22
21
  ReadTimeoutError,
@@ -52,7 +51,6 @@ _FailureCategory = Literal[
52
51
  'proxy_auth',
53
52
  'tls',
54
53
  'authentication',
55
- 'abort',
56
54
  'configuration',
57
55
  ]
58
56
  _FailurePhase = Literal['pre_send', 'ambiguous_after_send', 'http_status', 'body_read']
@@ -136,9 +134,7 @@ _SAFE_RPC_METHODS = frozenset(
136
134
  'work_schedule_read',
137
135
  }
138
136
  )
139
- _TERMINAL_FAILURE_CATEGORIES = frozenset(
140
- {'abort', 'authentication', 'configuration', 'proxy_auth', 'tls'}
141
- )
137
+ _TERMINAL_FAILURE_CATEGORIES = frozenset({'authentication', 'configuration', 'proxy_auth', 'tls'})
142
138
  _WRITE_METHODS = frozenset(
143
139
  {
144
140
  'create',
@@ -214,13 +210,11 @@ class OperationDescriptor:
214
210
  Attributes:
215
211
  category: Stable operation category.
216
212
  replay_safe: Whether a completed request may be replayed.
217
- body_restartable: Whether each attempt can obtain a fresh body.
218
213
  endpoint_role: Special endpoint role, when applicable.
219
214
  """
220
215
 
221
216
  category: OperationCategory
222
217
  replay_safe: bool
223
- body_restartable: bool
224
218
  endpoint_role: _EndpointRole | None
225
219
 
226
220
 
@@ -249,7 +243,7 @@ def _backoff(
249
243
  (
250
244
  operation.category,
251
245
  operation.replay_safe,
252
- operation.body_restartable,
246
+ True, # Preserve the established jitter seed for restartable bodies.
253
247
  operation.endpoint_role,
254
248
  attempt,
255
249
  base_interval,
@@ -327,6 +321,24 @@ def _classify_rpc(
327
321
  return category, replay_safe
328
322
 
329
323
 
324
+ def _classify(
325
+ method_name: str,
326
+ normalized_params: object,
327
+ has_one_use_auth_token: bool = False,
328
+ ) -> OperationDescriptor:
329
+ """Classify an operation for phase-aware retry decisions."""
330
+ category, replay_safe = _classify_rpc(
331
+ method_name,
332
+ normalized_params,
333
+ has_one_use_auth_token,
334
+ )
335
+ return OperationDescriptor(
336
+ category=category,
337
+ replay_safe=replay_safe,
338
+ endpoint_role=None,
339
+ )
340
+
341
+
330
342
  def _entity_optimization_disabled() -> bool:
331
343
  """Read the canonical public runtime setting without import-time coupling."""
332
344
  module = sys.modules.get(f'{__package__}.shotgun')
@@ -540,13 +552,11 @@ def build_payload(
540
552
 
541
553
  def classify_endpoint(
542
554
  endpoint_role: _EndpointRole,
543
- body_restartable: bool = True,
544
555
  ) -> OperationDescriptor:
545
556
  """Classify a non-RPC endpoint exchange.
546
557
 
547
558
  Args:
548
559
  endpoint_role: Endpoint role used for retry and route decisions.
549
- body_restartable: Whether the body can restart from byte zero.
550
560
 
551
561
  Returns:
552
562
  An immutable descriptor with conservative retry behavior.
@@ -568,44 +578,10 @@ def classify_endpoint(
568
578
  return OperationDescriptor(
569
579
  category=category,
570
580
  replay_safe=replay_safe,
571
- body_restartable=body_restartable,
572
581
  endpoint_role=known_role,
573
582
  )
574
583
 
575
584
 
576
- def classify(
577
- method_name: str,
578
- normalized_params: object,
579
- body_restartable: bool = True,
580
- has_one_use_auth_token: bool = False,
581
- ) -> OperationDescriptor:
582
- """Classify an operation for phase-aware retry decisions.
583
-
584
- Args:
585
- method_name: Normalized RPC method name.
586
- normalized_params: Normalized method parameters, including every batch
587
- member.
588
- body_restartable: Whether the request body can be sent again from byte
589
- zero.
590
- has_one_use_auth_token: Whether captured request authentication
591
- includes a one-use token outside method parameters.
592
-
593
- Returns:
594
- An immutable operation descriptor. Unknown inputs are not replay-safe.
595
- """
596
- category, replay_safe = _classify_rpc(
597
- method_name,
598
- normalized_params,
599
- has_one_use_auth_token,
600
- )
601
- return OperationDescriptor(
602
- category=category,
603
- replay_safe=replay_safe,
604
- body_restartable=body_restartable,
605
- endpoint_role=None,
606
- )
607
-
608
-
609
585
  def classify_rpc_operation(
610
586
  wire_method_name: str,
611
587
  logical_method_name: str | None,
@@ -629,10 +605,9 @@ def classify_rpc_operation(
629
605
  return OperationDescriptor(
630
606
  category='read',
631
607
  replay_safe=True,
632
- body_restartable=True,
633
608
  endpoint_role=None,
634
609
  )
635
- return classify(
610
+ return _classify(
636
611
  logical_method_name or wire_method_name,
637
612
  normalized_params,
638
613
  has_one_use_auth_token=has_one_use_auth_token,
@@ -652,12 +627,9 @@ def classify_transport_failure(
652
627
  Returns:
653
628
  Shared retry-policy failure vocabulary.
654
629
  """
655
- if isinstance(error, AbortedError):
656
- phase: _FailurePhase = 'body_read' if response_received else 'pre_send'
657
- category: _FailureCategory = 'abort'
658
- elif isinstance(error, ProxyError):
659
- phase = 'pre_send'
660
- category = 'proxy_auth'
630
+ if isinstance(error, ProxyError):
631
+ phase: _FailurePhase = 'pre_send'
632
+ category: _FailureCategory = 'proxy_auth'
661
633
  elif isinstance(error, TLSError):
662
634
  phase = 'pre_send'
663
635
  category = 'tls'
@@ -705,7 +677,6 @@ def decide( # noqa: PLR0913
705
677
  attempt < 1
706
678
  or max_attempts < 1
707
679
  or attempt >= max_attempts
708
- or not operation.body_restartable
709
680
  or (failure.phase != 'pre_send' and not operation.replay_safe)
710
681
  or not _failure_is_retryable(failure)
711
682
  )
@@ -1154,6 +1125,9 @@ def transform_outbound(data: object, convert_utc: bool) -> object:
1154
1125
  ValueError: If converting a naive local datetime to UTC exceeds the
1155
1126
  supported range. The message is `datetime conversion exceeds the
1156
1127
  supported range`, and the exception has no cause.
1128
+ OverflowError: If converting an aware datetime to UTC exceeds the
1129
+ supported datetime range.
1130
+ OSError: If the platform cannot resolve a local datetime.
1157
1131
  """
1158
1132
 
1159
1133
  def visit(value: object) -> object: