From 80f2bd32d96726203f5c466778cd26a1aed20a31 Mon Sep 17 00:00:00 2001 From: dailz Date: Thu, 16 Apr 2026 15:15:31 +0800 Subject: [PATCH] =?UTF-8?q?docs(openapi):=20update=20spec=20to=20match=20c?= =?UTF-8?q?ode=20=E2=80=94=20add=20Tasks,=20fix=20schemas,=20remove=20subm?= =?UTF-8?q?it=20endpoint?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add Tasks tag, /tasks paths, and Task schemas (CreateTaskRequest, TaskResponse, TaskListResponse) - Fix SubmitJobRequest.work_dir, InitUploadRequest mime_type/chunk_size, UploadSessionResponse.created_at - Fix FolderResponse: add file_count/subfolder_count, remove updated_at - Fix response wrapping for File/Upload/Folder endpoints to use ApiResponseSuccess - Remove /applications/{id}/submit path and ApplicationSubmitRequest schema - Update Applications tag description Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- hpc_server_openapi.json | 480 +++++++++++++++++++++++++++++++--------- 1 file changed, 376 insertions(+), 104 deletions(-) diff --git a/hpc_server_openapi.json b/hpc_server_openapi.json index 64dbc1e..a05608b 100644 --- a/hpc_server_openapi.json +++ b/hpc_server_openapi.json @@ -22,7 +22,7 @@ }, { "name": "Applications", - "description": "Application definition CRUD and job submission" + "description": "Application definition CRUD" }, { "name": "File Uploads", @@ -35,6 +35,10 @@ { "name": "Folders", "description": "Folder CRUD with materialized path hierarchy" + }, + { + "name": "Tasks", + "description": "Task creation, listing, and lifecycle management" } ], "paths": { @@ -1002,79 +1006,6 @@ } } }, - "/applications/{id}/submit": { - "post": { - "tags": ["Applications"], - "summary": "Submit a job from an application", - "description": "Submits a Slurm job using the application's script template and provided parameter values.", - "operationId": "submitApplication", - "parameters": [ - { "$ref": "#/components/parameters/ApplicationId" } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ApplicationSubmitRequest" - } - } - } - }, - "responses": { - "201": { - "description": "Job submitted successfully", - "content": { - "application/json": { - "schema": { - "allOf": [ - { "$ref": "#/components/schemas/ApiResponseSuccess" }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/components/schemas/JobResponse" - } - } - } - ] - } - } - } - }, - "400": { - "description": "Invalid request body or missing required parameter values", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ApiResponseError" - } - } - } - }, - "404": { - "description": "Application not found", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ApiResponseError" - } - } - } - }, - "502": { - "description": "Slurm backend error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ApiResponseError" - } - } - } - } - } - } - }, "/diag": { "get": { "tags": ["Cluster"], @@ -1138,7 +1069,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UploadSessionResponse" + "allOf": [ + { "$ref": "#/components/schemas/ApiResponseSuccess" }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/UploadSessionResponse" + } + } + } + ] } } } @@ -1148,7 +1089,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/FileResponse" + "allOf": [ + { "$ref": "#/components/schemas/ApiResponseSuccess" }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/FileResponse" + } + } + } + ] } } } @@ -1262,7 +1213,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/FileResponse" + "allOf": [ + { "$ref": "#/components/schemas/ApiResponseSuccess" }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/FileResponse" + } + } + } + ] } } } @@ -1317,7 +1278,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UploadSessionResponse" + "allOf": [ + { "$ref": "#/components/schemas/ApiResponseSuccess" }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/UploadSessionResponse" + } + } + } + ] } } } @@ -1418,7 +1389,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/FileListResponse" + "allOf": [ + { "$ref": "#/components/schemas/ApiResponseSuccess" }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/FileListResponse" + } + } + } + ] } } } @@ -1452,7 +1433,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/FileResponse" + "allOf": [ + { "$ref": "#/components/schemas/ApiResponseSuccess" }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/FileResponse" + } + } + } + ] } } } @@ -1602,7 +1593,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/FolderResponse" + "allOf": [ + { "$ref": "#/components/schemas/ApiResponseSuccess" }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/FolderResponse" + } + } + } + ] } } } @@ -1648,10 +1649,20 @@ "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/FolderResponse" - } + "allOf": [ + { "$ref": "#/components/schemas/ApiResponseSuccess" }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FolderResponse" + } + } + } + } + ] } } } @@ -1685,7 +1696,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/FolderResponse" + "allOf": [ + { "$ref": "#/components/schemas/ApiResponseSuccess" }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/FolderResponse" + } + } + } + ] } } } @@ -1758,6 +1779,144 @@ } } } + }, + "/tasks": { + "post": { + "tags": ["Tasks"], + "summary": "Create a new task", + "description": "Creates an HPC task from an application definition with parameter values.", + "operationId": "createTask", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateTaskRequest" + } + } + } + }, + "responses": { + "201": { + "description": "Task created successfully", + "content": { + "application/json": { + "schema": { + "allOf": [ + { "$ref": "#/components/schemas/ApiResponseSuccess" }, + { + "type": "object", + "properties": { + "data": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "Created task ID" + } + } + } + } + } + ] + } + } + } + }, + "400": { + "description": "Invalid request body", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiResponseError" + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiResponseError" + } + } + } + } + } + }, + "get": { + "tags": ["Tasks"], + "summary": "List tasks", + "description": "Retrieves a paginated list of tasks with optional status filter.", + "operationId": "listTasks", + "parameters": [ + { + "name": "page", + "in": "query", + "description": "Page number (starts from 1)", + "required": false, + "schema": { + "type": "integer", + "minimum": 1, + "default": 1 + } + }, + { + "name": "page_size", + "in": "query", + "description": "Number of items per page", + "required": false, + "schema": { + "type": "integer", + "minimum": 1, + "default": 20 + } + }, + { + "name": "status", + "in": "query", + "description": "Filter by task status", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Paginated list of tasks", + "content": { + "application/json": { + "schema": { + "allOf": [ + { "$ref": "#/components/schemas/ApiResponseSuccess" }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/TaskListResponse" + } + } + } + ] + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiResponseError" + } + } + } + } + } + } } }, "components": { @@ -1907,6 +2066,10 @@ "type": "string" }, "description": "Environment variables" + }, + "work_dir": { + "type": "string", + "description": "Job working directory" } } }, @@ -2448,19 +2611,6 @@ } } }, - "ApplicationSubmitRequest": { - "type": "object", - "required": ["values"], - "properties": { - "values": { - "type": "object", - "additionalProperties": { - "type": "string" - }, - "description": "Parameter name to value mapping" - } - } - }, "ApplicationListResponse": { "type": "object", "properties": { @@ -2487,7 +2637,7 @@ }, "InitUploadRequest": { "type": "object", - "required": ["file_name", "file_size", "sha256", "chunk_size"], + "required": ["file_name", "file_size", "sha256"], "properties": { "file_name": { "type": "string", @@ -2512,6 +2662,10 @@ "format": "int64", "description": "Target folder ID (null for root)", "nullable": true + }, + "mime_type": { + "type": "string", + "description": "MIME type of the file" } } }, @@ -2561,6 +2715,11 @@ "type": "string", "format": "date-time", "description": "Session expiration time" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Session creation time" } } }, @@ -2651,11 +2810,17 @@ "type": "string", "description": "Materialized path (e.g. /data/reports/)" }, - "created_at": { - "type": "string", - "format": "date-time" + "file_count": { + "type": "integer", + "format": "int64", + "description": "Number of files in this folder" }, - "updated_at": { + "subfolder_count": { + "type": "integer", + "format": "int64", + "description": "Number of sub-folders in this folder" + }, + "created_at": { "type": "string", "format": "date-time" } @@ -2676,6 +2841,113 @@ "nullable": true } } + }, + "CreateTaskRequest": { + "type": "object", + "required": ["app_id"], + "properties": { + "app_id": { + "type": "integer", + "format": "int64", + "description": "Application ID to create task from" + }, + "task_name": { + "type": "string", + "description": "Task name" + }, + "values": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Parameter name to value mapping" + }, + "file_ids": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "Input file IDs" + } + } + }, + "TaskResponse": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "description": "Task ID" + }, + "task_name": { + "type": "string", + "description": "Task name" + }, + "app_id": { + "type": "integer", + "format": "int64", + "description": "Application ID" + }, + "app_name": { + "type": "string", + "description": "Application name" + }, + "status": { + "type": "string", + "description": "Task status", + "enum": ["submitted", "preparing", "downloading", "ready", "queued", "running", "completed", "failed"] + }, + "current_step": { + "type": "string", + "description": "Current processing step" + }, + "retry_count": { + "type": "integer", + "description": "Number of retries" + }, + "slurm_job_id": { + "type": "integer", + "format": "int32", + "description": "Slurm job ID", + "nullable": true + }, + "work_dir": { + "type": "string", + "description": "Working directory" + }, + "error_message": { + "type": "string", + "description": "Error message if failed" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "Creation timestamp" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "Last update timestamp" + } + } + }, + "TaskListResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TaskResponse" + }, + "description": "List of tasks" + }, + "total": { + "type": "integer", + "format": "int64", + "description": "Total number of matching tasks" + } + } } } }