Skip to content

Commit

Permalink
Merge pull request #35 from Aratz/dev-2090_create_project_endpoint
Browse files Browse the repository at this point in the history
Get either token or token path through API
  • Loading branch information
Aratz authored Jun 7, 2022
2 parents 683593c + 8519a3e commit ffd41f2
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 31 deletions.
27 changes: 22 additions & 5 deletions delivery/handlers/dds_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from delivery.handlers import *
from delivery.handlers.utility_handlers import ArteriaDeliveryBaseHandler

import os
import tempfile
import logging
log = logging.getLogger(__name__)

Expand All @@ -25,7 +27,8 @@ async def post(self, project_name):
Create a new project in DDS. The project description as well as the
email of its pi must be specified in the request body. Project owners,
researchers, and whether the data is sensitive or not (default is yes),
can also be specified there. E.g.:
can also be specified there. "auth_token" can be either the path to
the authentication token or the token itself. E.g.:
import requests
Expand All @@ -37,16 +40,30 @@ async def post(self, project_name):
"researchers": ["[email protected]", "[email protected]"],
"owners": ["[email protected]"],
"non-sensitive": False,
"token_path": "/foo/bar"
"auth_token": "1234"
}
response = requests.request("POST", url, json=payload)
"""

required_members = ["token_path"]
project_metadata = self.body_as_object(required_members=required_members)
required_members = ["auth_token"]
project_metadata = self.body_as_object(
required_members=required_members)

dds_project_id = await self.dds_service.create_dds_project(project_name, project_metadata)
with tempfile.NamedTemporaryFile(mode='w', delete=True) as token_file:
if os.path.exists(project_metadata["auth_token"]):
token_path = project_metadata["auth_token"]
else:
token_file.write(project_metadata["auth_token"])
token_file.flush()

token_path = token_file.name

dds_project_id = await self.dds_service.create_dds_project(
project_name,
project_metadata,
token_path,
)

self.set_status(ACCEPTED)
self.write_json({'dds_project_id': dds_project_id})
32 changes: 22 additions & 10 deletions delivery/handlers/delivery_handlers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@

import os
import json
import logging
import tempfile

from tornado.gen import coroutine

Expand All @@ -24,16 +26,14 @@ def initialize(self, **kwargs):
def post(self, staging_id):
required_members = ["delivery_project_id"]
if self.dds:
required_members += ["token_path"]
required_members += ["auth_token"]
request_data = self.body_as_object(required_members=required_members)

delivery_project_id = request_data["delivery_project_id"]
token_path = request_data.get("token_path")
auth_token = request_data.get("auth_token")
md5sum_file = request_data.get("md5sums_file")

extra_args = {}
if token_path:
extra_args['token_path'] = token_path

# This should only be used for testing purposes /JD 20170202
skip_mover_request = request_data.get("skip_mover")
Expand All @@ -44,12 +44,24 @@ def post(self, staging_id):
log.debug("Will not skip running mover!")
skip_mover = False

delivery_id = yield self.delivery_service.deliver_by_staging_id(
staging_id=staging_id,
delivery_project=delivery_project_id,
md5sum_file=md5sum_file,
skip_mover=skip_mover,
**extra_args)
with tempfile.NamedTemporaryFile(mode='w', delete=True) as token_file:
if auth_token:
if os.path.exists(auth_token):
token_path = auth_token
else:
token_file.write(auth_token)
token_file.flush()

token_path = token_file.name

extra_args['token_path'] = token_path

delivery_id = yield self.delivery_service.deliver_by_staging_id(
staging_id=staging_id,
delivery_project=delivery_project_id,
md5sum_file=md5sum_file,
skip_mover=skip_mover,
**extra_args)

status_end_point = "{0}://{1}{2}".format(self.request.protocol,
self.request.host,
Expand Down
17 changes: 14 additions & 3 deletions delivery/services/dds_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,23 @@ def _parse_dds_project_id(dds_output):
else:
raise CannotParseDDSOutputException(f"Could not parse DDS project ID from: {dds_output}")

async def create_dds_project(self, project_name, project_metadata):
async def create_dds_project(
self,
project_name,
project_metadata,
token_path):
"""
Create a new project in dds
:param project_name: Project name from Clarity
:param project_metadata: dictionnary containing pi email, project
description, owner and researcher emails as well as whether the data is
sensitive or not.
:param token_path: path to DDS authentication token.
:return: project id in dds
"""
cmd = [
'dds',
'--token-path', project_metadata["token_path"],
'--token-path', token_path,
'--log-file', self.dds_conf["log_path"],
]

Expand Down Expand Up @@ -152,7 +157,13 @@ def _run_dds_put(
session.commit()

@gen.coroutine
def deliver_by_staging_id(self, staging_id, delivery_project, md5sum_file, token_path, skip_mover=False):
def deliver_by_staging_id(
self,
staging_id,
delivery_project,
md5sum_file,
token_path,
skip_mover=False):

stage_order = self.staging_service.get_stage_order_by_id(staging_id)
if not stage_order or not stage_order.status == StagingStatus.staging_successful:
Expand Down
10 changes: 5 additions & 5 deletions tests/integration_tests/test_integration_dds.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def test_can_stage_and_delivery_runfolder(self):
delivery_body = {
'delivery_project_id': 'fakedeliveryid2016',
'dds': True,
'token_path': 'token_path',
'auth_token': '1234',
'skip_mover': True,
}
delivery_resp = yield self.http_client.fetch(self.get_url(delivery_url), method='POST', body=json.dumps(delivery_body))
Expand Down Expand Up @@ -102,7 +102,7 @@ def test_can_stage_and_delivery_project_dir(self):
'delivery_project_id': 'fakedeliveryid2016',
'skip_mover': True,
'dds': True,
'token_path': 'token_path',
'auth_token': '1234',
}
delivery_resp = yield self.http_client.fetch(self.get_url(delivery_url), method='POST', body=json.dumps(delivery_body))
delivery_resp_as_json = json.loads(delivery_resp.body)
Expand Down Expand Up @@ -214,7 +214,7 @@ def test_can_create_project(self):
"researchers": ["[email protected]", "[email protected]"],
"owners": ["[email protected]"],
"non-sensitive": False,
"token_path": '/foo/bar/auth',
"auth_token": '1234',
}

response = yield self.http_client.fetch(
Expand All @@ -234,7 +234,7 @@ def test_can_create_two_projects(self):
"researchers": ["[email protected]", "[email protected]"],
"owners": ["[email protected]"],
"non-sensitive": False,
"token_path": '/foo/bar/auth',
"auth_token": '1234',
}

response = yield self.http_client.fetch(
Expand Down Expand Up @@ -294,7 +294,7 @@ def test_can_deliver_and_respond(self):
delivery_body = {
'delivery_project_id': 'fakedeliveryid2016',
'dds': True,
'token_path': 'token_path',
'auth_token': '1234',
'skip_mover': False,
}
delivery_response = self.http_client.fetch(self.get_url(delivery_url), method='POST', body=json.dumps(delivery_body))
Expand Down
23 changes: 15 additions & 8 deletions tests/unit_tests/services/test_dds.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,30 +186,37 @@ def test_parse_dds_project_id(self):
self.assertEqual(DDSService._parse_dds_project_id(dds_output), "snpseq00003")

@gen_test
def test_create_project(self):
def test_create_project_token_file(self):
project_name = "AA-1221"
project_metadata = {
"description": "Dummy project",
"pi": "[email protected]",
"researchers": ["[email protected]", "[email protected]"],
"owners": ["[email protected]"],
"non-sensitive": False,
"token_path": "/foo/bar/auth",
}

token_path = "/foo/bar/auth"

with patch(
'delivery.services.external_program_service'
'.ExternalProgramService.run_and_wait',
new_callable=AsyncMock) as mock_run,\
patch('delivery.services.dds_service.DDSService._parse_dds_project_id') as mock_parse_dds_project_id:
patch(
'delivery.services.dds_service'
'.DDSService._parse_dds_project_id'
) as mock_parse_dds_project_id:
mock_run.return_value.status_code = 0
mock_parse_dds_project_id.return_value = "snpseq00001"

yield self.dds_service.create_dds_project(project_name, project_metadata)
yield self.dds_service.create_dds_project(
project_name,
project_metadata,
token_path)

mock_run.assert_called_once_with([
'dds',
'--token-path', '/foo/bar/auth',
'--token-path', token_path,
'--log-file', '/foo/bar/log',
'project', 'create',
'--title', project_name,
Expand All @@ -220,6 +227,6 @@ def test_create_project(self):
'--researcher', project_metadata['researchers'][1],
])
self.mock_dds_project_repo.add_dds_project\
.assert_called_once_with(
project_name=project_name,
dds_project_id=mock_parse_dds_project_id.return_value)
.assert_called_once_with(
project_name=project_name,
dds_project_id=mock_parse_dds_project_id.return_value)

0 comments on commit ffd41f2

Please sign in to comment.