simplai-sdk 0.2.0__py3-none-any.whl → 0.2.1__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.
- simplai_sdk-0.2.1.dist-info/METADATA +728 -0
- {simplai_sdk-0.2.0.dist-info → simplai_sdk-0.2.1.dist-info}/RECORD +5 -5
- simplai_sdk-0.2.0.dist-info/METADATA +0 -46
- {simplai_sdk-0.2.0.dist-info → simplai_sdk-0.2.1.dist-info}/WHEEL +0 -0
- {simplai_sdk-0.2.0.dist-info → simplai_sdk-0.2.1.dist-info}/licenses/LICENSE +0 -0
- {simplai_sdk-0.2.0.dist-info → simplai_sdk-0.2.1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,728 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: simplai_sdk
|
|
3
|
+
Version: 0.2.1
|
|
4
|
+
Summary: SimplAI Python SDK for agents, workflows, and traces
|
|
5
|
+
Author-email: SimplAI <support@simplai.ai>
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2026 SimplAI
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Keywords: simplai,ai,agents,workflows,sdk
|
|
29
|
+
Classifier: Development Status :: 4 - Beta
|
|
30
|
+
Classifier: Intended Audience :: Developers
|
|
31
|
+
Classifier: Programming Language :: Python :: 3
|
|
32
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
33
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
34
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
35
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
36
|
+
Requires-Python: >=3.9
|
|
37
|
+
Description-Content-Type: text/markdown
|
|
38
|
+
License-File: LICENSE
|
|
39
|
+
Requires-Dist: httpx
|
|
40
|
+
Requires-Dist: pydantic
|
|
41
|
+
Requires-Dist: python-dotenv
|
|
42
|
+
Provides-Extra: dev
|
|
43
|
+
Requires-Dist: python-dotenv; extra == "dev"
|
|
44
|
+
Requires-Dist: pytest; extra == "dev"
|
|
45
|
+
Requires-Dist: pytest-asyncio; extra == "dev"
|
|
46
|
+
Dynamic: license-file
|
|
47
|
+
|
|
48
|
+
# SimplAI Python SDK
|
|
49
|
+
|
|
50
|
+
Python SDK for interacting with SimplAI's agents, workflows, and traces.
|
|
51
|
+
|
|
52
|
+
## Installation
|
|
53
|
+
|
|
54
|
+
### Install as a Package (Recommended)
|
|
55
|
+
|
|
56
|
+
Install the SDK in editable mode for development:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pip install simplai-sdk
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Install Dependencies
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pip install -r requirements.txt
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Quick Start
|
|
69
|
+
|
|
70
|
+
### Using the SimplAI Class
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
from simplai_sdk import SimplAI
|
|
74
|
+
import asyncio
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
async def main():
|
|
78
|
+
# Initialize the SDK
|
|
79
|
+
# - API key can be provided directly or loaded from .env (API_KEY)
|
|
80
|
+
# - Base URL is read from SIMPAI_BASE_URL in your environment/.env
|
|
81
|
+
simplai = SimplAI() # or SimplAI(api_key="your-api-key")
|
|
82
|
+
|
|
83
|
+
# Agent Chat (non-streaming)
|
|
84
|
+
result = await simplai.agent_chat(
|
|
85
|
+
agent_id="agent-123",
|
|
86
|
+
message="Hello!",
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
print(f"Response: {result.response}")
|
|
90
|
+
print(f"Trace ID: {result.trace_id}")
|
|
91
|
+
print(f"Node ID: {result.node_id}")
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
asyncio.run(main())
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Agent Chat (streaming)
|
|
98
|
+
|
|
99
|
+
Stream responses and optionally use `on_chunk` to handle each chunk. The first chunk may contain `trace_id` and `node_id` (in a `role: "trace"` message); the final `AgentResult` also has `trace_id` and `node_id`.
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
from simplai_sdk import SimplAI
|
|
103
|
+
import asyncio
|
|
104
|
+
import json
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
async def main():
|
|
108
|
+
simplai = SimplAI()
|
|
109
|
+
|
|
110
|
+
def on_chunk(chunk):
|
|
111
|
+
# chunk.content may be JSON; chunk.trace_id, chunk.node_id set from first trace chunk
|
|
112
|
+
raw = chunk.content
|
|
113
|
+
for part in raw.split("<-------->"):
|
|
114
|
+
part = part.strip()
|
|
115
|
+
if not part:
|
|
116
|
+
continue
|
|
117
|
+
try:
|
|
118
|
+
data = json.loads(part)
|
|
119
|
+
if isinstance(data, dict) and "content" in data:
|
|
120
|
+
print(data["content"], end="", flush=True)
|
|
121
|
+
else:
|
|
122
|
+
print(part, end="", flush=True)
|
|
123
|
+
except (json.JSONDecodeError, TypeError):
|
|
124
|
+
print(part, end="", flush=True)
|
|
125
|
+
|
|
126
|
+
result = await simplai.agent_chat_stream(
|
|
127
|
+
agent_id="agent-123",
|
|
128
|
+
message="Hello",
|
|
129
|
+
on_chunk=on_chunk,
|
|
130
|
+
)
|
|
131
|
+
print()
|
|
132
|
+
print("Done. trace_id:", result.trace_id, "node_id:", result.node_id)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
asyncio.run(main())
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Traces (get trace tree)
|
|
139
|
+
|
|
140
|
+
Fetch a trace sub-tree by `tree_id` (same as `trace_id`) and `node_id`. This is synchronous.
|
|
141
|
+
|
|
142
|
+
```python
|
|
143
|
+
from simplai_sdk import SimplAI
|
|
144
|
+
|
|
145
|
+
simplai = SimplAI()
|
|
146
|
+
|
|
147
|
+
tree = simplai.get_trace_tree(
|
|
148
|
+
tree_id="your-tree-id", # same as trace_id from agent_chat / agent_chat_stream
|
|
149
|
+
node_id="your-node-id",
|
|
150
|
+
)
|
|
151
|
+
print(tree)
|
|
152
|
+
|
|
153
|
+
# Raw API response instead of parsed TraceNode
|
|
154
|
+
raw = simplai.get_trace_tree(tree_id="...", node_id="...", raw_response=True)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Tool / Workflow Execution
|
|
158
|
+
|
|
159
|
+
The SDK provides several functions for executing workflows and managing their execution lifecycle.
|
|
160
|
+
|
|
161
|
+
#### 1. Execute Workflow (Async - Returns Immediately)
|
|
162
|
+
|
|
163
|
+
Execute a workflow and get the execution ID immediately without waiting for completion.
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
from simplai_sdk import SimplAI
|
|
167
|
+
import asyncio
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
async def main():
|
|
171
|
+
simplai = SimplAI() # API key + SIMPAI_BASE_URL loaded from .env
|
|
172
|
+
|
|
173
|
+
# Execute a workflow (returns immediately with execution ID)
|
|
174
|
+
execution_info = await simplai.execute_workflow(
|
|
175
|
+
workflow_id="your-workflow-id",
|
|
176
|
+
inputs={"number_1": 1, "number_2": 2}, # Key is app input variable name, value is the input value
|
|
177
|
+
)
|
|
178
|
+
print(f"Execution ID: {execution_info.get('execution_id')}")
|
|
179
|
+
print(f"Status: {execution_info.get('status')}")
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
asyncio.run(main())
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**Returns:**
|
|
186
|
+
- `execution_id` (str): The execution ID to track this workflow run
|
|
187
|
+
- `status` (str): Initial status of the execution
|
|
188
|
+
|
|
189
|
+
#### 2. Get Tool Result
|
|
190
|
+
|
|
191
|
+
Get the execution result and status by execution ID. Use this to check the status of a previously started execution.
|
|
192
|
+
|
|
193
|
+
```python
|
|
194
|
+
from simplai_sdk import SimplAI
|
|
195
|
+
import asyncio
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
async def main():
|
|
199
|
+
simplai = SimplAI()
|
|
200
|
+
|
|
201
|
+
# Get execution result by execution ID
|
|
202
|
+
result = await simplai.get_tool_result(
|
|
203
|
+
execution_id="your-execution-id",
|
|
204
|
+
)
|
|
205
|
+
print(f"Execution ID: {result.get('executionId')}")
|
|
206
|
+
print(f"Status: {result.get('status')}")
|
|
207
|
+
print(f"Trace ID: {result.get('traceId')}") # Optional
|
|
208
|
+
print(f"API Response: {result.get('api_response')}") # Optional, contains parsed result
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
asyncio.run(main())
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
**Returns:**
|
|
215
|
+
- `executionId` (str): The execution ID
|
|
216
|
+
- `status` (str): Current status (e.g., "PENDING", "COMPLETED", "FAILED")
|
|
217
|
+
- `traceId` (str, optional): Trace ID for this execution
|
|
218
|
+
- `api_response` (Any, optional): Parsed JSON result from the workflow execution
|
|
219
|
+
|
|
220
|
+
#### 3. Execute and Wait for Workflow
|
|
221
|
+
|
|
222
|
+
Execute a workflow and automatically poll until completion. This is a convenience function that combines `execute_workflow` and `get_tool_result` with polling logic.
|
|
223
|
+
|
|
224
|
+
```python
|
|
225
|
+
from simplai_sdk import SimplAI
|
|
226
|
+
import asyncio
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
async def main():
|
|
230
|
+
simplai = SimplAI()
|
|
231
|
+
|
|
232
|
+
# Execute a workflow and wait for completion
|
|
233
|
+
result = await simplai.execute_and_wait_workflow(
|
|
234
|
+
workflow_id="your-workflow-id",
|
|
235
|
+
inputs={"number_1": 1, "number_2": 2}, # Key is app input variable name, value is the input value
|
|
236
|
+
timeout=60.0, # Maximum time to wait in seconds (default: 60.0)
|
|
237
|
+
poll_interval=2.0, # Time between status checks in seconds (default: 2.0)
|
|
238
|
+
)
|
|
239
|
+
print(f"Execution ID: {result.get('executionId')}")
|
|
240
|
+
print(f"Status: {result.get('status')}")
|
|
241
|
+
print(f"Trace ID: {result.get('traceId')}") # Optional
|
|
242
|
+
print(f"API Response: {result.get('api_response')}") # Optional, contains parsed result
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
asyncio.run(main())
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
**Parameters:**
|
|
249
|
+
- `workflow_id` (str): The workflow ID to execute
|
|
250
|
+
- `inputs` (dict): Input parameters for the workflow (key = app input variable name, value = input value)
|
|
251
|
+
- `timeout` (float, optional): Maximum time to wait in seconds (default: 60.0)
|
|
252
|
+
- `poll_interval` (float, optional): Time between status checks in seconds (default: 2.0)
|
|
253
|
+
|
|
254
|
+
**Returns:**
|
|
255
|
+
- `executionId` (str): The execution ID
|
|
256
|
+
- `status` (str): Final status (e.g., "COMPLETED", "FAILED", "CANCELLED")
|
|
257
|
+
- `traceId` (str, optional): Trace ID for this execution
|
|
258
|
+
- `api_response` (Any, optional): Parsed JSON result from the workflow execution
|
|
259
|
+
|
|
260
|
+
**Raises:**
|
|
261
|
+
- `TimeoutException`: If the execution doesn't complete within the specified timeout
|
|
262
|
+
|
|
263
|
+
#### 4. Cancel Execution
|
|
264
|
+
|
|
265
|
+
Cancel a running or pending workflow execution.
|
|
266
|
+
|
|
267
|
+
```python
|
|
268
|
+
from simplai_sdk import SimplAI
|
|
269
|
+
import asyncio
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
async def main():
|
|
273
|
+
simplai = SimplAI()
|
|
274
|
+
|
|
275
|
+
# Cancel an execution
|
|
276
|
+
cancel_result = await simplai.cancel_execution(
|
|
277
|
+
execution_id="your-execution-id",
|
|
278
|
+
)
|
|
279
|
+
print(f"Execution ID: {cancel_result.get('execution_id')}")
|
|
280
|
+
print(f"Status: {cancel_result.get('status')}")
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
asyncio.run(main())
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
**Parameters:**
|
|
287
|
+
- `execution_id` (str): The execution ID to cancel
|
|
288
|
+
|
|
289
|
+
**Returns:**
|
|
290
|
+
- `execution_id` (str): The execution ID that was cancelled
|
|
291
|
+
- `status` (str): Status after cancellation (typically "CANCELLED")
|
|
292
|
+
|
|
293
|
+
### Bulk Runs
|
|
294
|
+
|
|
295
|
+
The SDK provides functions for executing workflows in bulk using CSV files. Bulk runs process multiple records from a file in batches.
|
|
296
|
+
|
|
297
|
+
#### 1. Trigger Bulk Run
|
|
298
|
+
|
|
299
|
+
Trigger a bulk run to process multiple records from a CSV file. The file should be accessible via a URL (e.g., S3, HTTP, etc.).
|
|
300
|
+
|
|
301
|
+
```python
|
|
302
|
+
from simplai_sdk import SimplAI
|
|
303
|
+
import asyncio
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
async def main():
|
|
307
|
+
simplai = SimplAI()
|
|
308
|
+
|
|
309
|
+
# Trigger a bulk run
|
|
310
|
+
bulk_run = await simplai.trigger_bulk_run(
|
|
311
|
+
workflow_id="your-workflow-id",
|
|
312
|
+
file_link="s3://your-bucket/your-file.csv", # URL to the CSV file
|
|
313
|
+
batch_size=100, # Number of records to process per batch
|
|
314
|
+
input_mapping=[
|
|
315
|
+
# Map workflow input fields to CSV column names
|
|
316
|
+
# app_input_field: The workflow input variable name from the platform
|
|
317
|
+
# file_input_field: The CSV column name (e.g., "A", "B", or column header)
|
|
318
|
+
{"app_input_field": "number_1", "file_input_field": "A"},
|
|
319
|
+
{"app_input_field": "number_2", "file_input_field": "B"},
|
|
320
|
+
],
|
|
321
|
+
)
|
|
322
|
+
bulk_run_id = bulk_run["bulk_run_id"]
|
|
323
|
+
print(f"Bulk Run ID: {bulk_run_id}")
|
|
324
|
+
print(f"Status: {bulk_run['status']}")
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
asyncio.run(main())
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
**Parameters:**
|
|
331
|
+
- `workflow_id` (str): The workflow ID to execute
|
|
332
|
+
- `file_link` (str): URL/link to the input CSV file (e.g., S3 URL, HTTP URL)
|
|
333
|
+
- `batch_size` (int): Number of records to process per batch
|
|
334
|
+
- `input_mapping` (list): List of dictionaries mapping workflow input fields to CSV columns
|
|
335
|
+
- `app_input_field` (str): The workflow input variable name from the platform
|
|
336
|
+
- `file_input_field` (str): The CSV column name (e.g., "A", "B", or column header name)
|
|
337
|
+
|
|
338
|
+
**Returns:**
|
|
339
|
+
- `bulk_run_id` (str): The bulk run ID to track this bulk execution
|
|
340
|
+
- `status` (str): Initial status of the bulk run
|
|
341
|
+
|
|
342
|
+
#### 2. Get Bulk Run Status
|
|
343
|
+
|
|
344
|
+
Get the current status and progress of a bulk run by bulk run ID.
|
|
345
|
+
|
|
346
|
+
```python
|
|
347
|
+
from simplai_sdk import SimplAI
|
|
348
|
+
import asyncio
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
async def main():
|
|
352
|
+
simplai = SimplAI()
|
|
353
|
+
|
|
354
|
+
# Get bulk run status
|
|
355
|
+
status = await simplai.get_bulk_run_status(
|
|
356
|
+
bulk_run_id="your-bulk-run-id",
|
|
357
|
+
)
|
|
358
|
+
print(f"Bulk Run ID: {status.get('bulk_run_id')}")
|
|
359
|
+
print(f"Status: {status.get('status')}")
|
|
360
|
+
print(f"Batches Completed: {status.get('batch_completed')}")
|
|
361
|
+
print(f"Total Batches: {status.get('total_batches')}")
|
|
362
|
+
print(f"Trace ID: {status.get('trace_id')}") # Optional
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
asyncio.run(main())
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
**Parameters:**
|
|
369
|
+
- `bulk_run_id` (str): The bulk run ID to check
|
|
370
|
+
|
|
371
|
+
**Returns:**
|
|
372
|
+
- `bulk_run_id` (str): The bulk run ID
|
|
373
|
+
- `status` (str): Current status (e.g., "PENDING", "RUNNING", "COMPLETED", "FAILED")
|
|
374
|
+
- `batch_completed` (int): Number of batches that have been completed
|
|
375
|
+
- `total_batches` (int): Total number of batches to process
|
|
376
|
+
- `trace_id` (str, optional): Trace ID for this bulk run
|
|
377
|
+
|
|
378
|
+
#### 3. Cancel Bulk Run
|
|
379
|
+
|
|
380
|
+
Cancel a running or pending bulk run.
|
|
381
|
+
|
|
382
|
+
```python
|
|
383
|
+
from simplai_sdk import SimplAI
|
|
384
|
+
import asyncio
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
async def main():
|
|
388
|
+
simplai = SimplAI()
|
|
389
|
+
|
|
390
|
+
# Cancel a bulk run
|
|
391
|
+
cancel_result = await simplai.cancel_bulk_run(
|
|
392
|
+
bulk_run_id="your-bulk-run-id",
|
|
393
|
+
)
|
|
394
|
+
print(f"Bulk Run ID: {cancel_result.get('bulk_run_id')}")
|
|
395
|
+
print(f"Status: {cancel_result.get('status')}")
|
|
396
|
+
print(f"Trace ID: {cancel_result.get('trace_id')}") # Optional
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
asyncio.run(main())
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
**Parameters:**
|
|
403
|
+
- `bulk_run_id` (str): The bulk run ID to cancel
|
|
404
|
+
|
|
405
|
+
**Returns:**
|
|
406
|
+
- `bulk_run_id` (str): The bulk run ID that was cancelled
|
|
407
|
+
- `status` (str): Status after cancellation (typically "CANCELLED")
|
|
408
|
+
- `trace_id` (str, optional): Trace ID for this bulk run
|
|
409
|
+
|
|
410
|
+
#### 4. Download Bulk Run Result
|
|
411
|
+
|
|
412
|
+
Download the results of a completed bulk run as CSV text.
|
|
413
|
+
|
|
414
|
+
```python
|
|
415
|
+
from simplai_sdk import SimplAI
|
|
416
|
+
import asyncio
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
async def main():
|
|
420
|
+
simplai = SimplAI()
|
|
421
|
+
|
|
422
|
+
# Download bulk run result as CSV
|
|
423
|
+
csv_text = await simplai.download_bulk_run_result(
|
|
424
|
+
bulk_run_id="your-bulk-run-id",
|
|
425
|
+
)
|
|
426
|
+
print(f"CSV Result (first 500 chars): {csv_text[:500]}")
|
|
427
|
+
|
|
428
|
+
# Optionally save to file
|
|
429
|
+
with open("bulk_result.csv", "w") as f:
|
|
430
|
+
f.write(csv_text)
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
asyncio.run(main())
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
**Parameters:**
|
|
437
|
+
- `bulk_run_id` (str): The bulk run ID to download results for
|
|
438
|
+
|
|
439
|
+
**Returns:**
|
|
440
|
+
- `str`: CSV text containing the bulk run results
|
|
441
|
+
|
|
442
|
+
**Note:** The bulk run must be completed before downloading results. Use `get_bulk_run_status()` to check if the bulk run has finished.
|
|
443
|
+
|
|
444
|
+
### Scheduled Runs
|
|
445
|
+
|
|
446
|
+
The SDK provides functions for scheduling workflows to run automatically at specified times using cron expressions. Scheduled runs support two types: BULK (processes data from a file) and MANUAL (uses static input values).
|
|
447
|
+
|
|
448
|
+
#### 1. Schedule Run
|
|
449
|
+
|
|
450
|
+
Schedule a workflow to run automatically based on a cron expression. Supports both BULK and MANUAL types.
|
|
451
|
+
|
|
452
|
+
**BULK Type Scheduled Run:**
|
|
453
|
+
|
|
454
|
+
Processes data from a CSV file on a schedule. Requires a file URL and batch size.
|
|
455
|
+
|
|
456
|
+
```python
|
|
457
|
+
from simplai_sdk import SimplAI
|
|
458
|
+
import asyncio
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
async def main():
|
|
462
|
+
simplai = SimplAI()
|
|
463
|
+
|
|
464
|
+
# Schedule a BULK type run
|
|
465
|
+
schedule = await simplai.schedule_run(
|
|
466
|
+
workflow_id="your-workflow-id",
|
|
467
|
+
scheduled_run_type="BULK",
|
|
468
|
+
cron_expression="0 */3 * ? * *", # Every 3 hours
|
|
469
|
+
time_zone="Asia/Kolkata", # IANA Time Zone identifier
|
|
470
|
+
input_mapping=[
|
|
471
|
+
# Map workflow input fields to CSV column names
|
|
472
|
+
# app_input_field: The workflow input variable name from the platform
|
|
473
|
+
# file_input_field: The CSV column name (e.g., "A", "B", or column header)
|
|
474
|
+
{"app_input_field": "number_1", "file_input_field": "A"},
|
|
475
|
+
{"app_input_field": "number_2", "file_input_field": "B"},
|
|
476
|
+
],
|
|
477
|
+
file_url="s3://your-bucket/your-file.csv", # Required for BULK type
|
|
478
|
+
batch_size=100, # Required for BULK type
|
|
479
|
+
)
|
|
480
|
+
print(f"Unique ID: {schedule.get('unique_id')}")
|
|
481
|
+
print(f"Job Master ID: {schedule.get('job_master_id')}")
|
|
482
|
+
print(f"Status: {schedule.get('status')}")
|
|
483
|
+
print(f"Trace ID: {schedule.get('trace_id')}") # Optional
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
asyncio.run(main())
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
**MANUAL Type Scheduled Run:**
|
|
490
|
+
|
|
491
|
+
Runs a workflow with static input values on a schedule. No file URL required.
|
|
492
|
+
|
|
493
|
+
```python
|
|
494
|
+
from simplai_sdk import SimplAI
|
|
495
|
+
import asyncio
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
async def main():
|
|
499
|
+
simplai = SimplAI()
|
|
500
|
+
|
|
501
|
+
# Schedule a MANUAL type run
|
|
502
|
+
schedule = await simplai.schedule_run(
|
|
503
|
+
workflow_id="your-workflow-id",
|
|
504
|
+
scheduled_run_type="MANUAL",
|
|
505
|
+
cron_expression="0 0 12 * * ?", # Daily at noon
|
|
506
|
+
time_zone="UTC",
|
|
507
|
+
input_mapping=[
|
|
508
|
+
# For MANUAL type, use "value" instead of "file_input_field"
|
|
509
|
+
# app_input_field: The workflow input variable name from the platform
|
|
510
|
+
# value: The static value to use for this input
|
|
511
|
+
{"app_input_field": "interview_id", "value": "0148eee6-a867-4c7a-8d42-f039a5ef6adf"},
|
|
512
|
+
{"app_input_field": "number_1", "value": 1},
|
|
513
|
+
{"app_input_field": "number_2", "value": 2},
|
|
514
|
+
],
|
|
515
|
+
# file_url is not required for MANUAL type (ignored if provided)
|
|
516
|
+
batch_size=1, # Optional for MANUAL type
|
|
517
|
+
)
|
|
518
|
+
print(f"Unique ID: {schedule.get('unique_id')}")
|
|
519
|
+
print(f"Job Master ID: {schedule.get('job_master_id')}")
|
|
520
|
+
print(f"Status: {schedule.get('status')}")
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
asyncio.run(main())
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
**Parameters:**
|
|
527
|
+
- `workflow_id` (str): The workflow ID to execute
|
|
528
|
+
- `scheduled_run_type` (str): Type of scheduled run - `"BULK"` or `"MANUAL"`
|
|
529
|
+
- `cron_expression` (str): Quartz-compatible cron expression for scheduling (e.g., `"0 */3 * ? * *"` for every 3 hours)
|
|
530
|
+
- Format: `"second minute hour day-of-month month day-of-week"`
|
|
531
|
+
- Uses Quartz cron syntax (supports `?` for day-of-month or day-of-week)
|
|
532
|
+
- Example: `"0 0 12 * * ?"` = Daily at 12:00 PM
|
|
533
|
+
- Example: `"0 */3 * ? * *"` = Every 3 hours
|
|
534
|
+
- `time_zone` (str): IANA Time Zone identifier for the schedule (e.g., `"Asia/Kolkata"`, `"UTC"`, `"America/New_York"`)
|
|
535
|
+
- `input_mapping` (list): List of dictionaries with input field mappings
|
|
536
|
+
- **For BULK type:**
|
|
537
|
+
- `app_input_field` (str): The workflow input variable name from the platform
|
|
538
|
+
- `file_input_field` (str): The CSV column name (e.g., `"A"`, `"B"`, or column header)
|
|
539
|
+
- **For MANUAL type:**
|
|
540
|
+
- `app_input_field` (str): The workflow input variable name from the platform
|
|
541
|
+
- `value` (str/int/float): The static value to use for this input
|
|
542
|
+
- `file_url` (str, optional): URL/link to the input CSV file (required for BULK, ignored for MANUAL)
|
|
543
|
+
- `batch_size` (int, optional): Number of records to process per batch (required for BULK, optional for MANUAL)
|
|
544
|
+
|
|
545
|
+
**Returns:**
|
|
546
|
+
- `unique_id` (str): Unique identifier for the scheduled run (used for cancellation)
|
|
547
|
+
- `job_master_id` (str): Job master identifier (used for cancellation)
|
|
548
|
+
- `status` (str): Status of the scheduled run creation
|
|
549
|
+
- `trace_id` (str, optional): Trace ID for this scheduled run
|
|
550
|
+
|
|
551
|
+
#### 2. Cancel Scheduled Run
|
|
552
|
+
|
|
553
|
+
Cancel a scheduled run using the `job_master_id` and `unique_id` returned from `schedule_run()`.
|
|
554
|
+
|
|
555
|
+
```python
|
|
556
|
+
from simplai_sdk import SimplAI
|
|
557
|
+
import asyncio
|
|
558
|
+
|
|
559
|
+
|
|
560
|
+
async def main():
|
|
561
|
+
simplai = SimplAI()
|
|
562
|
+
|
|
563
|
+
# Cancel a scheduled run
|
|
564
|
+
cancel_result = await simplai.cancel_schedule_run(
|
|
565
|
+
job_master_id=1238,
|
|
566
|
+
unique_id="4d5ec902-39d0-45fd-93e1-ed599b576256",
|
|
567
|
+
)
|
|
568
|
+
print(f"Status: {cancel_result.get('status')}")
|
|
569
|
+
print(f"Trace ID: {cancel_result.get('trace_id')}") # Optional
|
|
570
|
+
|
|
571
|
+
|
|
572
|
+
asyncio.run(main())
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
**Parameters:**
|
|
576
|
+
- `job_master_id` (int): Job master identifier from the scheduled run
|
|
577
|
+
- `unique_id` (str): Unique identifier from the scheduled run
|
|
578
|
+
|
|
579
|
+
**Returns:**
|
|
580
|
+
- `status` (str): Status after cancellation
|
|
581
|
+
- `trace_id` (str, optional): Trace ID for this cancellation operation
|
|
582
|
+
|
|
583
|
+
**Note:** Both `job_master_id` and `unique_id` are returned when you create a scheduled run using `schedule_run()`. Save these values if you need to cancel the schedule later.
|
|
584
|
+
|
|
585
|
+
### Billing
|
|
586
|
+
|
|
587
|
+
The SDK provides functions for accessing billing and usage information for workflow and agent executions.
|
|
588
|
+
|
|
589
|
+
#### Get Billing Detail
|
|
590
|
+
|
|
591
|
+
Get billing details (consumption, app name, app type) for a specific trace ID. This is useful for tracking costs and usage associated with a particular execution.
|
|
592
|
+
|
|
593
|
+
```python
|
|
594
|
+
from simplai_sdk import SimplAI
|
|
595
|
+
import asyncio
|
|
596
|
+
|
|
597
|
+
|
|
598
|
+
async def main():
|
|
599
|
+
simplai = SimplAI()
|
|
600
|
+
|
|
601
|
+
# Get billing details for a trace ID
|
|
602
|
+
billing = await simplai.get_billing_detail(
|
|
603
|
+
trace_id="your-trace-id", # Trace ID from workflow execution or agent chat
|
|
604
|
+
)
|
|
605
|
+
print(f"Total Consumption: {billing.get('totalConsumption')}")
|
|
606
|
+
print(f"App Name: {billing.get('appName')}")
|
|
607
|
+
print(f"App Type: {billing.get('appType')}")
|
|
608
|
+
|
|
609
|
+
|
|
610
|
+
asyncio.run(main())
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
**Parameters:**
|
|
614
|
+
- `trace_id` (str): The trace ID from a workflow execution or agent chat response
|
|
615
|
+
|
|
616
|
+
**Returns:**
|
|
617
|
+
- `totalConsumption` (int/float): Total consumption/cost for this trace
|
|
618
|
+
- `appName` (str): Name of the application/workflow/agent
|
|
619
|
+
- `appType` (str): Type of the application (e.g., "WORKFLOW", "AGENT")
|
|
620
|
+
|
|
621
|
+
**Note:** The trace ID can be obtained from:
|
|
622
|
+
- Workflow execution results: `result.get('traceId')` from `execute_and_wait_workflow()` or `get_tool_result()`
|
|
623
|
+
- Agent chat results: `result.trace_id` from `agent_chat()` or `agent_chat_stream()`
|
|
624
|
+
- Bulk run status: `status.get('trace_id')` from `get_bulk_run_status()`
|
|
625
|
+
|
|
626
|
+
**Raises:**
|
|
627
|
+
- `APIException`: If the trace ID is invalid or billing information is not available (e.g., 204 No Content)
|
|
628
|
+
|
|
629
|
+
### Using Core Functions Directly
|
|
630
|
+
|
|
631
|
+
```python
|
|
632
|
+
from simplai_sdk import SimplAI
|
|
633
|
+
import asyncio
|
|
634
|
+
|
|
635
|
+
|
|
636
|
+
async def main():
|
|
637
|
+
# API key is optional - will be loaded from .env if not provided
|
|
638
|
+
simplai = SimplAI()
|
|
639
|
+
|
|
640
|
+
result = await simplai.agent_chat(
|
|
641
|
+
agent_id="agent-123",
|
|
642
|
+
message="Hello!",
|
|
643
|
+
)
|
|
644
|
+
|
|
645
|
+
print(f"Trace ID: {result.trace_id}")
|
|
646
|
+
print(f"Node ID: {result.node_id}")
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
asyncio.run(main())
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
## Features
|
|
653
|
+
|
|
654
|
+
- **Agent Chat**: Non-streaming and streaming agent conversations
|
|
655
|
+
- **Workflows**: Execute and manage workflows
|
|
656
|
+
- **Bulk Runs**: Trigger and monitor bulk workflow executions
|
|
657
|
+
- **Traces**: Fetch and analyze execution traces
|
|
658
|
+
- **Billing**: Access usage and cost information
|
|
659
|
+
|
|
660
|
+
## Environment Setup
|
|
661
|
+
|
|
662
|
+
See [ENV_SETUP.md](ENV_SETUP.md) for detailed environment variable configuration.
|
|
663
|
+
|
|
664
|
+
At a minimum you should set the following in your `.env` or environment:
|
|
665
|
+
|
|
666
|
+
- `API_KEY` – your SimplAI API key (used by `SimplAI` and core functions)
|
|
667
|
+
- `SIMPAI_BASE_URL` – base URL for the SimplAI edge service
|
|
668
|
+
|
|
669
|
+
The SDK automatically loads `.env` and reads `SIMPAI_BASE_URL` in `src/constants/__init__.py`, and all HTTP clients derive their base URLs from this value.
|
|
670
|
+
|
|
671
|
+
## Testing
|
|
672
|
+
|
|
673
|
+
Run the test scripts from the project root (with the SDK installed, e.g. `pip install -e .`):
|
|
674
|
+
|
|
675
|
+
```bash
|
|
676
|
+
# Non-streaming agent chat (agent_chat)
|
|
677
|
+
python tests/test_agent_chat.py
|
|
678
|
+
|
|
679
|
+
# Streaming agent chat (agent_chat_stream with on_chunk)
|
|
680
|
+
python tests/test_agent_chat_stream.py
|
|
681
|
+
|
|
682
|
+
# Trace tree (get_trace_tree)
|
|
683
|
+
python tests/test_traces.py
|
|
684
|
+
```
|
|
685
|
+
|
|
686
|
+
### Test script overview
|
|
687
|
+
|
|
688
|
+
| Script | Function | Description |
|
|
689
|
+
|--------|----------|-------------|
|
|
690
|
+
| `tests/test_agent_chat.py` | `simplai.agent_chat(agent_id, message)` | Non-streaming agent chat; returns `AgentResult` with `response`, `trace_id`, `node_id`, `payload`. |
|
|
691
|
+
| `tests/test_agent_chat_stream.py` | `simplai.agent_chat_stream(agent_id, message, on_chunk=...)` | Streaming agent chat; `on_chunk` receives each chunk; first chunk may contain `trace_id`/`node_id`; final result has `trace_id`, `node_id`. |
|
|
692
|
+
| `tests/test_traces.py` | `simplai.get_trace_tree(tree_id, node_id)` | Fetches trace sub-tree; use `tree_id` (same as `trace_id` from agent calls) and `node_id`. Use `raw_response=True` to get raw API JSON. |
|
|
693
|
+
|
|
694
|
+
## Package Structure
|
|
695
|
+
|
|
696
|
+
```
|
|
697
|
+
python-sdk/
|
|
698
|
+
├── src/ # Source code (installed as package)
|
|
699
|
+
│ ├── core/ # Core SDK functionality
|
|
700
|
+
│ │ ├── agents/ # Agent chat and execution
|
|
701
|
+
│ │ └── workflows/ # Workflow execution and management
|
|
702
|
+
│ ├── simplai/ # High-level SimplAI class
|
|
703
|
+
│ ├── traces/ # Trace fetching and analysis
|
|
704
|
+
│ ├── billing/ # Billing and usage
|
|
705
|
+
│ ├── utils/ # Utility functions
|
|
706
|
+
│ └── exceptions/ # Custom exceptions
|
|
707
|
+
├── tests/ # Test scripts
|
|
708
|
+
├── pyproject.toml # Package configuration
|
|
709
|
+
└── README.md # This file
|
|
710
|
+
```
|
|
711
|
+
|
|
712
|
+
## Requirements
|
|
713
|
+
|
|
714
|
+
- Python >= 3.9
|
|
715
|
+
- httpx >= 0.25.0
|
|
716
|
+
- pydantic >= 2.0.0
|
|
717
|
+
|
|
718
|
+
## Documentation
|
|
719
|
+
|
|
720
|
+
- [Environment Setup Guide](ENV_SETUP.md)
|
|
721
|
+
|
|
722
|
+
## License
|
|
723
|
+
|
|
724
|
+
This SDK is proprietary software. See [LICENSE](LICENSE) for details.
|
|
725
|
+
|
|
726
|
+
Copyright (c) 2024 SimplAI. All rights reserved.
|
|
727
|
+
|
|
728
|
+
For licensing inquiries, please contact: support@simplai.ai
|
|
@@ -27,7 +27,7 @@ core/workflows/tool_execution/schema.py,sha256=To8uVGFNULcdupaCZbYnJTu4azAGTv0so
|
|
|
27
27
|
exceptions/__init__.py,sha256=bUAIwVmyYtHhPvHOpO7LAYRJrzhY9N_KMB3-AfZCUlU,522
|
|
28
28
|
simplai_sdk/__init__.py,sha256=vT8U1gQbTS4xXFyoVU767IMh9-5ZVqPaNjL5gF8YFKU,121
|
|
29
29
|
simplai_sdk/simplai.py,sha256=U-jf1E4ygd6fyKNx6lMqy79_F2Fh15dAzW4E-pFOISY,8116
|
|
30
|
-
simplai_sdk-0.2.
|
|
30
|
+
simplai_sdk-0.2.1.dist-info/licenses/LICENSE,sha256=byn2pn7QZM4hs8uCv8VSaiZ1XTk5KrpNSWZ7hYc2EpY,1064
|
|
31
31
|
traces/__init__.py,sha256=Wn1H6KU_JXIGlj-O0NBkz9lykh3Axwj9UqJf7Sa5QMk,37
|
|
32
32
|
traces/agents/__init__.py,sha256=wzwdX5Bxkol_ikS6x2M5wyM_zEAzlbM0NP6dJI9LmTU,1087
|
|
33
33
|
traces/agents/api.py,sha256=Afv_blHayN1GwBxaSmcyTgugioyg62E9Fg67xsBNTeA,10730
|
|
@@ -36,7 +36,7 @@ traces/agents/models.py,sha256=HVxHQJtixau-B0x0OwwUexnaJuOsKrAYkXRAtoPg0cs,8629
|
|
|
36
36
|
traces/workflows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
37
37
|
utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
38
38
|
utils/config.py,sha256=uaEGZ3QfYOhKK34d5RBbuIVP18Lue2ZcLz-Hpuv_p_c,3354
|
|
39
|
-
simplai_sdk-0.2.
|
|
40
|
-
simplai_sdk-0.2.
|
|
41
|
-
simplai_sdk-0.2.
|
|
42
|
-
simplai_sdk-0.2.
|
|
39
|
+
simplai_sdk-0.2.1.dist-info/METADATA,sha256=Pebt_UJw17kBHz5DqOfvXNeAb38BWvd2lhY0p7i2hpY,23685
|
|
40
|
+
simplai_sdk-0.2.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
41
|
+
simplai_sdk-0.2.1.dist-info/top_level.txt,sha256=CznxFBTncbDBZKLnqjDee5bfUXPKrrKXD4qVKq54SeA,59
|
|
42
|
+
simplai_sdk-0.2.1.dist-info/RECORD,,
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: simplai_sdk
|
|
3
|
-
Version: 0.2.0
|
|
4
|
-
Summary: SimplAI Python SDK for agents, workflows, and traces
|
|
5
|
-
Author-email: SimplAI <support@simplai.ai>
|
|
6
|
-
License: MIT License
|
|
7
|
-
|
|
8
|
-
Copyright (c) 2026 SimplAI
|
|
9
|
-
|
|
10
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
-
in the Software without restriction, including without limitation the rights
|
|
13
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
-
furnished to do so, subject to the following conditions:
|
|
16
|
-
|
|
17
|
-
The above copyright notice and this permission notice shall be included in all
|
|
18
|
-
copies or substantial portions of the Software.
|
|
19
|
-
|
|
20
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
-
SOFTWARE.
|
|
27
|
-
|
|
28
|
-
Keywords: simplai,ai,agents,workflows,sdk
|
|
29
|
-
Classifier: Development Status :: 4 - Beta
|
|
30
|
-
Classifier: Intended Audience :: Developers
|
|
31
|
-
Classifier: Programming Language :: Python :: 3
|
|
32
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
33
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
34
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
35
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
36
|
-
Requires-Python: >=3.9
|
|
37
|
-
Description-Content-Type: text/markdown
|
|
38
|
-
License-File: LICENSE
|
|
39
|
-
Requires-Dist: httpx
|
|
40
|
-
Requires-Dist: pydantic
|
|
41
|
-
Requires-Dist: python-dotenv
|
|
42
|
-
Provides-Extra: dev
|
|
43
|
-
Requires-Dist: python-dotenv; extra == "dev"
|
|
44
|
-
Requires-Dist: pytest; extra == "dev"
|
|
45
|
-
Requires-Dist: pytest-asyncio; extra == "dev"
|
|
46
|
-
Dynamic: license-file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|