Skip to content

Commit

Permalink
api: add listing output files endpoint
Browse files Browse the repository at this point in the history
* (closes #38).

Signed-off-by: Diego Rodriguez <diego.rodriguez@cern.ch>
  • Loading branch information
Diego Rodriguez committed Nov 6, 2017
1 parent 1c83342 commit 319cd0d
Show file tree
Hide file tree
Showing 4 changed files with 220 additions and 0 deletions.
75 changes: 75 additions & 0 deletions docs/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,81 @@
"summary": "Returns the list of input files for a specific workflow."
}
},
"/api/workflows/{workflow_id}/workspace/outputs": {
"get": {
"description": "This resource is expecting a workflow UUID and a filename to return its outputs.",
"operationId": "get_workflow_outputs",
"parameters": [
{
"description": "Required. Organization which the worklow belongs to.",
"in": "query",
"name": "organization",
"required": true,
"type": "string"
},
{
"description": "Required. UUID of workflow owner.",
"in": "query",
"name": "user",
"required": true,
"type": "string"
},
{
"description": "Required. Workflow UUID.",
"in": "path",
"name": "workflow_id",
"required": true,
"type": "string"
}
],
"produces": [
"multipart/form-data"
],
"responses": {
"200": {
"description": "Requests succeeded. The list of output files has been retrieved.",
"schema": {
"items": {
"properties": {
"last-modified": {
"format": "date-time",
"type": "string"
},
"name": {
"type": "string"
},
"size": {
"type": "integer"
}
},
"type": "object"
},
"type": "array"
}
},
"400": {
"description": "Request failed. The incoming data specification seems malformed."
},
"404": {
"description": "Request failed. User doesn't exist.",
"examples": {
"application/json": {
"message": "User 00000000-0000-0000-0000-000000000000 doesn't exist"
}
}
},
"500": {
"description": "Request failed. Internal controller error.",
"examples": {
"application/json": {
"message": "Either organization or user doesn't exist."
}
}
}
},
"summary": "Returns the list of output files for a specific workflow."
}
},
"/api/workflows/{workflow_id}/workspace/outputs/{file_name}": {
"get": {
"description": "This resource is expecting a workflow UUID and a filename to return its content.",
Expand Down
3 changes: 3 additions & 0 deletions reana_workflow_controller/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,6 @@

INPUTS_RELATIVE_PATH = 'inputs'
"""Inputs directory name."""

OUTPUTS_RELATIVE_PATH = 'outputs'
"""Outputs directory name."""
93 changes: 93 additions & 0 deletions reana_workflow_controller/rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,99 @@ def get_workflow_inputs(workflow_id): # noqa
return jsonify({"message": str(e)}), 500


@restapi_blueprint.route('/workflows/<workflow_id>/workspace/outputs',
methods=['GET'])
def get_workflow_outputs(workflow_id): # noqa
r"""List all workflow output files.
---
get:
summary: Returns the list of output files for a specific workflow.
description: >-
This resource is expecting a workflow UUID and a filename to return
its outputs.
operationId: get_workflow_outputs
produces:
- multipart/form-data
parameters:
- name: organization
in: query
description: Required. Organization which the worklow belongs to.
required: true
type: string
- name: user
in: query
description: Required. UUID of workflow owner.
required: true
type: string
- name: workflow_id
in: path
description: Required. Workflow UUID.
required: true
type: string
responses:
200:
description: >-
Requests succeeded. The list of output files has been retrieved.
schema:
type: array
items:
type: object
properties:
name:
type: string
last-modified:
type: string
format: date-time
size:
type: integer
400:
description: >-
Request failed. The incoming data specification seems malformed.
404:
description: >-
Request failed. User doesn't exist.
examples:
application/json:
{
"message": "User 00000000-0000-0000-0000-000000000000 doesn't
exist"
}
500:
description: >-
Request failed. Internal controller error.
examples:
application/json:
{
"message": "Either organization or user doesn't exist."
}
"""
try:
user_uuid = request.args['user']
user = User.query.filter(User.id_ == user_uuid).first()
if not user:
return jsonify(
{'message': 'User {} does not exist'.format(user)}), 404

workflow = Workflow.query.filter(Workflow.id_ == workflow_id).first()
if workflow:
outputs_directory = os.path.join(
current_app.config['SHARED_VOLUME_PATH'],
workflow.workspace_path,
current_app.config['OUTPUTS_RELATIVE_PATH'])

outputs_list = list_directory_files(outputs_directory)
return jsonify(outputs_list), 200
else:
return jsonify({'message': 'The workflow {} doesn\'t exist'.
format(str(workflow.id_))}), 404

except KeyError:
return jsonify({"message": "Malformed request."}), 400
except Exception as e:
return jsonify({"message": str(e)}), 500


@restapi_blueprint.route('/yadage/remote', methods=['POST'])
def run_yadage_workflow_from_remote_endpoint(): # noqa
r"""Create a new yadage workflow from a remote repository.
Expand Down
49 changes: 49 additions & 0 deletions tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,3 +318,52 @@ def test_get_workflow_inputs_list(app, db_session, default_user,
data=json.dumps(data))
for file_ in json.loads(res.data.decode()):
assert file_.get('name') in test_files


def test_get_workflow_outputs_list(app, db_session, default_user,
tmp_shared_volume_path):
"""Test get list of output files."""
with app.test_client() as client:
# create workflow
organization = 'default'
data = {'parameters': {'min_year': '1991',
'max_year': '2001'},
'specification': {'first': 'do this',
'second': 'do that'},
'type': 'cwl'}
res = client.post(url_for('api.create_workflow'),
query_string={
"user": default_user.id_,
"organization": organization},
content_type='application/json',
data=json.dumps(data))

response_data = json.loads(res.get_data(as_text=True))
workflow_uuid = response_data.get('workflow_id')
workflow = Workflow.query.filter(
Workflow.id_ == workflow_uuid).first()
# create file
absolute_path_workflow_workspace = \
os.path.join(tmp_shared_volume_path,
workflow.workspace_path)
fs_ = fs.open_fs(absolute_path_workflow_workspace)
# from config
outputs_realative_path = app.config['OUTPUTS_RELATIVE_PATH']
fs_.makedirs(outputs_realative_path)
test_files = []
for i in range(5):
file_name = '{0}.csv'.format(i)
subdir_name = str(uuid.uuid4())
subdir = fs.path.join(outputs_realative_path, subdir_name)
fs_.makedirs(subdir)
fs_.touch('{0}/{1}'.format(subdir, file_name))
test_files.append(os.path.join(subdir_name, file_name))

res = client.get(
url_for('api.get_workflow_outputs', workflow_id=workflow_uuid),
query_string={"user": default_user.id_,
"organization": organization},
content_type='application/json',
data=json.dumps(data))
for file_ in json.loads(res.data.decode()):
assert file_.get('name') in test_files

0 comments on commit 319cd0d

Please sign in to comment.