simplai-sdk 0.2.0__tar.gz → 0.2.1__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 (56) hide show
  1. simplai_sdk-0.2.1/PKG-INFO +728 -0
  2. simplai_sdk-0.2.1/README.md +681 -0
  3. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/pyproject.toml +1 -1
  4. simplai_sdk-0.2.1/src/simplai_sdk.egg-info/PKG-INFO +728 -0
  5. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/simplai_sdk.egg-info/SOURCES.txt +1 -0
  6. simplai_sdk-0.2.0/PKG-INFO +0 -46
  7. simplai_sdk-0.2.0/src/simplai_sdk.egg-info/PKG-INFO +0 -46
  8. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/ENV_SETUP.md +0 -0
  9. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/LICENSE +0 -0
  10. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/MANIFEST.in +0 -0
  11. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/requirements.txt +0 -0
  12. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/setup.cfg +0 -0
  13. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/billing/__init__.py +0 -0
  14. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/billing/api.py +0 -0
  15. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/billing/client.py +0 -0
  16. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/billing/schema.py +0 -0
  17. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/constants/__init__.py +0 -0
  18. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/core/__init__.py +0 -0
  19. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/core/agents/__init__.py +0 -0
  20. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/core/agents/execution/__init__.py +0 -0
  21. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/core/agents/execution/api.py +0 -0
  22. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/core/agents/execution/client.py +0 -0
  23. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/core/agents/models.py +0 -0
  24. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/core/workflows/WORKFLOW_ARCHITECTURE.md +0 -0
  25. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/core/workflows/__init__.py +0 -0
  26. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/core/workflows/bulk/__init__.py +0 -0
  27. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/core/workflows/bulk/api.py +0 -0
  28. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/core/workflows/bulk/client.py +0 -0
  29. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/core/workflows/bulk/schema.py +0 -0
  30. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/core/workflows/models.py +0 -0
  31. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/core/workflows/scheduling/__init__.py +0 -0
  32. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/core/workflows/scheduling/api.py +0 -0
  33. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/core/workflows/scheduling/client.py +0 -0
  34. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/core/workflows/scheduling/schema.py +0 -0
  35. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/core/workflows/tool_execution/__init__.py +0 -0
  36. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/core/workflows/tool_execution/api.py +0 -0
  37. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/core/workflows/tool_execution/client.py +0 -0
  38. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/core/workflows/tool_execution/schema.py +0 -0
  39. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/exceptions/__init__.py +0 -0
  40. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/simplai_sdk/__init__.py +0 -0
  41. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/simplai_sdk/simplai.py +0 -0
  42. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/simplai_sdk.egg-info/dependency_links.txt +0 -0
  43. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/simplai_sdk.egg-info/requires.txt +0 -0
  44. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/simplai_sdk.egg-info/top_level.txt +0 -0
  45. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/traces/__init__.py +0 -0
  46. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/traces/agents/__init__.py +0 -0
  47. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/traces/agents/api.py +0 -0
  48. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/traces/agents/client.py +0 -0
  49. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/traces/agents/models.py +0 -0
  50. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/traces/workflows/__init__.py +0 -0
  51. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/utils/__init__.py +0 -0
  52. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/src/utils/config.py +0 -0
  53. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/tests/test_agent_chat.py +0 -0
  54. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/tests/test_agent_chat_stream.py +0 -0
  55. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/tests/test_execution.py +0 -0
  56. {simplai_sdk-0.2.0 → simplai_sdk-0.2.1}/tests/test_traces.py +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