You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
while status["status"] in ["queued", "processing"]:
504
505
print(f"Current status: {status['status']}")
505
506
time.sleep(2) # Wait 2 seconds
506
-
status = client.get_job_status(result.task_id)
507
+
status = client.get_job_status(result.job_id)
507
508
508
509
if status["status"] =="completed":
509
510
print("Workflow completed!")
@@ -764,7 +765,7 @@ import { FAQ } from '@/components/ui/faq'
764
765
765
766
<FAQitems={[
766
767
{ question: "Do I need to deploy a workflow before I can execute it via the SDK?", answer: "Yes. Workflows must be deployed before they can be executed through the SDK. You can use the validate_workflow() method to check whether a workflow is deployed and ready. If it returns False, deploy the workflow from the Sim UI first and create or select an API key during deployment." },
767
-
{ question: "What is the difference between sync and async execution?", answer: "Sync execution (the default) blocks until the workflow completes and returns the full result. Async execution (async_execution=True) returns immediately with a task ID that you can poll using get_job_status(). Use async mode for long-running workflows to avoid request timeouts. Async job statuses include queued, processing, completed, failed, and cancelled." },
768
+
{ question: "What is the difference between sync and async execution?", answer: "Sync execution (the default) blocks until the workflow completes and returns the full result. Async execution (async_execution=True) returns immediately with a job ID and status URL that you can poll using get_job_status(). Use async mode for long-running workflows to avoid request timeouts. Async job statuses include queued, processing, completed, failed, and cancelled." },
768
769
{ question: "How does the SDK handle rate limiting?", answer: "The SDK provides built-in rate limiting support through the execute_with_retry() method. It uses exponential backoff (1s, 2s, 4s, 8s...) with 25% jitter to avoid thundering herd problems. If the API returns a retry-after header, that value is used instead. You can configure max_retries, initial_delay, max_delay, and backoff_multiplier. Use get_rate_limit_info() to check your current rate limit status." },
769
770
{ question: "Can I use the Python SDK as a context manager?", answer: "Yes. The SimStudioClient supports Python's context manager protocol. Use it with the 'with' statement to automatically close the underlying HTTP session when you are done, which is especially useful for scripts that create and discard client instances." },
770
771
{ question: "How do I handle different types of errors from the SDK?", answer: "The SDK raises SimStudioError with a code property for API-specific errors. Common error codes are UNAUTHORIZED (invalid API key), TIMEOUT (request timed out), RATE_LIMIT_EXCEEDED (too many requests), USAGE_LIMIT_EXCEEDED (billing limit reached), and EXECUTION_ERROR (workflow failed). Use the error code to implement targeted error handling and recovery logic." },
@@ -1022,7 +1021,7 @@ import { FAQ } from '@/components/ui/faq'
1022
1021
1023
1022
<FAQitems={[
1024
1023
{ question: "Do I need to deploy a workflow before I can execute it via the SDK?", answer: "Yes. Workflows must be deployed before they can be executed through the SDK. You can use the validateWorkflow() method to check whether a workflow is deployed and ready. If it returns false, deploy the workflow from the Sim UI first and create or select an API key during deployment." },
1025
-
{ question: "What is the difference between sync and async execution?", answer: "Sync execution (the default) blocks until the workflow completes and returns the full result. Async execution returns immediately with a task ID that you can poll using getJobStatus(). Use async mode for long-running workflows to avoid request timeouts. Async job statuses include queued, processing, completed, failed, and cancelled." },
1024
+
{ question: "What is the difference between sync and async execution?", answer: "Sync execution (the default) blocks until the workflow completes and returns the full result. Async execution returns immediately with a job ID and status URL that you can poll using getJobStatus(). Use async mode for long-running workflows to avoid request timeouts. Async job statuses include queued, processing, completed, failed, and cancelled." },
1026
1025
{ question: "How does streaming work with the SDK?", answer: "Enable streaming by setting stream: true and specifying selectedOutputs with block names and attributes in blockName.attribute format (e.g., ['agent1.content']). The response uses Server-Sent Events (SSE) format, sending incremental chunks as the workflow executes. Each chunk includes the blockId and the text content. A final done event includes the execution metadata." },
1027
1026
{ question: "How does the SDK handle rate limiting?", answer: "The SDK provides built-in rate limiting support through the executeWithRetry() method. It uses exponential backoff (1s, 2s, 4s, 8s...) with 25% jitter to avoid thundering herd problems. If the API returns a retry-after header, that value is used instead. You can configure maxRetries, initialDelay, maxDelay, and backoffMultiplier. Use getRateLimitInfo() to check your current rate limit status." },
1028
1027
{ question: "Is it safe to use the SDK in browser-side code?", answer: "You can use the SDK in the browser, but you should not expose your API key in client-side code. In production, use a backend proxy server to handle SDK calls, or use a public API key with limited permissions. The SDK works with both Node.js and browser environments, but sensitive keys should stay server-side." },
Copy file name to clipboardExpand all lines: apps/docs/content/docs/en/blocks/function.mdx
+47Lines changed: 47 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -185,6 +185,53 @@ plt.show()
185
185
186
186
## Best Practices
187
187
188
+
### Large Inputs and Payload Limits
189
+
190
+
Function blocks receive their code, parameters, resolved references, and previous block context in an internal execution request. Sim can safely reference oversized workflow outputs, such as large `loop.results` or `parallel.results`, when you select a smaller nested field like `<loop.results[0][0].id>`. Larger values are stored in execution storage and passed around as small references until code explicitly reads them.
191
+
192
+
File outputs are metadata-first by default. Referencing `<file.name>`, `<file.url>`, or similar metadata does not hydrate file contents. In JavaScript functions without imports, a direct base64 reference like `<readfile.file.base64>` is automatically rewritten to a lazy server-side read so the base64 string does not cross the Function request body.
193
+
194
+
You can also call the helper explicitly:
195
+
196
+
```javascript
197
+
constfile=<readfile.file>;
198
+
constbase64=awaitsim.files.readBase64(file);
199
+
```
200
+
201
+
`sim.files.readBase64(file)`, `sim.files.readText(file)`, `sim.files.readBase64Chunk(file, { offset, length })`, and `sim.files.readTextChunk(file, { offset, length })` read from server-side execution storage under memory caps. `sim.values.read(ref)` can explicitly read a large execution value reference. These helpers are available only in JavaScript functions without imports. JavaScript with imports, Python, and shell do not support these lazy helpers yet.
202
+
203
+
Very large full reads can still fail by design; use chunk helpers or return a file when you need to handle more data.
204
+
205
+
Use text chunks for text-like files such as logs, CSV, JSONL, and markdown:
Chunk `offset` and `length` are byte-based. For Unicode text, a chunk can split a multi-byte character at the boundary; use text chunks for approximate text processing and prefer smaller structured references when exact parsing matters.
230
+
231
+
Avoid passing a full large object into a Function block when you only need one field. For example, prefer `<api.data.customerId>` over `<api.data>` when the API response is large. If a JavaScript Function without imports references a large execution value, Sim automatically reads it through `sim.values.read(...)` at runtime under memory caps.
232
+
233
+
For large generated data, write the result to a file or table with `outputPath`, `outputSandboxPath`, or `outputTable` instead of returning the entire payload inline.
234
+
188
235
-**Keep functions focused**: Write functions that do one thing well to improve maintainability and debugging
189
236
-**Handle errors gracefully**: Use try/catch blocks to handle potential errors and provide meaningful error messages
190
237
-**Test edge cases**: Ensure your code handles unusual inputs, null values, and boundary conditions correctly
For large result sets, reference only the entry or field you need, such as `<processtasks.results[10][0].id>`. Sim keeps aggregate results indexable by storing oversized entries in execution storage and hydrating them only when an indexed server-side path is explicitly referenced.
145
+
146
+
### Batch Size
147
+
148
+
Parallel blocks run up to 20 branches at a time by default. Increase the total count or collection size to process more work; Sim will execute the next batch after the current batch finishes. You can lower the batch size to reduce concurrency for rate-limited APIs.
149
+
143
150
### Instance Isolation
144
151
145
152
Each parallel instance runs independently:
@@ -157,7 +164,7 @@ Each parallel instance runs independently:
157
164
While parallel execution is faster, be mindful of:
158
165
- API rate limits when making concurrent requests
159
166
- Memory usage with large datasets
160
-
- Maximum of 20 concurrent instances to prevent resource exhaustion
167
+
- Maximum of 20 concurrent instances per batch to prevent resource exhaustion
161
168
</Callout>
162
169
163
170
## Parallel vs Loop
@@ -186,6 +193,9 @@ Understanding when to use each:
186
193
<li>
187
194
<strong>Collection</strong>: Array or object to distribute (collection-based)
188
195
</li>
196
+
<li>
197
+
<strong>Batch size</strong>: Number of branches to run concurrently, from 1 to 20
0 commit comments