def add_file(workflow_id=None, task_spec_name=None, form_field_key=None): file = connexion.request.files['file'] if workflow_id: if form_field_key is None: raise ApiError( 'invalid_workflow_file', 'When adding a workflow related file, you must specify a form_field_key' ) if task_spec_name is None: raise ApiError( 'invalid_workflow_file', 'When adding a workflow related file, you must specify a task_spec_name' ) file_model = FileService.add_workflow_file( workflow_id=workflow_id, irb_doc_code=form_field_key, task_spec_name=task_spec_name, name=file.filename, content_type=file.content_type, binary_data=file.stream.read()) else: raise ApiError( "invalid_file", "You must supply either a workflow spec id or a workflow_id and form_field_key." ) return FileSchema().dump(to_file_api(file_model))
def update_file_data(file_id): file_model = session.query(FileModel).filter_by(id=file_id).with_for_update().first() file = connexion.request.files['file'] if file_model is None: raise ApiError('no_such_file', 'The file id you provided does not exist') file_model = FileService.update_file(file_model, file.stream.read(), file.content_type) return FileSchema().dump(to_file_api(file_model))
def get_file_info(file_id): file_model = session.query(FileModel).filter_by( id=file_id).with_for_update().first() if file_model is None: raise ApiError('no_such_file', f'The file id you provided ({file_id}) does not exist', status_code=404) return FileSchema().dump(to_file_api(file_model))
def get_spec_files(workflow_spec_id, include_libraries=False): if workflow_spec_id is None: raise ApiError(code='missing_spec_id', message='Please specify the workflow_spec_id.') file_models = SpecFileService.get_spec_files( workflow_spec_id=workflow_spec_id, include_libraries=include_libraries) files = [to_file_api(model) for model in file_models] return FileSchema(many=True).dump(files)
def update_reference_file_info(name, body): if name is None: raise ApiError(code='missing_parameter', message='Please provide a reference file name') file_model = session.query(FileModel).filter(FileModel.name==name).first() if file_model is None: raise ApiError(code='no_such_file', message=f"No reference file was found with name: {name}") new_file_model = ReferenceFileService.update_reference_file_info(file_model, body) return FileSchema().dump(to_file_api(new_file_model))
def get_reference_file_info(name): """Return metadata for a reference file""" file_model = session.query(FileModel).\ filter_by(name=name).with_for_update().\ filter_by(archived=False).with_for_update().\ first() if file_model is None: # TODO: Should this be 204 or 404? raise ApiError('no_such_file', f'The reference file name you provided ({name}) does not exist', status_code=404) return FileSchema().dump(to_file_api(file_model))
def update_spec_file_info(file_id, body): if file_id is None: raise ApiError('no_such_file', 'Please provide a valid File ID.') file_model = session.query(FileModel).filter( FileModel.id == file_id).first() if file_model is None: raise ApiError('unknown_file_model', 'The file_model "' + file_id + '" is not recognized.') new_file_model = SpecFileService().update_spec_file_info(file_model, body) return FileSchema().dump(to_file_api(new_file_model))
def get_files(workflow_spec_id=None, workflow_id=None, form_field_key=None): if all(v is None for v in [workflow_spec_id, workflow_id, form_field_key]): raise ApiError('missing_parameter', 'Please specify either a workflow_spec_id or a ' 'workflow_id with an optional form_field_key') file_models = FileService.get_files(workflow_spec_id=workflow_spec_id, workflow_id=workflow_id, irb_doc_code=form_field_key) files = (to_file_api(model) for model in file_models) return FileSchema(many=True).dump(files)
def update_file_info(file_id, body): if file_id is None: raise ApiError('no_such_file', 'Please provide a valid File ID.') file_model = session.query(FileModel).filter_by(id=file_id).first() if file_model is None: raise ApiError('unknown_file_model', 'The file_model "' + file_id + '" is not recognized.') file_model = FileModelSchema().load(body, session=session) session.add(file_model) session.commit() return FileSchema().dump(to_file_api(file_model))
def get_files(workflow_id=None, form_field_key=None, study_id=None): if workflow_id is None: raise ApiError( 'missing_parameter', 'Please specify a workflow_id with an optional form_field_key') if study_id is not None: file_models = FileService.get_files_for_study( study_id=study_id, irb_doc_code=form_field_key) else: file_models = FileService.get_files(workflow_id=workflow_id, irb_doc_code=form_field_key) files = (to_file_api(model) for model in file_models) return FileSchema(many=True).dump(files)
def do_task(self, task, study_id, workflow_id, *args, **kwargs): if 'file_ids' in kwargs.keys(): doc_info = StudyService().get_documents_status(study_id) if 'filename' in kwargs.keys(): zip_filename = kwargs['filename'] else: zip_filename = 'attachments.zip' file_ids = kwargs['file_ids'] files = session.query(FileModel).filter( FileModel.id.in_(file_ids)).all() if files: # Create a temporary zipfile with the requested files with tempfile.NamedTemporaryFile() as temp_file: with zipfile.ZipFile( temp_file, mode='w', compression=zipfile.ZIP_DEFLATED) as zfw: for file in files: zip_key_words = doc_info[ file.irb_doc_code]['zip_key_words'] file_name = f'{study_id} {zip_key_words} {file.name}' file_data = session.query(FileDataModel).filter( FileDataModel.file_model_id == file.id).first() zfw.writestr(file_name, file_data.data) with open(temp_file.name, mode='rb') as handle: file_model = FileService().add_workflow_file( workflow_id, None, task.get_name(), zip_filename, 'application/zip', handle.read()) # return file_model return FileSchema().dump(to_file_api(file_model)) else: raise ApiError(code='missing_file_ids', message='You must include a list of file_ids.')
def add_spec_file(workflow_spec_id): if workflow_spec_id: file = connexion.request.files['file'] # check if we have a primary already have_primary = FileModel.query.filter( FileModel.workflow_spec_id == workflow_spec_id, FileModel.type == FileType.bpmn, FileModel.primary == True).all() # set this to primary if we don't already have one if not have_primary: primary = True else: primary = False workflow_spec = session.query(WorkflowSpecModel).filter_by( id=workflow_spec_id).first() file_model = SpecFileService.add_workflow_spec_file(workflow_spec, file.filename, file.content_type, file.stream.read(), primary=primary) return FileSchema().dump(to_file_api(file_model)) else: raise ApiError(code='missing_workflow_spec_id', message="You must include a workflow_spec_id")
def update_reference_file_data(name): """Uses the file service to manage reference-files. They will be used in script tasks to compute values.""" if 'file' not in connexion.request.files: raise ApiError('invalid_file', 'Expected a file named "file" in the multipart form request', status_code=400) file = connexion.request.files['file'] name_extension = FileService.get_extension(name) file_extension = FileService.get_extension(file.filename) if name_extension != file_extension: raise ApiError('invalid_file_type', "The file you uploaded has an extension '%s', but it should have an extension of '%s' " % (file_extension, name_extension)) file_model = session.query(FileModel).filter(FileModel.name==name).first() if not file_model: raise ApiError(code='file_does_not_exist', message=f"The reference file {name} does not exist.") else: ReferenceFileService().update_reference_file(file_model, file.stream.read()) return FileSchema().dump(to_file_api(file_model))
def set_reference_file(name): """Uses the file service to manage reference-files. They will be used in script tasks to compute values.""" if 'file' not in connexion.request.files: raise ApiError('invalid_file', 'Expected a file named "file" in the multipart form request', status_code=400) file = connexion.request.files['file'] name_extension = FileService.get_extension(name) file_extension = FileService.get_extension(file.filename) if name_extension != file_extension: raise ApiError('invalid_file_type', "The file you uploaded has an extension '%s', but it should have an extension of '%s' " % (file_extension, name_extension)) file_models = FileService.get_files(name=name, is_reference=True) if len(file_models) == 0: file_model = FileService.add_reference_file(name, file.content_type, file.stream.read()) else: file_model = file_models[0] FileService.update_file(file_models[0], file.stream.read(), file.content_type) return FileSchema().dump(to_file_api(file_model))
def update_spec_file_data(file_id): file_model = session.query(FileModel).filter_by( id=file_id).with_for_update().first() if file_model is None: raise ApiError('no_such_file', f'The file id you provided ({file_id}) does not exist') if file_model.workflow_spec_id is None: raise ApiError( code='no_spec_id', message=f'There is no workflow_spec_id for file {file_id}.') workflow_spec_model = session.query(WorkflowSpecModel).filter( WorkflowSpecModel.id == file_model.workflow_spec_id).first() if workflow_spec_model is None: raise ApiError( code='missing_spec', message= f'The workflow spec for id {file_model.workflow_spec_id} does not exist.' ) file = connexion.request.files['file'] SpecFileService().update_spec_file_data(workflow_spec_model, file_model.name, file.stream.read()) return FileSchema().dump(to_file_api(file_model))
def get_documents_status(study_id): """Returns a list of documents related to the study, and any file information that is available..""" # Get PB required docs, if Protocol Builder Service is enabled. if ProtocolBuilderService.is_enabled() and study_id is not None: try: pb_docs = ProtocolBuilderService.get_required_docs( study_id=study_id) except requests.exceptions.ConnectionError as ce: app.logger.error( f'Failed to connect to the Protocol Builder - {str(ce)}', exc_info=True) pb_docs = [] else: pb_docs = [] # Loop through all known document types, get the counts for those files, # and use pb_docs to mark those as required. doc_dictionary = DocumentService.get_dictionary() documents = {} for code, doc in doc_dictionary.items(): doc['required'] = False if ProtocolBuilderService.is_enabled() and doc['id'] != '': pb_data = next( (item for item in pb_docs['AUXDOCS'] if int(item['SS_AUXILIARY_DOC_TYPE_ID']) == int(doc['id']) ), None) if pb_data: doc['required'] = True doc['study_id'] = study_id doc['code'] = code # Make a display name out of categories name_list = [] for cat_key in ['category1', 'category2', 'category3']: if doc[cat_key] not in ['', 'NULL', None]: name_list.append(doc[cat_key]) doc['display_name'] = ' / '.join(name_list) # For each file, get associated workflow status doc_files = FileService.get_files_for_study(study_id=study_id, irb_doc_code=code) doc['count'] = len(doc_files) doc['files'] = [] for file_model in doc_files: file = File.from_models( file_model, FileService.get_file_data(file_model.id), []) file_data = FileSchema().dump(file) del file_data['document'] doc['files'].append(Box(file_data)) # update the document status to match the status of the workflow it is in. if 'status' not in doc or doc['status'] is None: status = session.query(WorkflowModel.status).filter_by( id=file.workflow_id).scalar() doc['status'] = status.value documents[code] = doc return Box(documents)
def get_reference_files(): """Gets a list of all reference files""" results = ReferenceFileService.get_reference_files() files = (to_file_api(model) for model in results) return FileSchema(many=True).dump(files)
def add_reference_file(): file = connexion.request.files['file'] file_model = ReferenceFileService.add_reference_file(name=file.filename, content_type=file.content_type, binary_data=file.stream.read()) return FileSchema().dump(to_file_api(file_model))
def get_reference_files(): results = FileService.get_files(is_reference=True) files = (to_file_api(model) for model in results) return FileSchema(many=True).dump(files)