simplex 1.0.0__py3-none-any.whl → 1.0.6__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.
Potentially problematic release.
This version of simplex might be problematic. Click here for more details.
- simplex/__init__.py +34 -3
- simplex/client.py +355 -0
- simplex/errors.py +160 -0
- simplex/http_client.py +403 -0
- simplex/resources/__init__.py +10 -0
- simplex/resources/workflow.py +502 -0
- simplex/resources/workflow_session.py +333 -0
- simplex/types.py +276 -0
- simplex-1.0.6.dist-info/METADATA +423 -0
- simplex-1.0.6.dist-info/RECORD +13 -0
- {simplex-1.0.0.dist-info → simplex-1.0.6.dist-info}/WHEEL +1 -1
- {simplex-1.0.0.dist-info → simplex-1.0.6.dist-info/licenses}/LICENSE +2 -2
- simplex/constants.py +0 -1
- simplex/simplex.py +0 -187
- simplex/utils.py +0 -12
- simplex-1.0.0.dist-info/METADATA +0 -29
- simplex-1.0.0.dist-info/RECORD +0 -10
- simplex-1.0.0.dist-info/entry_points.txt +0 -2
- {simplex-1.0.0.dist-info → simplex-1.0.6.dist-info}/top_level.txt +0 -0
simplex/__init__.py
CHANGED
|
@@ -1,4 +1,35 @@
|
|
|
1
|
-
|
|
1
|
+
"""
|
|
2
|
+
Simplex Python SDK
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
Official Python SDK for the Simplex API - A workflow automation platform.
|
|
5
|
+
|
|
6
|
+
Example usage:
|
|
7
|
+
>>> from simplex import SimplexClient
|
|
8
|
+
>>> client = SimplexClient(api_key="your-api-key")
|
|
9
|
+
>>> result = client.workflows.run("workflow-id")
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from simplex.client import SimplexClient
|
|
13
|
+
from simplex.errors import (
|
|
14
|
+
SimplexError,
|
|
15
|
+
NetworkError,
|
|
16
|
+
ValidationError,
|
|
17
|
+
AuthenticationError,
|
|
18
|
+
RateLimitError,
|
|
19
|
+
WorkflowError,
|
|
20
|
+
)
|
|
21
|
+
from simplex.resources.workflow import Workflow
|
|
22
|
+
from simplex.resources.workflow_session import WorkflowSession
|
|
23
|
+
|
|
24
|
+
__version__ = "1.0.0"
|
|
25
|
+
__all__ = [
|
|
26
|
+
"SimplexClient",
|
|
27
|
+
"SimplexError",
|
|
28
|
+
"NetworkError",
|
|
29
|
+
"ValidationError",
|
|
30
|
+
"AuthenticationError",
|
|
31
|
+
"RateLimitError",
|
|
32
|
+
"WorkflowError",
|
|
33
|
+
"Workflow",
|
|
34
|
+
"WorkflowSession",
|
|
35
|
+
]
|
simplex/client.py
ADDED
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Main SimplexClient class for the Simplex SDK.
|
|
3
|
+
|
|
4
|
+
This module provides the SimplexClient, which is the primary entry point
|
|
5
|
+
for interacting with the Simplex API.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import json
|
|
9
|
+
from typing import Any, Dict, Optional
|
|
10
|
+
|
|
11
|
+
from simplex.errors import WorkflowError
|
|
12
|
+
from simplex.http_client import HttpClient
|
|
13
|
+
from simplex.resources.workflow import Workflow
|
|
14
|
+
from simplex.resources.workflow_session import WorkflowSession
|
|
15
|
+
from simplex.types import (
|
|
16
|
+
Add2FAConfigResponse,
|
|
17
|
+
CreateWorkflowSessionResponse,
|
|
18
|
+
GetSessionStoreResponse,
|
|
19
|
+
SimplexClientOptions,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class SimplexClient:
|
|
24
|
+
"""
|
|
25
|
+
Main client for interacting with the Simplex API.
|
|
26
|
+
|
|
27
|
+
This is the primary entry point for the SDK. It provides access to all
|
|
28
|
+
Simplex API functionality through resource classes and utility methods.
|
|
29
|
+
|
|
30
|
+
Example:
|
|
31
|
+
>>> from simplex import SimplexClient
|
|
32
|
+
>>> client = SimplexClient(api_key="your-api-key")
|
|
33
|
+
>>>
|
|
34
|
+
>>> # Run a workflow
|
|
35
|
+
>>> result = client.workflows.run("workflow-id")
|
|
36
|
+
>>>
|
|
37
|
+
>>> # Create a workflow session
|
|
38
|
+
>>> with client.create_workflow_session("test", "https://example.com") as session:
|
|
39
|
+
... session.goto("https://example.com/login")
|
|
40
|
+
... session.run_agent("Login Agent")
|
|
41
|
+
|
|
42
|
+
Attributes:
|
|
43
|
+
workflows: Resource for workflow operations
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
def __init__(
|
|
47
|
+
self,
|
|
48
|
+
api_key: str,
|
|
49
|
+
timeout: int = 30,
|
|
50
|
+
max_retries: int = 3,
|
|
51
|
+
retry_delay: int = 1,
|
|
52
|
+
base_url: str = "https://api.simplex.sh"
|
|
53
|
+
):
|
|
54
|
+
"""
|
|
55
|
+
Initialize the Simplex client.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
api_key: Your Simplex API key (required)
|
|
59
|
+
timeout: Request timeout in seconds (default: 30)
|
|
60
|
+
max_retries: Maximum number of retry attempts (default: 3)
|
|
61
|
+
retry_delay: Delay between retries in seconds (default: 1)
|
|
62
|
+
base_url: Base URL for the API (default: "https://api.simplex.sh")
|
|
63
|
+
|
|
64
|
+
Raises:
|
|
65
|
+
ValueError: If api_key is not provided
|
|
66
|
+
|
|
67
|
+
Example:
|
|
68
|
+
>>> client = SimplexClient(
|
|
69
|
+
... api_key="your-api-key",
|
|
70
|
+
... timeout=60,
|
|
71
|
+
... max_retries=5
|
|
72
|
+
... )
|
|
73
|
+
"""
|
|
74
|
+
if not api_key:
|
|
75
|
+
raise ValueError("api_key is required")
|
|
76
|
+
|
|
77
|
+
# Initialize HTTP client
|
|
78
|
+
self._http_client = HttpClient(
|
|
79
|
+
base_url=base_url,
|
|
80
|
+
api_key=api_key,
|
|
81
|
+
timeout=timeout,
|
|
82
|
+
retry_attempts=max_retries,
|
|
83
|
+
retry_delay=retry_delay
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
# Initialize resource classes
|
|
87
|
+
self.workflows = Workflow(self._http_client)
|
|
88
|
+
|
|
89
|
+
def create_workflow_session(
|
|
90
|
+
self,
|
|
91
|
+
name: str,
|
|
92
|
+
url: str,
|
|
93
|
+
proxies: bool = False,
|
|
94
|
+
session_data: Optional[Any] = None
|
|
95
|
+
) -> WorkflowSession:
|
|
96
|
+
"""
|
|
97
|
+
Create a new workflow session with context manager support.
|
|
98
|
+
|
|
99
|
+
This method creates a new browser session that can be controlled
|
|
100
|
+
programmatically. The returned WorkflowSession can be used as a
|
|
101
|
+
context manager for automatic cleanup.
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
name: Name for this workflow session
|
|
105
|
+
url: Starting URL for the browser session
|
|
106
|
+
proxies: Whether to use proxies (default: False)
|
|
107
|
+
session_data: Optional data to associate with the session
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
WorkflowSession object for interacting with the session
|
|
111
|
+
|
|
112
|
+
Raises:
|
|
113
|
+
WorkflowError: If session creation fails
|
|
114
|
+
|
|
115
|
+
Example:
|
|
116
|
+
>>> # Using as a context manager (recommended)
|
|
117
|
+
>>> with client.create_workflow_session("test", "https://example.com") as session:
|
|
118
|
+
... session.goto("https://example.com/login")
|
|
119
|
+
... session.run_agent("Login Agent")
|
|
120
|
+
... # Session automatically closed when exiting the with block
|
|
121
|
+
>>>
|
|
122
|
+
>>> # Or manage manually
|
|
123
|
+
>>> session = client.create_workflow_session("test", "https://example.com")
|
|
124
|
+
>>> try:
|
|
125
|
+
... session.goto("https://example.com/login")
|
|
126
|
+
... finally:
|
|
127
|
+
... session.close()
|
|
128
|
+
"""
|
|
129
|
+
# Ensure URL has protocol
|
|
130
|
+
if not url.startswith('http://') and not url.startswith('https://'):
|
|
131
|
+
url = 'https://' + url
|
|
132
|
+
|
|
133
|
+
request_data = {
|
|
134
|
+
'workflow_name': name,
|
|
135
|
+
'url': url,
|
|
136
|
+
'proxies': proxies
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if session_data is not None:
|
|
140
|
+
request_data['session_data'] = json.dumps(session_data)
|
|
141
|
+
|
|
142
|
+
try:
|
|
143
|
+
response: CreateWorkflowSessionResponse = self._http_client.post(
|
|
144
|
+
'/create_workflow_session',
|
|
145
|
+
data=request_data
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
# Create and return WorkflowSession object
|
|
149
|
+
return WorkflowSession(
|
|
150
|
+
self._http_client,
|
|
151
|
+
{
|
|
152
|
+
'sessionId': response['session_id'],
|
|
153
|
+
'workflowId': response['workflow_id'],
|
|
154
|
+
'livestreamUrl': response['livestream_url'],
|
|
155
|
+
'connectUrl': response['connect_url'],
|
|
156
|
+
'vncUrl': response['vnc_url']
|
|
157
|
+
}
|
|
158
|
+
)
|
|
159
|
+
except Exception as e:
|
|
160
|
+
raise WorkflowError(
|
|
161
|
+
f"Failed to create workflow session: {str(e)}"
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
def get_session_store(self, session_id: str) -> GetSessionStoreResponse:
|
|
165
|
+
"""
|
|
166
|
+
Retrieve session store data for a specific session.
|
|
167
|
+
|
|
168
|
+
The session store contains data that was saved during workflow execution.
|
|
169
|
+
|
|
170
|
+
Args:
|
|
171
|
+
session_id: ID of the session to retrieve store data for
|
|
172
|
+
|
|
173
|
+
Returns:
|
|
174
|
+
Response containing session store data
|
|
175
|
+
|
|
176
|
+
Raises:
|
|
177
|
+
WorkflowError: If retrieving session store fails
|
|
178
|
+
|
|
179
|
+
Example:
|
|
180
|
+
>>> store = client.get_session_store("session-123")
|
|
181
|
+
>>> if store['succeeded']:
|
|
182
|
+
... data = store['session_store']
|
|
183
|
+
... print(f"Session data: {data}")
|
|
184
|
+
"""
|
|
185
|
+
try:
|
|
186
|
+
response: GetSessionStoreResponse = self._http_client.post(
|
|
187
|
+
'/get_session_store',
|
|
188
|
+
data={'session_id': session_id}
|
|
189
|
+
)
|
|
190
|
+
return response
|
|
191
|
+
except Exception as e:
|
|
192
|
+
raise WorkflowError(
|
|
193
|
+
f"Failed to get session store: {str(e)}",
|
|
194
|
+
session_id=session_id
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
def download_session_files(
|
|
198
|
+
self,
|
|
199
|
+
session_id: str,
|
|
200
|
+
filename: Optional[str] = None
|
|
201
|
+
) -> bytes:
|
|
202
|
+
"""
|
|
203
|
+
Download files from a session.
|
|
204
|
+
|
|
205
|
+
This method downloads files that were created or downloaded during
|
|
206
|
+
a workflow session. If no filename is specified, all files are
|
|
207
|
+
downloaded as a zip archive.
|
|
208
|
+
|
|
209
|
+
Args:
|
|
210
|
+
session_id: ID of the session to download files from
|
|
211
|
+
filename: Optional specific filename to download
|
|
212
|
+
|
|
213
|
+
Returns:
|
|
214
|
+
File content as bytes
|
|
215
|
+
|
|
216
|
+
Raises:
|
|
217
|
+
WorkflowError: If file download fails
|
|
218
|
+
|
|
219
|
+
Example:
|
|
220
|
+
>>> # Download all files as zip
|
|
221
|
+
>>> zip_data = client.download_session_files("session-123")
|
|
222
|
+
>>> with open("session_files.zip", "wb") as f:
|
|
223
|
+
... f.write(zip_data)
|
|
224
|
+
>>>
|
|
225
|
+
>>> # Download specific file
|
|
226
|
+
>>> file_data = client.download_session_files("session-123", "report.pdf")
|
|
227
|
+
>>> with open("report.pdf", "wb") as f:
|
|
228
|
+
... f.write(file_data)
|
|
229
|
+
"""
|
|
230
|
+
try:
|
|
231
|
+
params = {'session_id': session_id}
|
|
232
|
+
if filename:
|
|
233
|
+
params['filename'] = filename
|
|
234
|
+
|
|
235
|
+
content = self._http_client.download_file('/download_session_files', params=params)
|
|
236
|
+
|
|
237
|
+
# Check if the response is a JSON error by trying to decode and parse it
|
|
238
|
+
try:
|
|
239
|
+
text = content.decode('utf-8')
|
|
240
|
+
data = json.loads(text)
|
|
241
|
+
if isinstance(data, dict) and data.get('succeeded') is False:
|
|
242
|
+
raise WorkflowError(
|
|
243
|
+
data.get('error') or 'Failed to download session files',
|
|
244
|
+
session_id=session_id
|
|
245
|
+
)
|
|
246
|
+
except (UnicodeDecodeError, json.JSONDecodeError):
|
|
247
|
+
# If decoding/parsing fails, it's binary data (the file), which is what we want
|
|
248
|
+
pass
|
|
249
|
+
|
|
250
|
+
return content
|
|
251
|
+
except WorkflowError:
|
|
252
|
+
raise
|
|
253
|
+
except Exception as e:
|
|
254
|
+
raise WorkflowError(
|
|
255
|
+
f"Failed to download session files: {str(e)}",
|
|
256
|
+
session_id=session_id
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
def add_2fa_config(
|
|
260
|
+
self,
|
|
261
|
+
seed: str,
|
|
262
|
+
name: Optional[str] = None,
|
|
263
|
+
partial_url: Optional[str] = None
|
|
264
|
+
) -> Add2FAConfigResponse:
|
|
265
|
+
"""
|
|
266
|
+
Add a 2FA (Two-Factor Authentication) configuration.
|
|
267
|
+
|
|
268
|
+
This allows workflows to automatically handle 2FA authentication
|
|
269
|
+
when encountering sites that require it.
|
|
270
|
+
|
|
271
|
+
Args:
|
|
272
|
+
seed: The 2FA seed/secret key
|
|
273
|
+
name: Optional name for this 2FA configuration
|
|
274
|
+
partial_url: Optional partial URL to match for auto-detection
|
|
275
|
+
|
|
276
|
+
Returns:
|
|
277
|
+
Response with configuration details
|
|
278
|
+
|
|
279
|
+
Raises:
|
|
280
|
+
WorkflowError: If adding the configuration fails
|
|
281
|
+
|
|
282
|
+
Example:
|
|
283
|
+
>>> result = client.add_2fa_config(
|
|
284
|
+
... seed="JBSWY3DPEHPK3PXP",
|
|
285
|
+
... name="My Service",
|
|
286
|
+
... partial_url="example.com"
|
|
287
|
+
... )
|
|
288
|
+
>>> if result['succeeded']:
|
|
289
|
+
... print(f"Total configs: {result['total_configs']}")
|
|
290
|
+
"""
|
|
291
|
+
request_data = {'seed': seed}
|
|
292
|
+
|
|
293
|
+
if name:
|
|
294
|
+
request_data['name'] = name
|
|
295
|
+
|
|
296
|
+
if partial_url:
|
|
297
|
+
request_data['partial_url'] = partial_url
|
|
298
|
+
|
|
299
|
+
try:
|
|
300
|
+
response: Add2FAConfigResponse = self._http_client.post_json(
|
|
301
|
+
'/add_2fa_config',
|
|
302
|
+
data=request_data
|
|
303
|
+
)
|
|
304
|
+
|
|
305
|
+
if not response.get('succeeded') and response.get('error'):
|
|
306
|
+
raise WorkflowError(
|
|
307
|
+
f"Failed to add 2FA config: {response['error']}"
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
return response
|
|
311
|
+
except WorkflowError:
|
|
312
|
+
raise
|
|
313
|
+
except Exception as e:
|
|
314
|
+
raise WorkflowError(
|
|
315
|
+
f"Failed to add 2FA config: {str(e)}"
|
|
316
|
+
)
|
|
317
|
+
|
|
318
|
+
def update_api_key(self, api_key: str) -> None:
|
|
319
|
+
"""
|
|
320
|
+
Update the API key used for authentication.
|
|
321
|
+
|
|
322
|
+
This allows you to change the API key without creating a new client instance.
|
|
323
|
+
|
|
324
|
+
Args:
|
|
325
|
+
api_key: New API key to use
|
|
326
|
+
|
|
327
|
+
Example:
|
|
328
|
+
>>> client.update_api_key("new-api-key")
|
|
329
|
+
"""
|
|
330
|
+
self._http_client.update_api_key(api_key)
|
|
331
|
+
|
|
332
|
+
def set_custom_header(self, key: str, value: str) -> None:
|
|
333
|
+
"""
|
|
334
|
+
Set a custom header to be included with all requests.
|
|
335
|
+
|
|
336
|
+
Args:
|
|
337
|
+
key: Header name
|
|
338
|
+
value: Header value
|
|
339
|
+
|
|
340
|
+
Example:
|
|
341
|
+
>>> client.set_custom_header("X-Custom-Header", "custom-value")
|
|
342
|
+
"""
|
|
343
|
+
self._http_client.set_header(key, value)
|
|
344
|
+
|
|
345
|
+
def remove_custom_header(self, key: str) -> None:
|
|
346
|
+
"""
|
|
347
|
+
Remove a custom header.
|
|
348
|
+
|
|
349
|
+
Args:
|
|
350
|
+
key: Header name to remove
|
|
351
|
+
|
|
352
|
+
Example:
|
|
353
|
+
>>> client.remove_custom_header("X-Custom-Header")
|
|
354
|
+
"""
|
|
355
|
+
self._http_client.remove_header(key)
|
simplex/errors.py
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Custom exception classes for the Simplex SDK.
|
|
3
|
+
|
|
4
|
+
This module defines a hierarchy of exceptions that can be raised by the SDK,
|
|
5
|
+
allowing for specific error handling based on the type of error encountered.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Any, Optional
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class SimplexError(Exception):
|
|
12
|
+
"""
|
|
13
|
+
Base exception class for all Simplex SDK errors.
|
|
14
|
+
|
|
15
|
+
All custom exceptions in the SDK inherit from this class, making it easy
|
|
16
|
+
to catch any SDK-related error with a single except clause.
|
|
17
|
+
|
|
18
|
+
Attributes:
|
|
19
|
+
message: Human-readable error message
|
|
20
|
+
status_code: HTTP status code if applicable
|
|
21
|
+
data: Additional error data or context
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def __init__(
|
|
25
|
+
self,
|
|
26
|
+
message: str,
|
|
27
|
+
status_code: Optional[int] = None,
|
|
28
|
+
data: Optional[Any] = None
|
|
29
|
+
):
|
|
30
|
+
"""
|
|
31
|
+
Initialize a SimplexError.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
message: Human-readable error message
|
|
35
|
+
status_code: HTTP status code if this is an HTTP error
|
|
36
|
+
data: Additional error context or data
|
|
37
|
+
"""
|
|
38
|
+
super().__init__(message)
|
|
39
|
+
self.message = message
|
|
40
|
+
self.status_code = status_code
|
|
41
|
+
self.data = data
|
|
42
|
+
|
|
43
|
+
def __str__(self) -> str:
|
|
44
|
+
"""Return a string representation of the error."""
|
|
45
|
+
if self.status_code:
|
|
46
|
+
return f"[{self.status_code}] {self.message}"
|
|
47
|
+
return self.message
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class NetworkError(SimplexError):
|
|
51
|
+
"""
|
|
52
|
+
Raised when a network-related error occurs.
|
|
53
|
+
|
|
54
|
+
This includes connection failures, timeouts, and other network issues
|
|
55
|
+
that prevent communication with the Simplex API.
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
def __init__(self, message: str):
|
|
59
|
+
"""
|
|
60
|
+
Initialize a NetworkError.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
message: Description of the network error
|
|
64
|
+
"""
|
|
65
|
+
super().__init__(f"Network error: {message}")
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class ValidationError(SimplexError):
|
|
69
|
+
"""
|
|
70
|
+
Raised when request validation fails (HTTP 400).
|
|
71
|
+
|
|
72
|
+
This indicates that the request data was invalid or malformed,
|
|
73
|
+
such as missing required fields or invalid parameter values.
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
def __init__(self, message: str, data: Optional[Any] = None):
|
|
77
|
+
"""
|
|
78
|
+
Initialize a ValidationError.
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
message: Description of the validation error
|
|
82
|
+
data: Additional validation error details
|
|
83
|
+
"""
|
|
84
|
+
super().__init__(message, status_code=400, data=data)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class AuthenticationError(SimplexError):
|
|
88
|
+
"""
|
|
89
|
+
Raised when authentication fails (HTTP 401 or 403).
|
|
90
|
+
|
|
91
|
+
This typically indicates an invalid API key or insufficient permissions
|
|
92
|
+
to access the requested resource.
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
def __init__(self, message: str):
|
|
96
|
+
"""
|
|
97
|
+
Initialize an AuthenticationError.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
message: Description of the authentication error
|
|
101
|
+
"""
|
|
102
|
+
super().__init__(message, status_code=401)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class RateLimitError(SimplexError):
|
|
106
|
+
"""
|
|
107
|
+
Raised when rate limit is exceeded (HTTP 429).
|
|
108
|
+
|
|
109
|
+
The Simplex API has rate limits to prevent abuse. When exceeded,
|
|
110
|
+
this error is raised with information about when to retry.
|
|
111
|
+
|
|
112
|
+
Attributes:
|
|
113
|
+
retry_after: Number of seconds to wait before retrying
|
|
114
|
+
"""
|
|
115
|
+
|
|
116
|
+
def __init__(self, message: str, retry_after: Optional[int] = None):
|
|
117
|
+
"""
|
|
118
|
+
Initialize a RateLimitError.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
message: Description of the rate limit error
|
|
122
|
+
retry_after: Number of seconds to wait before retrying
|
|
123
|
+
"""
|
|
124
|
+
super().__init__(message, status_code=429)
|
|
125
|
+
self.retry_after = retry_after
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class WorkflowError(SimplexError):
|
|
129
|
+
"""
|
|
130
|
+
Raised when a workflow operation fails.
|
|
131
|
+
|
|
132
|
+
This is a specialized error for workflow-related failures,
|
|
133
|
+
including session creation, workflow execution, and agent tasks.
|
|
134
|
+
|
|
135
|
+
Attributes:
|
|
136
|
+
workflow_id: The ID of the workflow that failed (if applicable)
|
|
137
|
+
session_id: The ID of the session that failed (if applicable)
|
|
138
|
+
"""
|
|
139
|
+
|
|
140
|
+
def __init__(
|
|
141
|
+
self,
|
|
142
|
+
message: str,
|
|
143
|
+
workflow_id: Optional[str] = None,
|
|
144
|
+
session_id: Optional[str] = None
|
|
145
|
+
):
|
|
146
|
+
"""
|
|
147
|
+
Initialize a WorkflowError.
|
|
148
|
+
|
|
149
|
+
Args:
|
|
150
|
+
message: Description of the workflow error
|
|
151
|
+
workflow_id: ID of the workflow (if applicable)
|
|
152
|
+
session_id: ID of the session (if applicable)
|
|
153
|
+
"""
|
|
154
|
+
super().__init__(
|
|
155
|
+
message,
|
|
156
|
+
status_code=500,
|
|
157
|
+
data={"workflow_id": workflow_id, "session_id": session_id}
|
|
158
|
+
)
|
|
159
|
+
self.workflow_id = workflow_id
|
|
160
|
+
self.session_id = session_id
|