JSON API Documentation

Disclaimer: The API is still under heavy development and breaking changes to endpoints or parameters may be made

If you make anything utilizing our API, please let us know about it - we would love to see!

Except where noted otherwise, all queries require the following header to receive a JSON response:

accept: application/json

Workflow

Search for an imported phenotype (Workflow)

POST
/phenoflow/phenotype/all

Parameters

Field Type Description
importedId String The original ID associated with the source phenotype that has been imported as a Workflow into Phenoflow (e.g. 'PH222', HDR UK Phenotype Library)

Input

{
    "importedId": "PH222"
}

Success

Field Type Description
github_url String A link to the Workflow source of the imported phenotype on GitHub
url String A link to a visualisation of the imported phenotype on Phenoflow
short_url String A shorthand link to a visualisation of the imported phenotype on Phenoflow. NB. although potentially easier to work with, this link makes assumptions about the nature of the Workflow that may not hold.
HTTP/1.1 200 OK
{
    "github_url":"https://github.com/phenoflow/Obstructive-and-reflux-uropathy---e0e470b0-1798-11ef-9de4-4d4ea830ad16",
    "url":"https://kclhi.org/phenoflow/workflows/github.com/phenoflow/Obstructive-and-reflux-uropathy---e0e470b0-1798-11ef-9de4-4d4ea830ad16/blob/read-potential-cases-fhir/Obstructive-and-reflux-uropathy.cwl",
    "short_url":"https://kclhi.org/phenoflow/Obstructive-and-reflux-uropathy---e0e470b0-1798-11ef-9de4-4d4ea830ad16"
}

Error

HTTP/1.1 404 Not Found

Add a new Workflow

Note: Due to cwltool run times, the creation of workflows is done asynchronously and an intermediate queue resource is used
POST
/workflows

Parameters

Field Type Description
url String The URL of the repository. Either a gitlab.com or github.com URL, or any Git repository URL. If a gitlab.com or github.com repository URL is used, the following fields will take priority over those parsed from the URL if provided.
branch String The branch of the repository. Required if the URL is not from gitlab.com or github.com.
path String The path within the repository to the workflow file. Required if the URL is not from gitlab.com or github.com.
packedId String The ID of the workflow, to be provided if the workflow file is packed (contains multiple descriptions with $graph).

Input

{
    "url": "https://github.com/common-workflow-language/workflows/tree/master/workflows/compile/compile1.cwl"
}
{
    "url": "https://bitbucket.org/markrobinson96/workflows.git",
    "branch": "master",
    "path": "/workflows/make-to-cwl/dna.cwl"
}

Success

HTTP/1.1 202 Accepted
Location: /queue/:queueid

Already Exists

HTTP/1.1 303 See Other
Location: /workflows/:URL

Packed Workflow with Multiple Choices

HTTP/1.1 422 Unprocessable Entity
{
    "message": "This workflow file is packed and contains multiple workflow descriptions. Please provide a packedId parameter with one of the following values"
    "packedId": [
        "workflow.cwl",
        "main",
        "workflow_exome.cwl",
        "align.cwl",
        "workflow.cwl_2"
    ]
}

Error

HTTP/1.1 400 Bad Request

Get Workflow Details

GET
/workflows/:url

Parameters

Field Type Description
url String Partial URL to the workflow eg "github.com/owner/repo/tree/branch/workflow.cwl" or "bitbucket.org/owner/repo.git/master/workflow.cwl

Success 200

Field Type Description
retrievedFrom.repoUrl String URL of the Github repository
retrievedFrom.branch String Github branch name or commit ID
retrievedFrom.path String Path to the workflow within the repository
retrievedFrom.packedId String The ID of the workflow within the file, if this is a packed CWL file (contains a document graph).
retrievedFrom.url URL The URL to the page on the site if type is not GENERIC, otherwise the same as repoUrl
retrievedFrom.rawUrl URL The URL directly to the file if type is not GENERIC, otherwise the same as repoUrl
retrievedFrom.type Enum One of GENERIC, GITHUB, GITLAB, BITBUCKET
retrievedOn Date The last time this workflow was updated from the branch
lastCommit String The last commit ID on the branch
label String The label string for the workflow from the CWL description
doc String The doc string for the workflow from the CWL description
inputs
outputs
steps
dockerLink String The URL to dockerhub or "true" if an unrecognised image is used in a docker hint or requirement
cwltoolVersion String The version of cwltool used to parse the workflow
visualisationDot String The DOT source used to generate the visualisation image
visualisationXdot URL A link to the xdot source code for the visualisation image
visualisationPng URL A link to the png format visualisation image
visualisationSvg URL A link to the svg format visualisation image
robundle URL A link to the Research Object Bundle download
Example URL
/workflows/github.com/common-workflow-language/workflows/tree/master/workflows/lobSTR/lobSTR-workflow.cwl
Example Response
{
    "retrievedFrom": {
        "repoUrl": "https://github.com/common-workflow-language/workflows.git",
        "branch": "master",
        "path": "workflows/lobSTR/lobSTR-workflow.cwl",
        "url": "https://github.com/common-workflow-language/workflows/blob/master/workflows/lobSTR/lobSTR-workflow.cwl",
        "rawUrl": "https://raw.githubusercontent.com/common-workflow-language/workflows/master/workflows/lobSTR/lobSTR-workflow.cwl",
        "type": "GITHUB"
    },
    "retrievedOn": 1502714218616,
    "lastCommit": "17b65ea19d81527090fded62ffa0e1ba3b25d561",
    "label": "lobSTR-workflow.cwl",
    "inputs": {
        "reference": {
            "type": "File"
        },
        "rg-sample": {
            "type": "String"
        },
        "p1": {
            "type": "ee54066e73d068edfbf9ca5059e14acd"
        },
        "p2": {
            "type": "79ab371b6d0fdbadbf9a4a89ef393353"
        },
        "output_prefix": {
            "type": "String"
        },
        "rg-lib": {
            "type": "String"
        },
        "strinfo": {
            "type": "File"
        },
        "noise_model": {
            "type": "File"
        }
    },
    "outputs": {
        "vcf": {
            "type": "File"
        },
        "vcf_stats": {
            "type": "File"
        },
        "bam_stats": {
            "type": "File"
        },
        "bam": {
            "type": "File"
        }
    },
    "steps": {
        "allelotype": {
            "run": "allelotype.cwl",
            "runType": "COMMANDLINETOOL",
            "sources": {
                "file:///data/git/3ec0d19076841a1140e71cc3a1b330a56099aac2/workflows/lobSTR/lobSTR-workflow.cwl#allelotype/bam": {
                    "sourceIDs": [
                        "samindex"
                    ]
                },
                "allelotype": {
                    "sourceIDs": [
                        "strinfo"
                    ]
                },
                "file:///data/git/3ec0d19076841a1140e71cc3a1b330a56099aac2/workflows/lobSTR/lobSTR-workflow.cwl#allelotype/noise_model": {
                    "sourceIDs": [
                        "noise_model"
                    ]
                },
                "file:///data/git/3ec0d19076841a1140e71cc3a1b330a56099aac2/workflows/lobSTR/lobSTR-workflow.cwl#allelotype/reference": {
                    "sourceIDs": [
                        "reference"
                    ]
                },
                "file:///data/git/3ec0d19076841a1140e71cc3a1b330a56099aac2/workflows/lobSTR/lobSTR-workflow.cwl#allelotype/output_prefix": {
                    "sourceIDs": [
                        "output_prefix"
                    ]
                }
            }
        },
        "samsort": {
            "run": "samtools-sort.cwl",
            "runType": "COMMANDLINETOOL",
            "sources": {
                "samsort": {
                    "sourceIDs": [
                        "lobSTR"
                    ]
                },
                "file:///data/git/3ec0d19076841a1140e71cc3a1b330a56099aac2/workflows/lobSTR/lobSTR-workflow.cwl#samsort/output_name": {
                    "defaultVal": "\\\"aligned.sorted.bam\\\""
                }
            }
        },
        "lobSTR": {
            "label": "lobSTR",
            "run": "lobSTR-tool.cwl",
            "runType": "COMMANDLINETOOL",
            "sources": {
                "lobSTR": {
                    "sourceIDs": [
                        "rg-lib"
                    ]
                },
                "file:///data/git/3ec0d19076841a1140e71cc3a1b330a56099aac2/workflows/lobSTR/lobSTR-workflow.cwl#lobSTR/p1": {
                    "sourceIDs": [
                        "p1"
                    ]
                },
                "file:///data/git/3ec0d19076841a1140e71cc3a1b330a56099aac2/workflows/lobSTR/lobSTR-workflow.cwl#lobSTR/p2": {
                    "sourceIDs": [
                        "p2"
                    ]
                },
                "file:///data/git/3ec0d19076841a1140e71cc3a1b330a56099aac2/workflows/lobSTR/lobSTR-workflow.cwl#lobSTR/output_prefix": {
                    "sourceIDs": [
                        "output_prefix"
                    ]
                },
                "file:///data/git/3ec0d19076841a1140e71cc3a1b330a56099aac2/workflows/lobSTR/lobSTR-workflow.cwl#lobSTR/rg-sample": {
                    "sourceIDs": [
                        "rg-sample"
                    ]
                },
                "file:///data/git/3ec0d19076841a1140e71cc3a1b330a56099aac2/workflows/lobSTR/lobSTR-workflow.cwl#lobSTR/reference": {
                    "sourceIDs": [
                        "reference"
                    ]
                }
            }
        },
        "samindex": {
            "run": "samtools-index.cwl",
            "runType": "COMMANDLINETOOL",
            "sources": {
                "samindex": {
                    "sourceIDs": [
                        "samsort"
                    ]
                }
            }
        }
    },
    "dockerLink": "https://hub.docker.com/r/rabix/lobstr",
    "cwltoolVersion": "1.0.20170810192106",
    "visualisationDot": "digraph workflow {\n  graph [\n    bgcolor = \"#eeeeee\"\n    color = \"black\"\n    fontsize = \"10\"\n    labeljust = \"left\"\n    clusterrank = \"local\"\n    ranksep = \"0.22\"\n    nodesep = \"0.05\"\n  ]\n  node [\n    fontname = \"Helvetica\"\n    fontsize = \"10\"\n    fontcolor = \"black\"\n    shape = \"record\"\n    height = \"0\"\n    width = \"0\"\n    color = \"black\"\n    fillcolor = \"lightgoldenrodyellow\"\n    style = \"filled\"\n  ];\n  edge [\n    fontname=\"Helvetica\"\n    fontsize=\"8\"\n    fontcolor=\"black\"\n    color=\"black\"\n    arrowsize=\"0.7\"\n  ];\n  subgraph cluster_inputs {\n    rank = \"same\";\n    style = \"dashed\";\n    label = \"Workflow Inputs\";\n    \"p2\" [fillcolor=\"#94DDF4\",label=\"p2\"];\n    \"p2\" [fillcolor=\"#94DDF4\",label=\"p2\"];\n    \"output_prefix\" [fillcolor=\"#94DDF4\",label=\"output_prefix\"];\n    \"reference\" [fillcolor=\"#94DDF4\",label=\"reference\"];\n    \"noise_model\" [fillcolor=\"#94DDF4\",label=\"noise_model\"];\n    \"strinfo\" [fillcolor=\"#94DDF4\",label=\"strinfo\"];\n    \"p1\" [fillcolor=\"#94DDF4\",label=\"p1\"];\n    \"p1\" [fillcolor=\"#94DDF4\",label=\"p1\"];\n    \"rg-lib\" [fillcolor=\"#94DDF4\",label=\"rg-lib\"];\n    \"rg-sample\" [fillcolor=\"#94DDF4\",label=\"rg-sample\"];\n  }\n  subgraph cluster_outputs {\n    rank = \"same\";\n    style = \"dashed\";\n    labelloc = \"b\";\n    label = \"Workflow Outputs\";\n    \"bam\" [fillcolor=\"#94DDF4\",label=\"bam\"];\n    \"vcf\" [fillcolor=\"#94DDF4\",label=\"vcf\"];\n    \"bam_stats\" [fillcolor=\"#94DDF4\",label=\"bam_stats\"];\n    \"vcf_stats\" [fillcolor=\"#94DDF4\",label=\"vcf_stats\"];\n  }\n  \"allelotype\" [label=\"allelotype\"];\n  \"samsort\" [label=\"samsort\"];\n  \"lobSTR\" [label=\"lobSTR\"];\n  \"samindex\" [label=\"samindex\"];\n  \"strinfo\" -> \"allelotype\" [label=\"strinfo\"];\n  \"reference\" -> \"allelotype\" [label=\"reference\"];\n  \"output_prefix\" -> \"allelotype\" [label=\"output_prefix\"];\n  \"noise_model\" -> \"allelotype\" [label=\"noise_model\"];\n  \"samindex\" -> \"allelotype\" [label=\"bam\"];\n  \"lobSTR\" -> \"samsort\" [label=\"input\"];\n  \"default1\" -> \"samsort\" [label=\"output_name\"];\n  \"default1\" [label=\"\\\"aligned.sorted.bam\\\"\", fillcolor=\"#D5AEFC\"];\n  \"rg-lib\" -> \"lobSTR\" [label=\"rg-lib\"];\n  \"rg-sample\" -> \"lobSTR\" [label=\"rg-sample\"];\n  \"p2\" -> \"lobSTR\" [label=\"p2\"];\n  \"p1\" -> \"lobSTR\" [label=\"p1\"];\n  \"reference\" -> \"lobSTR\" [label=\"reference\"];\n  \"output_prefix\" -> \"lobSTR\" [label=\"output_prefix\"];\n  \"samsort\" -> \"samindex\" [label=\"input\"];\n  \"samindex\" -> \"bam\";\n  \"allelotype\" -> \"vcf\";\n  \"lobSTR\" -> \"bam_stats\";\n  \"allelotype\" -> \"vcf_stats\";\n}\n",
    "visualisationPng": "/graph/png/github.com/common-workflow-language/workflows/blob/master/workflows/lobSTR/lobSTR-workflow.cwl",
    "visualisationSvg": "/graph/svg/github.com/common-workflow-language/workflows/blob/master/workflows/lobSTR/lobSTR-workflow.cwl",
    "roBundle": "/robundle/github.com/common-workflow-language/workflows/blob/master/workflows/lobSTR/lobSTR-workflow.cwl",
    "visualisationXdot": "/graph/xdot/github.com/common-workflow-language/workflows/blob/master/workflows/lobSTR/lobSTR-workflow.cwl"
}

View Workflows

GET
/workflows

Parameters

Field Type Description
search String Optional: Limits the workflows received to those containing this string in the label or doc
page Integer The page number to access (0 indexed, defaults to 0)
size Integer The page size requested (defaults to 10)

Success 200

Field Type Description
content List<Workflow> The workflows returned as per Get Workflow Details
last Boolean Whether this page is the last one
totalElements Integer The total number of workflows
totalPages Integer The total number of pages of this size
first Boolean Whether this page is the first one
numberOfElements Integer The number of workflows on this page
size Integer The page size requested
number Integer The current page number
Example Response
{
    "content": [
        {

        },
        {

        }
    ],
    "last": true,
    "totalElements": 2,
    "totalPages": 1,
    "sort": null,
    "first": true,
    "numberOfElements": 2,
    "size": 10,
    "number": 0
}

Queue

Check Queue Element

GET
/queue/:id

Parameters

Field Type Description
id String The ID of the queue element from the Location header of Add a new Workflow

Pending 200

Field Type Description
cwltoolStatus enum One of RUNNING, ERROR
cwltoolVersion String The version of cwltool being used to parse the workflow
message String Error message if cwltoolStatus is ERROR
Example Responses
{
    "cwltoolStatus": "RUNNING",
    "cwltoolVersion": "1.0.20170622090721",
}
{
    "cwltoolStatus": "ERROR",
    "cwltoolVersion": "1.0.20170622090721",
    "message": "Tool definition failed initialization:\n('https://sparql-test.commonwl.org/schema.rdf', SSLError(SSLError(CertificateError(\"hostname 'sparql-test.commonwl.org' doesn't match either of 'biowardrobe.com', 'demo.biowardrobe.com', 'www.biowardrobe.com'\",),),))\n"
}

Finished 303

HTTP/1.1 303 See Other
Location: /workflows/:url

Examples

Python - Build script for Travis

The API can be utilised as a build step in continuous integration such as in the following example

travis.yml

The python script can be included in the 'script' or 'after_success' areas of travis.yml depending on your usage

language: python

python:
  - "2.7"

install:
  - pip install requests

script:
  - ...

after_success:
  - python cwlviewer.py

cwlviewer.py

# Must list 'pip install requests' in travis.yml
import requests
import time
import os

# You can alternatively define these in travis.yml as env vars or arguments
BASE_URL = 'https://view.commonwl.org'
WORKFLOW_PATH = '/workflows/workflow.cwl'

# Travis environment variables
TRAVIS_COMMIT = os.getenv('TRAVIS_COMMIT')
TRAVIS_REPO_SLUG = os.getenv('TRAVIS_REPO_SLUG')

# Whole workflow URL on github
workflowURL = 'https://github.com/' + TRAVIS_REPO_SLUG + '/blob/' + TRAVIS_COMMIT + WORKFLOW_PATH

# Headers
HEADERS = {
    'user-agent': 'my-app/0.0.1',
    'accept': 'application/json'
}

# Add new workflow with the specific commit ID of this build
addResponse = requests.post(BASE_URL + '/workflows',
                            data={'url': workflowURL},
                            headers=HEADERS)

if addResponse.status_code == requests.codes.accepted:
    qLocation = addResponse.headers['location']

    # Get the queue item until success
    qResponse = requests.get(BASE_URL + qLocation,
                             headers=HEADERS,
                             allow_redirects=False)
    maxAttempts = 5
    while qResponse.status_code == requests.codes.ok and qResponse.json()['cwltoolStatus'] == 'RUNNING' and maxAttempts > 0:
        time.sleep(5)
        qResponse = requests.get(BASE_URL + qLocation,
                                 headers=HEADERS,
                                 allow_redirects=False)
        maxAttempts -= 1

    if qResponse.headers['location']:
        # Success, get the workflow
        workflowResponse = requests.get(BASE_URL + qResponse.headers['location'], headers=HEADERS)
        if (workflowResponse.status_code == requests.codes.ok):
            workflowJson = workflowResponse.json()
            # Do what you want with the workflow JSON
            # Include details in documentation files etc
            print(BASE_URL + workflowJson['visualisationSvg'])
            print('Verified with cwltool version ' + workflowJson['cwltoolVersion'])
            # etc...
        else:
            print('Could not get returned workflow')
    elif qResponse.json()['cwltoolStatus'] == 'ERROR':
        # Cwltool failed to run here
        print(qResponse.json()['message'])
    elif maxAttempts == 0:
        print('Timeout: Cwltool did not finish')

else:
    print('Error adding workflow')

SVG sketch of CWL workflow

Note: This method uses a brief YAML parsing of the standalone CWL file that does not support annotations like label or doc, and that does not check for validity or completeness.
POST
/graph/svg

Input

Content-Type: text/yaml
#!/usr/bin/env cwl-runner
  
cwlVersion: v1.0
class: Workflow

inputs:
  usermessage: string

outputs:
  response:
    outputSource: step0/response
    type: File

steps:
  step0:
    run:
      class: CommandLineTool
      inputs:
        message:
          type: string
          inputBinding:
            position: 1
      baseCommand: echo
      outputs:
        response:
          type: stdout
    in:
      message: usermessage
    out: [response]

Output

Content-Type: image/svg+xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="450pt" height="270pt"
     viewBox="0.00 0.00 463.00 278.00" xmlns="http://www.w3.org/2000/svg">
	<!-- ... -->
</svg>

Success

HTTP/1.1 200 OK
Content-Type: image/svg+xml

Error

HTTP/1.1 400 Bad Request

PNG sketch of CWL workflow

Note: This method uses a brief YAML parsing of the standalone CWL file that does not support annotations like label or doc, and that does not check for validity or completeness.
POST
/graph/png

Input

Content-Type: text/yaml
#!/usr/bin/env cwl-runner
  
cwlVersion: v1.0
class: Workflow

inputs:
  usermessage: string

outputs:
  response:
    outputSource: step0/response
    type: File

steps:
  step0:
    run:
      class: CommandLineTool
      inputs:
        message:
          type: string
          inputBinding:
            position: 1
      baseCommand: echo
      outputs:
        response:
          type: stdout
    in:
      message: usermessage
    out: [response]

Output

\x89PNG\n\x1a\n\x00\x00 (binary)

Success

HTTP/1.1 200 OK
Content-Type: image/png

Error

HTTP/1.1 400 Bad Request