Files
model-platform/contracts/openapi/demo-core-extension-v1.yaml
T

1094 lines
30 KiB
YAML

openapi: 3.1.0
info:
title: Model Platform Demo Core Extension
version: 1.0.0
description: |
第 15 小步冻结的快速 Demo 目标契约。此文件只描述尚待实现的公共接口;
已实现的脚本、稳定版本详情、文件锁和数据资源接口继续以
platform-api-v1.yaml 为准。两个文件共同组成 Demo 公共 API v1。
当前身份仍使用 X-User-ID 与 X-Workspace-ID,后续替换 JWT 时不改变业务 DTO。
x-implementation-status: frozen-target
paths:
/api/v1/session-context:
get:
tags: [context]
operationId: getSessionContext
summary: 获取当前用户、Workspace 和可切换上下文
parameters:
- $ref: '#/components/parameters/XUserId'
- $ref: '#/components/parameters/XWorkspaceId'
- $ref: '#/components/parameters/XRequestId'
responses:
'200':
description: 当前演示上下文
content:
application/json:
schema:
$ref: '#/components/schemas/SessionContextResponse'
'403':
$ref: '#/components/responses/ErrorResponse'
/api/v1/jupyter/access-tickets:
post:
tags: [jupyter]
operationId: createJupyterAccessTicket
x-implementation-status: implemented-step16
summary: 为已加锁编辑会话签发短期 Jupyter 访问票据
description: |
必须校验 edit_session_id、用户、Workspace 和 lock_token。
成功响应同时设置 HttpOnly、SameSite=Lax、Path=/jupyter/ 的
jupyter_access Cookie,浏览器不得获得 Jupyter 内部服务 token。
parameters:
- $ref: '#/components/parameters/XUserId'
- $ref: '#/components/parameters/XWorkspaceId'
- $ref: '#/components/parameters/XRequestId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateJupyterAccessTicketRequest'
responses:
'201':
description: 访问票据已签发
headers:
Set-Cookie:
schema:
type: string
description: jupyter_access HttpOnly Cookie
content:
application/json:
schema:
$ref: '#/components/schemas/JupyterAccessTicketResponse'
'403':
$ref: '#/components/responses/ErrorResponse'
'409':
$ref: '#/components/responses/ErrorResponse'
/api/v1/versions:
get:
tags: [versions]
operationId: listStableVersions
summary: 获取调度画布可用的稳定版本
parameters:
- $ref: '#/components/parameters/XUserId'
- $ref: '#/components/parameters/XWorkspaceId'
- $ref: '#/components/parameters/XRequestId'
- name: keyword
in: query
required: false
schema:
type: string
maxLength: 100
- name: script_type
in: query
required: false
schema:
type: string
enum: [python, notebook]
- name: limit
in: query
required: false
schema:
type: integer
minimum: 1
maximum: 200
default: 100
responses:
'200':
description: 当前 Workspace 可见稳定版本
content:
application/json:
schema:
$ref: '#/components/schemas/StableVersionListResponse'
'403':
$ref: '#/components/responses/ErrorResponse'
/api/v1/schedules:
get:
tags: [schedules]
operationId: listSchedules
summary: 查询调度方案
parameters:
- $ref: '#/components/parameters/XUserId'
- $ref: '#/components/parameters/XWorkspaceId'
- $ref: '#/components/parameters/XRequestId'
- name: keyword
in: query
required: false
schema:
type: string
maxLength: 100
- name: enabled
in: query
required: false
schema:
type: boolean
responses:
'200':
description: 调度方案列表
content:
application/json:
schema:
$ref: '#/components/schemas/ScheduleListResponse'
'403':
$ref: '#/components/responses/ErrorResponse'
post:
tags: [schedules]
operationId: createSchedule
summary: 创建调度方案及完整 DAG
parameters:
- $ref: '#/components/parameters/XUserId'
- $ref: '#/components/parameters/XWorkspaceId'
- $ref: '#/components/parameters/XRequestId'
- $ref: '#/components/parameters/IdempotencyKey'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateScheduleRequest'
responses:
'201':
description: 调度方案已创建
content:
application/json:
schema:
$ref: '#/components/schemas/ScheduleResponse'
'409':
$ref: '#/components/responses/ErrorResponse'
'422':
$ref: '#/components/responses/ErrorResponse'
/api/v1/schedules/preview:
post:
tags: [schedules]
operationId: previewScheduleCron
summary: 校验 Cron 并预览未来执行时间
parameters:
- $ref: '#/components/parameters/XUserId'
- $ref: '#/components/parameters/XWorkspaceId'
- $ref: '#/components/parameters/XRequestId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CronPreviewRequest'
responses:
'200':
description: Cron 有效
content:
application/json:
schema:
$ref: '#/components/schemas/CronPreviewResponse'
'422':
$ref: '#/components/responses/ErrorResponse'
/api/v1/schedules/{schedule_id}:
parameters:
- $ref: '#/components/parameters/ScheduleId'
get:
tags: [schedules]
operationId: getSchedule
summary: 获取调度方案及完整 DAG
parameters:
- $ref: '#/components/parameters/XUserId'
- $ref: '#/components/parameters/XWorkspaceId'
- $ref: '#/components/parameters/XRequestId'
responses:
'200':
description: 调度方案详情
content:
application/json:
schema:
$ref: '#/components/schemas/ScheduleResponse'
'404':
$ref: '#/components/responses/ErrorResponse'
put:
tags: [schedules]
operationId: updateSchedule
summary: 使用 workflow_version 乐观锁替换调度方案和 DAG
parameters:
- $ref: '#/components/parameters/XUserId'
- $ref: '#/components/parameters/XWorkspaceId'
- $ref: '#/components/parameters/XRequestId'
- $ref: '#/components/parameters/IdempotencyKey'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateScheduleRequest'
responses:
'200':
description: 调度方案已更新,workflow_version 已递增
content:
application/json:
schema:
$ref: '#/components/schemas/ScheduleResponse'
'404':
$ref: '#/components/responses/ErrorResponse'
'409':
$ref: '#/components/responses/ErrorResponse'
'412':
$ref: '#/components/responses/ErrorResponse'
'422':
$ref: '#/components/responses/ErrorResponse'
delete:
tags: [schedules]
operationId: deleteSchedule
summary: 软删除调度方案并保留历史运行
parameters:
- $ref: '#/components/parameters/XUserId'
- $ref: '#/components/parameters/XWorkspaceId'
- $ref: '#/components/parameters/XRequestId'
responses:
'200':
description: 调度方案已删除
content:
application/json:
schema:
$ref: '#/components/schemas/ScheduleResponse'
'404':
$ref: '#/components/responses/ErrorResponse'
/api/v1/schedules/{schedule_id}/run:
post:
tags: [schedule-runs]
operationId: runScheduleNow
summary: 为当前 workflow_version 创建一次立即运行
parameters:
- $ref: '#/components/parameters/ScheduleId'
- $ref: '#/components/parameters/XUserId'
- $ref: '#/components/parameters/XWorkspaceId'
- $ref: '#/components/parameters/XRequestId'
- $ref: '#/components/parameters/IdempotencyKey'
requestBody:
required: false
content:
application/json:
schema:
$ref: '#/components/schemas/RunScheduleRequest'
responses:
'202':
description: 运行事件已进入 Transactional Outbox
content:
application/json:
schema:
$ref: '#/components/schemas/ScheduleRunResponse'
'404':
$ref: '#/components/responses/ErrorResponse'
'409':
$ref: '#/components/responses/ErrorResponse'
/api/v1/schedules/{schedule_id}/enable:
post:
tags: [schedules]
operationId: enableSchedule
summary: 启用 Cron 调度
parameters:
- $ref: '#/components/parameters/ScheduleId'
- $ref: '#/components/parameters/XUserId'
- $ref: '#/components/parameters/XWorkspaceId'
- $ref: '#/components/parameters/XRequestId'
- $ref: '#/components/parameters/IdempotencyKey'
responses:
'200':
description: 调度已启用
content:
application/json:
schema:
$ref: '#/components/schemas/ScheduleResponse'
'404':
$ref: '#/components/responses/ErrorResponse'
'409':
$ref: '#/components/responses/ErrorResponse'
/api/v1/schedules/{schedule_id}/disable:
post:
tags: [schedules]
operationId: disableSchedule
summary: 暂停 Cron 调度
parameters:
- $ref: '#/components/parameters/ScheduleId'
- $ref: '#/components/parameters/XUserId'
- $ref: '#/components/parameters/XWorkspaceId'
- $ref: '#/components/parameters/XRequestId'
- $ref: '#/components/parameters/IdempotencyKey'
responses:
'200':
description: 调度已暂停
content:
application/json:
schema:
$ref: '#/components/schemas/ScheduleResponse'
'404':
$ref: '#/components/responses/ErrorResponse'
/api/v1/schedule-runs:
get:
tags: [schedule-runs]
operationId: listScheduleRuns
summary: 查询最近调度运行
parameters:
- $ref: '#/components/parameters/XUserId'
- $ref: '#/components/parameters/XWorkspaceId'
- $ref: '#/components/parameters/XRequestId'
- name: schedule_id
in: query
required: false
schema:
$ref: '#/components/schemas/Ulid'
- name: status
in: query
required: false
schema:
$ref: '#/components/schemas/RunStatus'
- name: limit
in: query
required: false
schema:
type: integer
minimum: 1
maximum: 200
default: 50
responses:
'200':
description: 最近运行列表
content:
application/json:
schema:
$ref: '#/components/schemas/ScheduleRunListResponse'
'403':
$ref: '#/components/responses/ErrorResponse'
/api/v1/schedule-runs/{run_id}:
get:
tags: [schedule-runs]
operationId: getScheduleRun
summary: 获取运行及各节点状态
parameters:
- $ref: '#/components/parameters/RunId'
- $ref: '#/components/parameters/XUserId'
- $ref: '#/components/parameters/XWorkspaceId'
- $ref: '#/components/parameters/XRequestId'
responses:
'200':
description: 调度运行详情
content:
application/json:
schema:
$ref: '#/components/schemas/ScheduleRunResponse'
'404':
$ref: '#/components/responses/ErrorResponse'
/api/v1/schedule-runs/{run_id}/cancel:
post:
tags: [schedule-runs]
operationId: cancelScheduleRun
summary: 请求取消尚未结束的调度运行
parameters:
- $ref: '#/components/parameters/RunId'
- $ref: '#/components/parameters/XUserId'
- $ref: '#/components/parameters/XWorkspaceId'
- $ref: '#/components/parameters/XRequestId'
- $ref: '#/components/parameters/IdempotencyKey'
responses:
'202':
description: 取消请求已接受
content:
application/json:
schema:
$ref: '#/components/schemas/ScheduleRunResponse'
'404':
$ref: '#/components/responses/ErrorResponse'
'409':
$ref: '#/components/responses/ErrorResponse'
components:
parameters:
XUserId:
name: X-User-ID
in: header
required: true
schema:
$ref: '#/components/schemas/Ulid'
XWorkspaceId:
name: X-Workspace-ID
in: header
required: true
schema:
$ref: '#/components/schemas/Ulid'
XRequestId:
name: X-Request-ID
in: header
required: false
schema:
type: string
minLength: 1
maxLength: 64
IdempotencyKey:
name: Idempotency-Key
in: header
required: true
schema:
type: string
minLength: 8
maxLength: 128
ScheduleId:
name: schedule_id
in: path
required: true
schema:
$ref: '#/components/schemas/Ulid'
RunId:
name: run_id
in: path
required: true
schema:
$ref: '#/components/schemas/Ulid'
responses:
ErrorResponse:
description: 标准错误响应
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorEnvelope'
schemas:
Ulid:
type: string
minLength: 26
maxLength: 26
pattern: '^[0-9A-HJKMNP-TV-Z]{26}$'
UtcDateTime:
type: string
format: date-time
RunStatus:
type: string
enum: [queued, running, succeeded, failed, cancelled, timed_out]
NodeRunStatus:
type: string
enum: [queued, running, succeeded, failed, skipped, cancelled, timed_out]
ErrorEnvelope:
type: object
additionalProperties: false
required: [request_id, error]
properties:
request_id:
type: string
error:
type: object
additionalProperties: false
required: [code, message, retryable, details]
properties:
code:
type: string
pattern: '^[A-Z][A-Z0-9_]+$'
message:
type: string
retryable:
type: boolean
details:
type: object
UserSummary:
type: object
additionalProperties: false
required: [user_id, username, display_name, role_code]
properties:
user_id:
$ref: '#/components/schemas/Ulid'
username:
type: string
display_name:
type: string
role_code:
type: string
WorkspaceSummary:
type: object
additionalProperties: false
required: [workspace_id, workspace_code, workspace_name]
properties:
workspace_id:
$ref: '#/components/schemas/Ulid'
workspace_code:
type: string
workspace_name:
type: string
SessionContextResponse:
type: object
additionalProperties: false
required: [request_id, data, meta]
properties:
request_id:
type: string
data:
type: object
additionalProperties: false
required: [current_user, current_workspace, workspaces, workspace_members]
properties:
current_user:
$ref: '#/components/schemas/UserSummary'
current_workspace:
$ref: '#/components/schemas/WorkspaceSummary'
workspaces:
type: array
items:
$ref: '#/components/schemas/WorkspaceSummary'
workspace_members:
type: array
items:
$ref: '#/components/schemas/UserSummary'
meta:
type: object
CreateJupyterAccessTicketRequest:
type: object
additionalProperties: false
required: [edit_session_id, lock_token]
properties:
edit_session_id:
$ref: '#/components/schemas/Ulid'
lock_token:
type: string
minLength: 32
maxLength: 256
JupyterAccessTicketResponse:
type: object
additionalProperties: false
required: [request_id, data, meta]
properties:
request_id:
type: string
data:
type: object
additionalProperties: false
required: [edit_session_id, jupyter_url, expires_at]
properties:
edit_session_id:
$ref: '#/components/schemas/Ulid'
jupyter_url:
type: string
pattern: '^/jupyter/'
expires_at:
$ref: '#/components/schemas/UtcDateTime'
meta:
type: object
StableVersionSummary:
type: object
additionalProperties: false
required:
- versions_id
- script_id
- script_name
- script_type
- version_label
- artifact_object_id
- source_path
- visibility
- created_by
- created_at
properties:
versions_id:
$ref: '#/components/schemas/Ulid'
script_id:
$ref: '#/components/schemas/Ulid'
script_name:
type: string
script_type:
type: string
enum: [python, notebook]
version_label:
type: string
artifact_object_id:
$ref: '#/components/schemas/Ulid'
source_path:
type: string
visibility:
type: string
enum: [private, workspace, public]
created_by:
$ref: '#/components/schemas/Ulid'
created_at:
$ref: '#/components/schemas/UtcDateTime'
StableVersionListResponse:
type: object
additionalProperties: false
required: [request_id, data, meta]
properties:
request_id:
type: string
data:
type: array
items:
$ref: '#/components/schemas/StableVersionSummary'
meta:
type: object
required: [count]
properties:
count:
type: integer
minimum: 0
ScheduleNodeInput:
type: object
required:
- node_key
- node_name
- versions_id
- timeout_seconds
- retry_count
- retry_interval_sec
- position_x
- position_y
- arguments
properties:
node_key:
type: string
minLength: 1
maxLength: 64
pattern: '^[A-Za-z0-9_-]+$'
node_name:
type: string
minLength: 1
maxLength: 255
versions_id:
$ref: '#/components/schemas/Ulid'
timeout_seconds:
type: integer
minimum: 1
maximum: 86400
default: 600
retry_count:
type: integer
minimum: 0
maximum: 10
default: 0
retry_interval_sec:
type: integer
minimum: 0
maximum: 3600
default: 5
position_x:
type: number
position_y:
type: number
arguments:
type: array
maxItems: 100
items:
type: string
maxLength: 1000
ScheduleEdgeInput:
type: object
required: [source_node_key, target_node_key]
properties:
source_node_key:
type: string
minLength: 1
maxLength: 64
target_node_key:
type: string
minLength: 1
maxLength: 64
ScheduleDefinitionBase:
type: object
required:
- schedule_name
- trigger_type
- timezone
- max_concurrency
- failure_policy
- nodes
- edges
properties:
schedule_name:
type: string
minLength: 1
maxLength: 255
description:
type: [string, 'null']
maxLength: 1000
trigger_type:
type: string
enum: [manual, cron, api]
default: cron
cron_expression:
type: [string, 'null']
maxLength: 128
timezone:
type: string
minLength: 1
maxLength: 64
default: Asia/Shanghai
max_concurrency:
type: integer
minimum: 1
maximum: 100
default: 1
failure_policy:
type: string
enum: [stop, continue]
default: stop
nodes:
type: array
minItems: 1
maxItems: 100
items:
$ref: '#/components/schemas/ScheduleNodeInput'
edges:
type: array
maxItems: 500
items:
$ref: '#/components/schemas/ScheduleEdgeInput'
CreateScheduleRequest:
unevaluatedProperties: false
allOf:
- $ref: '#/components/schemas/ScheduleDefinitionBase'
UpdateScheduleRequest:
unevaluatedProperties: false
allOf:
- $ref: '#/components/schemas/ScheduleDefinitionBase'
- type: object
required: [workflow_version]
properties:
workflow_version:
type: integer
minimum: 1
ScheduleNode:
unevaluatedProperties: false
allOf:
- $ref: '#/components/schemas/ScheduleNodeInput'
- type: object
required: [node_id]
properties:
node_id:
$ref: '#/components/schemas/Ulid'
ScheduleEdge:
unevaluatedProperties: false
allOf:
- $ref: '#/components/schemas/ScheduleEdgeInput'
- type: object
required: [edge_id, source_node_id, target_node_id]
properties:
edge_id:
$ref: '#/components/schemas/Ulid'
source_node_id:
$ref: '#/components/schemas/Ulid'
target_node_id:
$ref: '#/components/schemas/Ulid'
Schedule:
type: object
additionalProperties: false
required:
- schedule_id
- workspace_id
- schedule_name
- trigger_type
- timezone
- enabled
- workflow_version
- max_concurrency
- failure_policy
- nodes
- edges
- created_by
- updated_by
- created_at
- updated_at
properties:
schedule_id:
$ref: '#/components/schemas/Ulid'
workspace_id:
$ref: '#/components/schemas/Ulid'
schedule_name:
type: string
description:
type: [string, 'null']
trigger_type:
type: string
enum: [manual, cron, api]
cron_expression:
type: [string, 'null']
timezone:
type: string
enabled:
type: boolean
workflow_version:
type: integer
minimum: 1
max_concurrency:
type: integer
failure_policy:
type: string
enum: [stop, continue]
next_run_at:
type: [string, 'null']
format: date-time
last_run_at:
type: [string, 'null']
format: date-time
nodes:
type: array
items:
$ref: '#/components/schemas/ScheduleNode'
edges:
type: array
items:
$ref: '#/components/schemas/ScheduleEdge'
created_by:
$ref: '#/components/schemas/Ulid'
updated_by:
$ref: '#/components/schemas/Ulid'
created_at:
$ref: '#/components/schemas/UtcDateTime'
updated_at:
$ref: '#/components/schemas/UtcDateTime'
ScheduleResponse:
type: object
additionalProperties: false
required: [request_id, data, meta]
properties:
request_id:
type: string
data:
$ref: '#/components/schemas/Schedule'
meta:
type: object
ScheduleListResponse:
type: object
additionalProperties: false
required: [request_id, data, meta]
properties:
request_id:
type: string
data:
type: array
items:
$ref: '#/components/schemas/Schedule'
meta:
type: object
required: [count]
properties:
count:
type: integer
minimum: 0
CronPreviewRequest:
type: object
additionalProperties: false
required: [cron_expression, timezone]
properties:
cron_expression:
type: string
minLength: 9
maxLength: 128
timezone:
type: string
minLength: 1
maxLength: 64
default: Asia/Shanghai
count:
type: integer
minimum: 1
maximum: 20
default: 5
CronPreviewResponse:
type: object
additionalProperties: false
required: [request_id, data, meta]
properties:
request_id:
type: string
data:
type: object
additionalProperties: false
required: [cron_expression, timezone, next_runs]
properties:
cron_expression:
type: string
timezone:
type: string
next_runs:
type: array
items:
$ref: '#/components/schemas/UtcDateTime'
meta:
type: object
RunScheduleRequest:
type: object
additionalProperties: false
properties:
reason:
type: string
maxLength: 255
default: manual_run
ScheduleRunSummary:
type: object
required:
- run_id
- schedule_id
- workspace_id
- workflow_version
- trigger_type
- run_status
- state_version
- queued_at
properties:
run_id:
$ref: '#/components/schemas/Ulid'
schedule_id:
$ref: '#/components/schemas/Ulid'
workspace_id:
$ref: '#/components/schemas/Ulid'
workflow_version:
type: integer
trigger_type:
type: string
enum: [manual, cron, api, retry]
run_status:
$ref: '#/components/schemas/RunStatus'
state_version:
type: integer
minimum: 0
queued_at:
$ref: '#/components/schemas/UtcDateTime'
started_at:
type: [string, 'null']
format: date-time
finished_at:
type: [string, 'null']
format: date-time
duration_ms:
type: [integer, 'null']
minimum: 0
error_code:
type: [string, 'null']
error_message:
type: [string, 'null']
logs_object_id:
oneOf:
- $ref: '#/components/schemas/Ulid'
- type: 'null'
result_object_id:
oneOf:
- $ref: '#/components/schemas/Ulid'
- type: 'null'
ScheduleNodeRun:
type: object
additionalProperties: false
required:
- node_run_id
- run_id
- node_id
- versions_id
- attempt_no
- node_status
- state_version
properties:
node_run_id:
$ref: '#/components/schemas/Ulid'
run_id:
$ref: '#/components/schemas/Ulid'
node_id:
$ref: '#/components/schemas/Ulid'
versions_id:
$ref: '#/components/schemas/Ulid'
attempt_no:
type: integer
minimum: 1
node_status:
$ref: '#/components/schemas/NodeRunStatus'
state_version:
type: integer
minimum: 0
started_at:
type: [string, 'null']
format: date-time
finished_at:
type: [string, 'null']
format: date-time
duration_ms:
type: [integer, 'null']
minimum: 0
exit_code:
type: [integer, 'null']
message:
type: [string, 'null']
logs_object_id:
oneOf:
- $ref: '#/components/schemas/Ulid'
- type: 'null'
result_object_id:
oneOf:
- $ref: '#/components/schemas/Ulid'
- type: 'null'
ScheduleRunDetail:
unevaluatedProperties: false
allOf:
- $ref: '#/components/schemas/ScheduleRunSummary'
- type: object
required: [node_runs]
properties:
node_runs:
type: array
items:
$ref: '#/components/schemas/ScheduleNodeRun'
ScheduleRunResponse:
type: object
additionalProperties: false
required: [request_id, data, meta]
properties:
request_id:
type: string
data:
$ref: '#/components/schemas/ScheduleRunDetail'
meta:
type: object
ScheduleRunListResponse:
type: object
additionalProperties: false
required: [request_id, data, meta]
properties:
request_id:
type: string
data:
type: array
items:
$ref: '#/components/schemas/ScheduleRunSummary'
meta:
type: object
required: [count]
properties:
count:
type: integer
minimum: 0