@databricks/appkit-ui 0.26.1 → 0.27.1
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/CLAUDE.md +7 -0
- package/NOTICE.md +1 -0
- package/dist/schemas/plugin-manifest.generated.d.ts +5 -5
- package/dist/schemas/plugin-manifest.generated.d.ts.map +1 -1
- package/docs/api/appkit/Interface.BasePluginConfig.md +4 -0
- package/docs/api/appkit/Interface.IJobsConfig.md +86 -0
- package/docs/api/appkit/Interface.JobAPI.md +163 -0
- package/docs/api/appkit/Interface.JobConfig.md +36 -0
- package/docs/api/appkit/Interface.JobsConnectorConfig.md +10 -0
- package/docs/api/appkit/TypeAlias.JobHandle.md +29 -0
- package/docs/api/appkit/TypeAlias.JobsExport.md +34 -0
- package/docs/api/appkit.md +6 -0
- package/docs/plugins/jobs.md +252 -0
- package/docs/plugins.md +2 -1
- package/llms.txt +7 -0
- package/package.json +1 -1
- package/sbom.cdx.json +1 -1
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
# Jobs plugin
|
|
2
|
+
|
|
3
|
+
Trigger and monitor [Databricks Lakeflow Jobs](https://docs.databricks.com/en/jobs/index.html) from your AppKit application.
|
|
4
|
+
|
|
5
|
+
**Key features:**
|
|
6
|
+
|
|
7
|
+
* Multi-job support with named job keys
|
|
8
|
+
* Auto-discovery of jobs from environment variables
|
|
9
|
+
* Run-and-wait with SSE streaming status updates
|
|
10
|
+
* Parameter validation with Zod schemas
|
|
11
|
+
* Task-type-aware parameter mapping (notebook, python\_wheel, sql, etc.)
|
|
12
|
+
* Optional on-behalf-of (OBO) user execution via `.asUser(req)`
|
|
13
|
+
|
|
14
|
+
## Basic usage[](#basic-usage "Direct link to Basic usage")
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
import { createApp, server, jobs } from "@databricks/appkit";
|
|
18
|
+
|
|
19
|
+
await createApp({
|
|
20
|
+
plugins: [server(), jobs()],
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
With no explicit `jobs` config, the plugin reads `DATABRICKS_JOB_ID` from the environment and registers it under the `default` key.
|
|
26
|
+
|
|
27
|
+
## Configuration options[](#configuration-options "Direct link to Configuration options")
|
|
28
|
+
|
|
29
|
+
| Option | Type | Default | Description |
|
|
30
|
+
| ---------------- | --------------------------- | ------- | ----------------------------------------------------- |
|
|
31
|
+
| `timeout` | `number` | `60000` | Default timeout for Jobs API calls in ms |
|
|
32
|
+
| `pollIntervalMs` | `number` | `5000` | Poll interval for `runAndWait` in ms |
|
|
33
|
+
| `jobs` | `Record<string, JobConfig>` | — | Named jobs to expose. Each key becomes a job accessor |
|
|
34
|
+
|
|
35
|
+
### Per-job config (`JobConfig`)[](#per-job-config-jobconfig "Direct link to per-job-config-jobconfig")
|
|
36
|
+
|
|
37
|
+
| Option | Type | Default | Description |
|
|
38
|
+
| ------------- | ----------- | -------- | ------------------------------------------- |
|
|
39
|
+
| `waitTimeout` | `number` | `600000` | Override the polling timeout for this job |
|
|
40
|
+
| `taskType` | `TaskType` | — | Task type for automatic parameter mapping |
|
|
41
|
+
| `params` | `z.ZodType` | — | Zod schema for runtime parameter validation |
|
|
42
|
+
|
|
43
|
+
## Environment variables[](#environment-variables "Direct link to Environment variables")
|
|
44
|
+
|
|
45
|
+
### Single-job mode[](#single-job-mode "Direct link to Single-job mode")
|
|
46
|
+
|
|
47
|
+
Set `DATABRICKS_JOB_ID` to expose one job under the `default` key:
|
|
48
|
+
|
|
49
|
+
```env
|
|
50
|
+
DATABRICKS_JOB_ID=123456
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
const handle = AppKit.jobs("default");
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Multi-job mode[](#multi-job-mode "Direct link to Multi-job mode")
|
|
60
|
+
|
|
61
|
+
Set `DATABRICKS_JOB_<NAME>` for each job:
|
|
62
|
+
|
|
63
|
+
```env
|
|
64
|
+
DATABRICKS_JOB_ETL=123456
|
|
65
|
+
DATABRICKS_JOB_ML=789012
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
const etl = AppKit.jobs("etl");
|
|
71
|
+
const ml = AppKit.jobs("ml");
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Environment variable names are uppercased; job keys are lowercased. Jobs discovered from the environment are merged with any explicit `jobs` config — explicit config wins.
|
|
76
|
+
|
|
77
|
+
## Parameter validation[](#parameter-validation "Direct link to Parameter validation")
|
|
78
|
+
|
|
79
|
+
Use `params` to enforce a Zod schema at runtime. Invalid parameters are rejected with a `400` before the job is triggered:
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
import { z } from "zod";
|
|
83
|
+
|
|
84
|
+
jobs({
|
|
85
|
+
jobs: {
|
|
86
|
+
etl: {
|
|
87
|
+
params: z.object({
|
|
88
|
+
startDate: z.string(),
|
|
89
|
+
endDate: z.string(),
|
|
90
|
+
dryRun: z.boolean().optional(),
|
|
91
|
+
}),
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Task type mapping[](#task-type-mapping "Direct link to Task type mapping")
|
|
99
|
+
|
|
100
|
+
When `taskType` is set, the plugin maps validated parameters to the correct SDK request fields automatically:
|
|
101
|
+
|
|
102
|
+
| Task type | SDK field | Parameter shape |
|
|
103
|
+
| --------------- | --------------------- | --------------------------------------------------- |
|
|
104
|
+
| `notebook` | `notebook_params` | `Record<string, string>` — values coerced to string |
|
|
105
|
+
| `python_wheel` | `python_named_params` | `Record<string, string>` — values coerced to string |
|
|
106
|
+
| `python_script` | `python_params` | `{ args: string[] }` — positional args |
|
|
107
|
+
| `spark_jar` | `jar_params` | `{ args: string[] }` — positional args |
|
|
108
|
+
| `sql` | `sql_params` | `Record<string, string>` — values coerced to string |
|
|
109
|
+
| `dbt` | — | No parameters accepted |
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
jobs({
|
|
113
|
+
jobs: {
|
|
114
|
+
etl: {
|
|
115
|
+
taskType: "notebook",
|
|
116
|
+
params: z.object({
|
|
117
|
+
startDate: z.string(),
|
|
118
|
+
endDate: z.string(),
|
|
119
|
+
}),
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
When `taskType` is omitted, parameters are passed through to the SDK as-is.
|
|
127
|
+
|
|
128
|
+
## Execution context[](#execution-context "Direct link to Execution context")
|
|
129
|
+
|
|
130
|
+
HTTP routes run as the **app's service principal** by default. Jobs are typically shared infrastructure, and the app's resource binding (`databricks.yml`) grants `CAN_MANAGE_RUN` to the SP — so users trigger runs without needing individual grants.
|
|
131
|
+
|
|
132
|
+
Per-run attribution in the Jobs UI will show the app's SP, not the human user. If you need user-level attribution (or want the Databricks permission check to use the user's grants), opt in to OBO explicitly in a custom handler via `.asUser(req)`:
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
// Default: runs as the app's service principal
|
|
136
|
+
const result = await AppKit.jobs("etl").runNow({ startDate: "2025-01-01" });
|
|
137
|
+
|
|
138
|
+
// Opt-in: runs as the logged-in user (requires `jobs.jobs` in
|
|
139
|
+
// `databricks.yml` user_api_scopes AND the user's own CAN_MANAGE_RUN grant)
|
|
140
|
+
const result = await AppKit.jobs("etl").asUser(req).runNow({ startDate: "2025-01-01" });
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## HTTP endpoints[](#http-endpoints "Direct link to HTTP endpoints")
|
|
145
|
+
|
|
146
|
+
All routes are mounted under `/api/jobs`.
|
|
147
|
+
|
|
148
|
+
### Trigger a run[](#trigger-a-run "Direct link to Trigger a run")
|
|
149
|
+
|
|
150
|
+
```text
|
|
151
|
+
POST /api/jobs/:jobKey/run
|
|
152
|
+
Content-Type: application/json
|
|
153
|
+
|
|
154
|
+
{ "params": { "startDate": "2025-01-01" } }
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Returns `{ "runId": 12345 }`.
|
|
159
|
+
|
|
160
|
+
Add `?stream=true` to receive SSE status updates that poll until the run completes:
|
|
161
|
+
|
|
162
|
+
```text
|
|
163
|
+
POST /api/jobs/:jobKey/run?stream=true
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Each SSE event contains `{ status, timestamp, run }`.
|
|
168
|
+
|
|
169
|
+
### List runs[](#list-runs "Direct link to List runs")
|
|
170
|
+
|
|
171
|
+
```text
|
|
172
|
+
GET /api/jobs/:jobKey/runs?limit=20
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Returns `{ "runs": [...] }`. Limit is clamped to 1–100, default 20.
|
|
177
|
+
|
|
178
|
+
### Get run details[](#get-run-details "Direct link to Get run details")
|
|
179
|
+
|
|
180
|
+
```text
|
|
181
|
+
GET /api/jobs/:jobKey/runs/:runId
|
|
182
|
+
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Get latest status[](#get-latest-status "Direct link to Get latest status")
|
|
186
|
+
|
|
187
|
+
```text
|
|
188
|
+
GET /api/jobs/:jobKey/status
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Returns `{ "status": "TERMINATED", "run": { ... } }` for the most recent run.
|
|
193
|
+
|
|
194
|
+
### Cancel a run[](#cancel-a-run "Direct link to Cancel a run")
|
|
195
|
+
|
|
196
|
+
```text
|
|
197
|
+
DELETE /api/jobs/:jobKey/runs/:runId
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Returns `204 No Content` on success.
|
|
202
|
+
|
|
203
|
+
## Programmatic access[](#programmatic-access "Direct link to Programmatic access")
|
|
204
|
+
|
|
205
|
+
The plugin exports a callable that selects a job by key:
|
|
206
|
+
|
|
207
|
+
```ts
|
|
208
|
+
const AppKit = await createApp({
|
|
209
|
+
plugins: [
|
|
210
|
+
server(),
|
|
211
|
+
jobs({
|
|
212
|
+
jobs: {
|
|
213
|
+
etl: { taskType: "notebook" },
|
|
214
|
+
},
|
|
215
|
+
}),
|
|
216
|
+
],
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
const etl = AppKit.jobs("etl");
|
|
220
|
+
|
|
221
|
+
// Trigger a run
|
|
222
|
+
const result = await etl.runNow({ startDate: "2025-01-01" });
|
|
223
|
+
if (result.ok) {
|
|
224
|
+
console.log("Run ID:", result.data.run_id);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Trigger and poll until completion
|
|
228
|
+
for await (const status of etl.runAndWait({ startDate: "2025-01-01" })) {
|
|
229
|
+
console.log(status.status); // "PENDING", "RUNNING", "TERMINATED", etc.
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Read operations
|
|
233
|
+
await etl.lastRun();
|
|
234
|
+
await etl.listRuns({ limit: 10 });
|
|
235
|
+
await etl.getRun(12345);
|
|
236
|
+
await etl.getRunOutput(12345);
|
|
237
|
+
await etl.getJob();
|
|
238
|
+
|
|
239
|
+
// Cancel
|
|
240
|
+
await etl.cancelRun(12345);
|
|
241
|
+
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
All methods return [`ExecutionResult<T>`](./docs/api/appkit/TypeAlias.ExecutionResult.md) — check `result.ok` before accessing `result.data`.
|
|
245
|
+
|
|
246
|
+
## Execution defaults[](#execution-defaults "Direct link to Execution defaults")
|
|
247
|
+
|
|
248
|
+
| Tier | Cache | Retry | Timeout | Methods |
|
|
249
|
+
| ------ | -------- | ---------------------- | ------- | --------------------------------------------------------- |
|
|
250
|
+
| Read | 60s TTL | 3 attempts, 1s backoff | 30s | `getRun`, `getJob`, `listRuns`, `lastRun`, `getRunOutput` |
|
|
251
|
+
| Write | Disabled | Disabled | 120s | `runNow`, `cancelRun` |
|
|
252
|
+
| Stream | Disabled | Disabled | 600s | `runAndWait` (SSE polling) |
|
package/docs/plugins.md
CHANGED
|
@@ -9,7 +9,7 @@ For complete API documentation, see the [`Plugin`](./docs/api/appkit/Class.Plugi
|
|
|
9
9
|
Configure plugins when creating your AppKit instance:
|
|
10
10
|
|
|
11
11
|
```typescript
|
|
12
|
-
import { createApp, server, analytics, genie, files } from "@databricks/appkit";
|
|
12
|
+
import { createApp, server, analytics, genie, files, jobs } from "@databricks/appkit";
|
|
13
13
|
|
|
14
14
|
const AppKit = await createApp({
|
|
15
15
|
plugins: [
|
|
@@ -17,6 +17,7 @@ const AppKit = await createApp({
|
|
|
17
17
|
analytics(),
|
|
18
18
|
genie(),
|
|
19
19
|
files(),
|
|
20
|
+
jobs(),
|
|
20
21
|
],
|
|
21
22
|
});
|
|
22
23
|
|
package/llms.txt
CHANGED
|
@@ -48,6 +48,7 @@ npx @databricks/appkit docs <query>
|
|
|
48
48
|
- [Execution context](./docs/plugins/execution-context.md): AppKit manages Databricks authentication via two contexts:
|
|
49
49
|
- [Files plugin](./docs/plugins/files.md): File operations against Databricks Unity Catalog Volumes. Supports listing, reading, downloading, uploading, deleting, and previewing files with built-in caching, retry, and timeout handling via the execution interceptor pipeline.
|
|
50
50
|
- [Genie plugin](./docs/plugins/genie.md): Integrates Databricks AI/BI Genie spaces into your AppKit application, enabling natural language data queries via a conversational interface.
|
|
51
|
+
- [Jobs plugin](./docs/plugins/jobs.md): Trigger and monitor Databricks Lakeflow Jobs from your AppKit application.
|
|
51
52
|
- [Lakebase plugin](./docs/plugins/lakebase.md): Provides a PostgreSQL connection pool for Databricks Lakebase Autoscaling with automatic OAuth token refresh.
|
|
52
53
|
- [Model Serving plugin](./docs/plugins/model-serving.md): Provides an authenticated proxy to Databricks Model Serving endpoints, with invoke and streaming support.
|
|
53
54
|
- [Plugin management](./docs/plugins/plugin-management.md): AppKit includes a CLI for managing plugins. All commands are available under npx @databricks/appkit plugin.
|
|
@@ -93,7 +94,11 @@ npx @databricks/appkit docs <query>
|
|
|
93
94
|
- [Interface: FilePolicyUser](./docs/api/appkit/Interface.FilePolicyUser.md): Minimal user identity passed to the policy function.
|
|
94
95
|
- [Interface: FileResource](./docs/api/appkit/Interface.FileResource.md): Describes the file or directory being acted upon.
|
|
95
96
|
- [Interface: GenerateDatabaseCredentialRequest](./docs/api/appkit/Interface.GenerateDatabaseCredentialRequest.md): Request parameters for generating database OAuth credentials
|
|
97
|
+
- [Interface: IJobsConfig](./docs/api/appkit/Interface.IJobsConfig.md): Configuration for the Jobs plugin.
|
|
96
98
|
- [Interface: ITelemetry](./docs/api/appkit/Interface.ITelemetry.md): Plugin-facing interface for OpenTelemetry instrumentation.
|
|
99
|
+
- [Interface: JobAPI](./docs/api/appkit/Interface.JobAPI.md): User-facing API for a single configured job.
|
|
100
|
+
- [Interface: JobConfig](./docs/api/appkit/Interface.JobConfig.md): Per-job configuration options.
|
|
101
|
+
- [Interface: JobsConnectorConfig](./docs/api/appkit/Interface.JobsConnectorConfig.md): Properties
|
|
97
102
|
- [Interface: LakebasePoolConfig](./docs/api/appkit/Interface.LakebasePoolConfig.md): Configuration for creating a Lakebase connection pool
|
|
98
103
|
- [Interface: PluginManifest<TName>](./docs/api/appkit/Interface.PluginManifest.md): Plugin manifest that declares metadata and resource requirements.
|
|
99
104
|
- [Interface: RequestedClaims](./docs/api/appkit/Interface.RequestedClaims.md): Optional claims for fine-grained Unity Catalog table permissions
|
|
@@ -111,6 +116,8 @@ npx @databricks/appkit docs <query>
|
|
|
111
116
|
- [Type Alias: FileAction](./docs/api/appkit/TypeAlias.FileAction.md): Every action the files plugin can perform.
|
|
112
117
|
- [Type Alias: FilePolicy()](./docs/api/appkit/TypeAlias.FilePolicy.md): A policy function that decides whether user may perform action on
|
|
113
118
|
- [Type Alias: IAppRouter](./docs/api/appkit/TypeAlias.IAppRouter.md): Express router type for plugin route registration
|
|
119
|
+
- [Type Alias: JobHandle](./docs/api/appkit/TypeAlias.JobHandle.md): Job handle returned by appkit.jobs("etl").
|
|
120
|
+
- [Type Alias: JobsExport()](./docs/api/appkit/TypeAlias.JobsExport.md): Public API shape of the jobs plugin.
|
|
114
121
|
- [Type Alias: PluginData<T, U, N>](./docs/api/appkit/TypeAlias.PluginData.md): Tuple of plugin class, config, and name. Created by toPlugin() and passed to createApp().
|
|
115
122
|
- [Type Alias: ResourcePermission](./docs/api/appkit/TypeAlias.ResourcePermission.md): Union of all possible permission levels across all resource types.
|
|
116
123
|
- [Type Alias: ServingFactory](./docs/api/appkit/TypeAlias.ServingFactory.md): Factory function returned by AppKit.serving.
|