Sapporo WES Agent Skill¶
LLM agent reference for running bioinformatics workflows via Sapporo WES using curl.
For the full request/response schema, see openapi/sapporo-wes-spec-2.1.0.yml or the interactive docs at $SAPPORO_ENDPOINT/docs.
Tight on context? Use
docs/agent-quick-ref.md— the essential 4 commands in ~40 lines.
Prerequisites¶
curlandjqSAPPORO_ENDPOINTset to the base URL (default:http://localhost:1122)
Phase 0: Start a local server (if needed)¶
If that fails, start with Docker Compose:
curl -O https://raw.githubusercontent.com/sapporo-wes/sapporo-service/main/compose.yml
docker compose up -d
Phase 1: Submit a workflow¶
POST /runs accepts application/json (remote files) or multipart/form-data (local file upload). For the full list of fields and types, see the OpenAPI spec. The four required fields are workflow_type, workflow_type_version, workflow_url, and workflow_engine.
To find what engines and types your server supports:
curl -s $SAPPORO_ENDPOINT/service-info | jq '{engines: .workflow_engine_versions, types: .workflow_type_versions}'
Submit via JSON:
RUN_ID=$(curl -s -X POST $SAPPORO_ENDPOINT/runs \
-H "Content-Type: application/json" \
-d '{
"workflow_type": "CWL",
"workflow_type_version": "v1.0",
"workflow_url": "https://example.com/workflow.cwl",
"workflow_engine": "cwltool",
"workflow_params": {"input": "https://example.com/data.txt"}
}' | jq -r .run_id)
Submit via form (with local file upload):
RUN_ID=$(curl -s -X POST $SAPPORO_ENDPOINT/runs \
-F "workflow_type=CWL" \
-F "workflow_type_version=v1.0" \
-F "workflow_url=https://example.com/workflow.cwl" \
-F "workflow_engine=cwltool" \
-F 'workflow_params={"input": "data.txt"}' \
-F "workflow_attachment=@local_file.txt" \
| jq -r .run_id)
Phase 2: Poll until complete¶
State machine¶
QUEUED → INITIALIZING → RUNNING → COMPLETE
↘ EXECUTOR_ERROR (workflow engine failed — check stderr)
↘ SYSTEM_ERROR (infrastructure failure)
↘ CANCELED
CANCELING, DELETING, and DELETED are transient/lifecycle states. All others are terminal.
Poll loop:
while true; do
STATE=$(curl -s $SAPPORO_ENDPOINT/runs/$RUN_ID/status | jq -r .state)
echo "State: $STATE"
case $STATE in COMPLETE|EXECUTOR_ERROR|SYSTEM_ERROR|CANCELED) break ;; esac
sleep 10
done
Phase 3: Retrieve outputs¶
List output files (each entry has file_name and file_url):
Download a specific file:
Download all outputs as zip:
RO-Crate provenance metadata:
Error handling¶
On EXECUTOR_ERROR or SYSTEM_ERROR, check the run log:
curl -s $SAPPORO_ENDPOINT/runs/$RUN_ID | jq '{exit_code: .run_log.exit_code, stderr: .run_log.stderr}'
API errors (4xx/5xx) return {"msg": "...", "status_code": N}. Common ones:
400 Workflow is not in the executable workflows list— checkGET /executable-workflows404 Run not found— invalidrun_id
End-to-end example: CWL trimming + QC¶
export SAPPORO_ENDPOINT=http://localhost:1122
# 1. Submit
RUN_ID=$(curl -s -X POST $SAPPORO_ENDPOINT/runs \
-H "Content-Type: application/json" \
-d '{
"workflow_type": "CWL",
"workflow_type_version": "v1.0",
"workflow_url": "https://raw.githubusercontent.com/sapporo-wes/sapporo-service/main/tests/resources/cwltool/trimming_and_qc_remote.cwl",
"workflow_engine": "cwltool",
"workflow_params": {
"fastq_1": {"class": "File", "location": "https://raw.githubusercontent.com/sapporo-wes/sapporo-service/main/tests/resources/cwltool/ERR034597_1.small.fq.gz"},
"fastq_2": {"class": "File", "location": "https://raw.githubusercontent.com/sapporo-wes/sapporo-service/main/tests/resources/cwltool/ERR034597_2.small.fq.gz"}
}
}' | jq -r .run_id)
echo "Submitted: $RUN_ID"
# 2. Poll
while true; do
STATE=$(curl -s $SAPPORO_ENDPOINT/runs/$RUN_ID/status | jq -r .state)
echo "State: $STATE"
case $STATE in COMPLETE|EXECUTOR_ERROR|SYSTEM_ERROR|CANCELED) break ;; esac
sleep 10
done
# 3. Outputs
curl -s $SAPPORO_ENDPOINT/runs/$RUN_ID/outputs | jq .
End-to-end example: Nextflow hello world¶
RUN_ID=$(curl -s -X POST $SAPPORO_ENDPOINT/runs \
-H "Content-Type: application/json" \
-d '{
"workflow_type": "NFL",
"workflow_type_version": "DSL2",
"workflow_url": "https://raw.githubusercontent.com/nextflow-io/hello/master/main.nf",
"workflow_engine": "nextflow"
}' | jq -r .run_id)
Authentication (when enabled)¶
TOKEN=$(curl -s -X POST $SAPPORO_ENDPOINT/token \
-F "username=user1" -F "password=secret" | jq -r .access_token)
curl -s -H "Authorization: Bearer $TOKEN" $SAPPORO_ENDPOINT/runs | jq .
References¶
- OpenAPI spec (interactive):
$SAPPORO_ENDPOINT/docs - OpenAPI YAML:
openapi/sapporo-wes-spec-2.1.0.yml - WES compatibility:
docs/wes-compatibility.md - Configuration:
docs/configuration.md