@superblocksteam/sdk-api 2.0.105 → 2.0.106-next.0
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.
- package/README.md +439 -89
- package/dist/api/definition.d.ts +11 -6
- package/dist/api/definition.d.ts.map +1 -1
- package/dist/api/definition.js +19 -12
- package/dist/api/definition.js.map +1 -1
- package/dist/api/definition.test.js +39 -15
- package/dist/api/definition.test.js.map +1 -1
- package/dist/errors.d.ts +1 -1
- package/dist/errors.js +1 -1
- package/dist/index.d.ts +10 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -5
- package/dist/index.js.map +1 -1
- package/dist/integrations/base/index.d.ts +2 -1
- package/dist/integrations/base/index.d.ts.map +1 -1
- package/dist/integrations/base/index.js +1 -0
- package/dist/integrations/base/index.js.map +1 -1
- package/dist/integrations/base/rest-api-client-base.d.ts +48 -0
- package/dist/integrations/base/rest-api-client-base.d.ts.map +1 -0
- package/dist/integrations/base/rest-api-client-base.js +98 -0
- package/dist/integrations/base/rest-api-client-base.js.map +1 -0
- package/dist/integrations/base/rest-api-integration-client.d.ts +10 -20
- package/dist/integrations/base/rest-api-integration-client.d.ts.map +1 -1
- package/dist/integrations/base/rest-api-integration-client.js +10 -65
- package/dist/integrations/base/rest-api-integration-client.js.map +1 -1
- package/dist/integrations/box/types.d.ts +1 -1
- package/dist/integrations/declarations.d.ts +5 -73
- package/dist/integrations/declarations.d.ts.map +1 -1
- package/dist/integrations/declarations.js +5 -68
- package/dist/integrations/declarations.js.map +1 -1
- package/dist/integrations/documentation.test.js +0 -2
- package/dist/integrations/documentation.test.js.map +1 -1
- package/dist/integrations/googledrive/types.d.ts +1 -1
- package/dist/integrations/index.d.ts +1 -11
- package/dist/integrations/index.d.ts.map +1 -1
- package/dist/integrations/index.js +1 -7
- package/dist/integrations/index.js.map +1 -1
- package/dist/integrations/registry.d.ts +1 -11
- package/dist/integrations/registry.d.ts.map +1 -1
- package/dist/integrations/registry.js +0 -29
- package/dist/integrations/registry.js.map +1 -1
- package/dist/integrations/slack/client.d.ts +13 -9
- package/dist/integrations/slack/client.d.ts.map +1 -1
- package/dist/integrations/slack/client.js +60 -8
- package/dist/integrations/slack/client.js.map +1 -1
- package/dist/integrations/slack/client.test.d.ts +11 -0
- package/dist/integrations/slack/client.test.d.ts.map +1 -0
- package/dist/integrations/slack/client.test.js +368 -0
- package/dist/integrations/slack/client.test.js.map +1 -0
- package/dist/integrations/slack/index.d.ts +2 -1
- package/dist/integrations/slack/index.d.ts.map +1 -1
- package/dist/integrations/slack/index.js +1 -0
- package/dist/integrations/slack/index.js.map +1 -1
- package/dist/integrations/slack/types.d.ts +127 -28
- package/dist/integrations/slack/types.d.ts.map +1 -1
- package/dist/integrations/slack/types.js +27 -1
- package/dist/integrations/slack/types.js.map +1 -1
- package/dist/integrations/snowflake/client.d.ts +2 -2
- package/dist/integrations/snowflake/client.js +2 -2
- package/dist/runtime/context.d.ts +1 -1
- package/dist/runtime/executor.d.ts +2 -2
- package/dist/types.d.ts +15 -6
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/api/definition.test.ts +40 -15
- package/src/api/definition.ts +19 -12
- package/src/errors.ts +1 -1
- package/src/index.ts +13 -33
- package/src/integrations/asana/README.md +12 -12
- package/src/integrations/base/index.ts +2 -1
- package/src/integrations/base/rest-api-client-base.ts +134 -0
- package/src/integrations/base/rest-api-integration-client.ts +12 -89
- package/src/integrations/bitbucket/README.md +19 -19
- package/src/integrations/box/README.md +24 -24
- package/src/integrations/box/types.ts +1 -1
- package/src/integrations/circleci/README.md +18 -18
- package/src/integrations/declarations.ts +5 -105
- package/src/integrations/documentation.test.ts +0 -2
- package/src/integrations/googledrive/README.md +25 -22
- package/src/integrations/googledrive/types.ts +1 -1
- package/src/integrations/graphql/README.md +2 -2
- package/src/integrations/groq/README.md +8 -8
- package/src/integrations/index.ts +0 -51
- package/src/integrations/perplexity/README.md +39 -48
- package/src/integrations/registry.ts +1 -39
- package/src/integrations/salesforce/README.md +11 -9
- package/src/integrations/slack/README.md +62 -19
- package/src/integrations/slack/client.test.ts +553 -0
- package/src/integrations/slack/client.ts +92 -12
- package/src/integrations/slack/index.ts +6 -1
- package/src/integrations/slack/types.ts +142 -29
- package/src/integrations/snowflake/client.ts +2 -2
- package/src/integrations/zoom/README.md +15 -15
- package/src/runtime/context.ts +1 -1
- package/src/runtime/executor.ts +2 -2
- package/src/types.ts +15 -6
- package/dist/integrations/couchbase/client.d.ts +0 -36
- package/dist/integrations/couchbase/client.d.ts.map +0 -1
- package/dist/integrations/couchbase/client.js +0 -148
- package/dist/integrations/couchbase/client.js.map +0 -1
- package/dist/integrations/couchbase/index.d.ts +0 -8
- package/dist/integrations/couchbase/index.d.ts.map +0 -1
- package/dist/integrations/couchbase/index.js +0 -7
- package/dist/integrations/couchbase/index.js.map +0 -1
- package/dist/integrations/couchbase/types.d.ts +0 -100
- package/dist/integrations/couchbase/types.d.ts.map +0 -1
- package/dist/integrations/couchbase/types.js +0 -5
- package/dist/integrations/couchbase/types.js.map +0 -1
- package/dist/integrations/kafka/client.d.ts +0 -25
- package/dist/integrations/kafka/client.d.ts.map +0 -1
- package/dist/integrations/kafka/client.js +0 -124
- package/dist/integrations/kafka/client.js.map +0 -1
- package/dist/integrations/kafka/index.d.ts +0 -8
- package/dist/integrations/kafka/index.d.ts.map +0 -1
- package/dist/integrations/kafka/index.js +0 -7
- package/dist/integrations/kafka/index.js.map +0 -1
- package/dist/integrations/kafka/types.d.ts +0 -113
- package/dist/integrations/kafka/types.d.ts.map +0 -1
- package/dist/integrations/kafka/types.js +0 -5
- package/dist/integrations/kafka/types.js.map +0 -1
- package/dist/integrations/kinesis/client.d.ts +0 -31
- package/dist/integrations/kinesis/client.d.ts.map +0 -1
- package/dist/integrations/kinesis/client.js +0 -101
- package/dist/integrations/kinesis/client.js.map +0 -1
- package/dist/integrations/kinesis/index.d.ts +0 -8
- package/dist/integrations/kinesis/index.d.ts.map +0 -1
- package/dist/integrations/kinesis/index.js +0 -7
- package/dist/integrations/kinesis/index.js.map +0 -1
- package/dist/integrations/kinesis/types.d.ts +0 -97
- package/dist/integrations/kinesis/types.d.ts.map +0 -1
- package/dist/integrations/kinesis/types.js +0 -7
- package/dist/integrations/kinesis/types.js.map +0 -1
- package/dist/integrations/python/client.d.ts +0 -42
- package/dist/integrations/python/client.d.ts.map +0 -1
- package/dist/integrations/python/client.js +0 -89
- package/dist/integrations/python/client.js.map +0 -1
- package/dist/integrations/python/client.test.d.ts +0 -5
- package/dist/integrations/python/client.test.d.ts.map +0 -1
- package/dist/integrations/python/client.test.js +0 -214
- package/dist/integrations/python/client.test.js.map +0 -1
- package/dist/integrations/python/index.d.ts +0 -6
- package/dist/integrations/python/index.d.ts.map +0 -1
- package/dist/integrations/python/index.js +0 -5
- package/dist/integrations/python/index.js.map +0 -1
- package/dist/integrations/python/types.d.ts +0 -85
- package/dist/integrations/python/types.d.ts.map +0 -1
- package/dist/integrations/python/types.js +0 -5
- package/dist/integrations/python/types.js.map +0 -1
- package/dist/integrations/redis/client.d.ts +0 -43
- package/dist/integrations/redis/client.d.ts.map +0 -1
- package/dist/integrations/redis/client.js +0 -142
- package/dist/integrations/redis/client.js.map +0 -1
- package/dist/integrations/redis/index.d.ts +0 -8
- package/dist/integrations/redis/index.d.ts.map +0 -1
- package/dist/integrations/redis/index.js +0 -7
- package/dist/integrations/redis/index.js.map +0 -1
- package/dist/integrations/redis/types.d.ts +0 -137
- package/dist/integrations/redis/types.d.ts.map +0 -1
- package/dist/integrations/redis/types.js +0 -5
- package/dist/integrations/redis/types.js.map +0 -1
- package/src/integrations/couchbase/README.md +0 -138
- package/src/integrations/couchbase/client.ts +0 -225
- package/src/integrations/couchbase/index.ts +0 -8
- package/src/integrations/couchbase/types.ts +0 -126
- package/src/integrations/kafka/README.md +0 -144
- package/src/integrations/kafka/client.ts +0 -216
- package/src/integrations/kafka/index.ts +0 -14
- package/src/integrations/kafka/types.ts +0 -128
- package/src/integrations/kinesis/README.md +0 -153
- package/src/integrations/kinesis/client.ts +0 -146
- package/src/integrations/kinesis/index.ts +0 -14
- package/src/integrations/kinesis/types.ts +0 -114
- package/src/integrations/python/README.md +0 -566
- package/src/integrations/python/client.test.ts +0 -341
- package/src/integrations/python/client.ts +0 -136
- package/src/integrations/python/index.ts +0 -6
- package/src/integrations/python/types.ts +0 -92
- package/src/integrations/redis/README.md +0 -200
- package/src/integrations/redis/client.ts +0 -208
- package/src/integrations/redis/index.ts +0 -8
- package/src/integrations/redis/types.ts +0 -167
|
@@ -1,566 +0,0 @@
|
|
|
1
|
-
# Python Client
|
|
2
|
-
|
|
3
|
-
Execute Python scripts with type-safe inputs and outputs using the Superblocks SDK.
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
|
|
7
|
-
The Python client allows you to run Python code with:
|
|
8
|
-
|
|
9
|
-
- Type-safe input bindings via `{{}}` syntax
|
|
10
|
-
- Output validation using Zod schemas
|
|
11
|
-
- Full Python 3 standard library support
|
|
12
|
-
- Access to installed packages (requests, etc.)
|
|
13
|
-
|
|
14
|
-
## Basic Usage
|
|
15
|
-
|
|
16
|
-
```typescript
|
|
17
|
-
import { api, z, python } from "@superblocksteam/sdk-api";
|
|
18
|
-
|
|
19
|
-
// Integration ID from the integrations panel
|
|
20
|
-
const PYTHON_RUNTIME = "a1b2c3d4-5678-90ab-cdef-python00001";
|
|
21
|
-
|
|
22
|
-
export default api({
|
|
23
|
-
name: "PythonExample",
|
|
24
|
-
integrations: {
|
|
25
|
-
runtime: python(PYTHON_RUNTIME),
|
|
26
|
-
},
|
|
27
|
-
input: z.object({
|
|
28
|
-
userId: z.string(),
|
|
29
|
-
}),
|
|
30
|
-
|
|
31
|
-
output: z.object({
|
|
32
|
-
greeting: z.string(),
|
|
33
|
-
timestamp: z.number(),
|
|
34
|
-
}),
|
|
35
|
-
|
|
36
|
-
async run(ctx, { userId }) {
|
|
37
|
-
const result = await ctx.integrations.runtime.run(
|
|
38
|
-
`
|
|
39
|
-
import time
|
|
40
|
-
|
|
41
|
-
# userId is available as a direct Python variable
|
|
42
|
-
current_time = int(time.time())
|
|
43
|
-
|
|
44
|
-
# Return a dictionary matching your output schema
|
|
45
|
-
return {
|
|
46
|
-
"greeting": f"Hello user {userId}!",
|
|
47
|
-
"timestamp": current_time
|
|
48
|
-
}
|
|
49
|
-
`,
|
|
50
|
-
z.object({
|
|
51
|
-
greeting: z.string(),
|
|
52
|
-
timestamp: z.number(),
|
|
53
|
-
}),
|
|
54
|
-
{
|
|
55
|
-
userId,
|
|
56
|
-
},
|
|
57
|
-
);
|
|
58
|
-
|
|
59
|
-
return result;
|
|
60
|
-
},
|
|
61
|
-
});
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
## API Reference
|
|
65
|
-
|
|
66
|
-
### `ctx.integrations.<name>.run<T>(code, schema, bindings?, metadata?): Promise<T>`
|
|
67
|
-
|
|
68
|
-
Executes Python code with validated output. Use the **key name** you declared in `integrations` (e.g. `ctx.integrations.runtime.run(...)` if you declared `runtime: python(...)`).
|
|
69
|
-
|
|
70
|
-
**Parameters:**
|
|
71
|
-
|
|
72
|
-
- `code` (string): Python script to execute. Bindings are automatically injected as Python variables.
|
|
73
|
-
- `schema` (ZodSchema<T>): **Required** Zod schema for validating the return value.
|
|
74
|
-
- `bindings` (Record<string, unknown>, optional): Key/value pairs that become Python variables in your code. Do not pass `TraceMetadata` here; use the `metadata` parameter instead.
|
|
75
|
-
- `metadata` (TraceMetadata, optional): Trace metadata for diagnostics labeling (see [Trace Metadata](#trace-metadata)).
|
|
76
|
-
|
|
77
|
-
**Returns:** Promise resolving to validated result matching the schema.
|
|
78
|
-
|
|
79
|
-
**Throws:** `CodeExecutionError` if execution fails or validation fails.
|
|
80
|
-
|
|
81
|
-
**Important:** Your Python code must use a `return` statement to return a value.
|
|
82
|
-
|
|
83
|
-
> **Note:** Because `bindings` and `metadata` are both plain objects, take care not
|
|
84
|
-
> to pass metadata as the third argument. If you need metadata but no bindings,
|
|
85
|
-
> pass `undefined` for `bindings` explicitly:
|
|
86
|
-
>
|
|
87
|
-
> ```typescript
|
|
88
|
-
> await ctx.integrations.runtime.run(code, schema, undefined, {
|
|
89
|
-
> label: "My trace label",
|
|
90
|
-
> });
|
|
91
|
-
> ```
|
|
92
|
-
|
|
93
|
-
## Binding Syntax
|
|
94
|
-
|
|
95
|
-
Bindings are passed as a map and automatically injected as Python variables. Reference them directly in your code by their key names:
|
|
96
|
-
|
|
97
|
-
```typescript
|
|
98
|
-
// In your run(): use the key you declared in integrations (e.g. runtime: python(...))
|
|
99
|
-
const result = await ctx.integrations.runtime.run(
|
|
100
|
-
`
|
|
101
|
-
# Bindings are available as direct Python variables
|
|
102
|
-
# No {{}} syntax needed - just use the variable names directly
|
|
103
|
-
return {
|
|
104
|
-
"message": f"{userName} is {userAge} years old",
|
|
105
|
-
"active": isActive
|
|
106
|
-
}
|
|
107
|
-
`,
|
|
108
|
-
z.object({
|
|
109
|
-
message: z.string(),
|
|
110
|
-
active: z.boolean(),
|
|
111
|
-
}),
|
|
112
|
-
{
|
|
113
|
-
userName: "Alice",
|
|
114
|
-
userAge: 30,
|
|
115
|
-
isActive: true,
|
|
116
|
-
},
|
|
117
|
-
);
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
The SDK automatically injects bindings as Python variables before your code executes, making them available for immediate use.
|
|
121
|
-
|
|
122
|
-
## Examples
|
|
123
|
-
|
|
124
|
-
### Data Transformation
|
|
125
|
-
|
|
126
|
-
Transform data from another step or API:
|
|
127
|
-
|
|
128
|
-
```typescript
|
|
129
|
-
// Transform user data (use ctx.integrations.runtime if you declared runtime: python(...))
|
|
130
|
-
const transformed = await ctx.integrations.runtime.run(
|
|
131
|
-
`
|
|
132
|
-
import json
|
|
133
|
-
|
|
134
|
-
users = {{userList}}
|
|
135
|
-
|
|
136
|
-
# Filter and transform
|
|
137
|
-
active_users = [
|
|
138
|
-
{
|
|
139
|
-
"id": u["id"],
|
|
140
|
-
"email": u["email"],
|
|
141
|
-
"displayName": f"{u['firstName']} {u['lastName']}"
|
|
142
|
-
}
|
|
143
|
-
for u in users
|
|
144
|
-
if u["status"] == "active"
|
|
145
|
-
]
|
|
146
|
-
|
|
147
|
-
return {"users": active_users, "count": len(active_users)}
|
|
148
|
-
`,
|
|
149
|
-
z.object({
|
|
150
|
-
users: z.array(
|
|
151
|
-
z.object({
|
|
152
|
-
id: z.string(),
|
|
153
|
-
email: z.string(),
|
|
154
|
-
displayName: z.string(),
|
|
155
|
-
}),
|
|
156
|
-
),
|
|
157
|
-
count: z.number(),
|
|
158
|
-
}),
|
|
159
|
-
{
|
|
160
|
-
userList: await getUsersFromDatabase(),
|
|
161
|
-
},
|
|
162
|
-
);
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
### HTTP Requests with Requests Library
|
|
166
|
-
|
|
167
|
-
Make HTTP requests using the `requests` library:
|
|
168
|
-
|
|
169
|
-
```typescript
|
|
170
|
-
const apiData = await ctx.integrations.runtime.run(
|
|
171
|
-
`
|
|
172
|
-
import requests
|
|
173
|
-
|
|
174
|
-
api_url = {{apiUrl}}
|
|
175
|
-
api_key = {{apiKey}}
|
|
176
|
-
|
|
177
|
-
response = requests.get(
|
|
178
|
-
api_url,
|
|
179
|
-
headers={"Authorization": f"Bearer {api_key}"}
|
|
180
|
-
)
|
|
181
|
-
|
|
182
|
-
data = response.json()
|
|
183
|
-
|
|
184
|
-
return {
|
|
185
|
-
"status": response.status_code,
|
|
186
|
-
"data": data
|
|
187
|
-
}
|
|
188
|
-
`,
|
|
189
|
-
z.object({
|
|
190
|
-
status: z.number(),
|
|
191
|
-
data: z.any(),
|
|
192
|
-
}),
|
|
193
|
-
{
|
|
194
|
-
apiUrl: "https://api.example.com/data",
|
|
195
|
-
apiKey: ctx.env.API_KEY,
|
|
196
|
-
},
|
|
197
|
-
);
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
### Complex Data Processing
|
|
201
|
-
|
|
202
|
-
Process and aggregate data:
|
|
203
|
-
|
|
204
|
-
```typescript
|
|
205
|
-
const stats = await ctx.integrations.runtime.run(
|
|
206
|
-
`
|
|
207
|
-
import statistics
|
|
208
|
-
|
|
209
|
-
values = {{values}}
|
|
210
|
-
|
|
211
|
-
return {
|
|
212
|
-
"mean": statistics.mean(values),
|
|
213
|
-
"median": statistics.median(values),
|
|
214
|
-
"stdev": statistics.stdev(values),
|
|
215
|
-
"min": min(values),
|
|
216
|
-
"max": max(values)
|
|
217
|
-
}
|
|
218
|
-
`,
|
|
219
|
-
z.object({
|
|
220
|
-
mean: z.number(),
|
|
221
|
-
median: z.number(),
|
|
222
|
-
stdev: z.number(),
|
|
223
|
-
min: z.number(),
|
|
224
|
-
max: z.number(),
|
|
225
|
-
}),
|
|
226
|
-
{
|
|
227
|
-
values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
|
|
228
|
-
},
|
|
229
|
-
);
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
### Combining with Database Queries
|
|
233
|
-
|
|
234
|
-
Use Python to process database results:
|
|
235
|
-
|
|
236
|
-
```typescript
|
|
237
|
-
import { api, z, postgres, python } from "@superblocksteam/sdk-api";
|
|
238
|
-
|
|
239
|
-
const PROD_POSTGRES = "a1b2c3d4-5678-90ab-cdef-postgres01";
|
|
240
|
-
const PYTHON_RUNTIME = "a1b2c3d4-5678-90ab-cdef-python00001";
|
|
241
|
-
|
|
242
|
-
export default api({
|
|
243
|
-
name: "PythonExample",
|
|
244
|
-
integrations: {
|
|
245
|
-
db: postgres(PROD_POSTGRES),
|
|
246
|
-
runtime: python(PYTHON_RUNTIME),
|
|
247
|
-
},
|
|
248
|
-
input: z.object({
|
|
249
|
-
startDate: z.string(),
|
|
250
|
-
endDate: z.string(),
|
|
251
|
-
}),
|
|
252
|
-
|
|
253
|
-
output: z.object({
|
|
254
|
-
summary: z.string(),
|
|
255
|
-
totalSales: z.number(),
|
|
256
|
-
topProducts: z.array(z.string()),
|
|
257
|
-
}),
|
|
258
|
-
|
|
259
|
-
async run(ctx, { startDate, endDate }) {
|
|
260
|
-
// Query database via ctx.integrations.db
|
|
261
|
-
const sales = await ctx.integrations.db.query(
|
|
262
|
-
`SELECT product_id, product_name, amount
|
|
263
|
-
FROM sales
|
|
264
|
-
WHERE sale_date BETWEEN $1 AND $2`,
|
|
265
|
-
z.object({
|
|
266
|
-
product_id: z.string(),
|
|
267
|
-
product_name: z.string(),
|
|
268
|
-
amount: z.number(),
|
|
269
|
-
}),
|
|
270
|
-
[startDate, endDate],
|
|
271
|
-
);
|
|
272
|
-
|
|
273
|
-
// Process with Python via ctx.integrations.runtime
|
|
274
|
-
const analysis = await ctx.integrations.runtime.run(
|
|
275
|
-
`
|
|
276
|
-
sales_data = {{salesData}}
|
|
277
|
-
|
|
278
|
-
# Group by product
|
|
279
|
-
from collections import defaultdict
|
|
280
|
-
product_totals = defaultdict(float)
|
|
281
|
-
|
|
282
|
-
for sale in sales_data:
|
|
283
|
-
product_totals[sale["product_name"]] += sale["amount"]
|
|
284
|
-
|
|
285
|
-
# Get top products
|
|
286
|
-
sorted_products = sorted(
|
|
287
|
-
product_totals.items(),
|
|
288
|
-
key=lambda x: x[1],
|
|
289
|
-
reverse=True
|
|
290
|
-
)
|
|
291
|
-
top_5 = [p[0] for p in sorted_products[:5]]
|
|
292
|
-
|
|
293
|
-
total = sum(product_totals.values())
|
|
294
|
-
|
|
295
|
-
return {
|
|
296
|
-
"summary": f"Analyzed {len(sales_data)} sales across {len(product_totals)} products",
|
|
297
|
-
"totalSales": total,
|
|
298
|
-
"topProducts": top_5
|
|
299
|
-
}
|
|
300
|
-
`,
|
|
301
|
-
z.object({
|
|
302
|
-
summary: z.string(),
|
|
303
|
-
totalSales: z.number(),
|
|
304
|
-
topProducts: z.array(z.string()),
|
|
305
|
-
}),
|
|
306
|
-
{
|
|
307
|
-
salesData: sales,
|
|
308
|
-
},
|
|
309
|
-
);
|
|
310
|
-
|
|
311
|
-
return analysis;
|
|
312
|
-
},
|
|
313
|
-
});
|
|
314
|
-
```
|
|
315
|
-
|
|
316
|
-
## Trace Metadata
|
|
317
|
-
|
|
318
|
-
All methods accept an optional `metadata` parameter as the last argument for diagnostics labeling. See the [root SDK README](../../../README.md#trace-metadata) for details.
|
|
319
|
-
|
|
320
|
-
## Error Handling
|
|
321
|
-
|
|
322
|
-
The client throws `CodeExecutionError` when execution or validation fails:
|
|
323
|
-
|
|
324
|
-
```typescript
|
|
325
|
-
import { CodeExecutionError } from "@superblocksteam/sdk-api";
|
|
326
|
-
|
|
327
|
-
try {
|
|
328
|
-
const result = await ctx.integrations.runtime.run(
|
|
329
|
-
`
|
|
330
|
-
x = {{value}}
|
|
331
|
-
return {"result": x * 2}
|
|
332
|
-
`,
|
|
333
|
-
z.object({ result: z.number() }),
|
|
334
|
-
{ value: 10 },
|
|
335
|
-
);
|
|
336
|
-
} catch (error) {
|
|
337
|
-
if (error instanceof CodeExecutionError) {
|
|
338
|
-
console.error("Python execution failed:", error.message);
|
|
339
|
-
|
|
340
|
-
if (error.details?.zodError) {
|
|
341
|
-
// Validation error - result didn't match schema
|
|
342
|
-
console.error("Validation errors:", error.details.zodError.issues);
|
|
343
|
-
console.error("Actual result:", error.details.result);
|
|
344
|
-
} else if (error.details?.originalError) {
|
|
345
|
-
// Runtime error in Python code
|
|
346
|
-
console.error("Python error:", error.details.originalError);
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
```
|
|
351
|
-
|
|
352
|
-
## Common Patterns
|
|
353
|
-
|
|
354
|
-
### Environment Variables
|
|
355
|
-
|
|
356
|
-
Access environment variables in Python:
|
|
357
|
-
|
|
358
|
-
```typescript
|
|
359
|
-
const result = await ctx.integrations.runtime.run(
|
|
360
|
-
`
|
|
361
|
-
# apiKey and environment are directly available as Python variables
|
|
362
|
-
return {
|
|
363
|
-
"configured": apiKey is not None,
|
|
364
|
-
"environment": environment
|
|
365
|
-
}
|
|
366
|
-
`,
|
|
367
|
-
z.object({
|
|
368
|
-
configured: z.boolean(),
|
|
369
|
-
environment: z.string(),
|
|
370
|
-
}),
|
|
371
|
-
{
|
|
372
|
-
apiKey: ctx.env.API_KEY,
|
|
373
|
-
environment: ctx.env.NODE_ENV,
|
|
374
|
-
},
|
|
375
|
-
);
|
|
376
|
-
```
|
|
377
|
-
|
|
378
|
-
### JSON Processing
|
|
379
|
-
|
|
380
|
-
Work with JSON data:
|
|
381
|
-
|
|
382
|
-
```typescript
|
|
383
|
-
const processed = await ctx.integrations.runtime.run(
|
|
384
|
-
`
|
|
385
|
-
import json
|
|
386
|
-
|
|
387
|
-
json_str = {{jsonString}}
|
|
388
|
-
data = json.loads(json_str)
|
|
389
|
-
|
|
390
|
-
# Modify data
|
|
391
|
-
data["processed"] = True
|
|
392
|
-
data["timestamp"] = 1234567890
|
|
393
|
-
|
|
394
|
-
return {"result": json.dumps(data)}
|
|
395
|
-
`,
|
|
396
|
-
z.object({
|
|
397
|
-
result: z.string(),
|
|
398
|
-
}),
|
|
399
|
-
{
|
|
400
|
-
jsonString: JSON.stringify({ foo: "bar" }),
|
|
401
|
-
},
|
|
402
|
-
);
|
|
403
|
-
```
|
|
404
|
-
|
|
405
|
-
## Best Practices
|
|
406
|
-
|
|
407
|
-
### 1. Keep Python Code Focused
|
|
408
|
-
|
|
409
|
-
Python steps should perform data transformation and processing. Use integration clients for I/O operations:
|
|
410
|
-
|
|
411
|
-
✅ **Good:**
|
|
412
|
-
|
|
413
|
-
```typescript
|
|
414
|
-
// Fetch data with integration client
|
|
415
|
-
const data = await postgres.query(...);
|
|
416
|
-
|
|
417
|
-
// Transform with Python
|
|
418
|
-
const processed = await ctx.integrations.runtime.run(`...transform logic...`, schema, { data });
|
|
419
|
-
```
|
|
420
|
-
|
|
421
|
-
❌ **Avoid:**
|
|
422
|
-
|
|
423
|
-
```typescript
|
|
424
|
-
// Don't make database connections in Python
|
|
425
|
-
await ctx.integrations.runtime.run(
|
|
426
|
-
`
|
|
427
|
-
import psycopg2
|
|
428
|
-
conn = psycopg2.connect(...) # Avoid this
|
|
429
|
-
...
|
|
430
|
-
`,
|
|
431
|
-
schema,
|
|
432
|
-
);
|
|
433
|
-
```
|
|
434
|
-
|
|
435
|
-
### 2. Validate All Inputs and Outputs
|
|
436
|
-
|
|
437
|
-
Always provide a schema to validate Python return values:
|
|
438
|
-
|
|
439
|
-
✅ **Good:**
|
|
440
|
-
|
|
441
|
-
```typescript
|
|
442
|
-
const result = await ctx.integrations.runtime.run(
|
|
443
|
-
code,
|
|
444
|
-
z.object({
|
|
445
|
-
value: z.number(),
|
|
446
|
-
message: z.string(),
|
|
447
|
-
}),
|
|
448
|
-
bindings,
|
|
449
|
-
);
|
|
450
|
-
```
|
|
451
|
-
|
|
452
|
-
❌ **Avoid:**
|
|
453
|
-
|
|
454
|
-
```typescript
|
|
455
|
-
// Missing schema - no type safety!
|
|
456
|
-
const result = await ctx.integrations.runtime.run(code, z.any(), bindings);
|
|
457
|
-
```
|
|
458
|
-
|
|
459
|
-
### 3. Use Meaningful Binding Names
|
|
460
|
-
|
|
461
|
-
Choose clear binding names that match Python conventions:
|
|
462
|
-
|
|
463
|
-
✅ **Good:**
|
|
464
|
-
|
|
465
|
-
```typescript
|
|
466
|
-
{
|
|
467
|
-
user_id: "123",
|
|
468
|
-
start_date: "2024-01-01",
|
|
469
|
-
is_active: true
|
|
470
|
-
}
|
|
471
|
-
```
|
|
472
|
-
|
|
473
|
-
❌ **Avoid:**
|
|
474
|
-
|
|
475
|
-
```typescript
|
|
476
|
-
{
|
|
477
|
-
userId: "123", // Mixing camelCase in Python
|
|
478
|
-
StartDate: "...", // PascalCase doesn't fit Python
|
|
479
|
-
}
|
|
480
|
-
```
|
|
481
|
-
|
|
482
|
-
### 4. Handle Errors Gracefully
|
|
483
|
-
|
|
484
|
-
Use try/catch and check for specific error types:
|
|
485
|
-
|
|
486
|
-
```typescript
|
|
487
|
-
try {
|
|
488
|
-
const result = await ctx.integrations.runtime.run(code, schema, bindings);
|
|
489
|
-
return result;
|
|
490
|
-
} catch (error) {
|
|
491
|
-
if (error instanceof CodeExecutionError) {
|
|
492
|
-
ctx.log.error("Python execution failed", {
|
|
493
|
-
code: error.details?.code,
|
|
494
|
-
bindings: error.details?.bindings,
|
|
495
|
-
});
|
|
496
|
-
// Provide fallback or rethrow
|
|
497
|
-
throw new Error("Data processing failed");
|
|
498
|
-
}
|
|
499
|
-
throw error;
|
|
500
|
-
}
|
|
501
|
-
```
|
|
502
|
-
|
|
503
|
-
## Troubleshooting
|
|
504
|
-
|
|
505
|
-
### "Python execution result validation failed"
|
|
506
|
-
|
|
507
|
-
The return value from your Python code doesn't match the provided schema.
|
|
508
|
-
|
|
509
|
-
**Solution:** Check that your Python `return` statement matches the schema exactly:
|
|
510
|
-
|
|
511
|
-
```typescript
|
|
512
|
-
// Schema expects
|
|
513
|
-
z.object({ count: z.number(), items: z.array(z.string()) });
|
|
514
|
-
|
|
515
|
-
// Python must return
|
|
516
|
-
return { count: 5, items: ["a", "b", "c"] };
|
|
517
|
-
```
|
|
518
|
-
|
|
519
|
-
### "Python execution failed"
|
|
520
|
-
|
|
521
|
-
The Python code had a runtime error.
|
|
522
|
-
|
|
523
|
-
**Common causes:**
|
|
524
|
-
|
|
525
|
-
- Syntax errors in Python code
|
|
526
|
-
- Undefined variables or bindings
|
|
527
|
-
- Import errors for unavailable packages
|
|
528
|
-
- Division by zero or other runtime exceptions
|
|
529
|
-
|
|
530
|
-
**Solution:** Test Python code snippets independently, check that all `{{}}` bindings are provided.
|
|
531
|
-
|
|
532
|
-
### Missing Binding Values
|
|
533
|
-
|
|
534
|
-
If a binding is `undefined` or `null`, the orchestrator may handle it differently.
|
|
535
|
-
|
|
536
|
-
**Solution:** Always provide explicit values for bindings:
|
|
537
|
-
|
|
538
|
-
```typescript
|
|
539
|
-
// In your run function with destructured input:
|
|
540
|
-
async run(ctx, { value, name }) {
|
|
541
|
-
const result = await ctx.integrations.runtime.run(
|
|
542
|
-
code,
|
|
543
|
-
schema,
|
|
544
|
-
{
|
|
545
|
-
value: value ?? 0, // Provide default
|
|
546
|
-
name: name || "Unknown"
|
|
547
|
-
}
|
|
548
|
-
);
|
|
549
|
-
}
|
|
550
|
-
```
|
|
551
|
-
|
|
552
|
-
## Available Python Packages
|
|
553
|
-
|
|
554
|
-
The Python runtime includes:
|
|
555
|
-
|
|
556
|
-
- Python 3.x standard library
|
|
557
|
-
- `requests` - HTTP library
|
|
558
|
-
- Common data science packages (check with your Superblocks administrator for the full list)
|
|
559
|
-
|
|
560
|
-
For specific package requirements, consult your Superblocks environment documentation.
|
|
561
|
-
|
|
562
|
-
## See Also
|
|
563
|
-
|
|
564
|
-
- [API Reference](../../../README.md) - Main SDK documentation
|
|
565
|
-
- [Error Handling](../../../README.md#error-handling) - Error types and handling strategies
|
|
566
|
-
- [Best Practices](../../../README.md#best-practices) - General SDK best practices
|