refactor: delete contracts
This commit is contained in:
@@ -1,15 +0,0 @@
|
|||||||
# Contracts
|
|
||||||
|
|
||||||
模块接口契约公共目录:
|
|
||||||
|
|
||||||
```text
|
|
||||||
openapi/ HTTP OpenAPI 3 契约
|
|
||||||
events/ MySQL Outbox 内部事件 JSON Schema
|
|
||||||
runtime/ Runtime Adapter 契约
|
|
||||||
locks/ Notebook 编辑锁契约
|
|
||||||
```
|
|
||||||
|
|
||||||
各服务实现必须以本目录中的版本化契约为准。
|
|
||||||
|
|
||||||
快速 Demo 的跨模块边界、状态枚举和事件路由统一见
|
|
||||||
`demo-core-v1.md`。
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
"""Executable cross-service contracts."""
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
# 快速 Demo 核心契约 V1
|
|
||||||
|
|
||||||
冻结日期:2026-07-27
|
|
||||||
状态:`frozen-target`
|
|
||||||
|
|
||||||
## 1. 契约边界
|
|
||||||
|
|
||||||
Demo 公共 HTTP API 由两部分共同组成:
|
|
||||||
|
|
||||||
1. `openapi/platform-api-v1.yaml`:已经运行的脚本、稳定版本详情、数据资源和文件编辑锁接口。
|
|
||||||
2. `openapi/demo-core-extension-v1.yaml`:第 15 小步冻结、后续小步实现的上下文、Jupyter 票据、稳定版本列表、调度和运行查询接口。
|
|
||||||
|
|
||||||
内部 Storage 与 Runtime 接口继续分别以
|
|
||||||
`openapi/storage-api-internal-v1.yaml` 和
|
|
||||||
`openapi/runtime-api-internal-v1.yaml` 为准。
|
|
||||||
|
|
||||||
## 2. 不可变约束
|
|
||||||
|
|
||||||
- 主标识使用 ULID;调度节点只引用不可变的 `versions_id`。
|
|
||||||
- 当前认证上下文由 `X-User-ID`、`X-Workspace-ID` 提供;以后换成 JWT 时不得改变业务 DTO。
|
|
||||||
- 修改调度方案必须提交 `workflow_version`,冲突返回 `412`。
|
|
||||||
- 创建调度、立即运行、启停和取消使用 `Idempotency-Key`。
|
|
||||||
- `schedule_runs.schedule_snapshot` 固化本次执行 DAG,后续编辑不影响已创建的运行。
|
|
||||||
- 浏览器不能拿到 Jupyter 内部 Token,只能获得短期访问 Cookie。
|
|
||||||
|
|
||||||
## 3. 状态值
|
|
||||||
|
|
||||||
- 调度运行:`queued / running / succeeded / failed / cancelled / timed_out`
|
|
||||||
- 节点运行:`queued / running / succeeded / failed / skipped / cancelled / timed_out`
|
|
||||||
- 失败策略:`stop / continue`
|
|
||||||
- 触发类型:`manual / cron / api / retry`
|
|
||||||
|
|
||||||
## 4. MySQL Outbox 与 HTTP 推送
|
|
||||||
|
|
||||||
| 事件 | 写入方 | 处理方 |
|
|
||||||
|---|---|---|
|
|
||||||
| `schedule.run.requested` | Backend / Cron Dispatcher | Schedule Executor |
|
|
||||||
| `job.node.execute` | Schedule Executor | Schedule Executor Worker |
|
|
||||||
| `job.node.finished` | Schedule Executor Worker | Schedule Executor |
|
|
||||||
|
|
||||||
业务事务先写 `outbox_events`。Backend 对“立即运行”执行一次内部 HTTP 推送,
|
|
||||||
Executor 同时轮询 MySQL 作为兜底;`consumer_inbox` 防止同一事件重复执行。
|
|
||||||
|
|
||||||
## 5. 模块所有权
|
|
||||||
|
|
||||||
| 模块 | 拥有的数据与职责 |
|
|
||||||
|---|---|
|
|
||||||
| Platform API | 脚本、稳定版本、调度定义、运行查询、Outbox 写入 |
|
|
||||||
| Runtime Manager | Workspace/Jupyter 生命周期与内部运行态 |
|
|
||||||
| Nginx | 统一入口、Jupyter HTTP/WebSocket 代理 |
|
|
||||||
| Schedule Orchestrator | 消费调度请求、解析 DAG、推进节点状态 |
|
|
||||||
| Job Worker | 读取稳定版本、执行节点、保存日志/结果、报告终态 |
|
|
||||||
| Storage Service | RustFS 对象元数据与预签名访问 |
|
|
||||||
|
|
||||||
模块间不得复制定义 DTO、状态枚举、错误结构或事件字段;契约变更必须先
|
|
||||||
升级本目录中的版本化文件。
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
# Database Event Schemas
|
|
||||||
|
|
||||||
内部事件以 JSON Schema Draft 2020-12 定义:
|
|
||||||
|
|
||||||
- `event-envelope-v1.json`:公共事件信封;
|
|
||||||
- `schedule-run-requested-v1.json`:请求启动一次调度运行;
|
|
||||||
- `job-node-execute-v1.json`:请求执行一个稳定版本节点;
|
|
||||||
- `job-node-finished-v1.json`:节点终态。
|
|
||||||
|
|
||||||
事件先随业务事务写入 MySQL `outbox_events`,Schedule Executor 直接轮询处理;
|
|
||||||
`consumer_inbox` 提供幂等保护。字段和状态值不得在生产者或消费者中另行定义。
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
||||||
"$id": "event-envelope-v1.json",
|
|
||||||
"title": "Model Platform Event Envelope V1",
|
|
||||||
"description": "MySQL Outbox 中所有内部业务事件共用的不可变信封。",
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": false,
|
|
||||||
"required": [
|
|
||||||
"event_id",
|
|
||||||
"event_type",
|
|
||||||
"schema_version",
|
|
||||||
"occurred_at",
|
|
||||||
"producer",
|
|
||||||
"trace_id",
|
|
||||||
"aggregate_type",
|
|
||||||
"aggregate_id",
|
|
||||||
"idempotency_key",
|
|
||||||
"payload"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"event_id": {
|
|
||||||
"$ref": "#/$defs/ulid"
|
|
||||||
},
|
|
||||||
"event_type": {
|
|
||||||
"type": "string",
|
|
||||||
"pattern": "^[a-z][a-z0-9]*(\\.[a-z][a-z0-9_]*)+$"
|
|
||||||
},
|
|
||||||
"schema_version": {
|
|
||||||
"const": 1
|
|
||||||
},
|
|
||||||
"occurred_at": {
|
|
||||||
"type": "string",
|
|
||||||
"format": "date-time"
|
|
||||||
},
|
|
||||||
"producer": {
|
|
||||||
"type": "string",
|
|
||||||
"minLength": 1,
|
|
||||||
"maxLength": 64
|
|
||||||
},
|
|
||||||
"trace_id": {
|
|
||||||
"type": "string",
|
|
||||||
"minLength": 1,
|
|
||||||
"maxLength": 64
|
|
||||||
},
|
|
||||||
"aggregate_type": {
|
|
||||||
"type": "string",
|
|
||||||
"minLength": 1,
|
|
||||||
"maxLength": 64
|
|
||||||
},
|
|
||||||
"aggregate_id": {
|
|
||||||
"type": "string",
|
|
||||||
"minLength": 1,
|
|
||||||
"maxLength": 128
|
|
||||||
},
|
|
||||||
"idempotency_key": {
|
|
||||||
"type": "string",
|
|
||||||
"minLength": 8,
|
|
||||||
"maxLength": 128
|
|
||||||
},
|
|
||||||
"payload": {
|
|
||||||
"type": "object"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"$defs": {
|
|
||||||
"ulid": {
|
|
||||||
"type": "string",
|
|
||||||
"minLength": 26,
|
|
||||||
"maxLength": 26,
|
|
||||||
"pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,125 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
||||||
"$id": "job-node-execute-v1.json",
|
|
||||||
"title": "Job Node Execute V1",
|
|
||||||
"description": "调度编排器请求 Job Worker 执行一个稳定版本节点。",
|
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"$ref": "event-envelope-v1.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"event_type": {
|
|
||||||
"const": "job.node.execute"
|
|
||||||
},
|
|
||||||
"aggregate_type": {
|
|
||||||
"const": "schedule_node_run"
|
|
||||||
},
|
|
||||||
"payload": {
|
|
||||||
"$ref": "job-node-execute-v1.json#/$defs/payload"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"$defs": {
|
|
||||||
"ulid": {
|
|
||||||
"type": "string",
|
|
||||||
"minLength": 26,
|
|
||||||
"maxLength": 26,
|
|
||||||
"pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
|
|
||||||
},
|
|
||||||
"payload": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": false,
|
|
||||||
"required": [
|
|
||||||
"workspace_id",
|
|
||||||
"run_id",
|
|
||||||
"node_run_id",
|
|
||||||
"node_id",
|
|
||||||
"versions_id",
|
|
||||||
"attempt_no",
|
|
||||||
"script_type",
|
|
||||||
"artifact_object_id",
|
|
||||||
"artifact_path",
|
|
||||||
"timeout_seconds",
|
|
||||||
"arguments"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"workspace_id": {
|
|
||||||
"$ref": "job-node-execute-v1.json#/$defs/ulid"
|
|
||||||
},
|
|
||||||
"run_id": {
|
|
||||||
"$ref": "job-node-execute-v1.json#/$defs/ulid"
|
|
||||||
},
|
|
||||||
"node_run_id": {
|
|
||||||
"$ref": "job-node-execute-v1.json#/$defs/ulid"
|
|
||||||
},
|
|
||||||
"node_id": {
|
|
||||||
"$ref": "job-node-execute-v1.json#/$defs/ulid"
|
|
||||||
},
|
|
||||||
"versions_id": {
|
|
||||||
"$ref": "job-node-execute-v1.json#/$defs/ulid"
|
|
||||||
},
|
|
||||||
"attempt_no": {
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 1,
|
|
||||||
"maximum": 11
|
|
||||||
},
|
|
||||||
"script_type": {
|
|
||||||
"enum": [
|
|
||||||
"python",
|
|
||||||
"notebook"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"artifact_object_id": {
|
|
||||||
"$ref": "job-node-execute-v1.json#/$defs/ulid"
|
|
||||||
},
|
|
||||||
"artifact_path": {
|
|
||||||
"type": "string",
|
|
||||||
"minLength": 1,
|
|
||||||
"maxLength": 1024
|
|
||||||
},
|
|
||||||
"timeout_seconds": {
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 1,
|
|
||||||
"maximum": 86400
|
|
||||||
},
|
|
||||||
"arguments": {
|
|
||||||
"type": "array",
|
|
||||||
"maxItems": 100,
|
|
||||||
"items": {
|
|
||||||
"type": "string",
|
|
||||||
"maxLength": 1000
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"examples": [
|
|
||||||
{
|
|
||||||
"event_id": "01K123456789ABCDEFGHJKMNPZ",
|
|
||||||
"event_type": "job.node.execute",
|
|
||||||
"schema_version": 1,
|
|
||||||
"occurred_at": "2026-07-27T08:00:01Z",
|
|
||||||
"producer": "schedule-orchestrator",
|
|
||||||
"trace_id": "req-demo-0001",
|
|
||||||
"aggregate_type": "schedule_node_run",
|
|
||||||
"aggregate_id": "01K123456789ABCDEFGHJKMNQ0",
|
|
||||||
"idempotency_key": "01K123456789ABCDEFGHJKMNQ0:1",
|
|
||||||
"payload": {
|
|
||||||
"workspace_id": "01K123456789ABCDEFGHJKMNPS",
|
|
||||||
"run_id": "01K123456789ABCDEFGHJKMNPR",
|
|
||||||
"node_run_id": "01K123456789ABCDEFGHJKMNQ0",
|
|
||||||
"node_id": "01K123456789ABCDEFGHJKMNPW",
|
|
||||||
"versions_id": "01K123456789ABCDEFGHJKMNPX",
|
|
||||||
"attempt_no": 1,
|
|
||||||
"script_type": "python",
|
|
||||||
"artifact_object_id": "01K123456789ABCDEFGHJKMNPY",
|
|
||||||
"artifact_path": "versions/prepare/v1.py",
|
|
||||||
"timeout_seconds": 600,
|
|
||||||
"arguments": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,162 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
||||||
"$id": "job-node-finished-v1.json",
|
|
||||||
"title": "Job Node Finished V1",
|
|
||||||
"description": "Job Worker 报告一次节点执行的终态,调度编排器据此推进 DAG。",
|
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"$ref": "event-envelope-v1.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"event_type": {
|
|
||||||
"const": "job.node.finished"
|
|
||||||
},
|
|
||||||
"aggregate_type": {
|
|
||||||
"const": "schedule_node_run"
|
|
||||||
},
|
|
||||||
"payload": {
|
|
||||||
"$ref": "job-node-finished-v1.json#/$defs/payload"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"$defs": {
|
|
||||||
"ulid": {
|
|
||||||
"type": "string",
|
|
||||||
"minLength": 26,
|
|
||||||
"maxLength": 26,
|
|
||||||
"pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
|
|
||||||
},
|
|
||||||
"nullableUlid": {
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"$ref": "job-node-finished-v1.json#/$defs/ulid"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "null"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"payload": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": false,
|
|
||||||
"required": [
|
|
||||||
"workspace_id",
|
|
||||||
"run_id",
|
|
||||||
"node_run_id",
|
|
||||||
"node_id",
|
|
||||||
"versions_id",
|
|
||||||
"attempt_no",
|
|
||||||
"node_status",
|
|
||||||
"exit_code",
|
|
||||||
"started_at",
|
|
||||||
"finished_at",
|
|
||||||
"duration_ms",
|
|
||||||
"logs_object_id",
|
|
||||||
"result_object_id",
|
|
||||||
"error_code",
|
|
||||||
"error_message"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"workspace_id": {
|
|
||||||
"$ref": "job-node-finished-v1.json#/$defs/ulid"
|
|
||||||
},
|
|
||||||
"run_id": {
|
|
||||||
"$ref": "job-node-finished-v1.json#/$defs/ulid"
|
|
||||||
},
|
|
||||||
"node_run_id": {
|
|
||||||
"$ref": "job-node-finished-v1.json#/$defs/ulid"
|
|
||||||
},
|
|
||||||
"node_id": {
|
|
||||||
"$ref": "job-node-finished-v1.json#/$defs/ulid"
|
|
||||||
},
|
|
||||||
"versions_id": {
|
|
||||||
"$ref": "job-node-finished-v1.json#/$defs/ulid"
|
|
||||||
},
|
|
||||||
"attempt_no": {
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 1,
|
|
||||||
"maximum": 11
|
|
||||||
},
|
|
||||||
"node_status": {
|
|
||||||
"enum": [
|
|
||||||
"succeeded",
|
|
||||||
"failed",
|
|
||||||
"cancelled",
|
|
||||||
"timed_out"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"exit_code": {
|
|
||||||
"type": [
|
|
||||||
"integer",
|
|
||||||
"null"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"started_at": {
|
|
||||||
"type": "string",
|
|
||||||
"format": "date-time"
|
|
||||||
},
|
|
||||||
"finished_at": {
|
|
||||||
"type": "string",
|
|
||||||
"format": "date-time"
|
|
||||||
},
|
|
||||||
"duration_ms": {
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 0
|
|
||||||
},
|
|
||||||
"logs_object_id": {
|
|
||||||
"$ref": "job-node-finished-v1.json#/$defs/nullableUlid"
|
|
||||||
},
|
|
||||||
"result_object_id": {
|
|
||||||
"$ref": "job-node-finished-v1.json#/$defs/nullableUlid"
|
|
||||||
},
|
|
||||||
"error_code": {
|
|
||||||
"type": [
|
|
||||||
"string",
|
|
||||||
"null"
|
|
||||||
],
|
|
||||||
"maxLength": 64
|
|
||||||
},
|
|
||||||
"error_message": {
|
|
||||||
"type": [
|
|
||||||
"string",
|
|
||||||
"null"
|
|
||||||
],
|
|
||||||
"maxLength": 2000
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"examples": [
|
|
||||||
{
|
|
||||||
"event_id": "01K123456789ABCDEFGHJKMNQ1",
|
|
||||||
"event_type": "job.node.finished",
|
|
||||||
"schema_version": 1,
|
|
||||||
"occurred_at": "2026-07-27T08:00:03Z",
|
|
||||||
"producer": "job-worker",
|
|
||||||
"trace_id": "req-demo-0001",
|
|
||||||
"aggregate_type": "schedule_node_run",
|
|
||||||
"aggregate_id": "01K123456789ABCDEFGHJKMNQ0",
|
|
||||||
"idempotency_key": "01K123456789ABCDEFGHJKMNQ0:1:finished",
|
|
||||||
"payload": {
|
|
||||||
"workspace_id": "01K123456789ABCDEFGHJKMNPS",
|
|
||||||
"run_id": "01K123456789ABCDEFGHJKMNPR",
|
|
||||||
"node_run_id": "01K123456789ABCDEFGHJKMNQ0",
|
|
||||||
"node_id": "01K123456789ABCDEFGHJKMNPW",
|
|
||||||
"versions_id": "01K123456789ABCDEFGHJKMNPX",
|
|
||||||
"attempt_no": 1,
|
|
||||||
"node_status": "succeeded",
|
|
||||||
"exit_code": 0,
|
|
||||||
"started_at": "2026-07-27T08:00:01Z",
|
|
||||||
"finished_at": "2026-07-27T08:00:03Z",
|
|
||||||
"duration_ms": 2000,
|
|
||||||
"logs_object_id": null,
|
|
||||||
"result_object_id": null,
|
|
||||||
"error_code": null,
|
|
||||||
"error_message": null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,255 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
||||||
"$id": "schedule-run-requested-v1.json",
|
|
||||||
"title": "Schedule Run Requested V1",
|
|
||||||
"description": "Platform API 或 Cron Dispatcher 请求调度编排器启动一次固化 DAG。",
|
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"$ref": "event-envelope-v1.json"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"event_type": {
|
|
||||||
"const": "schedule.run.requested"
|
|
||||||
},
|
|
||||||
"aggregate_type": {
|
|
||||||
"const": "schedule_run"
|
|
||||||
},
|
|
||||||
"payload": {
|
|
||||||
"$ref": "schedule-run-requested-v1.json#/$defs/payload"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"$defs": {
|
|
||||||
"ulid": {
|
|
||||||
"type": "string",
|
|
||||||
"minLength": 26,
|
|
||||||
"maxLength": 26,
|
|
||||||
"pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
|
|
||||||
},
|
|
||||||
"node": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": false,
|
|
||||||
"required": [
|
|
||||||
"node_id",
|
|
||||||
"node_key",
|
|
||||||
"versions_id",
|
|
||||||
"script_type",
|
|
||||||
"artifact_object_id",
|
|
||||||
"artifact_path",
|
|
||||||
"timeout_seconds",
|
|
||||||
"retry_count",
|
|
||||||
"retry_interval_sec",
|
|
||||||
"arguments"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"node_id": {
|
|
||||||
"$ref": "schedule-run-requested-v1.json#/$defs/ulid"
|
|
||||||
},
|
|
||||||
"node_key": {
|
|
||||||
"type": "string",
|
|
||||||
"minLength": 1,
|
|
||||||
"maxLength": 64
|
|
||||||
},
|
|
||||||
"versions_id": {
|
|
||||||
"$ref": "schedule-run-requested-v1.json#/$defs/ulid"
|
|
||||||
},
|
|
||||||
"script_type": {
|
|
||||||
"enum": [
|
|
||||||
"python",
|
|
||||||
"notebook"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"artifact_object_id": {
|
|
||||||
"$ref": "schedule-run-requested-v1.json#/$defs/ulid"
|
|
||||||
},
|
|
||||||
"artifact_path": {
|
|
||||||
"type": "string",
|
|
||||||
"minLength": 1,
|
|
||||||
"maxLength": 1024
|
|
||||||
},
|
|
||||||
"timeout_seconds": {
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 1,
|
|
||||||
"maximum": 86400
|
|
||||||
},
|
|
||||||
"retry_count": {
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 0,
|
|
||||||
"maximum": 10
|
|
||||||
},
|
|
||||||
"retry_interval_sec": {
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 0,
|
|
||||||
"maximum": 3600
|
|
||||||
},
|
|
||||||
"arguments": {
|
|
||||||
"type": "array",
|
|
||||||
"maxItems": 100,
|
|
||||||
"items": {
|
|
||||||
"type": "string",
|
|
||||||
"maxLength": 1000
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"edge": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": false,
|
|
||||||
"required": [
|
|
||||||
"source_node_id",
|
|
||||||
"target_node_id"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"source_node_id": {
|
|
||||||
"$ref": "schedule-run-requested-v1.json#/$defs/ulid"
|
|
||||||
},
|
|
||||||
"target_node_id": {
|
|
||||||
"$ref": "schedule-run-requested-v1.json#/$defs/ulid"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"snapshot": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": false,
|
|
||||||
"required": [
|
|
||||||
"schedule_name",
|
|
||||||
"workflow_version",
|
|
||||||
"max_concurrency",
|
|
||||||
"failure_policy",
|
|
||||||
"nodes",
|
|
||||||
"edges"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"schedule_name": {
|
|
||||||
"type": "string",
|
|
||||||
"minLength": 1,
|
|
||||||
"maxLength": 255
|
|
||||||
},
|
|
||||||
"workflow_version": {
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 1
|
|
||||||
},
|
|
||||||
"max_concurrency": {
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 1,
|
|
||||||
"maximum": 100
|
|
||||||
},
|
|
||||||
"failure_policy": {
|
|
||||||
"enum": [
|
|
||||||
"stop",
|
|
||||||
"continue"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"nodes": {
|
|
||||||
"type": "array",
|
|
||||||
"minItems": 1,
|
|
||||||
"maxItems": 100,
|
|
||||||
"items": {
|
|
||||||
"$ref": "schedule-run-requested-v1.json#/$defs/node"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"edges": {
|
|
||||||
"type": "array",
|
|
||||||
"maxItems": 500,
|
|
||||||
"items": {
|
|
||||||
"$ref": "schedule-run-requested-v1.json#/$defs/edge"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"payload": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": false,
|
|
||||||
"required": [
|
|
||||||
"workspace_id",
|
|
||||||
"schedule_id",
|
|
||||||
"run_id",
|
|
||||||
"workflow_version",
|
|
||||||
"trigger_type",
|
|
||||||
"triggered_by",
|
|
||||||
"schedule_snapshot"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"workspace_id": {
|
|
||||||
"$ref": "schedule-run-requested-v1.json#/$defs/ulid"
|
|
||||||
},
|
|
||||||
"schedule_id": {
|
|
||||||
"$ref": "schedule-run-requested-v1.json#/$defs/ulid"
|
|
||||||
},
|
|
||||||
"run_id": {
|
|
||||||
"$ref": "schedule-run-requested-v1.json#/$defs/ulid"
|
|
||||||
},
|
|
||||||
"workflow_version": {
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 1
|
|
||||||
},
|
|
||||||
"trigger_type": {
|
|
||||||
"enum": [
|
|
||||||
"manual",
|
|
||||||
"cron",
|
|
||||||
"api",
|
|
||||||
"retry"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"triggered_by": {
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"$ref": "schedule-run-requested-v1.json#/$defs/ulid"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "null"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"schedule_snapshot": {
|
|
||||||
"$ref": "schedule-run-requested-v1.json#/$defs/snapshot"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"examples": [
|
|
||||||
{
|
|
||||||
"event_id": "01K123456789ABCDEFGHJKMNPQ",
|
|
||||||
"event_type": "schedule.run.requested",
|
|
||||||
"schema_version": 1,
|
|
||||||
"occurred_at": "2026-07-27T08:00:00Z",
|
|
||||||
"producer": "platform-api",
|
|
||||||
"trace_id": "req-demo-0001",
|
|
||||||
"aggregate_type": "schedule_run",
|
|
||||||
"aggregate_id": "01K123456789ABCDEFGHJKMNPR",
|
|
||||||
"idempotency_key": "run-demo-0001",
|
|
||||||
"payload": {
|
|
||||||
"workspace_id": "01K123456789ABCDEFGHJKMNPS",
|
|
||||||
"schedule_id": "01K123456789ABCDEFGHJKMNPT",
|
|
||||||
"run_id": "01K123456789ABCDEFGHJKMNPR",
|
|
||||||
"workflow_version": 1,
|
|
||||||
"trigger_type": "manual",
|
|
||||||
"triggered_by": "01K123456789ABCDEFGHJKMNPV",
|
|
||||||
"schedule_snapshot": {
|
|
||||||
"schedule_name": "每日模型演示",
|
|
||||||
"workflow_version": 1,
|
|
||||||
"max_concurrency": 1,
|
|
||||||
"failure_policy": "stop",
|
|
||||||
"nodes": [
|
|
||||||
{
|
|
||||||
"node_id": "01K123456789ABCDEFGHJKMNPW",
|
|
||||||
"node_key": "prepare",
|
|
||||||
"versions_id": "01K123456789ABCDEFGHJKMNPX",
|
|
||||||
"script_type": "python",
|
|
||||||
"artifact_object_id": "01K123456789ABCDEFGHJKMNPY",
|
|
||||||
"artifact_path": "versions/prepare/v1.py",
|
|
||||||
"timeout_seconds": 600,
|
|
||||||
"retry_count": 0,
|
|
||||||
"retry_interval_sec": 5,
|
|
||||||
"arguments": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"edges": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# File Edit Lock
|
|
||||||
|
|
||||||
当前版本见 [file-edit-lock-v1.md](file-edit-lock-v1.md)。MySQL 租约是实时锁权威。
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
# 文件编辑锁契约 v1
|
|
||||||
|
|
||||||
## 公共接口
|
|
||||||
|
|
||||||
```text
|
|
||||||
POST /api/v1/files/{storage_object_id}/lock
|
|
||||||
POST /api/v1/file-locks/{edit_session_id}/heartbeat
|
|
||||||
DELETE /api/v1/file-locks/{edit_session_id}
|
|
||||||
```
|
|
||||||
|
|
||||||
三个接口均要求 `X-User-ID` 和 `X-Workspace-ID`。加锁成功返回一次性原始
|
|
||||||
`lock_token`;心跳和释放请求体均为:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{"lock_token": "raw-token-returned-by-acquire"}
|
|
||||||
```
|
|
||||||
|
|
||||||
原始 token 只由客户端持有,数据库只保存 SHA-256 摘要。
|
|
||||||
|
|
||||||
## MySQL 租约
|
|
||||||
|
|
||||||
`edit_sessions` 是实时锁权威:
|
|
||||||
|
|
||||||
- `session_status=active` 且 `expires_at > now()` 表示锁有效;
|
|
||||||
- 同一 `storage_object_id` 同时只能存在一个有效编辑会话;
|
|
||||||
- 心跳更新 `last_heartbeat_at` 与 `expires_at`;
|
|
||||||
- 主动释放将状态改为 `closed`;
|
|
||||||
- 后台清理将超时租约改为 `expired`。
|
|
||||||
|
|
||||||
加锁、心跳和释放都在数据库事务中校验 `edit_session_id + lock_token_hash`。
|
|
||||||
部署时 Runtime 保持单副本;若扩展到多副本,应为加锁查询增加数据库行锁或唯一
|
|
||||||
租约表约束。
|
|
||||||
|
|
||||||
## 状态与错误
|
|
||||||
|
|
||||||
- 冲突返回 HTTP 409、错误码 `FILE_LOCK_CONFLICT`,并包含当前编辑者和租约到期时间;
|
|
||||||
- 错误 token 返回 HTTP 403,且不得续期或释放现有锁;
|
|
||||||
- 浏览器建议每 15 秒心跳,默认租约为 45 秒。
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
# OpenAPI 契约
|
|
||||||
|
|
||||||
- `platform-api-v1.yaml`:浏览器访问的公共业务接口。
|
|
||||||
- `demo-core-extension-v1.yaml`:第 15 小步冻结的 Demo 目标扩展接口;
|
|
||||||
与 `platform-api-v1.yaml` 合并后构成完整公共 API v1。
|
|
||||||
- `storage-api-internal-v1.yaml`:Storage Service 内部接口。
|
|
||||||
- `runtime-api-internal-v1.yaml`:Runtime Manager 内部接口。
|
|
||||||
|
|
||||||
现有服务契约由对应 FastAPI 应用生成;目标扩展契约先冻结、后实现,不能
|
|
||||||
标记为已上线。所有文件均纳入结构校验。公共接口统一使用 `/api/v1`,
|
|
||||||
内部服务接口统一使用 `/internal/v1`。
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,699 +0,0 @@
|
|||||||
openapi: 3.1.0
|
|
||||||
info:
|
|
||||||
title: runtime-manager service
|
|
||||||
version: 0.1.0
|
|
||||||
paths:
|
|
||||||
/:
|
|
||||||
get:
|
|
||||||
summary: Root
|
|
||||||
operationId: root__get
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful Response
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
additionalProperties:
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
title: Response Root Get
|
|
||||||
/health/live:
|
|
||||||
get:
|
|
||||||
summary: Live
|
|
||||||
operationId: live_health_live_get
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful Response
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
additionalProperties:
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
title: Response Live Health Live Get
|
|
||||||
/api/v1/health:
|
|
||||||
get:
|
|
||||||
summary: Public Health
|
|
||||||
operationId: public_health_api_v1_health_get
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful Response
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
additionalProperties:
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
title: Response Public Health Api V1 Health Get
|
|
||||||
/health/ready:
|
|
||||||
get:
|
|
||||||
summary: Ready
|
|
||||||
operationId: ready_health_ready_get
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful Response
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
additionalProperties: true
|
|
||||||
type: object
|
|
||||||
title: Response Ready Health Ready Get
|
|
||||||
/internal/v1/file-locks/acquire:
|
|
||||||
post:
|
|
||||||
summary: Acquire File Lock
|
|
||||||
operationId: acquire_file_lock_internal_v1_file_locks_acquire_post
|
|
||||||
parameters:
|
|
||||||
- name: X-Service-Token
|
|
||||||
in: header
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: X-Service-Token
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/AcquireFileLockRequest'
|
|
||||||
responses:
|
|
||||||
'201':
|
|
||||||
description: Successful Response
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
additionalProperties: true
|
|
||||||
title: Response Acquire File Lock Internal V1 File Locks Acquire Post
|
|
||||||
'422':
|
|
||||||
description: Validation Error
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/HTTPValidationError'
|
|
||||||
/internal/v1/file-locks/{edit_session_id}/heartbeat:
|
|
||||||
post:
|
|
||||||
summary: Heartbeat File Lock
|
|
||||||
operationId: heartbeat_file_lock_internal_v1_file_locks__edit_session_id__heartbeat_post
|
|
||||||
parameters:
|
|
||||||
- name: edit_session_id
|
|
||||||
in: path
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: Edit Session Id
|
|
||||||
- name: X-Service-Token
|
|
||||||
in: header
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: X-Service-Token
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/FileLockTokenRequest'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful Response
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
additionalProperties: true
|
|
||||||
title: Response Heartbeat File Lock Internal V1 File Locks Edit Session Id Heartbeat
|
|
||||||
Post
|
|
||||||
'422':
|
|
||||||
description: Validation Error
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/HTTPValidationError'
|
|
||||||
/internal/v1/file-locks/{edit_session_id}:
|
|
||||||
delete:
|
|
||||||
summary: Release File Lock
|
|
||||||
operationId: release_file_lock_internal_v1_file_locks__edit_session_id__delete
|
|
||||||
parameters:
|
|
||||||
- name: edit_session_id
|
|
||||||
in: path
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: Edit Session Id
|
|
||||||
- name: X-Service-Token
|
|
||||||
in: header
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: X-Service-Token
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/FileLockTokenRequest'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful Response
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
additionalProperties: true
|
|
||||||
title: Response Release File Lock Internal V1 File Locks Edit Session Id Delete
|
|
||||||
'422':
|
|
||||||
description: Validation Error
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/HTTPValidationError'
|
|
||||||
/internal/v1/jupyter/access-tickets/{edit_session_id}:
|
|
||||||
post:
|
|
||||||
summary: Create Jupyter Access Ticket
|
|
||||||
operationId: create_jupyter_access_ticket_internal_v1_jupyter_access_tickets__edit_session_id__post
|
|
||||||
parameters:
|
|
||||||
- name: edit_session_id
|
|
||||||
in: path
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: Edit Session Id
|
|
||||||
- name: X-Service-Token
|
|
||||||
in: header
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: X-Service-Token
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/FileLockTokenRequest'
|
|
||||||
responses:
|
|
||||||
'201':
|
|
||||||
description: Successful Response
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
additionalProperties: true
|
|
||||||
title: Response Create Jupyter Access Ticket Internal V1 Jupyter Access Tickets Edit
|
|
||||||
Session Id Post
|
|
||||||
'422':
|
|
||||||
description: Validation Error
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/HTTPValidationError'
|
|
||||||
/internal/v1/jupyter/authorize:
|
|
||||||
get:
|
|
||||||
summary: Authorize Jupyter Proxy
|
|
||||||
operationId: authorize_jupyter_proxy_internal_v1_jupyter_authorize_get
|
|
||||||
parameters:
|
|
||||||
- name: X-Original-URI
|
|
||||||
in: header
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: X-Original-Uri
|
|
||||||
- name: X-Service-Token
|
|
||||||
in: header
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: X-Service-Token
|
|
||||||
- name: jupyter_access
|
|
||||||
in: cookie
|
|
||||||
required: false
|
|
||||||
schema:
|
|
||||||
anyOf:
|
|
||||||
- type: string
|
|
||||||
- type: 'null'
|
|
||||||
title: Jupyter Access
|
|
||||||
responses:
|
|
||||||
'204':
|
|
||||||
description: Successful Response
|
|
||||||
'422':
|
|
||||||
description: Validation Error
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/HTTPValidationError'
|
|
||||||
/internal/v1/runtimes/ensure:
|
|
||||||
post:
|
|
||||||
summary: Ensure Runtime
|
|
||||||
operationId: ensure_runtime_internal_v1_runtimes_ensure_post
|
|
||||||
parameters:
|
|
||||||
- name: X-Service-Token
|
|
||||||
in: header
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: X-Service-Token
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/EnsureRuntimeApiRequest'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful Response
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
additionalProperties: true
|
|
||||||
title: Response Ensure Runtime Internal V1 Runtimes Ensure Post
|
|
||||||
'422':
|
|
||||||
description: Validation Error
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/HTTPValidationError'
|
|
||||||
/internal/v1/runtimes/{runtime_id}:
|
|
||||||
get:
|
|
||||||
summary: Get Runtime
|
|
||||||
operationId: get_runtime_internal_v1_runtimes__runtime_id__get
|
|
||||||
parameters:
|
|
||||||
- name: runtime_id
|
|
||||||
in: path
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: Runtime Id
|
|
||||||
- name: workspace_id
|
|
||||||
in: query
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
minLength: 26
|
|
||||||
maxLength: 26
|
|
||||||
title: Workspace Id
|
|
||||||
- name: user_id
|
|
||||||
in: query
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
minLength: 26
|
|
||||||
maxLength: 26
|
|
||||||
title: User Id
|
|
||||||
- name: X-Service-Token
|
|
||||||
in: header
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: X-Service-Token
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful Response
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
additionalProperties: true
|
|
||||||
title: Response Get Runtime Internal V1 Runtimes Runtime Id Get
|
|
||||||
'422':
|
|
||||||
description: Validation Error
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/HTTPValidationError'
|
|
||||||
delete:
|
|
||||||
summary: Stop Runtime
|
|
||||||
operationId: stop_runtime_internal_v1_runtimes__runtime_id__delete
|
|
||||||
parameters:
|
|
||||||
- name: runtime_id
|
|
||||||
in: path
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: Runtime Id
|
|
||||||
- name: X-Service-Token
|
|
||||||
in: header
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: X-Service-Token
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/StopRuntimeApiRequest'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful Response
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
additionalProperties: true
|
|
||||||
title: Response Stop Runtime Internal V1 Runtimes Runtime Id Delete
|
|
||||||
'422':
|
|
||||||
description: Validation Error
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/HTTPValidationError'
|
|
||||||
/internal/v1/runtimes/{runtime_id}/restart:
|
|
||||||
post:
|
|
||||||
summary: Restart Runtime
|
|
||||||
operationId: restart_runtime_internal_v1_runtimes__runtime_id__restart_post
|
|
||||||
parameters:
|
|
||||||
- name: runtime_id
|
|
||||||
in: path
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: Runtime Id
|
|
||||||
- name: X-Service-Token
|
|
||||||
in: header
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: X-Service-Token
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/RuntimeIdentityRequest'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful Response
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
additionalProperties: true
|
|
||||||
title: Response Restart Runtime Internal V1 Runtimes Runtime Id Restart Post
|
|
||||||
'422':
|
|
||||||
description: Validation Error
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/HTTPValidationError'
|
|
||||||
/internal/v1/runtimes/{runtime_id}/sessions:
|
|
||||||
post:
|
|
||||||
summary: Create Runtime Session
|
|
||||||
operationId: create_runtime_session_internal_v1_runtimes__runtime_id__sessions_post
|
|
||||||
parameters:
|
|
||||||
- name: runtime_id
|
|
||||||
in: path
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: Runtime Id
|
|
||||||
- name: X-Service-Token
|
|
||||||
in: header
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: X-Service-Token
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/CreateRuntimeSessionApiRequest'
|
|
||||||
responses:
|
|
||||||
'201':
|
|
||||||
description: Successful Response
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
additionalProperties: true
|
|
||||||
title: Response Create Runtime Session Internal V1 Runtimes Runtime Id Sessions Post
|
|
||||||
'422':
|
|
||||||
description: Validation Error
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/HTTPValidationError'
|
|
||||||
/internal/v1/runtimes/{runtime_id}/sessions/{session_id}:
|
|
||||||
delete:
|
|
||||||
summary: Terminate Runtime Session
|
|
||||||
operationId: terminate_runtime_session_internal_v1_runtimes__runtime_id__sessions__session_id__delete
|
|
||||||
parameters:
|
|
||||||
- name: runtime_id
|
|
||||||
in: path
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: Runtime Id
|
|
||||||
- name: session_id
|
|
||||||
in: path
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: Session Id
|
|
||||||
- name: X-Service-Token
|
|
||||||
in: header
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: X-Service-Token
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/RuntimeIdentityRequest'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful Response
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
additionalProperties: true
|
|
||||||
title: Response Terminate Runtime Session Internal V1 Runtimes Runtime Id Sessions Session
|
|
||||||
Id Delete
|
|
||||||
'422':
|
|
||||||
description: Validation Error
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/HTTPValidationError'
|
|
||||||
/internal/health/runtime:
|
|
||||||
get:
|
|
||||||
summary: Internal Health
|
|
||||||
operationId: internal_health_internal_health_runtime_get
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful Response
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
additionalProperties:
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
title: Response Internal Health Internal Health Runtime Get
|
|
||||||
components:
|
|
||||||
schemas:
|
|
||||||
AcquireFileLockRequest:
|
|
||||||
properties:
|
|
||||||
workspace_id:
|
|
||||||
type: string
|
|
||||||
maxLength: 26
|
|
||||||
minLength: 26
|
|
||||||
title: Workspace Id
|
|
||||||
storage_object_id:
|
|
||||||
type: string
|
|
||||||
maxLength: 26
|
|
||||||
minLength: 26
|
|
||||||
title: Storage Object Id
|
|
||||||
user_id:
|
|
||||||
type: string
|
|
||||||
maxLength: 26
|
|
||||||
minLength: 26
|
|
||||||
title: User Id
|
|
||||||
request_id:
|
|
||||||
anyOf:
|
|
||||||
- type: string
|
|
||||||
maxLength: 64
|
|
||||||
minLength: 1
|
|
||||||
- type: 'null'
|
|
||||||
title: Request Id
|
|
||||||
additionalProperties: false
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- workspace_id
|
|
||||||
- storage_object_id
|
|
||||||
- user_id
|
|
||||||
title: AcquireFileLockRequest
|
|
||||||
CreateRuntimeSessionApiRequest:
|
|
||||||
properties:
|
|
||||||
workspace_id:
|
|
||||||
type: string
|
|
||||||
maxLength: 26
|
|
||||||
minLength: 26
|
|
||||||
title: Workspace Id
|
|
||||||
user_id:
|
|
||||||
type: string
|
|
||||||
maxLength: 26
|
|
||||||
minLength: 26
|
|
||||||
title: User Id
|
|
||||||
request_id:
|
|
||||||
anyOf:
|
|
||||||
- type: string
|
|
||||||
maxLength: 64
|
|
||||||
minLength: 1
|
|
||||||
- type: 'null'
|
|
||||||
title: Request Id
|
|
||||||
storage_object_id:
|
|
||||||
type: string
|
|
||||||
maxLength: 26
|
|
||||||
minLength: 26
|
|
||||||
title: Storage Object Id
|
|
||||||
relative_path:
|
|
||||||
type: string
|
|
||||||
maxLength: 1024
|
|
||||||
minLength: 1
|
|
||||||
title: Relative Path
|
|
||||||
additionalProperties: false
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- workspace_id
|
|
||||||
- user_id
|
|
||||||
- storage_object_id
|
|
||||||
- relative_path
|
|
||||||
title: CreateRuntimeSessionApiRequest
|
|
||||||
EnsureRuntimeApiRequest:
|
|
||||||
properties:
|
|
||||||
workspace_id:
|
|
||||||
type: string
|
|
||||||
maxLength: 26
|
|
||||||
minLength: 26
|
|
||||||
title: Workspace Id
|
|
||||||
user_id:
|
|
||||||
type: string
|
|
||||||
maxLength: 26
|
|
||||||
minLength: 26
|
|
||||||
title: User Id
|
|
||||||
request_id:
|
|
||||||
anyOf:
|
|
||||||
- type: string
|
|
||||||
maxLength: 64
|
|
||||||
minLength: 1
|
|
||||||
- type: 'null'
|
|
||||||
title: Request Id
|
|
||||||
additionalProperties: false
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- workspace_id
|
|
||||||
- user_id
|
|
||||||
title: EnsureRuntimeApiRequest
|
|
||||||
FileLockTokenRequest:
|
|
||||||
properties:
|
|
||||||
workspace_id:
|
|
||||||
type: string
|
|
||||||
maxLength: 26
|
|
||||||
minLength: 26
|
|
||||||
title: Workspace Id
|
|
||||||
user_id:
|
|
||||||
type: string
|
|
||||||
maxLength: 26
|
|
||||||
minLength: 26
|
|
||||||
title: User Id
|
|
||||||
lock_token:
|
|
||||||
type: string
|
|
||||||
maxLength: 256
|
|
||||||
minLength: 32
|
|
||||||
title: Lock Token
|
|
||||||
additionalProperties: false
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- workspace_id
|
|
||||||
- user_id
|
|
||||||
- lock_token
|
|
||||||
title: FileLockTokenRequest
|
|
||||||
HTTPValidationError:
|
|
||||||
properties:
|
|
||||||
detail:
|
|
||||||
items:
|
|
||||||
$ref: '#/components/schemas/ValidationError'
|
|
||||||
type: array
|
|
||||||
title: Detail
|
|
||||||
type: object
|
|
||||||
title: HTTPValidationError
|
|
||||||
RuntimeIdentityRequest:
|
|
||||||
properties:
|
|
||||||
workspace_id:
|
|
||||||
type: string
|
|
||||||
maxLength: 26
|
|
||||||
minLength: 26
|
|
||||||
title: Workspace Id
|
|
||||||
user_id:
|
|
||||||
type: string
|
|
||||||
maxLength: 26
|
|
||||||
minLength: 26
|
|
||||||
title: User Id
|
|
||||||
request_id:
|
|
||||||
anyOf:
|
|
||||||
- type: string
|
|
||||||
maxLength: 64
|
|
||||||
minLength: 1
|
|
||||||
- type: 'null'
|
|
||||||
title: Request Id
|
|
||||||
additionalProperties: false
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- workspace_id
|
|
||||||
- user_id
|
|
||||||
title: RuntimeIdentityRequest
|
|
||||||
StopRuntimeApiRequest:
|
|
||||||
properties:
|
|
||||||
workspace_id:
|
|
||||||
type: string
|
|
||||||
maxLength: 26
|
|
||||||
minLength: 26
|
|
||||||
title: Workspace Id
|
|
||||||
user_id:
|
|
||||||
type: string
|
|
||||||
maxLength: 26
|
|
||||||
minLength: 26
|
|
||||||
title: User Id
|
|
||||||
request_id:
|
|
||||||
anyOf:
|
|
||||||
- type: string
|
|
||||||
maxLength: 64
|
|
||||||
minLength: 1
|
|
||||||
- type: 'null'
|
|
||||||
title: Request Id
|
|
||||||
reason:
|
|
||||||
type: string
|
|
||||||
maxLength: 64
|
|
||||||
minLength: 1
|
|
||||||
title: Reason
|
|
||||||
default: client_request
|
|
||||||
additionalProperties: false
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- workspace_id
|
|
||||||
- user_id
|
|
||||||
title: StopRuntimeApiRequest
|
|
||||||
ValidationError:
|
|
||||||
properties:
|
|
||||||
loc:
|
|
||||||
items:
|
|
||||||
anyOf:
|
|
||||||
- type: string
|
|
||||||
- type: integer
|
|
||||||
type: array
|
|
||||||
title: Location
|
|
||||||
msg:
|
|
||||||
type: string
|
|
||||||
title: Message
|
|
||||||
type:
|
|
||||||
type: string
|
|
||||||
title: Error Type
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- loc
|
|
||||||
- msg
|
|
||||||
- type
|
|
||||||
title: ValidationError
|
|
||||||
@@ -1,550 +0,0 @@
|
|||||||
openapi: 3.1.0
|
|
||||||
info:
|
|
||||||
title: storage-api service
|
|
||||||
version: 0.1.0
|
|
||||||
paths:
|
|
||||||
/:
|
|
||||||
get:
|
|
||||||
summary: Root
|
|
||||||
operationId: root__get
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful Response
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
additionalProperties:
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
title: Response Root Get
|
|
||||||
/health/live:
|
|
||||||
get:
|
|
||||||
summary: Live
|
|
||||||
operationId: live_health_live_get
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful Response
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
additionalProperties:
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
title: Response Live Health Live Get
|
|
||||||
/api/v1/health:
|
|
||||||
get:
|
|
||||||
summary: Public Health
|
|
||||||
operationId: public_health_api_v1_health_get
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful Response
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
additionalProperties:
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
title: Response Public Health Api V1 Health Get
|
|
||||||
/health/ready:
|
|
||||||
get:
|
|
||||||
summary: Ready
|
|
||||||
operationId: ready_health_ready_get
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful Response
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
additionalProperties: true
|
|
||||||
type: object
|
|
||||||
title: Response Ready Health Ready Get
|
|
||||||
/internal/v1/uploads:
|
|
||||||
post:
|
|
||||||
summary: Create Upload
|
|
||||||
operationId: create_upload_internal_v1_uploads_post
|
|
||||||
parameters:
|
|
||||||
- name: X-Service-Token
|
|
||||||
in: header
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: X-Service-Token
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/CreateUploadRequest'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful Response
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
additionalProperties: true
|
|
||||||
title: Response Create Upload Internal V1 Uploads Post
|
|
||||||
'422':
|
|
||||||
description: Validation Error
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/HTTPValidationError'
|
|
||||||
/internal/v1/uploads/{upload_id}/complete:
|
|
||||||
post:
|
|
||||||
summary: Complete Upload
|
|
||||||
operationId: complete_upload_internal_v1_uploads__upload_id__complete_post
|
|
||||||
parameters:
|
|
||||||
- name: upload_id
|
|
||||||
in: path
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: Upload Id
|
|
||||||
- name: X-Service-Token
|
|
||||||
in: header
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: X-Service-Token
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/CompleteUploadRequest'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful Response
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
additionalProperties: true
|
|
||||||
title: Response Complete Upload Internal V1 Uploads Upload Id Complete Post
|
|
||||||
'422':
|
|
||||||
description: Validation Error
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/HTTPValidationError'
|
|
||||||
/internal/v1/uploads/{upload_id}/abort:
|
|
||||||
post:
|
|
||||||
summary: Abort Upload
|
|
||||||
operationId: abort_upload_internal_v1_uploads__upload_id__abort_post
|
|
||||||
parameters:
|
|
||||||
- name: upload_id
|
|
||||||
in: path
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: Upload Id
|
|
||||||
- name: X-Service-Token
|
|
||||||
in: header
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: X-Service-Token
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful Response
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
additionalProperties: true
|
|
||||||
title: Response Abort Upload Internal V1 Uploads Upload Id Abort Post
|
|
||||||
'422':
|
|
||||||
description: Validation Error
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/HTTPValidationError'
|
|
||||||
/internal/v1/objects:
|
|
||||||
post:
|
|
||||||
summary: Create Server Object
|
|
||||||
operationId: create_server_object_internal_v1_objects_post
|
|
||||||
parameters:
|
|
||||||
- name: X-Service-Token
|
|
||||||
in: header
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: X-Service-Token
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ServerObjectRequest'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful Response
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
additionalProperties: true
|
|
||||||
title: Response Create Server Object Internal V1 Objects Post
|
|
||||||
'422':
|
|
||||||
description: Validation Error
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/HTTPValidationError'
|
|
||||||
/internal/v1/workspace-objects:
|
|
||||||
post:
|
|
||||||
summary: Register Workspace Object
|
|
||||||
operationId: register_workspace_object_internal_v1_workspace_objects_post
|
|
||||||
parameters:
|
|
||||||
- name: X-Service-Token
|
|
||||||
in: header
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: X-Service-Token
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/RegisterWorkspaceObjectRequest'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful Response
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
additionalProperties: true
|
|
||||||
title: Response Register Workspace Object Internal V1 Workspace Objects Post
|
|
||||||
'422':
|
|
||||||
description: Validation Error
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/HTTPValidationError'
|
|
||||||
/internal/v1/objects/{storage_object_id}/download-url:
|
|
||||||
post:
|
|
||||||
summary: Create Download Url
|
|
||||||
operationId: create_download_url_internal_v1_objects__storage_object_id__download_url_post
|
|
||||||
parameters:
|
|
||||||
- name: storage_object_id
|
|
||||||
in: path
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: Storage Object Id
|
|
||||||
- name: X-Service-Token
|
|
||||||
in: header
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: X-Service-Token
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/DownloadUrlRequest'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful Response
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
additionalProperties: true
|
|
||||||
title: Response Create Download Url Internal V1 Objects Storage Object Id Download Url
|
|
||||||
Post
|
|
||||||
'422':
|
|
||||||
description: Validation Error
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/HTTPValidationError'
|
|
||||||
/internal/v1/objects/{storage_object_id}:
|
|
||||||
delete:
|
|
||||||
summary: Delete Object
|
|
||||||
operationId: delete_object_internal_v1_objects__storage_object_id__delete
|
|
||||||
parameters:
|
|
||||||
- name: storage_object_id
|
|
||||||
in: path
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: Storage Object Id
|
|
||||||
- name: X-Service-Token
|
|
||||||
in: header
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
title: X-Service-Token
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful Response
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
additionalProperties: true
|
|
||||||
title: Response Delete Object Internal V1 Objects Storage Object Id Delete
|
|
||||||
'422':
|
|
||||||
description: Validation Error
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/HTTPValidationError'
|
|
||||||
/internal/health/storage:
|
|
||||||
get:
|
|
||||||
summary: Internal Health
|
|
||||||
operationId: internal_health_internal_health_storage_get
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful Response
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
additionalProperties:
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
title: Response Internal Health Internal Health Storage Get
|
|
||||||
components:
|
|
||||||
schemas:
|
|
||||||
CompleteUploadRequest:
|
|
||||||
properties:
|
|
||||||
usage_type:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- data_resource
|
|
||||||
- version_artifact
|
|
||||||
- snapshot
|
|
||||||
- run_log
|
|
||||||
- run_result
|
|
||||||
title: Usage Type
|
|
||||||
visibility:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- private
|
|
||||||
- workspace
|
|
||||||
- public
|
|
||||||
title: Visibility
|
|
||||||
default: private
|
|
||||||
is_immutable:
|
|
||||||
type: boolean
|
|
||||||
title: Is Immutable
|
|
||||||
default: false
|
|
||||||
additionalProperties: false
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- usage_type
|
|
||||||
title: CompleteUploadRequest
|
|
||||||
CreateUploadRequest:
|
|
||||||
properties:
|
|
||||||
workspace_id:
|
|
||||||
type: string
|
|
||||||
maxLength: 26
|
|
||||||
minLength: 26
|
|
||||||
title: Workspace Id
|
|
||||||
user_id:
|
|
||||||
type: string
|
|
||||||
maxLength: 26
|
|
||||||
minLength: 26
|
|
||||||
title: User Id
|
|
||||||
usage_type:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- data_resource
|
|
||||||
- version_artifact
|
|
||||||
- snapshot
|
|
||||||
- run_log
|
|
||||||
- run_result
|
|
||||||
title: Usage Type
|
|
||||||
file_name:
|
|
||||||
type: string
|
|
||||||
maxLength: 255
|
|
||||||
minLength: 1
|
|
||||||
title: File Name
|
|
||||||
content_type:
|
|
||||||
type: string
|
|
||||||
maxLength: 255
|
|
||||||
minLength: 1
|
|
||||||
title: Content Type
|
|
||||||
expected_size_bytes:
|
|
||||||
type: integer
|
|
||||||
maximum: 104857600.0
|
|
||||||
minimum: 0.0
|
|
||||||
title: Expected Size Bytes
|
|
||||||
expected_hash:
|
|
||||||
anyOf:
|
|
||||||
- type: string
|
|
||||||
maxLength: 64
|
|
||||||
minLength: 64
|
|
||||||
- type: 'null'
|
|
||||||
title: Expected Hash
|
|
||||||
idempotency_key:
|
|
||||||
type: string
|
|
||||||
maxLength: 128
|
|
||||||
minLength: 8
|
|
||||||
title: Idempotency Key
|
|
||||||
url_scope:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- public
|
|
||||||
- internal
|
|
||||||
title: Url Scope
|
|
||||||
default: public
|
|
||||||
additionalProperties: false
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- workspace_id
|
|
||||||
- user_id
|
|
||||||
- usage_type
|
|
||||||
- file_name
|
|
||||||
- content_type
|
|
||||||
- expected_size_bytes
|
|
||||||
- idempotency_key
|
|
||||||
title: CreateUploadRequest
|
|
||||||
DownloadUrlRequest:
|
|
||||||
properties:
|
|
||||||
expires_seconds:
|
|
||||||
type: integer
|
|
||||||
maximum: 3600.0
|
|
||||||
minimum: 30.0
|
|
||||||
title: Expires Seconds
|
|
||||||
default: 300
|
|
||||||
additionalProperties: false
|
|
||||||
type: object
|
|
||||||
title: DownloadUrlRequest
|
|
||||||
HTTPValidationError:
|
|
||||||
properties:
|
|
||||||
detail:
|
|
||||||
items:
|
|
||||||
$ref: '#/components/schemas/ValidationError'
|
|
||||||
type: array
|
|
||||||
title: Detail
|
|
||||||
type: object
|
|
||||||
title: HTTPValidationError
|
|
||||||
RegisterWorkspaceObjectRequest:
|
|
||||||
properties:
|
|
||||||
workspace_id:
|
|
||||||
type: string
|
|
||||||
maxLength: 26
|
|
||||||
minLength: 26
|
|
||||||
title: Workspace Id
|
|
||||||
user_id:
|
|
||||||
type: string
|
|
||||||
maxLength: 26
|
|
||||||
minLength: 26
|
|
||||||
title: User Id
|
|
||||||
relative_path:
|
|
||||||
type: string
|
|
||||||
maxLength: 1024
|
|
||||||
minLength: 1
|
|
||||||
title: Relative Path
|
|
||||||
usage_type:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- working_copy
|
|
||||||
- public_script
|
|
||||||
title: Usage Type
|
|
||||||
visibility:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- private
|
|
||||||
- workspace
|
|
||||||
- public
|
|
||||||
title: Visibility
|
|
||||||
default: private
|
|
||||||
additionalProperties: false
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- workspace_id
|
|
||||||
- user_id
|
|
||||||
- relative_path
|
|
||||||
- usage_type
|
|
||||||
title: RegisterWorkspaceObjectRequest
|
|
||||||
ServerObjectRequest:
|
|
||||||
properties:
|
|
||||||
workspace_id:
|
|
||||||
type: string
|
|
||||||
maxLength: 26
|
|
||||||
minLength: 26
|
|
||||||
title: Workspace Id
|
|
||||||
user_id:
|
|
||||||
type: string
|
|
||||||
maxLength: 26
|
|
||||||
minLength: 26
|
|
||||||
title: User Id
|
|
||||||
usage_type:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- data_resource
|
|
||||||
- version_artifact
|
|
||||||
- snapshot
|
|
||||||
- run_log
|
|
||||||
- run_result
|
|
||||||
title: Usage Type
|
|
||||||
file_name:
|
|
||||||
type: string
|
|
||||||
maxLength: 255
|
|
||||||
minLength: 1
|
|
||||||
title: File Name
|
|
||||||
content_type:
|
|
||||||
type: string
|
|
||||||
maxLength: 255
|
|
||||||
minLength: 1
|
|
||||||
title: Content Type
|
|
||||||
content_base64:
|
|
||||||
type: string
|
|
||||||
minLength: 1
|
|
||||||
title: Content Base64
|
|
||||||
visibility:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- private
|
|
||||||
- workspace
|
|
||||||
- public
|
|
||||||
title: Visibility
|
|
||||||
default: private
|
|
||||||
is_immutable:
|
|
||||||
type: boolean
|
|
||||||
title: Is Immutable
|
|
||||||
default: false
|
|
||||||
idempotency_key:
|
|
||||||
type: string
|
|
||||||
maxLength: 128
|
|
||||||
minLength: 8
|
|
||||||
title: Idempotency Key
|
|
||||||
additionalProperties: false
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- workspace_id
|
|
||||||
- user_id
|
|
||||||
- usage_type
|
|
||||||
- file_name
|
|
||||||
- content_type
|
|
||||||
- content_base64
|
|
||||||
- idempotency_key
|
|
||||||
title: ServerObjectRequest
|
|
||||||
ValidationError:
|
|
||||||
properties:
|
|
||||||
loc:
|
|
||||||
items:
|
|
||||||
anyOf:
|
|
||||||
- type: string
|
|
||||||
- type: integer
|
|
||||||
type: array
|
|
||||||
title: Location
|
|
||||||
msg:
|
|
||||||
type: string
|
|
||||||
title: Message
|
|
||||||
type:
|
|
||||||
type: string
|
|
||||||
title: Error Type
|
|
||||||
type: object
|
|
||||||
required:
|
|
||||||
- loc
|
|
||||||
- msg
|
|
||||||
- type
|
|
||||||
title: ValidationError
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
# Runtime Adapter 契约
|
|
||||||
|
|
||||||
`runtime_adapter.py` 是 Runtime Manager 与具体运行环境之间的可执行契约。
|
|
||||||
|
|
||||||
当前 Compose 环境使用 `SharedJupyterAdapter`。它把共享 Jupyter Server 作为
|
|
||||||
首期 Provider,并在 MySQL 中为每个 `Workspace` 建立并复用一个逻辑
|
|
||||||
Runtime。每个打开的 Notebook 在该 Runtime 中建立独立 Jupyter Session,
|
|
||||||
每个 Session 绑定自己的 Kernel。
|
|
||||||
后续 Docker/Kubernetes Provider 必须实现同一 Protocol,公共锁接口和
|
|
||||||
`runtime_instances` 状态模型保持不变。
|
|
||||||
|
|
||||||
核心约束:
|
|
||||||
|
|
||||||
- `ensure_running` 对同一作用域必须幂等;
|
|
||||||
- Runtime 的唯一复用作用域是 Workspace,不能按用户重复创建;
|
|
||||||
- Runtime 的期望状态、实际状态和租约写入 MySQL;
|
|
||||||
- Notebook 对应独立 Jupyter Session/Kernel,其创建和终止只能由 Runtime
|
|
||||||
Manager 调用;
|
|
||||||
- Provider 不能依赖 Platform API 的进程内状态;
|
|
||||||
- `proxy_base_path` 与 Jupyter 内部 `base_url` 必须一致。
|
|
||||||
- Provider 调用必须携带内部服务凭据,不能通过关闭 XSRF 检查规避认证;
|
|
||||||
- Workspace 的目录、文件权限必须同时满足 Platform 原子写入和 Jupyter
|
|
||||||
读写,当前 Compose 环境使用共享 Unix 组完成。
|
|
||||||
|
|
||||||
Jupyter 浏览器代理、访问票据和 WebSocket 约束见
|
|
||||||
`jupyter-proxy-v1.md`。
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
"""Runtime adapter contract package."""
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
# Jupyter 代理与访问票据契约 V1
|
|
||||||
|
|
||||||
## 1. 浏览器访问流程
|
|
||||||
|
|
||||||
1. 前端携带用户、Workspace、`edit_session_id` 和 `lock_token` 调用
|
|
||||||
`POST /api/v1/jupyter/access-tickets`。
|
|
||||||
2. Platform API 校验编辑锁、Runtime 与 Jupyter Session 的归属及状态。
|
|
||||||
3. 成功后返回 `/jupyter/...` 地址,并设置短期
|
|
||||||
`jupyter_access` Cookie。
|
|
||||||
4. 前端在当前平台页面的编辑区内嵌同源 `/jupyter/...` 页面,不新开浏览器
|
|
||||||
标签页。
|
|
||||||
5. 内嵌页面经 Nginx 访问 Jupyter HTTP/WebSocket;Nginx 先执行内部鉴权
|
|
||||||
子请求,再把内部 Token 注入上游请求。
|
|
||||||
|
|
||||||
一个 Workspace 只建立或复用一个 Jupyter Runtime/Server;同一 Server
|
|
||||||
中的每个 Notebook 使用独立 Jupyter Session 和独立 Kernel。
|
|
||||||
|
|
||||||
浏览器响应、URL、JavaScript 和日志中都不得出现 Jupyter 内部 Token。
|
|
||||||
|
|
||||||
## 2. 访问票据
|
|
||||||
|
|
||||||
- 票据绑定:`user_id`、`workspace_id`、`edit_session_id`、
|
|
||||||
`runtime_id`、`jupyter_session_id`。
|
|
||||||
- 默认有效期:60 秒;最长不超过 5 分钟。
|
|
||||||
- Cookie:`HttpOnly; SameSite=Lax; Path=/jupyter/`,生产环境必须增加
|
|
||||||
`Secure`。
|
|
||||||
- 票据只授权当前 Workspace 的 Jupyter 路径,不能跨 Workspace 使用。
|
|
||||||
- Jupyter 页面必须与平台使用同一站点入口,并允许同源 iframe 嵌入。
|
|
||||||
|
|
||||||
## 3. Nginx 内部鉴权接口
|
|
||||||
|
|
||||||
```http
|
|
||||||
GET /internal/v1/jupyter/authorize
|
|
||||||
Cookie: jupyter_access=<opaque-ticket>
|
|
||||||
X-Original-URI: /jupyter/...
|
|
||||||
X-Request-ID: <request-id>
|
|
||||||
```
|
|
||||||
|
|
||||||
该接口只允许 Nginx 在内部网络调用:
|
|
||||||
|
|
||||||
- `204`:票据有效,响应头提供上游地址和内部认证信息。
|
|
||||||
- `401`:票据缺失、伪造或过期。
|
|
||||||
- `403`:用户、Workspace、Session 不匹配,或编辑锁/Runtime 已失效。
|
|
||||||
|
|
||||||
成功响应头:
|
|
||||||
|
|
||||||
```http
|
|
||||||
X-Jupyter-Upstream: http://jupyter:8888
|
|
||||||
X-Jupyter-Authorization: token <internal-token>
|
|
||||||
X-Workspace-ID: <workspace-id>
|
|
||||||
```
|
|
||||||
|
|
||||||
Nginx 必须删除客户端传入的 `Authorization`,使用内部鉴权结果重建上游
|
|
||||||
认证头。
|
|
||||||
|
|
||||||
## 4. WebSocket 约束
|
|
||||||
|
|
||||||
- `/jupyter/api/kernels/*/channels` 与其他 WebSocket 路径使用 HTTP/1.1。
|
|
||||||
- 转发 `Upgrade`、`Connection`、`Host`、`Origin` 和请求 ID。
|
|
||||||
- 关闭代理缓冲,读超时不小于 3600 秒。
|
|
||||||
- HTTP 和 WebSocket 使用同一票据校验规则。
|
|
||||||
- 连接关闭只断开交互连接,不自动停止 Workspace Runtime。
|
|
||||||
- Compose Demo 使用最长 5 分钟票据;前端必须继续发送编辑锁心跳,并在
|
|
||||||
票据到期前重新签发。
|
|
||||||
- Jupyter Lab HTML 中出现的内部 Token 必须由 Nginx 在返回浏览器前清除。
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from dataclasses import dataclass
|
|
||||||
from datetime import datetime
|
|
||||||
from typing import Protocol
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class EnsureRuntimeRequest:
|
|
||||||
runtime_id: str
|
|
||||||
workspace_id: str
|
|
||||||
workspace_code: str
|
|
||||||
owner_user_id: str
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class RuntimeEndpoint:
|
|
||||||
runtime_id: str
|
|
||||||
runtime_type: str
|
|
||||||
provider: str
|
|
||||||
runtime_ref: str
|
|
||||||
internal_url: str
|
|
||||||
proxy_base_path: str
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class RuntimeHealth:
|
|
||||||
runtime_id: str
|
|
||||||
healthy: bool
|
|
||||||
checked_at: datetime
|
|
||||||
detail: str | None = None
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class CreateSessionRequest:
|
|
||||||
runtime_id: str
|
|
||||||
workspace_code: str
|
|
||||||
relative_path: str
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class RuntimeSession:
|
|
||||||
runtime_id: str
|
|
||||||
session_id: str
|
|
||||||
jupyter_url: str
|
|
||||||
reused: bool
|
|
||||||
|
|
||||||
|
|
||||||
class RuntimeAdapter(Protocol):
|
|
||||||
async def ensure_running(
|
|
||||||
self,
|
|
||||||
request: EnsureRuntimeRequest,
|
|
||||||
) -> RuntimeEndpoint: ...
|
|
||||||
|
|
||||||
async def stop(self, runtime_id: str, reason: str) -> None: ...
|
|
||||||
|
|
||||||
async def restart(self, runtime_id: str) -> RuntimeEndpoint: ...
|
|
||||||
|
|
||||||
async def health(self, runtime_id: str) -> RuntimeHealth: ...
|
|
||||||
|
|
||||||
async def create_session(
|
|
||||||
self,
|
|
||||||
request: CreateSessionRequest,
|
|
||||||
) -> RuntimeSession: ...
|
|
||||||
|
|
||||||
async def terminate_session(
|
|
||||||
self,
|
|
||||||
runtime_id: str,
|
|
||||||
session_id: str,
|
|
||||||
) -> None: ...
|
|
||||||
@@ -1,122 +0,0 @@
|
|||||||
# 调度定义 API 契约 V1
|
|
||||||
|
|
||||||
冻结日期:2026-07-28
|
|
||||||
状态:`implemented`
|
|
||||||
|
|
||||||
## 1. 范围
|
|
||||||
|
|
||||||
本契约只覆盖调度定义,不触发任务执行:
|
|
||||||
|
|
||||||
- 调度方案增删改查;
|
|
||||||
- 稳定版本制品列表;
|
|
||||||
- 节点和连线增删改;
|
|
||||||
- 五段 Cron 校验与未来时间预览;
|
|
||||||
- DAG 完整性和有向无环校验。
|
|
||||||
|
|
||||||
立即运行、Cron 自动触发和 Executor 执行已经由独立 Schedule 服务承接。
|
|
||||||
|
|
||||||
## 2. 请求上下文
|
|
||||||
|
|
||||||
所有接口都要求:
|
|
||||||
|
|
||||||
| Header | 含义 |
|
|
||||||
|---|---|
|
|
||||||
| `X-User-ID` | 当前用户 |
|
|
||||||
| `X-Workspace-ID` | 当前 Workspace |
|
|
||||||
| `X-Request-ID` | 请求追踪 ID;可省略,由服务端生成 |
|
|
||||||
|
|
||||||
服务端只返回当前 Workspace 的调度。节点引用的 `versions_id` 必须属于当前
|
|
||||||
Workspace,且当前用户有权读取。
|
|
||||||
|
|
||||||
## 3. HTTP 接口
|
|
||||||
|
|
||||||
| 方法 | 路径 | 作用 |
|
|
||||||
|---|---|---|
|
|
||||||
| `GET` | `/api/v1/schedule-artifacts` | 查询可加入调度的稳定版本 |
|
|
||||||
| `POST` | `/api/v1/cron/preview` | 校验 Cron 并预览未来时间 |
|
|
||||||
| `GET` | `/api/v1/schedules` | 查询调度列表 |
|
|
||||||
| `POST` | `/api/v1/schedules` | 新建调度 |
|
|
||||||
| `GET` | `/api/v1/schedules/{schedule_id}` | 查询调度及完整 DAG |
|
|
||||||
| `PUT/PATCH` | `/api/v1/schedules/{schedule_id}` | 修改调度基本信息 |
|
|
||||||
| `DELETE` | `/api/v1/schedules/{schedule_id}` | 软删除调度 |
|
|
||||||
| `POST` | `/api/v1/schedules/{schedule_id}/nodes` | 新建节点 |
|
|
||||||
| `PUT` | `/api/v1/schedules/{schedule_id}/nodes/{node_id}` | 修改节点 |
|
|
||||||
| `DELETE` | `/api/v1/schedules/{schedule_id}/nodes/{node_id}` | 删除节点及关联连线 |
|
|
||||||
| `POST` | `/api/v1/schedules/{schedule_id}/edges` | 新建有向连线 |
|
|
||||||
| `PUT` | `/api/v1/schedules/{schedule_id}/edges/{edge_id}` | 修改连线条件 |
|
|
||||||
| `DELETE` | `/api/v1/schedules/{schedule_id}/edges/{edge_id}` | 删除连线 |
|
|
||||||
| `POST` | `/api/v1/schedules/{schedule_id}/validate` | 校验当前 DAG |
|
|
||||||
|
|
||||||
成功响应统一为:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"request_id": "01...",
|
|
||||||
"data": {},
|
|
||||||
"meta": {}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 4. 并发修改契约
|
|
||||||
|
|
||||||
新建调度时 `workflow_version=1`。每次修改调度、节点或连线都必须在请求体中
|
|
||||||
提交当前 `workflow_version`,成功后版本号加一。
|
|
||||||
|
|
||||||
版本不一致时返回 `412 Precondition Failed`:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"detail": {
|
|
||||||
"code": "WORKFLOW_VERSION_CONFLICT",
|
|
||||||
"message": "schedule was modified by another request",
|
|
||||||
"expected": 3,
|
|
||||||
"current": 4
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
前端收到 `412` 后必须重新读取调度,不得用旧画布直接覆盖。
|
|
||||||
|
|
||||||
## 5. 调度与 Cron 约束
|
|
||||||
|
|
||||||
- `trigger_type`:`manual / cron / api`;
|
|
||||||
- `failure_policy`:`stop / continue`;
|
|
||||||
- Cron 固定为五段:`minute hour day month weekday`;
|
|
||||||
- 时区使用 IANA 名称,例如 `Asia/Shanghai`;
|
|
||||||
- `cron` 类型必须提供 `cron_expression`,其他类型不得提供;
|
|
||||||
- 新建的空调度不能直接启用;
|
|
||||||
- 只有 DAG 校验通过的调度才能设为 `enabled=true`;
|
|
||||||
- `next_run_at` 在数据库和接口中按 UTC 保存和返回。
|
|
||||||
|
|
||||||
Cron 预览请求示例:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"cron_expression": "*/5 * * * *",
|
|
||||||
"timezone": "Asia/Shanghai",
|
|
||||||
"count": 5,
|
|
||||||
"base_time": "2026-07-28T08:00:00+08:00"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 6. 节点与 DAG 约束
|
|
||||||
|
|
||||||
- 节点必须引用不可变稳定版本 `versions_id`,不能引用工作副本;
|
|
||||||
- 同一个调度内 `node_key` 唯一;
|
|
||||||
- 节点保存超时、重试、位置、参数和环境引用;
|
|
||||||
- 连线的起点、终点必须属于同一调度;
|
|
||||||
- 不允许自环、重复连线和有向环;
|
|
||||||
- 删除节点会同时删除与该节点相连的边;
|
|
||||||
- 已有运行历史的节点不能物理删除;
|
|
||||||
- 校验结果返回根节点、叶节点、拓扑顺序和错误列表。
|
|
||||||
|
|
||||||
## 7. 典型状态码
|
|
||||||
|
|
||||||
| 状态码 | 场景 |
|
|
||||||
|---|---|
|
|
||||||
| `201` | 调度、节点或连线创建成功 |
|
|
||||||
| `404` | 调度、稳定版本、节点或连线不存在/不可见 |
|
|
||||||
| `409` | 名称冲突、重复连线、DAG 成环或无效 DAG 启用 |
|
|
||||||
| `412` | `workflow_version` 已过期 |
|
|
||||||
| `422` | 请求字段、Cron、时区或节点归属不合法 |
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user