Beispiel #1
0
def replace_workflow_module(project_id, branch_id, module_id):
    """Replace a module in the current project workflow branch and execute the
    resulting workflow.

    Request
    -------
    {
      "packageId": "string",
      "commandId": "string",
      "arguments": []
    }
    """
    # Abort with BAD REQUEST if request body is not in Json format or does not
    # contain the expected elements.
    cmd = srv.validate_json_request(
        request, required=['packageId', 'commandId', 'arguments'])
    # Extend and execute workflow. This will throw a ValueError if the command
    # cannot be parsed.
    try:
        # Result is None if project, branch or module are not found.
        modules = api.workflows.replace_workflow_module(
            project_id=project_id,
            branch_id=branch_id,
            module_id=module_id,
            package_id=cmd['packageId'],
            command_id=cmd['commandId'],
            arguments=cmd['arguments'])
        if not modules is None:
            return jsonify(modules)
    except ValueError as ex:
        raise srv.InvalidRequest(str(ex))
    raise srv.ResourceNotFound('unknown project \'' + project_id +
                               '\' branch \'' + branch_id + '\' or module \'' +
                               module_id + '\'')
Beispiel #2
0
def create_project():
    """Create a new project. The request is expected to contain a Json object
    with an optional list of properties as (key,value)-pairs.

    Request
    -------
    {
      "properties": [
        {
          "key": "string",
          "value": "string"
        }
      ]
    }
    """
    # Abort with BAD REQUEST if request body is not in Json format or if any
    # of the provided project properties is not a dict with key and value.
    obj = srv.validate_json_request(request, required=['properties'])
    if not isinstance(obj['properties'], list):
        raise srv.InvalidRequest('expected a list of properties')
    properties = deserialize.PROPERTIES(obj['properties'])
    # Create project and return the project descriptor
    try:
        return jsonify(api.projects.create_project(properties)), 201
    except ValueError as ex:
        raise srv.InvalidRequest(str(ex))
Beispiel #3
0
def update_branch(project_id, branch_id):
    """Update properties for a given project workflow branch. Expects a set of
    key,value-pairs in the request body. Properties with given key but missing
    value will be deleted.

    Request
    -------
    {
      "properties": [
        {
          "key": "string",
          "value": "string"
        }
      ]
    }
    """
    # Abort with BAD REQUEST if request body is not in Json format or does not
    # contain a properties key.
    obj = srv.validate_json_request(request, required=['properties'])
    # Update properties for the given branch and return branch descriptor.
    properties = deserialize.PROPERTIES(obj['properties'], allow_null=True)
    try:
        # Result is None if project or branch are not found.
        branch = api.branches.update_branch(project_id=project_id,
                                            branch_id=branch_id,
                                            properties=properties)
        if not branch is None:
            return jsonify(branch)
    except ValueError as ex:
        raise srv.InvalidRequest(str(ex))
    raise srv.ResourceNotFound('unknown project \'' + project_id +
                               '\' or branch \'' + branch_id + '\'')
Beispiel #4
0
def append_branch_head(project_id, branch_id):
    """Append a module to the workflow that is at the HEAD of the given branch.

    Request
    -------
    {
      "packageId": "string",
      "commandId": "string",
      "arguments": []
    }
    """
    # Abort with BAD REQUEST if request body is not in Json format or does not
    # contain the expected elements.
    cmd = srv.validate_json_request(
        request, required=['packageId', 'commandId', 'arguments'])
    # Extend and execute workflow. This will throw a ValueError if the command
    # cannot be parsed.
    try:

        # Result is None if project or branch are not found
        module = api.workflows.append_workflow_module(
            project_id=project_id,
            branch_id=branch_id,
            package_id=cmd['packageId'],
            command_id=cmd['commandId'],
            arguments=cmd['arguments'],
        )
        if not module is None:
            return jsonify(module)
    except ValueError as ex:
        raise srv.InvalidRequest(str(ex))
    raise srv.ResourceNotFound('unknown project \'' + project_id +
                               '\' or branch \'' + branch_id + '\'')
Beispiel #5
0
def update_project(project_id):
    """Update the set of user-defined properties. Expects a Json object with
    a list of property update statements. These statements are (key,value)
    pairs, where the value is optional (i.e., missing value for delete
    statements).

    Request
    -------
    {
      "properties": [
        {
          "key": "string",
          "value": "scalar or list of scalars"
        }
      ]
    }
    """
    # Abort with BAD REQUEST if request body is not in Json format or if any
    # of the project property update statements are invalid.
    obj = srv.validate_json_request(request, required=['properties'])
    if not isinstance(obj['properties'], list):
        raise srv.InvalidRequest('expected a list of properties')
    # Update project and return the project descriptor. If no project with
    # the given identifier exists the update result will be None
    properties = deserialize.PROPERTIES(obj['properties'], allow_null=True)
    try:
        pj = api.projects.update_project(project_id, properties)
        if not pj is None:
            return jsonify(pj)
    except ValueError as ex:
        raise srv.InvalidRequest(str(ex))
    raise srv.ResourceNotFound('unknown project \'' + project_id + '\'')
Beispiel #6
0
def execute_task():
    """Execute a task against a given project context.

    Request
    -------
    {
      "id": "string",
      "command": {
        "packageId": "string",
        "commandId": "string",
        "arguments": [
          null
        ]
      },
      "context": [
        {
          "id": "string",
          "name": "string"
        }
      ],
      "resources": {}
    }
    """
    # Abort with BAD REQUEST if request body is not in Json format or does not
    # contain the expected elements.
    obj = srv.validate_json_request(
        request,
        required=[labels.ID, labels.COMMAND, labels.CONTEXT],
        optional=[labels.RESOURCES])
    # Validate module command
    cmd = obj[labels.COMMAND]
    for key in [
            labels.COMMAND_PACKAGE, labels.COMMAND_ID, labels.COMMAND_ARGS
    ]:
        if not key in cmd:
            raise srv.InvalidRequest('missing element \'' + key +
                                     '\' in command specification')
    # Get database state
    context = dict()
    for ds in obj[labels.CONTEXT]:
        for key in [labels.ID, labels.NAME]:
            if not key in ds:
                raise srv.InvalidRequest('missing element \'' + key +
                                         '\' in dataset identifier')
        context[ds[labels.NAME]] = ds[labels.ID]
    try:
        # Execute module. Result should not be None.
        result = api.tasks.execute_task(
            project_id=config.project_id,
            task_id=obj[labels.ID],
            command=ModuleCommand(package_id=cmd[labels.COMMAND_PACKAGE],
                                  command_id=cmd[labels.COMMAND_ID],
                                  arguments=cmd[labels.COMMAND_ARGS],
                                  packages=api.engine.packages),
            context=context,
            resources=obj[labels.RESOURCES]
            if labels.RESOURCES in obj else None)
        return jsonify(result)
    except ValueError as ex:
        raise srv.InvalidRequest(str(ex))
Beispiel #7
0
def create_dataset():
    """Create a new dataset in the datastore for the project. The dataset
    schema and rows are given in the request body. Dataset annotations are
    optional. The expected request body format is:

    {
      "columns": [
        {
          "id": 0,
          "name": "string",
          "type": "string"
        }
      ],
      "rows": [
        {
          "id": 0,
          "values": [
            "string"
          ]
        }
      ],
      "annotations": [
        {
          "columnId": 0,
          "rowId": 0,
          "key": "string",
          "value": "string"
        }
      ]
    }
    """
    # Validate the request
    obj = srv.validate_json_request(
        request,
        required=[labels.COLUMNS, labels.ROWS],
        optional=[labels.ANNOTATIONS]
    )
    columns = deserialize.DATASET_COLUMNS(obj[labels.COLUMNS])
    rows = [deserialize.DATASET_ROW(row) for row in obj[labels.ROWS]]
    annotations = None
    if labels.ANNOTATIONS in obj:
        annotations = DatasetMetadata()
        for anno in obj[labels.ANNOTATIONS]:
            a = deserialize.ANNOTATION(anno)
            if a.column_id is None:
                annotations.rows.append(a)
            elif a.row_id is None:
                annotations.columns.append(a)
            else:
                annotations.cells.append(a)
    try:
        dataset = api.datasets.create_dataset(
            project_id=config.project_id,
            columns=columns,
            rows=rows,
            annotations=annotations
        )
        return jsonify(dataset)
    except ValueError as ex:
        raise srv.InvalidRequest(str(ex))
Beispiel #8
0
def create_branch(project_id):
    """Create a new branch for a project. Expects a description of the parent
    workflow in the request body together with an optional list of branch
    properties (e.g., containing a branch name).

    Request
    -------
    {
      "source": {
        "branchId": "string",
        "workflowId": "string"
        "moduleId": "string"
      },
      "properties": [
        {
          "key": "string",
          "value": "string"
        }
      ]
    }
    """
    # Abort with BAD REQUEST if request body is not in Json format or does not
    # contain the expected elements.
    obj = srv.validate_json_request(request,
                                    required=['properties'],
                                    optional=['source'])
    # Get the branch point. If the source is given the dictionary should at
    # most contain the three identifier
    branch_id = None
    workflow_id = None
    module_id = None
    if 'source' in obj:
        source = obj['source']
        for key in source:
            if key == 'branchId':
                branch_id = source[key]
            elif key == 'workflowId':
                workflow_id = source[key]
            elif key == 'moduleId':
                module_id = source[key]
            else:
                raise srv.InvalidRequest('invalid element \'' + key +
                                         '\' for branch point')
    # Get the properties for the new branch
    properties = deserialize.PROPERTIES(obj['properties'])
    # Create a new workflow. The result is the descriptor for the new workflow
    # or None if the specified project does not exist. Will raise a ValueError
    # if the specified workflow version or module do not exist
    try:
        branch = api.branches.create_branch(project_id=project_id,
                                            branch_id=branch_id,
                                            workflow_id=workflow_id,
                                            module_id=module_id,
                                            properties=properties)
        if not branch is None:
            return jsonify(branch)
    except ValueError as ex:
        raise srv.InvalidRequest(str(ex))
    raise srv.ResourceNotFound('unknown project \'' + project_id + '\'')
Beispiel #9
0
def create_dataset(project_id):
    """Create a new dataset in the datastore for the given project. The dataset
    schema and rows are given in the request body. Dataset annotations are
    optional. The expected request body format is:

    {
      "columns": [
        {
          "id": 0,
          "name": "string",
          "type": "string"
        }
      ],
      "rows": [
        {
          "id": 0,
          "values": [
            "string"
          ]
        }
      ],
      "annotations": [
        {
          "columnId": 0,
          "rowId": 0,
          "key": "string",
          "value": "string"
        }
      ]
    }
    """
    # Validate the request
    obj = srv.validate_json_request(request,
                                    required=[labels.COLUMNS, labels.ROWS],
                                    optional=[labels.PROPERTIES])
    columns = deserialize.DATASET_COLUMNS(obj[labels.COLUMNS])
    rows = [deserialize.DATASET_ROW(row) for row in obj[labels.ROWS]]
    properties = obj.get(labels.PROPERTIES, dict())
    try:
        dataset = api.datasets.create_dataset(project_id=project_id,
                                              columns=columns,
                                              rows=rows,
                                              properties=properties)
        if not dataset is None:
            return jsonify(dataset)
    except ValueError as ex:
        raise srv.InvalidRequest(str(ex))
    raise srv.ResourceNotFound('unknown project \'' + project_id + '\'')
Beispiel #10
0
def update_dataset_annotation(dataset_id):
    """Update an annotation that is associated with a component of the given
    dataset.

    Request
    -------
    {
      "columnId": 0,
      "rowId": 0,
      "key": "string",
      "oldValue": "string", or "int", or "float"
      "newValue": "string", or "int", or "float"
    }
    """
    # Validate the request
    obj = srv.validate_json_request(
        request,
        required=['key'],
        optional=['columnId', 'rowId', 'key', 'oldValue', 'newValue']
    )
    # Create update statement and execute. The result is None if no dataset with
    # given identifier exists.
    key = obj[labels.KEY] if labels.KEY in obj else None
    column_id = obj[labels.COLUMN_ID] if labels.COLUMN_ID in obj else None
    row_id = obj[labels.ROW_ID] if labels.ROW_ID in obj else None
    old_value = obj[labels.OLD_VALUE] if labels.OLD_VALUE in obj else None
    new_value = obj[labels.NEW_VALUE] if labels.NEW_VALUE in obj else None
    try:
        annotations = api.datasets.update_annotation(
            project_id=config.project_id,
            dataset_id=dataset_id,
            key=key,
            column_id=column_id,
            row_id=row_id,
            old_value=old_value,
            new_value=new_value
        )
        if not annotations is None:
            return jsonify(annotations)
    except ValueError as ex:
        raise srv.InvalidRequest(str(ex))
    raise srv.ResourceNotFound('unknown dataset \'' + dataset_id + '\'')
Beispiel #11
0
def update_task_state(task_id):
    """Update the state of a running task."""
    # Abort with BAD REQUEST if request body is not in Json format or does not
    # contain the expected elements.
    obj = srv.validate_json_request(request,
                                    required=[labels.STATE],
                                    optional=[
                                        labels.STARTED_AT, labels.FINISHED_AT,
                                        labels.OUTPUTS, labels.PROVENANCE
                                    ])
    # Update task state. The contents of the request body depend on the value of
    # the new task state. The request body is evaluated by the API. The API will
    # raise a ValueError if the request body is invalid. The result is None if
    # the project or task are unknown.
    try:
        # Result is None if task is not found.
        result = api.tasks.update_task_state(task_id=task_id,
                                             state=obj[labels.STATE],
                                             body=obj)
        if not result is None:
            return jsonify(result)
    except ValueError as ex:
        raise srv.InvalidRequest(str(ex))
    raise srv.ResourceNotFound('unknown task \'' + task_id + '\'')