diff --git a/services/workflow/src/workflow/server.py b/services/workflow/src/workflow/server.py index a3a066f0d26353e51f0168e441112ba32957e65c..544248f4bb2eb5e17c48b09703828029b7655a9e 100644 --- a/services/workflow/src/workflow/server.py +++ b/services/workflow/src/workflow/server.py @@ -24,12 +24,12 @@ def lookup_workflow(request): return request.info.lookup_workflow_definition(request.matchdict['name']) -# def lookup_request(request): -# return request.info.lookup_workflow_request(request.matchdict['requests']) +def lookup_request(request): + return request.info.lookup_workflow_request(request.matchdict['request_id']) def lookup_file(request): - return lookup_workflow(request)['files'][request.matchdict['filename']] + return next(file for file in lookup_workflow(request).files if file.filename == request.matchdict['filename']) @view_defaults(route_name='workflows', renderer='json') @@ -52,8 +52,31 @@ class WorkflowRestService: """ return self.request.info.all_workflows() - @view_config(request_method='POST', route_name='create_workflow') - def create_workflow(self): + @view_config(request_method='GET', route_name='workflow') + def get_workflow(self): + """ + Look up a workflow request + + Audience: front-end + :return: + """ + return self.request.context + + +@view_defaults(route_name='workflow_request', renderer='json') +class WorkflowRequestRestService: + """ + Services for the user-submitted files attached to workflows. + """ + def __init__(self, request): + self.request = request + + @view_config(request_method='GET') + def get_workflow_request(self): + return self.request.context + + @view_config(request_method='POST', route_name='create_workflow_request') + def create_workflow_request(self): """ Create a new workflow request from the name/arguments supplied. @@ -63,21 +86,10 @@ class WorkflowRestService: # all we should have to do here is take the WorkflowRequest from the context and # hand it to WorkflowInfo to save it, but we're still conflating # workflows and workflow requests right now - request = self.request.info.create_workflow_request( - workflow_name=self.request.context.workflow_name, argument=self.request.GET.getall('args')) + request = self.request.info.create_workflow_request(self.request.context, self.request.GET.getall('args')) return request - @view_config(request_method='GET', route_name='workflow') - def get_workflow(self): - """ - Look up a workflow request - - Audience: front-end - :return: - """ - return self.request.context - - @view_config(request_method='POST', route_name='submit_workflow') + @view_config(request_method='POST', route_name='submit_workflow_request') def submit_workflow(self): """ Submit this workflow request for processing. @@ -89,7 +101,7 @@ class WorkflowRestService: return self.request.workflows.execute(self.request.context) -@view_defaults(route_name='workflow_files', renderer='json') +@view_defaults(route_name='workflow_request_files', renderer='json') class WorkflowFilesRestService: """ Services for the user-submitted files attached to workflows. @@ -97,7 +109,7 @@ class WorkflowFilesRestService: def __init__(self, request): self.request = request - @view_config(request_method='POST', route_name='add_file') + @view_config(request_method='PUT', route_name='add_file_to_workflow_request') def add_file(self): """ Add a file to this workflow request. @@ -105,9 +117,9 @@ class WorkflowFilesRestService: Audience: front-end and CLI """ print('Adding a file') - file = self.request.info.save_file(request_id=self.request.GET.get("request"), - filename=self.request.GET.get("filename"), - content=self.request.GET.get("content")) + file = self.request.info.save_file(request_id=self.request.matchdict['request_id'], + filename=self.request.matchdict['filename'], + content=self.request.body) return file @view_config(request_method='GET') @@ -194,13 +206,20 @@ def main(global_config, **settings): # make workflow_service available for use in Pyramid config.add_request_method(lambda r: WorkflowService(r.info), 'workflows', reify=True) + # GET /workflows <- list of workflows + # GET /workflows/null <- info about the null workflow + # POST /workflows/null/requests/create <- create a request for the null workflow + # PUT /workflows/requests/23/files/foo.txt <- attach foo.txt to request #23 on workflow null + # POST /workflows/requests/23/submit <- launch request #23 + config.add_route('workflows', '/workflows') config.add_route('workflow', '/workflows/{name}', factory=lookup_workflow) - config.add_route('create_workflow', '/workflows/{name}/create', factory=lookup_workflow) - config.add_route('submit_workflow', '/workflows/{name}/submit', factory=lookup_workflow) - config.add_route('add_file', '/workflows/file') - config.add_route('workflow_files', '/workflows/{name}/files', factory=lookup_workflow) - config.add_route('workflow_file', '/workflows/{name}/files/{filename}', factory=lookup_file) + config.add_route('create_workflow_request', '/workflows/{name}/requests/create', factory=lookup_workflow) + config.add_route('workflow_request', '/workflows/requests/{request_id}', factory=lookup_request) + config.add_route('workflow_request_files', '/workflows/requests/{request_id}/files', factory=lookup_request) + config.add_route('add_file_to_workflow_request', '/workflows/requests/{request_id}/files/{filename}', factory=lookup_request) + config.add_route('submit_workflow_request', '/workflows/requests/{request_id}/submit', factory=lookup_request) + config.add_route('workflow_file', '/workflows/requests/{request_id}/files/{filename}', factory=lookup_file) config.include('pyramid_beaker') config.scan('.') diff --git a/shared/workspaces/src/workspaces/services.py b/shared/workspaces/src/workspaces/services.py index d3b3959f5fcf651b493d9250c61ae39c570a6a47..d71da7331fbe66e70863e99fcefa5326a28a6954 100644 --- a/shared/workspaces/src/workspaces/services.py +++ b/shared/workspaces/src/workspaces/services.py @@ -398,6 +398,14 @@ class WorkflowService(WorkflowServiceIF): """ Executes workflows; should be a freestanding service. """ + # The next few things that need to happen here are in response to + # WorkflowEvents that we receive from wf_monitor as the workflow + # execution evolves. So we have to set up listening at some point + # in this class + def __init__(self, info: WorkflowInfoIF): + # 1. Start listening for events from the wf_monitor stream + # self.channel = workflow_events.listen(self.on_workflow_event) + self.info = info def execute(self, workflow_name: str, argument: Dict, files: List[Path]): """ @@ -405,11 +413,10 @@ class WorkflowService(WorkflowServiceIF): """ # 1. look up workflow, returns workflow - info = WorkflowInfo(self) - definition = info.lookup_workflow_definition(workflow_name) + definition = self.info.lookup_workflow_definition(workflow_name) # 2. create and save request, return request id - record = info.create_workflow_request(workflow_name, argument) + record = self.info.create_workflow_request(workflow_name, argument) # 3. render templates to files, returns list of rendered files contents = definition.render_templates(argument, files) @@ -475,15 +482,6 @@ class WorkflowService(WorkflowServiceIF): # return the logfile return logfile - # The next few things that need to happen here are in response to - # WorkflowEvents that we receive from wf_monitor as the workflow - # execution evolves. So we have to set up listening at some point - # in this class - def __init__(self): - # 1. Start listening for events from the wf_monitor stream - # self.channel = workflow_events.listen(self.on_workflow_event) - pass - def on_workflow_event( self, event: WorkflowEvent, request_record: WorkflowRequest, tmp_folder: Path ): @@ -564,7 +562,7 @@ class WorkflowInfo(WorkflowInfoIF): def create_workflow_request( self, - workflow_name: str, + workflow: Workflow, argument: Dict) -> WorkflowRequest: """ Create new workflow request and save to database @@ -572,7 +570,7 @@ class WorkflowInfo(WorkflowInfoIF): :param argument: workflow arguments :return: new WorkflowRequest """ - request = WorkflowRequest(workflow_name=workflow_name, argument=argument) + request = WorkflowRequest(workflow_name=workflow.workflow_name, argument=argument) self.save_request(request) return request