driftstack-sdk 0.1.3__tar.gz → 0.1.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (20) hide show
  1. {driftstack_sdk-0.1.3 → driftstack_sdk-0.1.5}/PKG-INFO +1 -1
  2. {driftstack_sdk-0.1.3 → driftstack_sdk-0.1.5}/pyproject.toml +1 -1
  3. {driftstack_sdk-0.1.3 → driftstack_sdk-0.1.5}/src/driftstack/__init__.py +4 -0
  4. {driftstack_sdk-0.1.3 → driftstack_sdk-0.1.5}/src/driftstack/_generated/models.py +1 -1
  5. {driftstack_sdk-0.1.3 → driftstack_sdk-0.1.5}/src/driftstack/_version.py +1 -1
  6. {driftstack_sdk-0.1.3 → driftstack_sdk-0.1.5}/src/driftstack/errors.py +46 -0
  7. {driftstack_sdk-0.1.3 → driftstack_sdk-0.1.5}/src/driftstack/http.py +33 -0
  8. {driftstack_sdk-0.1.3 → driftstack_sdk-0.1.5}/.gitignore +0 -0
  9. {driftstack_sdk-0.1.3 → driftstack_sdk-0.1.5}/README.md +0 -0
  10. {driftstack_sdk-0.1.3 → driftstack_sdk-0.1.5}/src/driftstack/_generated/__init__.py +0 -0
  11. {driftstack_sdk-0.1.3 → driftstack_sdk-0.1.5}/src/driftstack/client.py +0 -0
  12. {driftstack_sdk-0.1.3 → driftstack_sdk-0.1.5}/src/driftstack/py.typed +0 -0
  13. {driftstack_sdk-0.1.3 → driftstack_sdk-0.1.5}/src/driftstack/resources/__init__.py +0 -0
  14. {driftstack_sdk-0.1.3 → driftstack_sdk-0.1.5}/src/driftstack/resources/_common.py +0 -0
  15. {driftstack_sdk-0.1.3 → driftstack_sdk-0.1.5}/src/driftstack/resources/api_keys.py +0 -0
  16. {driftstack_sdk-0.1.3 → driftstack_sdk-0.1.5}/src/driftstack/resources/sessions.py +0 -0
  17. {driftstack_sdk-0.1.3 → driftstack_sdk-0.1.5}/src/driftstack/resources/usage.py +0 -0
  18. {driftstack_sdk-0.1.3 → driftstack_sdk-0.1.5}/src/driftstack/resources/webhooks.py +0 -0
  19. {driftstack_sdk-0.1.3 → driftstack_sdk-0.1.5}/src/driftstack/retry.py +0 -0
  20. {driftstack_sdk-0.1.3 → driftstack_sdk-0.1.5}/src/driftstack/webhook_signature.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: driftstack-sdk
3
- Version: 0.1.3
3
+ Version: 0.1.5
4
4
  Summary: Driftstack Python SDK — stealth iPhone Safari automation. Import as `driftstack`.
5
5
  Project-URL: Homepage, https://driftstack.dev
6
6
  Project-URL: Repository, https://github.com/driftstackdev/driftstack-api
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "driftstack-sdk"
7
- version = "0.1.3"
7
+ version = "0.1.5"
8
8
  description = "Driftstack Python SDK — stealth iPhone Safari automation. Import as `driftstack`."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -29,8 +29,10 @@ from driftstack.errors import (
29
29
  QuotaExceededError,
30
30
  RateLimitError,
31
31
  RevokedKeyError,
32
+ LegalAcceptanceRequiredError,
32
33
  SessionDestroyedError,
33
34
  SessionNotFoundError,
35
+ SessionTimeoutError,
34
36
  TransportError,
35
37
  ValidationError,
36
38
  )
@@ -53,6 +55,8 @@ __all__ = [
53
55
  "ConcurrencyLimitError",
54
56
  "SessionNotFoundError",
55
57
  "SessionDestroyedError",
58
+ "SessionTimeoutError",
59
+ "LegalAcceptanceRequiredError",
56
60
  "DriverError",
57
61
  "ValidationError",
58
62
  "TransportError",
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: openapi.json
3
- # timestamp: 2026-05-03T10:05:29+00:00
3
+ # timestamp: 2026-05-03T12:11:01+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -7,4 +7,4 @@ needed — useful for tools that scrape the version without installing.
7
7
 
8
8
  from __future__ import annotations
9
9
 
10
- __version__ = "0.1.3"
10
+ __version__ = "0.1.5"
@@ -94,6 +94,50 @@ class SessionDestroyedError(DriftstackError):
94
94
  """The session was destroyed; further operations on it are rejected (410)."""
95
95
 
96
96
 
97
+ class LegalAcceptanceRequiredError(DriftstackError):
98
+ """409 when an operation (e.g. creating an API key) is gated on the
99
+ customer accepting one or more legal documents.
100
+
101
+ ``pending_acceptances`` carries the document keys + current versions
102
+ so the client can drive the user through the acceptance flow without
103
+ a follow-up GET.
104
+ """
105
+
106
+ def __init__(
107
+ self,
108
+ message: str,
109
+ *,
110
+ pending_acceptances: list[dict[str, str]] | None = None,
111
+ status: int | None = 409,
112
+ problem_type: str | None = None,
113
+ problem: dict[str, Any] | None = None,
114
+ ) -> None:
115
+ super().__init__(message, status=status, problem_type=problem_type, problem=problem)
116
+ self.pending_acceptances = pending_acceptances or []
117
+
118
+
119
+ class SessionTimeoutError(DriftstackError):
120
+ """The operation exceeded the per-call ``timeout_ms`` (504).
121
+
122
+ Distinguished from ``DriverError`` so customers can react specifically
123
+ to "didn't finish in time" without conflating with downstream driver
124
+ failures. ``timeout_ms`` is the bound the server actually applied
125
+ (may differ from the request if the server clamped it).
126
+ """
127
+
128
+ def __init__(
129
+ self,
130
+ message: str,
131
+ *,
132
+ timeout_ms: int | None = None,
133
+ status: int | None = 504,
134
+ problem_type: str | None = None,
135
+ problem: dict[str, Any] | None = None,
136
+ ) -> None:
137
+ super().__init__(message, status=status, problem_type=problem_type, problem=problem)
138
+ self.timeout_ms = timeout_ms
139
+
140
+
97
141
  # ── Rate / quota (429) ────────────────────────────────────────────────────
98
142
 
99
143
 
@@ -188,6 +232,8 @@ PROBLEM_TYPE_TO_ERROR: dict[str, type[DriftstackError]] = {
188
232
  "https://errors.driftstack.dev/expired-key": ExpiredKeyError,
189
233
  "https://errors.driftstack.dev/invalid-key": InvalidKeyError,
190
234
  "https://errors.driftstack.dev/session-destroyed": SessionDestroyedError,
235
+ "https://errors.driftstack.dev/session-timeout": SessionTimeoutError,
236
+ "https://errors.driftstack.dev/legal-acceptance-required": LegalAcceptanceRequiredError,
191
237
  "https://errors.driftstack.dev/driver-error": DriverError,
192
238
  "https://errors.driftstack.dev/driver-not-integrated": DriverError,
193
239
  "https://errors.driftstack.dev/validation-failed": ValidationError,
@@ -25,6 +25,8 @@ from driftstack._version import __version__
25
25
  from driftstack.errors import (
26
26
  PROBLEM_TYPE_TO_ERROR,
27
27
  ConcurrencyLimitError,
28
+ LegalAcceptanceRequiredError,
29
+ SessionTimeoutError,
28
30
  DriftstackError,
29
31
  QuotaExceededError,
30
32
  RateLimitError,
@@ -126,6 +128,37 @@ def _error_from_response_data(
126
128
  problem_type=problem_type,
127
129
  problem=problem,
128
130
  )
131
+ if error_cls is SessionTimeoutError:
132
+ return SessionTimeoutError(
133
+ detail,
134
+ timeout_ms=_int_or_none(problem.get("timeout_ms")),
135
+ status=status,
136
+ problem_type=problem_type,
137
+ problem=problem,
138
+ )
139
+ if error_cls is LegalAcceptanceRequiredError:
140
+ raw = problem.get("pending_acceptances")
141
+ pending: list[dict[str, str]] = []
142
+ if isinstance(raw, list):
143
+ for entry in raw:
144
+ if (
145
+ isinstance(entry, dict)
146
+ and isinstance(entry.get("document_key"), str)
147
+ and isinstance(entry.get("current_version"), str)
148
+ ):
149
+ pending.append(
150
+ {
151
+ "document_key": entry["document_key"],
152
+ "current_version": entry["current_version"],
153
+ }
154
+ )
155
+ return LegalAcceptanceRequiredError(
156
+ detail,
157
+ pending_acceptances=pending,
158
+ status=status,
159
+ problem_type=problem_type,
160
+ problem=problem,
161
+ )
129
162
  return error_cls(detail, status=status, problem_type=problem_type, problem=problem)
130
163
 
131
164
 
File without changes