def _load_sample_workflow_specs(self): workflow_spec_category = session.query( WorkflowSpecCategoryModel).first() spec_model_1 = WorkflowSpecModel(id='test_spec_1', display_name='Test Spec 1', description='Test Spec 1 Description', category_id=workflow_spec_category.id, standalone=False) rv_1 = self.app.post('/v1.0/workflow-specification', headers=self.logged_in_headers(), content_type="application/json", data=json.dumps( WorkflowSpecModelSchema().dump(spec_model_1))) spec_model_2 = WorkflowSpecModel(id='test_spec_2', display_name='Test Spec 2', description='Test Spec 2 Description', category_id=workflow_spec_category.id, standalone=False) rv_2 = self.app.post('/v1.0/workflow-specification', headers=self.logged_in_headers(), content_type="application/json", data=json.dumps( WorkflowSpecModelSchema().dump(spec_model_2))) spec_model_3 = WorkflowSpecModel(id='test_spec_3', display_name='Test Spec 3', description='Test Spec 3 Description', category_id=workflow_spec_category.id, standalone=False) rv_3 = self.app.post('/v1.0/workflow-specification', headers=self.logged_in_headers(), content_type="application/json", data=json.dumps( WorkflowSpecModelSchema().dump(spec_model_3))) return rv_1, rv_2, rv_3
def test_update_workflow_specification(self): self.load_example_data() category_id = 99 category = WorkflowSpecCategoryModel(id=category_id, name='trap', display_name="It's a trap!", display_order=0) session.add(category) session.commit() db_spec_before: WorkflowSpecModel = session.query( WorkflowSpecModel).first() spec_id = db_spec_before.id self.assertNotEqual(db_spec_before.category_id, category_id) db_spec_before.category_id = category_id rv = self.app.put('/v1.0/workflow-specification/%s' % spec_id, content_type="application/json", headers=self.logged_in_headers(), data=json.dumps( WorkflowSpecModelSchema().dump(db_spec_before))) self.assert_success(rv) json_data = json.loads(rv.get_data(as_text=True)) api_spec = WorkflowSpecModelSchema().load(json_data, session=session) self.assertEqual(db_spec_before, api_spec) db_spec_after: WorkflowSpecModel = session.query( WorkflowSpecModel).filter_by(id=spec_id).first() self.assertIsNotNone(db_spec_after.category_id) self.assertIsNotNone(db_spec_after.category) self.assertEqual(db_spec_after.category.display_name, category.display_name) self.assertEqual(db_spec_after.category.display_order, category.display_order)
def add_workflow_specification(body): category_id = body['category_id'] WorkflowService.cleanup_workflow_spec_display_order(category_id) count = session.query(WorkflowSpecModel).filter_by( category_id=category_id).count() body['display_order'] = count # Libraries and standalone workflows don't get a category_id if body['library'] is True or body['standalone'] is True: body['category_id'] = None new_spec: WorkflowSpecModel = WorkflowSpecModelSchema().load( body, session=session) session.add(new_spec) session.commit() return WorkflowSpecModelSchema().dump(new_spec)
def update_workflow_specification(spec_id, body): if spec_id is None: raise ApiError('unknown_spec', 'Please provide a valid Workflow Spec ID.') spec = session.query(WorkflowSpecModel).filter_by(id=spec_id).first() if spec is None: raise ApiError('unknown_study', 'The spec "' + spec_id + '" is not recognized.') schema = WorkflowSpecModelSchema() spec = schema.load(body, session=session, instance=spec, partial=True) session.add(spec) session.commit() return schema.dump(spec)
def test_add_new_workflow_specification(self): self.load_example_data() num_before = session.query(WorkflowSpecModel).count() category_id = session.query(WorkflowSpecCategoryModel).first().id category_count = session.query(WorkflowSpecModel).filter_by( category_id=category_id).count() spec = WorkflowSpecModel(id='make_cookies', display_name='Cooooookies', description='Om nom nom delicious cookies', category_id=category_id, standalone=False) rv = self.app.post('/v1.0/workflow-specification', headers=self.logged_in_headers(), content_type="application/json", data=json.dumps( WorkflowSpecModelSchema().dump(spec))) self.assert_success(rv) db_spec = session.query(WorkflowSpecModel).filter_by( id='make_cookies').first() self.assertEqual(spec.display_name, db_spec.display_name) num_after = session.query(WorkflowSpecModel).count() self.assertEqual(num_after, num_before + 1) self.assertEqual(category_count, db_spec.display_order) category_count_after = session.query(WorkflowSpecModel).filter_by( category_id=category_id).count() self.assertEqual(category_count_after, category_count + 1)
def reorder_workflow_specification(spec_id, direction): if direction not in ('up', 'down'): raise ApiError(code='bad_direction', message='The direction must be `up` or `down`.') spec = session.query(WorkflowSpecModel).filter( WorkflowSpecModel.id == spec_id).first() if spec: WorkflowService.cleanup_workflow_spec_display_order(spec.category_id) ordered_specs = WorkflowService.reorder_workflow_spec(spec, direction) else: raise ApiError( code='bad_spec_id', message= f'The spec_id {spec_id} did not return a specification. Please check that it is valid.' ) schema = WorkflowSpecModelSchema(many=True) return schema.dump(ordered_specs)
def test_get_workflow_specification(self): self.load_example_data() db_spec = session.query(WorkflowSpecModel).first() rv = self.app.get('/v1.0/workflow-specification/%s' % db_spec.id, headers=self.logged_in_headers()) self.assert_success(rv) json_data = json.loads(rv.get_data(as_text=True)) api_spec = WorkflowSpecModelSchema().load(json_data, session=session) self.assertEqual(db_spec, api_spec)
def create_or_update_local_spec(remote, workflow_spec_id): specdict = WorkflowSyncService.get_remote_workflow_spec( remote, workflow_spec_id) # if we are updating from a master spec, then we want to make sure it is the only # master spec in our local system, turn all other master_specs off if specdict['is_master_spec']: master_specs = session.query(WorkflowSpecModel).filter( WorkflowSpecModel.is_master_spec == True).all() for master_spec in master_specs: master_spec.is_master_spec = False session.add(master_spec) # Update local_spec, or create a new one if one does not exist. local_spec = session.query(WorkflowSpecModel).filter( WorkflowSpecModel.id == workflow_spec_id).first() local_spec = WorkflowSpecModelSchema().load(specdict, session=session, instance=local_spec) # Set the category if specdict['category'] is not None: local_category = session.query(WorkflowSpecCategoryModel).\ filter(WorkflowSpecCategoryModel.id == specdict['category']['id']).first() local_category = WorkflowSpecCategoryModelSchema().load( specdict['category'], session=session, instance=local_category) session.add(local_category) local_spec.category = local_category # Add the local spec to the database, then we can link the libraries. session.add(local_spec) # Set the libraries session.query(WorkflowLibraryModel).filter( WorkflowLibraryModel.workflow_spec_id == local_spec.id).delete() for library in specdict['libraries']: # Assure refernced libraries are local, and link them. create_or_update_local_spec(remote, library['id']) local_lib = WorkflowLibraryModel(workflow_spec_id=local_spec.id, library_spec_id=library['id']) session.add(local_lib) session.commit()
def process_workflow_spec(location, workflow_spec, category_name_string): # Make sure a directory exists for the workflow spec # Add a json file dumped from the workflow spec model workflow_spec_path = os.path.join(location, category_name_string, workflow_spec.display_name) os.makedirs(os.path.dirname(workflow_spec_path), exist_ok=True) json_file_name = f'{workflow_spec.display_name}.json' json_file_path = os.path.join(location, category_name_string, json_file_name) workflow_spec_schema = WorkflowSpecModelSchema().dumps(workflow_spec) with open(json_file_path, 'w') as j_handle: j_handle.write(workflow_spec_schema)
def all_specifications(libraries=False, standalone=False): if libraries and standalone: raise ApiError( 'inconceivable!', 'You should specify libraries or standalone, but not both') schema = WorkflowSpecModelSchema(many=True) if libraries: return schema.dump(session.query(WorkflowSpecModel)\ .filter(WorkflowSpecModel.library==True).all()) if standalone: return schema.dump(session.query(WorkflowSpecModel)\ .filter(WorkflowSpecModel.standalone==True).all()) # return standard workflows (not library, not standalone) return schema.dump( session.query(WorkflowSpecModel).filter( (WorkflowSpecModel.library == False) | (WorkflowSpecModel.library == None)).filter( (WorkflowSpecModel.standalone == False) | (WorkflowSpecModel.standalone == None)).all())
def do_task(self, task, study_id, workflow_id, *args, **kwargs): if len(args) < 1: raise ApiError( code='missing_parameter', message='Please pass in a workflow_id to use in the search.') passed_workflow_id = args[0] workflow = session.query(WorkflowModel).filter( WorkflowModel.id == passed_workflow_id).first() workflow_spec = session.query(WorkflowSpecModel).filter( WorkflowSpecModel.id == workflow.workflow_spec_id).first() if workflow_spec: return WorkflowSpecModelSchema().dump(workflow_spec)
def get_workflow_specification(spec_id): if spec_id is None: raise ApiError('unknown_spec', 'Please provide a valid Workflow Specification ID.') spec: WorkflowSpecModel = session.query(WorkflowSpecModel).filter_by( id=spec_id).first() if spec is None: raise ApiError( 'unknown_spec', 'The Workflow Specification "' + spec_id + '" is not recognized.') return WorkflowSpecModelSchema().dump(spec)
def update_workflow_specification(spec_id, body): if spec_id is None: raise ApiError('unknown_spec', 'Please provide a valid Workflow Spec ID.') spec = session.query(WorkflowSpecModel).filter_by(id=spec_id).first() if spec is None: raise ApiError('unknown_study', 'The spec "' + spec_id + '" is not recognized.') # Make sure they don't try to change the display_order # There is a separate endpoint for this body['display_order'] = spec.display_order # Libraries and standalone workflows don't get a category_id if body['library'] is True or body['standalone'] is True: body['category_id'] = None schema = WorkflowSpecModelSchema() spec = schema.load(body, session=session, instance=spec, partial=True) session.add(spec) session.commit() return schema.dump(spec)
def test_list_workflow_specifications(self): self.load_example_data() spec = session.query(WorkflowSpecModel).first() rv = self.app.get('/v1.0/workflow-specification', follow_redirects=True, content_type="application/json", headers=self.logged_in_headers()) self.assert_success(rv) json_data = json.loads(rv.get_data(as_text=True)) specs = WorkflowSpecModelSchema(many=True).load(json_data, session=session) spec2 = specs[0] self.assertEqual(spec.id, spec2.id) self.assertEqual(spec.display_name, spec2.display_name) self.assertEqual(spec.description, spec2.description)
def test_add_library_with_category_id(self): self.load_example_data() category_id = session.query(WorkflowSpecCategoryModel).first().id spec = WorkflowSpecModel(id='test_spec', display_name='Test Spec', description='Library with a category id', category_id=category_id, standalone=False, library=True) rv = self.app.post('/v1.0/workflow-specification', headers=self.logged_in_headers(), content_type="application/json", data=json.dumps( WorkflowSpecModelSchema().dump(spec))) self.assert_success(rv) # libraries don't get category_ids # so, the category_id should not get set self.assertIsNone(rv.json['category_id'])
def test_auto_set_primary_bpmn(self): self.load_example_data() category_id = session.query(WorkflowSpecCategoryModel).first().id # Add a workflow spec spec = WorkflowSpecModel(id='make_cookies', display_name='Cooooookies', description='Om nom nom delicious cookies', category_id=category_id, standalone=False) rv = self.app.post('/v1.0/workflow-specification', headers=self.logged_in_headers(), content_type="application/json", data=json.dumps( WorkflowSpecModelSchema().dump(spec))) self.assert_success(rv) # grab the spec from the db db_spec = session.query(WorkflowSpecModel).filter_by( id='make_cookies').first() self.assertEqual(spec.display_name, db_spec.display_name) # Make sure we don't already have a primary bpmn file have_primary = FileModel.query.filter( FileModel.workflow_spec_id == db_spec.id, FileModel.type == FileType.bpmn, FileModel.primary == True).all() self.assertEqual(have_primary, []) data = {} data['file'] = io.BytesIO( self.minimal_bpmn("abcdef")), 'my_new_file.bpmn' # Add a new BPMN file to the specification rv = self.app.post('/v1.0/spec_file?workflow_spec_id=%s' % db_spec.id, data=data, follow_redirects=True, content_type='multipart/form-data', headers=self.logged_in_headers()) self.assert_success(rv) file_id = rv.json['id'] # Make sure we now have a primary bpmn have_primary = FileModel.query.filter( FileModel.workflow_spec_id == db_spec.id, FileModel.type == FileType.bpmn, FileModel.primary == True).all() self.assertEqual(len(have_primary), 1) self.assertEqual(file_id, have_primary[0].id)
def add_workflow_specification(body): new_spec: WorkflowSpecModel = WorkflowSpecModelSchema().load( body, session=session) session.add(new_spec) session.commit() return WorkflowSpecModelSchema().dump(new_spec)
def all_specifications(): schema = WorkflowSpecModelSchema(many=True) return schema.dump(session.query(WorkflowSpecModel).all())