- 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 <clio-agent@sisyphuslabs.ai>
2955 lines
83 KiB
JSON
2955 lines
83 KiB
JSON
{
|
|
"openapi": "3.0.3",
|
|
"info": {
|
|
"title": "GCY HPC Server API",
|
|
"description": "Slurm HPC cluster management API for job submission and cluster monitoring.",
|
|
"version": "0.1.0"
|
|
},
|
|
"servers": [
|
|
{
|
|
"url": "/api/v1",
|
|
"description": "API v1"
|
|
}
|
|
],
|
|
"tags": [
|
|
{
|
|
"name": "Jobs",
|
|
"description": "Job submission, listing, cancellation, and history"
|
|
},
|
|
{
|
|
"name": "Cluster",
|
|
"description": "Cluster node, partition, and diagnostic information"
|
|
},
|
|
{
|
|
"name": "Applications",
|
|
"description": "Application definition CRUD"
|
|
},
|
|
{
|
|
"name": "File Uploads",
|
|
"description": "Chunked file upload with SHA256 dedup, breakpoint resume, and instant upload"
|
|
},
|
|
{
|
|
"name": "Files",
|
|
"description": "File listing, metadata, download (with Range support), and deletion"
|
|
},
|
|
{
|
|
"name": "Folders",
|
|
"description": "Folder CRUD with materialized path hierarchy"
|
|
},
|
|
{
|
|
"name": "Tasks",
|
|
"description": "Task creation, listing, and lifecycle management"
|
|
}
|
|
],
|
|
"paths": {
|
|
"/jobs/submit": {
|
|
"post": {
|
|
"tags": ["Jobs"],
|
|
"summary": "Submit a new job",
|
|
"description": "Submits a Slurm job with the specified script and optional parameters.",
|
|
"operationId": "submitJob",
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/SubmitJobRequest"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"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 fields",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
},
|
|
"examples": {
|
|
"invalid_body": {
|
|
"value": {
|
|
"success": false,
|
|
"error": "invalid request body"
|
|
}
|
|
},
|
|
"missing_script": {
|
|
"value": {
|
|
"success": false,
|
|
"error": "script is required"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"502": {
|
|
"description": "Slurm backend error",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/jobs": {
|
|
"get": {
|
|
"tags": ["Jobs"],
|
|
"summary": "List all jobs with pagination",
|
|
"description": "Retrieves a paginated list of all current jobs.",
|
|
"operationId": "getJobs",
|
|
"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
|
|
}
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Paginated list of jobs",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"allOf": [
|
|
{ "$ref": "#/components/schemas/ApiResponseSuccess" },
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"data": {
|
|
"$ref": "#/components/schemas/JobListResponse"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Invalid query parameters",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/jobs/history": {
|
|
"get": {
|
|
"tags": ["Jobs"],
|
|
"summary": "Get job history",
|
|
"description": "Retrieves paginated job history with optional filters.",
|
|
"operationId": "getJobHistory",
|
|
"parameters": [
|
|
{
|
|
"name": "users",
|
|
"in": "query",
|
|
"description": "Filter by username(s)",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "start_time",
|
|
"in": "query",
|
|
"description": "Filter by start time (Unix timestamp or date string)",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "end_time",
|
|
"in": "query",
|
|
"description": "Filter by end time (Unix timestamp or date string)",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "account",
|
|
"in": "query",
|
|
"description": "Filter by account",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "partition",
|
|
"in": "query",
|
|
"description": "Filter by partition",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "state",
|
|
"in": "query",
|
|
"description": "Filter by job state",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "job_name",
|
|
"in": "query",
|
|
"description": "Filter by job name",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "submit_time",
|
|
"in": "query",
|
|
"description": "Filter by submit time (Unix timestamp)",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "cluster",
|
|
"in": "query",
|
|
"description": "Filter by cluster name",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "qos",
|
|
"in": "query",
|
|
"description": "Filter by QOS policy",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "constraints",
|
|
"in": "query",
|
|
"description": "Filter by node constraints",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "exit_code",
|
|
"in": "query",
|
|
"description": "Filter by exit code",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "node",
|
|
"in": "query",
|
|
"description": "Filter by allocated node",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "reservation",
|
|
"in": "query",
|
|
"description": "Filter by reservation name",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "groups",
|
|
"in": "query",
|
|
"description": "Filter by user groups",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "wckey",
|
|
"in": "query",
|
|
"description": "Filter by WCKey (Workload Characterization Key)",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
{
|
|
"name": "page",
|
|
"in": "query",
|
|
"description": "Page number (default: 1)",
|
|
"schema": {
|
|
"type": "integer",
|
|
"minimum": 1,
|
|
"default": 1
|
|
}
|
|
},
|
|
{
|
|
"name": "page_size",
|
|
"in": "query",
|
|
"description": "Items per page (default: 20)",
|
|
"schema": {
|
|
"type": "integer",
|
|
"minimum": 1,
|
|
"default": 20
|
|
}
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Paginated job history",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"allOf": [
|
|
{ "$ref": "#/components/schemas/ApiResponseSuccess" },
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"data": {
|
|
"$ref": "#/components/schemas/JobListResponse"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Invalid query parameters",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/jobs/{id}": {
|
|
"get": {
|
|
"tags": ["Jobs"],
|
|
"summary": "Get job by ID",
|
|
"description": "Retrieves details for a specific job. If the job is not found in the active queue, automatically queries SlurmDBD history.",
|
|
"operationId": "getJob",
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/JobId"
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Job details",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"allOf": [
|
|
{ "$ref": "#/components/schemas/ApiResponseSuccess" },
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"data": {
|
|
"$ref": "#/components/schemas/JobResponse"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "Job not found",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"delete": {
|
|
"tags": ["Jobs"],
|
|
"summary": "Cancel a job",
|
|
"description": "Cancels a running or pending job by ID.",
|
|
"operationId": "cancelJob",
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/JobId"
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Job cancelled successfully",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"allOf": [
|
|
{ "$ref": "#/components/schemas/ApiResponseSuccess" },
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"message": {
|
|
"type": "string",
|
|
"example": "job cancelled"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"502": {
|
|
"description": "Slurm backend error",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/nodes": {
|
|
"get": {
|
|
"tags": ["Cluster"],
|
|
"summary": "List all nodes",
|
|
"description": "Retrieves a list of all cluster nodes.",
|
|
"operationId": "getNodes",
|
|
"responses": {
|
|
"200": {
|
|
"description": "List of nodes",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"allOf": [
|
|
{ "$ref": "#/components/schemas/ApiResponseSuccess" },
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"data": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/NodeResponse"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/nodes/{name}": {
|
|
"get": {
|
|
"tags": ["Cluster"],
|
|
"summary": "Get node by name",
|
|
"description": "Retrieves details for a specific cluster node.",
|
|
"operationId": "getNode",
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/NodeName"
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Node details",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"allOf": [
|
|
{ "$ref": "#/components/schemas/ApiResponseSuccess" },
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"data": {
|
|
"$ref": "#/components/schemas/NodeResponse"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "Node not found",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/partitions": {
|
|
"get": {
|
|
"tags": ["Cluster"],
|
|
"summary": "List all partitions",
|
|
"description": "Retrieves a list of all cluster partitions.",
|
|
"operationId": "getPartitions",
|
|
"responses": {
|
|
"200": {
|
|
"description": "List of partitions",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"allOf": [
|
|
{ "$ref": "#/components/schemas/ApiResponseSuccess" },
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"data": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/PartitionResponse"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/partitions/{name}": {
|
|
"get": {
|
|
"tags": ["Cluster"],
|
|
"summary": "Get partition by name",
|
|
"description": "Retrieves details for a specific cluster partition.",
|
|
"operationId": "getPartition",
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/PartitionName"
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Partition details",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"allOf": [
|
|
{ "$ref": "#/components/schemas/ApiResponseSuccess" },
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"data": {
|
|
"$ref": "#/components/schemas/PartitionResponse"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "Partition not found",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/applications": {
|
|
"get": {
|
|
"tags": ["Applications"],
|
|
"summary": "List applications",
|
|
"description": "Retrieves a paginated list of application definitions.",
|
|
"operationId": "listApplications",
|
|
"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
|
|
}
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Paginated list of applications",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"allOf": [
|
|
{ "$ref": "#/components/schemas/ApiResponseSuccess" },
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"data": {
|
|
"$ref": "#/components/schemas/ApplicationListResponse"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"post": {
|
|
"tags": ["Applications"],
|
|
"summary": "Create an application",
|
|
"description": "Creates a new application definition.",
|
|
"operationId": "createApplication",
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/CreateApplicationRequest"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"201": {
|
|
"description": "Application 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 application ID"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Invalid request body or missing required fields",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/applications/{id}": {
|
|
"get": {
|
|
"tags": ["Applications"],
|
|
"summary": "Get application by ID",
|
|
"description": "Retrieves a specific application definition.",
|
|
"operationId": "getApplication",
|
|
"parameters": [
|
|
{ "$ref": "#/components/parameters/ApplicationId" }
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Application details",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"allOf": [
|
|
{ "$ref": "#/components/schemas/ApiResponseSuccess" },
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"data": {
|
|
"$ref": "#/components/schemas/Application"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "Application not found",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"put": {
|
|
"tags": ["Applications"],
|
|
"summary": "Update an application",
|
|
"description": "Updates an existing application definition.",
|
|
"operationId": "updateApplication",
|
|
"parameters": [
|
|
{ "$ref": "#/components/parameters/ApplicationId" }
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/UpdateApplicationRequest"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Application updated successfully",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"allOf": [
|
|
{ "$ref": "#/components/schemas/ApiResponseSuccess" },
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"message": {
|
|
"type": "string",
|
|
"example": "application updated"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Invalid request body",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "Application not found",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"delete": {
|
|
"tags": ["Applications"],
|
|
"summary": "Delete an application",
|
|
"description": "Deletes an application definition by ID.",
|
|
"operationId": "deleteApplication",
|
|
"parameters": [
|
|
{ "$ref": "#/components/parameters/ApplicationId" }
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Application deleted successfully",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"allOf": [
|
|
{ "$ref": "#/components/schemas/ApiResponseSuccess" },
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"data": {
|
|
"type": "object",
|
|
"properties": {
|
|
"message": {
|
|
"type": "string",
|
|
"example": "application deleted"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "Application not found",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/diag": {
|
|
"get": {
|
|
"tags": ["Cluster"],
|
|
"summary": "Get cluster diagnostics",
|
|
"description": "Retrieves diagnostic information about the Slurm cluster.",
|
|
"operationId": "getDiag",
|
|
"responses": {
|
|
"200": {
|
|
"description": "Cluster diagnostics",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"allOf": [
|
|
{ "$ref": "#/components/schemas/ApiResponseSuccess" },
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"data": {
|
|
"type": "object",
|
|
"description": "Slurm cluster diagnostic data"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/files/uploads": {
|
|
"post": {
|
|
"tags": ["File Uploads"],
|
|
"operationId": "initUpload",
|
|
"summary": "Initialize a chunked upload session",
|
|
"description": "Creates an upload session for chunked file upload. If a file with the same SHA256 already exists, returns the existing file immediately (instant upload / dedup).",
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/InitUploadRequest"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"201": {
|
|
"description": "Upload session created",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"allOf": [
|
|
{ "$ref": "#/components/schemas/ApiResponseSuccess" },
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"data": {
|
|
"$ref": "#/components/schemas/UploadSessionResponse"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"200": {
|
|
"description": "Dedup hit - file already exists, returns existing file",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"allOf": [
|
|
{ "$ref": "#/components/schemas/ApiResponseSuccess" },
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"data": {
|
|
"$ref": "#/components/schemas/FileResponse"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Invalid request",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/files/uploads/{sessionId}/chunks/{chunkIndex}": {
|
|
"put": {
|
|
"tags": ["File Uploads"],
|
|
"operationId": "uploadChunk",
|
|
"summary": "Upload a single chunk",
|
|
"description": "Uploads a file chunk for the specified session. Chunks can be uploaded in any order and are idempotent.",
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/SessionId"
|
|
},
|
|
{
|
|
"$ref": "#/components/parameters/ChunkIndex"
|
|
}
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"multipart/form-data": {
|
|
"schema": {
|
|
"type": "object",
|
|
"required": ["chunk"],
|
|
"properties": {
|
|
"chunk": {
|
|
"type": "string",
|
|
"format": "binary",
|
|
"description": "File chunk data"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Chunk uploaded successfully"
|
|
},
|
|
"400": {
|
|
"description": "Invalid request",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "Upload session not found",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/files/uploads/{sessionId}/complete": {
|
|
"post": {
|
|
"tags": ["File Uploads"],
|
|
"operationId": "completeUpload",
|
|
"summary": "Complete an upload session",
|
|
"description": "Finalizes the upload by merging all chunks via ComposeObject. Supports retry if previously failed.",
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/SessionId"
|
|
}
|
|
],
|
|
"responses": {
|
|
"201": {
|
|
"description": "Upload completed, returns file",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"allOf": [
|
|
{ "$ref": "#/components/schemas/ApiResponseSuccess" },
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"data": {
|
|
"$ref": "#/components/schemas/FileResponse"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Invalid request or missing chunks",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "Upload session not found",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/files/uploads/{sessionId}": {
|
|
"get": {
|
|
"tags": ["File Uploads"],
|
|
"operationId": "getUploadStatus",
|
|
"summary": "Get upload session status",
|
|
"description": "Returns the current status of an upload session including list of uploaded chunk indices.",
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/SessionId"
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Upload session status",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"allOf": [
|
|
{ "$ref": "#/components/schemas/ApiResponseSuccess" },
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"data": {
|
|
"$ref": "#/components/schemas/UploadSessionResponse"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "Upload session not found",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"delete": {
|
|
"tags": ["File Uploads"],
|
|
"operationId": "cancelUpload",
|
|
"summary": "Cancel an upload session",
|
|
"description": "Cancels an in-progress upload, deletes uploaded chunks from MinIO, and removes the session.",
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/SessionId"
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Upload cancelled successfully"
|
|
},
|
|
"404": {
|
|
"description": "Upload session not found",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/files": {
|
|
"get": {
|
|
"tags": ["Files"],
|
|
"operationId": "listFiles",
|
|
"summary": "List files with pagination",
|
|
"parameters": [
|
|
{
|
|
"name": "page",
|
|
"in": "query",
|
|
"schema": { "type": "integer", "default": 1 }
|
|
},
|
|
{
|
|
"name": "page_size",
|
|
"in": "query",
|
|
"schema": { "type": "integer", "default": 20 }
|
|
},
|
|
{
|
|
"name": "folder_id",
|
|
"in": "query",
|
|
"required": false,
|
|
"description": "Filter by folder ID",
|
|
"schema": { "type": "integer", "format": "int64" }
|
|
},
|
|
{
|
|
"name": "search",
|
|
"in": "query",
|
|
"required": false,
|
|
"description": "Search files by name",
|
|
"schema": { "type": "string" }
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "List of files",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"allOf": [
|
|
{ "$ref": "#/components/schemas/ApiResponseSuccess" },
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"data": {
|
|
"$ref": "#/components/schemas/FileListResponse"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/files/{id}": {
|
|
"get": {
|
|
"tags": ["Files"],
|
|
"operationId": "getFile",
|
|
"summary": "Get file metadata",
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/FileId"
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "File metadata",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"allOf": [
|
|
{ "$ref": "#/components/schemas/ApiResponseSuccess" },
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"data": {
|
|
"$ref": "#/components/schemas/FileResponse"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "File not found",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"delete": {
|
|
"tags": ["Files"],
|
|
"operationId": "deleteFile",
|
|
"summary": "Delete a file",
|
|
"description": "Soft-deletes a file. If no other files reference the same blob, the blob is removed from MinIO.",
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/FileId"
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "File deleted successfully"
|
|
},
|
|
"404": {
|
|
"description": "File not found",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/files/{id}/download": {
|
|
"get": {
|
|
"tags": ["Files"],
|
|
"operationId": "downloadFile",
|
|
"summary": "Download a file",
|
|
"description": "Downloads the file content. Supports HTTP Range header for partial content delivery.",
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/FileId"
|
|
},
|
|
{
|
|
"name": "Range",
|
|
"in": "header",
|
|
"required": false,
|
|
"description": "Byte range for partial content",
|
|
"example": "bytes=0-1023",
|
|
"schema": { "type": "string" }
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Full file content",
|
|
"content": {
|
|
"application/octet-stream": {
|
|
"schema": {
|
|
"type": "string",
|
|
"format": "binary"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"206": {
|
|
"description": "Partial content",
|
|
"content": {
|
|
"application/octet-stream": {
|
|
"schema": {
|
|
"type": "string",
|
|
"format": "binary"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "File not found",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/files/folders": {
|
|
"post": {
|
|
"tags": ["Folders"],
|
|
"operationId": "createFolder",
|
|
"summary": "Create a folder",
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/CreateFolderRequest"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"201": {
|
|
"description": "Folder created",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"allOf": [
|
|
{ "$ref": "#/components/schemas/ApiResponseSuccess" },
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"data": {
|
|
"$ref": "#/components/schemas/FolderResponse"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"400": {
|
|
"description": "Invalid request",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"get": {
|
|
"tags": ["Folders"],
|
|
"operationId": "listFolders",
|
|
"summary": "List folders",
|
|
"parameters": [
|
|
{
|
|
"name": "parent_id",
|
|
"in": "query",
|
|
"required": false,
|
|
"description": "Parent folder ID (null for root)",
|
|
"schema": { "type": "integer", "format": "int64" }
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "List of folders",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"allOf": [
|
|
{ "$ref": "#/components/schemas/ApiResponseSuccess" },
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"data": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/FolderResponse"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/files/folders/{id}": {
|
|
"get": {
|
|
"tags": ["Folders"],
|
|
"operationId": "getFolder",
|
|
"summary": "Get folder details",
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/FolderId"
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Folder details",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"allOf": [
|
|
{ "$ref": "#/components/schemas/ApiResponseSuccess" },
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"data": {
|
|
"$ref": "#/components/schemas/FolderResponse"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "Folder not found",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"delete": {
|
|
"tags": ["Folders"],
|
|
"operationId": "deleteFolder",
|
|
"summary": "Delete a folder",
|
|
"description": "Deletes an empty folder. Cannot delete folders that contain files or sub-folders.",
|
|
"parameters": [
|
|
{
|
|
"$ref": "#/components/parameters/FolderId"
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Folder deleted successfully"
|
|
},
|
|
"400": {
|
|
"description": "Folder is not empty",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"404": {
|
|
"description": "Folder not found",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"500": {
|
|
"description": "Internal server error",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"$ref": "#/components/schemas/ApiResponseError"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/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": {
|
|
"parameters": {
|
|
"JobId": {
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "Job ID",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"NodeName": {
|
|
"name": "name",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "Node name",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"PartitionName": {
|
|
"name": "name",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "Partition name",
|
|
"schema": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"ApplicationId": {
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "Application ID",
|
|
"schema": {
|
|
"type": "integer",
|
|
"format": "int64"
|
|
}
|
|
},
|
|
"SessionId": {
|
|
"name": "sessionId",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "Upload session ID",
|
|
"schema": {
|
|
"type": "integer",
|
|
"format": "int64"
|
|
}
|
|
},
|
|
"ChunkIndex": {
|
|
"name": "chunkIndex",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "Chunk index (0-based)",
|
|
"schema": {
|
|
"type": "integer",
|
|
"minimum": 0
|
|
}
|
|
},
|
|
"FileId": {
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "File ID",
|
|
"schema": {
|
|
"type": "integer",
|
|
"format": "int64"
|
|
}
|
|
},
|
|
"FolderId": {
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"description": "Folder ID",
|
|
"schema": {
|
|
"type": "integer",
|
|
"format": "int64"
|
|
}
|
|
}
|
|
},
|
|
"schemas": {
|
|
"ApiResponseSuccess": {
|
|
"type": "object",
|
|
"required": ["success"],
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"enum": [true]
|
|
},
|
|
"data": {
|
|
"description": "Response payload"
|
|
}
|
|
}
|
|
},
|
|
"ApiResponseError": {
|
|
"type": "object",
|
|
"required": ["success", "error"],
|
|
"properties": {
|
|
"success": {
|
|
"type": "boolean",
|
|
"enum": [false]
|
|
},
|
|
"error": {
|
|
"type": "string",
|
|
"description": "Error message"
|
|
}
|
|
}
|
|
},
|
|
"SubmitJobRequest": {
|
|
"type": "object",
|
|
"required": ["script"],
|
|
"properties": {
|
|
"script": {
|
|
"type": "string",
|
|
"description": "Job script content"
|
|
},
|
|
"partition": {
|
|
"type": "string",
|
|
"description": "Target partition"
|
|
},
|
|
"qos": {
|
|
"type": "string",
|
|
"description": "Quality of Service"
|
|
},
|
|
"cpus": {
|
|
"type": "integer",
|
|
"format": "int32",
|
|
"description": "Number of CPUs required"
|
|
},
|
|
"memory": {
|
|
"type": "string",
|
|
"description": "Memory requirement (e.g. \"4G\")"
|
|
},
|
|
"time_limit": {
|
|
"type": "string",
|
|
"description": "Time limit (e.g. \"1:00:00\")"
|
|
},
|
|
"job_name": {
|
|
"type": "string",
|
|
"description": "Job name"
|
|
},
|
|
"environment": {
|
|
"type": "object",
|
|
"additionalProperties": {
|
|
"type": "string"
|
|
},
|
|
"description": "Environment variables"
|
|
},
|
|
"work_dir": {
|
|
"type": "string",
|
|
"description": "Job working directory"
|
|
}
|
|
}
|
|
},
|
|
"JobResponse": {
|
|
"type": "object",
|
|
"properties": {
|
|
"job_id": {
|
|
"type": "integer",
|
|
"format": "int32",
|
|
"description": "Slurm job ID"
|
|
},
|
|
"name": {
|
|
"type": "string",
|
|
"description": "Job name"
|
|
},
|
|
"job_state": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"description": "Current job state(s) (e.g. [\"RUNNING\"], [\"PENDING\",\"REQUEUED\"])"
|
|
},
|
|
"state_reason": {
|
|
"type": "string",
|
|
"description": "Reason for job pending or failure"
|
|
},
|
|
"partition": {
|
|
"type": "string",
|
|
"description": "Assigned partition"
|
|
},
|
|
"qos": {
|
|
"type": "string",
|
|
"description": "Quality of Service policy"
|
|
},
|
|
"priority": {
|
|
"type": "integer",
|
|
"format": "int32",
|
|
"description": "Job priority",
|
|
"nullable": true
|
|
},
|
|
"time_limit": {
|
|
"type": "string",
|
|
"description": "Time limit in minutes (\"UNLIMITED\" for unlimited)"
|
|
},
|
|
"account": {
|
|
"type": "string",
|
|
"description": "Billing account"
|
|
},
|
|
"user": {
|
|
"type": "string",
|
|
"description": "Submitting user"
|
|
},
|
|
"cluster": {
|
|
"type": "string",
|
|
"description": "Cluster name"
|
|
},
|
|
"cpus": {
|
|
"type": "integer",
|
|
"format": "int32",
|
|
"description": "Allocated/requested CPU cores",
|
|
"nullable": true
|
|
},
|
|
"tasks": {
|
|
"type": "integer",
|
|
"format": "int32",
|
|
"description": "Number of tasks",
|
|
"nullable": true
|
|
},
|
|
"node_count": {
|
|
"type": "integer",
|
|
"format": "int32",
|
|
"description": "Number of allocated nodes",
|
|
"nullable": true
|
|
},
|
|
"nodes": {
|
|
"type": "string",
|
|
"description": "Allocated node list"
|
|
},
|
|
"batch_host": {
|
|
"type": "string",
|
|
"description": "Batch host node"
|
|
},
|
|
"submit_time": {
|
|
"type": "integer",
|
|
"format": "int64",
|
|
"description": "Submit time (Unix timestamp)",
|
|
"nullable": true
|
|
},
|
|
"start_time": {
|
|
"type": "integer",
|
|
"format": "int64",
|
|
"description": "Start time (Unix timestamp)",
|
|
"nullable": true
|
|
},
|
|
"end_time": {
|
|
"type": "integer",
|
|
"format": "int64",
|
|
"description": "End time (Unix timestamp)",
|
|
"nullable": true
|
|
},
|
|
"exit_code": {
|
|
"type": "integer",
|
|
"format": "int32",
|
|
"description": "Exit code (null if not finished)",
|
|
"nullable": true
|
|
},
|
|
"standard_output": {
|
|
"type": "string",
|
|
"description": "Stdout file path"
|
|
},
|
|
"standard_error": {
|
|
"type": "string",
|
|
"description": "Stderr file path"
|
|
},
|
|
"standard_input": {
|
|
"type": "string",
|
|
"description": "Stdin file path"
|
|
},
|
|
"working_directory": {
|
|
"type": "string",
|
|
"description": "Working directory"
|
|
},
|
|
"command": {
|
|
"type": "string",
|
|
"description": "Executed command"
|
|
},
|
|
"array_job_id": {
|
|
"type": "integer",
|
|
"format": "int32",
|
|
"description": "Parent job ID for array jobs",
|
|
"nullable": true
|
|
},
|
|
"array_task_id": {
|
|
"type": "integer",
|
|
"format": "int32",
|
|
"description": "Task ID within array job",
|
|
"nullable": true
|
|
}
|
|
}
|
|
},
|
|
"JobListResponse": {
|
|
"type": "object",
|
|
"properties": {
|
|
"jobs": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/JobResponse"
|
|
},
|
|
"description": "List of jobs"
|
|
},
|
|
"total": {
|
|
"type": "integer",
|
|
"description": "Total number of matching jobs"
|
|
},
|
|
"page": {
|
|
"type": "integer",
|
|
"description": "Current page number (starts at 1)"
|
|
},
|
|
"page_size": {
|
|
"type": "integer",
|
|
"description": "Items per page"
|
|
}
|
|
}
|
|
},
|
|
"NodeResponse": {
|
|
"type": "object",
|
|
"properties": {
|
|
"name": {
|
|
"type": "string",
|
|
"description": "Node hostname"
|
|
},
|
|
"state": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"description": "Node state(s) (e.g. [\"IDLE\"], [\"ALLOCATED\",\"COMPLETING\"])"
|
|
},
|
|
"reason": {
|
|
"type": "string",
|
|
"description": "Reason for DOWN/DRAIN state"
|
|
},
|
|
"reason_set_by_user": {
|
|
"type": "string",
|
|
"description": "User who set the reason"
|
|
},
|
|
"cpus": {
|
|
"type": "integer",
|
|
"format": "int32",
|
|
"description": "Total CPU cores"
|
|
},
|
|
"alloc_cpus": {
|
|
"type": "integer",
|
|
"format": "int32",
|
|
"description": "Allocated CPU cores",
|
|
"nullable": true
|
|
},
|
|
"cores": {
|
|
"type": "integer",
|
|
"format": "int32",
|
|
"description": "Physical cores",
|
|
"nullable": true
|
|
},
|
|
"sockets": {
|
|
"type": "integer",
|
|
"format": "int32",
|
|
"description": "CPU sockets",
|
|
"nullable": true
|
|
},
|
|
"threads": {
|
|
"type": "integer",
|
|
"format": "int32",
|
|
"description": "Threads per core",
|
|
"nullable": true
|
|
},
|
|
"cpu_load": {
|
|
"type": "integer",
|
|
"format": "int32",
|
|
"description": "CPU load (kernel nice value * 100)",
|
|
"nullable": true
|
|
},
|
|
"real_memory": {
|
|
"type": "integer",
|
|
"format": "int64",
|
|
"description": "Total physical memory (MiB)"
|
|
},
|
|
"alloc_memory": {
|
|
"type": "integer",
|
|
"format": "int64",
|
|
"description": "Allocated memory (MiB)"
|
|
},
|
|
"free_mem": {
|
|
"type": "integer",
|
|
"format": "int64",
|
|
"description": "Free memory (MiB)",
|
|
"nullable": true
|
|
},
|
|
"architecture": {
|
|
"type": "string",
|
|
"description": "System architecture (e.g. x86_64)"
|
|
},
|
|
"operating_system": {
|
|
"type": "string",
|
|
"description": "Operating system version"
|
|
},
|
|
"gres": {
|
|
"type": "string",
|
|
"description": "Available generic resources (e.g. \"gpu:4\")"
|
|
},
|
|
"gres_used": {
|
|
"type": "string",
|
|
"description": "Used generic resources (e.g. \"gpu:2\")"
|
|
},
|
|
"address": {
|
|
"type": "string",
|
|
"description": "Node address (IP)"
|
|
},
|
|
"hostname": {
|
|
"type": "string",
|
|
"description": "Node hostname (may differ from name)"
|
|
},
|
|
"weight": {
|
|
"type": "integer",
|
|
"format": "int32",
|
|
"description": "Scheduling weight",
|
|
"nullable": true
|
|
},
|
|
"features": {
|
|
"type": "string",
|
|
"description": "Node feature tags (modifiable)"
|
|
},
|
|
"active_features": {
|
|
"type": "string",
|
|
"description": "Active feature tags (read-only)"
|
|
}
|
|
}
|
|
},
|
|
"PartitionResponse": {
|
|
"type": "object",
|
|
"properties": {
|
|
"name": {
|
|
"type": "string",
|
|
"description": "Partition name"
|
|
},
|
|
"state": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"description": "Partition state(s) (e.g. [\"UP\"], [\"DOWN\",\"DRAIN\"])"
|
|
},
|
|
"default": {
|
|
"type": "boolean",
|
|
"description": "Whether this is the default partition"
|
|
},
|
|
"nodes": {
|
|
"type": "string",
|
|
"description": "Node range string"
|
|
},
|
|
"total_nodes": {
|
|
"type": "integer",
|
|
"format": "int32",
|
|
"description": "Total nodes in partition"
|
|
},
|
|
"total_cpus": {
|
|
"type": "integer",
|
|
"format": "int32",
|
|
"description": "Total CPUs in partition"
|
|
},
|
|
"max_cpus_per_node": {
|
|
"type": "integer",
|
|
"format": "int32",
|
|
"description": "Max CPUs per node",
|
|
"nullable": true
|
|
},
|
|
"max_time": {
|
|
"type": "string",
|
|
"description": "Maximum time limit (\"UNLIMITED\" for unlimited)"
|
|
},
|
|
"max_nodes": {
|
|
"type": "integer",
|
|
"format": "int32",
|
|
"description": "Max nodes per job",
|
|
"nullable": true
|
|
},
|
|
"min_nodes": {
|
|
"type": "integer",
|
|
"format": "int32",
|
|
"description": "Min nodes per job",
|
|
"nullable": true
|
|
},
|
|
"default_time": {
|
|
"type": "string",
|
|
"description": "Default time limit"
|
|
},
|
|
"grace_time": {
|
|
"type": "integer",
|
|
"format": "int32",
|
|
"description": "Grace time after preemption (seconds)",
|
|
"nullable": true
|
|
},
|
|
"priority": {
|
|
"type": "integer",
|
|
"format": "int32",
|
|
"description": "Job priority factor within partition",
|
|
"nullable": true
|
|
},
|
|
"qos_allowed": {
|
|
"type": "string",
|
|
"description": "Allowed QOS list"
|
|
},
|
|
"qos_deny": {
|
|
"type": "string",
|
|
"description": "Denied QOS list"
|
|
},
|
|
"qos_assigned": {
|
|
"type": "string",
|
|
"description": "Default assigned QOS"
|
|
},
|
|
"accounts_allowed": {
|
|
"type": "string",
|
|
"description": "Allowed accounts list"
|
|
},
|
|
"accounts_deny": {
|
|
"type": "string",
|
|
"description": "Denied accounts list"
|
|
}
|
|
}
|
|
},
|
|
"ParameterSchema": {
|
|
"type": "object",
|
|
"required": ["name", "type"],
|
|
"properties": {
|
|
"name": {
|
|
"type": "string",
|
|
"description": "Parameter name"
|
|
},
|
|
"label": {
|
|
"type": "string",
|
|
"description": "Display label"
|
|
},
|
|
"type": {
|
|
"type": "string",
|
|
"enum": ["string", "integer", "enum", "file", "directory", "boolean"],
|
|
"description": "Parameter type"
|
|
},
|
|
"required": {
|
|
"type": "boolean",
|
|
"description": "Whether this parameter is required"
|
|
},
|
|
"default": {
|
|
"type": "string",
|
|
"description": "Default value"
|
|
},
|
|
"options": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"description": "Available options for enum type"
|
|
},
|
|
"description": {
|
|
"type": "string",
|
|
"description": "Parameter description"
|
|
}
|
|
}
|
|
},
|
|
"Application": {
|
|
"type": "object",
|
|
"properties": {
|
|
"id": {
|
|
"type": "integer",
|
|
"format": "int64",
|
|
"description": "Application ID"
|
|
},
|
|
"name": {
|
|
"type": "string",
|
|
"description": "Application name"
|
|
},
|
|
"description": {
|
|
"type": "string",
|
|
"description": "Application description"
|
|
},
|
|
"icon": {
|
|
"type": "string",
|
|
"description": "Application icon"
|
|
},
|
|
"category": {
|
|
"type": "string",
|
|
"description": "Application category"
|
|
},
|
|
"script_template": {
|
|
"type": "string",
|
|
"description": "Job script template"
|
|
},
|
|
"parameters": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/ParameterSchema"
|
|
},
|
|
"description": "Parameter definitions"
|
|
},
|
|
"scope": {
|
|
"type": "string",
|
|
"description": "Application scope",
|
|
"default": "system"
|
|
},
|
|
"created_by": {
|
|
"type": "integer",
|
|
"format": "int64",
|
|
"description": "Creator user ID",
|
|
"nullable": true
|
|
},
|
|
"created_at": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "Creation timestamp",
|
|
"nullable": true
|
|
},
|
|
"updated_at": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "Last update timestamp",
|
|
"nullable": true
|
|
}
|
|
}
|
|
},
|
|
"CreateApplicationRequest": {
|
|
"type": "object",
|
|
"required": ["name", "script_template"],
|
|
"properties": {
|
|
"name": {
|
|
"type": "string",
|
|
"description": "Application name"
|
|
},
|
|
"description": {
|
|
"type": "string",
|
|
"description": "Application description"
|
|
},
|
|
"icon": {
|
|
"type": "string",
|
|
"description": "Application icon"
|
|
},
|
|
"category": {
|
|
"type": "string",
|
|
"description": "Application category"
|
|
},
|
|
"script_template": {
|
|
"type": "string",
|
|
"description": "Job script template"
|
|
},
|
|
"parameters": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/ParameterSchema"
|
|
},
|
|
"description": "Parameter definitions"
|
|
},
|
|
"scope": {
|
|
"type": "string",
|
|
"description": "Application scope",
|
|
"default": "system"
|
|
}
|
|
}
|
|
},
|
|
"UpdateApplicationRequest": {
|
|
"type": "object",
|
|
"properties": {
|
|
"name": {
|
|
"type": "string",
|
|
"description": "Application name"
|
|
},
|
|
"description": {
|
|
"type": "string",
|
|
"description": "Application description"
|
|
},
|
|
"icon": {
|
|
"type": "string",
|
|
"description": "Application icon"
|
|
},
|
|
"category": {
|
|
"type": "string",
|
|
"description": "Application category"
|
|
},
|
|
"script_template": {
|
|
"type": "string",
|
|
"description": "Job script template"
|
|
},
|
|
"parameters": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/ParameterSchema"
|
|
},
|
|
"description": "Parameter definitions"
|
|
},
|
|
"scope": {
|
|
"type": "string",
|
|
"description": "Application scope"
|
|
}
|
|
}
|
|
},
|
|
"ApplicationListResponse": {
|
|
"type": "object",
|
|
"properties": {
|
|
"applications": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/Application"
|
|
},
|
|
"description": "List of applications"
|
|
},
|
|
"total": {
|
|
"type": "integer",
|
|
"description": "Total number of applications"
|
|
},
|
|
"page": {
|
|
"type": "integer",
|
|
"description": "Current page number"
|
|
},
|
|
"page_size": {
|
|
"type": "integer",
|
|
"description": "Items per page"
|
|
}
|
|
}
|
|
},
|
|
"InitUploadRequest": {
|
|
"type": "object",
|
|
"required": ["file_name", "file_size", "sha256"],
|
|
"properties": {
|
|
"file_name": {
|
|
"type": "string",
|
|
"description": "File name"
|
|
},
|
|
"file_size": {
|
|
"type": "integer",
|
|
"format": "int64",
|
|
"description": "Total file size in bytes"
|
|
},
|
|
"sha256": {
|
|
"type": "string",
|
|
"description": "SHA256 hash of the entire file (hex encoded)"
|
|
},
|
|
"chunk_size": {
|
|
"type": "integer",
|
|
"format": "int64",
|
|
"description": "Chunk size in bytes (must be >= min_chunk_size config)"
|
|
},
|
|
"folder_id": {
|
|
"type": "integer",
|
|
"format": "int64",
|
|
"description": "Target folder ID (null for root)",
|
|
"nullable": true
|
|
},
|
|
"mime_type": {
|
|
"type": "string",
|
|
"description": "MIME type of the file"
|
|
}
|
|
}
|
|
},
|
|
"UploadSessionResponse": {
|
|
"type": "object",
|
|
"properties": {
|
|
"id": {
|
|
"type": "integer",
|
|
"format": "int64",
|
|
"description": "Session ID"
|
|
},
|
|
"file_name": {
|
|
"type": "string",
|
|
"description": "File name"
|
|
},
|
|
"file_size": {
|
|
"type": "integer",
|
|
"format": "int64",
|
|
"description": "Total file size in bytes"
|
|
},
|
|
"chunk_size": {
|
|
"type": "integer",
|
|
"format": "int64",
|
|
"description": "Chunk size in bytes"
|
|
},
|
|
"total_chunks": {
|
|
"type": "integer",
|
|
"description": "Total number of chunks"
|
|
},
|
|
"sha256": {
|
|
"type": "string",
|
|
"description": "SHA256 hash of the entire file"
|
|
},
|
|
"status": {
|
|
"type": "string",
|
|
"enum": ["pending", "uploading", "merging", "completed", "failed", "cancelled", "expired"],
|
|
"description": "Session status"
|
|
},
|
|
"uploaded_chunks": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "integer"
|
|
},
|
|
"description": "List of uploaded chunk indices"
|
|
},
|
|
"expires_at": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "Session expiration time"
|
|
},
|
|
"created_at": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "Session creation time"
|
|
}
|
|
}
|
|
},
|
|
"FileResponse": {
|
|
"type": "object",
|
|
"properties": {
|
|
"id": {
|
|
"type": "integer",
|
|
"format": "int64",
|
|
"description": "File ID"
|
|
},
|
|
"name": {
|
|
"type": "string",
|
|
"description": "File name"
|
|
},
|
|
"folder_id": {
|
|
"type": "integer",
|
|
"format": "int64",
|
|
"description": "Parent folder ID",
|
|
"nullable": true
|
|
},
|
|
"size": {
|
|
"type": "integer",
|
|
"format": "int64",
|
|
"description": "File size in bytes"
|
|
},
|
|
"mime_type": {
|
|
"type": "string",
|
|
"description": "MIME type"
|
|
},
|
|
"sha256": {
|
|
"type": "string",
|
|
"description": "SHA256 hash"
|
|
},
|
|
"created_at": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
},
|
|
"updated_at": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
}
|
|
}
|
|
},
|
|
"FileListResponse": {
|
|
"type": "object",
|
|
"properties": {
|
|
"files": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/components/schemas/FileResponse"
|
|
},
|
|
"description": "List of files"
|
|
},
|
|
"total": {
|
|
"type": "integer",
|
|
"description": "Total number of matching files"
|
|
},
|
|
"page": {
|
|
"type": "integer",
|
|
"description": "Current page number"
|
|
},
|
|
"page_size": {
|
|
"type": "integer",
|
|
"description": "Items per page"
|
|
}
|
|
}
|
|
},
|
|
"FolderResponse": {
|
|
"type": "object",
|
|
"properties": {
|
|
"id": {
|
|
"type": "integer",
|
|
"format": "int64",
|
|
"description": "Folder ID"
|
|
},
|
|
"name": {
|
|
"type": "string",
|
|
"description": "Folder name"
|
|
},
|
|
"parent_id": {
|
|
"type": "integer",
|
|
"format": "int64",
|
|
"description": "Parent folder ID (null for root)",
|
|
"nullable": true
|
|
},
|
|
"path": {
|
|
"type": "string",
|
|
"description": "Materialized path (e.g. /data/reports/)"
|
|
},
|
|
"file_count": {
|
|
"type": "integer",
|
|
"format": "int64",
|
|
"description": "Number of files in this folder"
|
|
},
|
|
"subfolder_count": {
|
|
"type": "integer",
|
|
"format": "int64",
|
|
"description": "Number of sub-folders in this folder"
|
|
},
|
|
"created_at": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
}
|
|
}
|
|
},
|
|
"CreateFolderRequest": {
|
|
"type": "object",
|
|
"required": ["name"],
|
|
"properties": {
|
|
"name": {
|
|
"type": "string",
|
|
"description": "Folder name (no path traversal characters)"
|
|
},
|
|
"parent_id": {
|
|
"type": "integer",
|
|
"format": "int64",
|
|
"description": "Parent folder ID (null for root)",
|
|
"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"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|