def search_studies(tags=None, version=None, projectID=None): """ :param tags: optional list of tags :param version: :param projectID: :return: studies that match the filters """ db_session = orm.get_session() study = orm.models.Study try: studies = db_session.query(study) if version: studies = studies.filter(study.version.like('%' + version + '%')) if tags: # return any study that matches at least one tag studies = studies.filter( or_(*[study.tags.contains(tag) for tag in tags])) if projectID: validate_uuid_string('projectID', projectID) studies = studies.filter(study.parentProjectID == projectID) except IdentifierFormatError as e: _report_search_failed('project', e) return [], 200 except orm.ORMException as e: err = _report_search_failed('project', e) return err, 500 return [orm.dump(x) for x in studies], 200
def post_change_log(change_log_record): db_session = orm.get_session() change_version = change_log_record.get('version') change_log_record['created'] = datetime.datetime.utcnow() try: orm_changelog = orm.models.ChangeLog(**change_log_record) except TypeError as e: err = _report_conversion_error('changelog', e, **change_log_record) return err, 400 try: db_session.add(orm_changelog) db_session.commit() except exc.IntegrityError: db_session.rollback() err = _report_object_exists( 'changelog: ' + change_log_record['version'], **change_log_record) return err, 405 except orm.ORMException as e: err = _report_write_error('changelog', e, **change_log_record) return err, 500 logger().info( struct_log(action='post_change_log', status='created', change_version=change_version, **change_log_record)) return change_log_record, 201, { 'Location': BasePath + '/changelog/' + change_version }
def filter_expression_data(version, tags, study_id, project_id): """ Performs the database queries to filter expression files """ db_session = orm.get_session() expression = orm.models.File # TODO: find better way to filter for expression data? expressions = db_session.query(expression).filter( expression.fileType == "h5") # db queries if version: expressions = expressions.filter( expression.version.like('%' + version + '%')) if tags: # return any project that matches at least one tag expressions = expressions.filter( or_(*[expression.tags.contains(tag) for tag in tags])) if study_id: validate_uuid_string('studyID', study_id) expressions = expressions.filter(expression.studyID == study_id) if project_id: validate_uuid_string('projectID', project_id) study_list = get_study_by_project(project_id) expressions = expressions.filter(expression.studyID.in_(study_list)) return expressions
def search_files(tags=None, projectID=None, studyID=None, fileType=None): """ :param tags: optional comma separated tag list :param projectID: optional project identifier :param studyID: optional study identifier :param fileType: optional file type :return: manifest of download URL(s) for matching files """ db_session = orm.get_session() file = orm.models.File try: files = db_session.query(file) if tags: files = files.filter( or_(*[file.tags.contains(tag) for tag in tags])) if projectID: validate_uuid_string('projectID', projectID) study_list = get_study_by_project(projectID) files = files.filter(file.studyID.in_(study_list)) if studyID: validate_uuid_string('studyID', studyID) files = files.filter(file.studyID == studyID) if fileType: files = files.filter(file.fileType == fileType) except IdentifierFormatError as e: _report_search_failed('file', e) return [], 200 except orm.ORMException as e: err = _report_search_failed('file', e) return err, 500 return [orm.dump(x) for x in files], 200
def post_expression(expression_record): db_session = orm.get_session() if expression_record.get('__filepath__'): file_path = expression_record['__filepath__'] if not os.path.isfile(file_path): err = Error(message="Invalid file path: " + file_path, code=400) return err, 400 else: err = Error(message="An absolute __filepath__ is required", code=400) return err, 400 if not expression_record.get('id'): iid = uuid.uuid1() expression_record['id'] = iid else: iid = expression_record['id'] if not expression_record.get('version'): expression_record['version'] = Version if not expression_record.get('URL'): base_url = app.config.get('BASE_DL_URL') + BasePath expression_record[ 'URL'] = base_url + '/expressions/download/' + os.path.basename( file_path) expression_record['created'] = datetime.datetime.utcnow() try: orm_expression = orm.models.File(**expression_record) except TypeError as e: err = _report_conversion_error('file', e, **expression_record) return err, 400 try: db_session.add(orm_expression) db_session.commit() except exc.IntegrityError: db_session.rollback() err = _report_object_exists('expression: ' + expression_record['URL'], **expression_record) return err, 405 except orm.ORMException as e: db_session.rollback() err = _report_write_error('expression', e, **expression_record) return err, 500 logger().info( struct_log(action='post_expression', status='created', expression_id=str(iid), **expression_record)) return expression_record, 201, { 'Location': BasePath + '/expressions/' + str(iid) }
def download_file(token, temp_file=False): """ :param token: file identifier :param temp_file: boolean specifier for temporary files :return: Content-Type string """ try: if not temp_file: access_file = get_expression_file_path(token) if isinstance(access_file, tuple): return download_error("File not found", 404) mimetype = get_mimetype(token.split(".")[-1]) response = flask.send_file(access_file, as_attachment=True, mimetype=mimetype) # use tmp directory file ID's else: db_session = orm.get_session() temp_file = orm.models.TempFile try: access_file = db_session.query(temp_file).get(token) except exc.StatementError: return download_error("Invalid file token: " + str(token), 400) if not access_file: return download_error("File not found (link may have expired)", 404) file_path = access_file.__filepath__ if os.path.isfile(file_path): mimetype = get_mimetype(access_file.fileType) if access_file.fileType == "json": with open(file_path, 'r') as json_file: data = json.load(json_file) response = flask.make_response(json.dumps(data)) else: response = flask.send_file(file_path, as_attachment=True, mimetype=mimetype) else: return download_error("File not found (link may have expired)", 404) response.direct_passthrough = False return response except (orm.ORMException, FileNotFoundError): message = "Something went wrong while generating your file. Please try again or contact [email protected]" return download_error(message, 500)
def get_study_by_project(projectID): """ :param projectID: :return: list of study id's associated with a given project """ db_session = orm.get_session() study = orm.models.Study study_id_list = [] studies = db_session.query(study.id)\ .filter(study.parentProjectID == projectID) if studies: study_id_list = [x.id for x in studies] return study_id_list
def get_versions(): """ :return: release versions of the database """ db_session = orm.get_session() change_log = orm.models.ChangeLog try: versions = db_session.query(change_log.version) except orm.ORMException as e: err = _report_search_failed('versions', e) return err, 500 return [entry.version for entry in versions], 200
def post_project(project_record): db_session = orm.get_session() if not project_record.get('id'): iid = uuid.uuid1() project_record['id'] = iid else: iid = project_record['id'] if not project_record.get('version'): project_record['version'] = Version project_record['created'] = datetime.datetime.utcnow() try: orm_project = orm.models.Project(**project_record) except TypeError as e: err = _report_conversion_error('project', e, **project_record) return err, 400 try: db_session.add(orm_project) db_session.commit() except exc.IntegrityError: db_session.rollback() err = _report_object_exists('project: ' + project_record['id'], **project_record) return err, 405 except orm.ORMException as e: db_session.rollback() err = _report_write_error('project', e, **project_record) return err, 500 logger().info( struct_log(action='post_project', status='created', project_id=str(iid), **project_record)) return project_record, 201, { 'Location': BasePath + '/projects/' + str(iid) }
def get_expression_file_path(file): """ :param expressionId: required identifier :return: internal expression matrix filepath """ db_session = orm.get_session() expression = orm.models.File base_url = app.config.get('BASE_DL_URL') + BasePath file_url = base_url + '/expressions/download/' + file try: expr_matrix = db_session.query(expression).filter( expression.URL == file_url).one() except orm.ORMException as e: err = _report_search_failed('file', e, URL=file_url) return err, 404 return expr_matrix.__filepath__
def get_change_log(version): """ :param version: required release version :return: changes associated with specified release version """ db_session = orm.get_session() change_log = orm.models.ChangeLog try: log = db_session.query(change_log)\ .get(version) except orm.ORMException as e: err = _report_search_failed('change log', e) return err, 500 if not log: err = Error(message="Change log not found", code=404) return err, 404 return orm.dump(log), 200
def get_expression_by_id(expressionId): """ :param expressionId: required identifier :return: a single specified expression matrix """ db_session = orm.get_session() expression = orm.models.File try: validate_uuid_string('id', expressionId) expr_matrix = db_session.query(expression).get(expressionId) except IdentifierFormatError as e: err = Error(message=str(e), code=404) return err, 404 if not expr_matrix: err = Error(message="Expression matrix not found: " + expressionId, code=404) return err, 404 return orm.dump(expr_matrix), 200
def post_study(body): db_session = orm.get_session() if not body.get('id'): iid = uuid.uuid1() body['id'] = iid else: iid = body['id'] if not body.get('version'): body['version'] = Version body['created'] = datetime.datetime.utcnow() try: orm_study = orm.models.Study(**body) except TypeError as e: err = _report_conversion_error('study', e, **body) return err, 400 try: db_session.add(orm_study) db_session.commit() except exc.IntegrityError: db_session.rollback() err = _report_object_exists('study: ' + body['id'], **body) return err, 405 except orm.ORMException as e: db_session.rollback() err = _report_write_error('study', e, **body) return err, 500 logger().info( struct_log(action='post_study', status='created', project_id=str(iid), **body)) return body, 201, {'Location': BasePath + '/studies/' + str(iid)}
def get_project_by_id(projectId): """ :param projectId: :return: all projects or if projectId specified, corresponding project """ db_session = orm.get_session() project = orm.models.Project try: validate_uuid_string('id', projectId) specified_project = db_session.query(project)\ .get(projectId) except IdentifierFormatError as e: err = Error(message=str(e), code=404) return err, 404 if not specified_project: err = Error(message="Project not found: " + str(projectId), code=404) return err, 404 return orm.dump(specified_project), 200
def create_tmp_file_record(file_record): db_session = orm.get_session() try: orm_expression = orm.models.TempFile(**file_record) except TypeError as e: err = _report_conversion_error('file', e, **file_record) return err, 400 del file_record['__filepath__'] try: db_session.add(orm_expression) db_session.commit() except exc.IntegrityError: err = _report_object_exists('file: ' + file_record['id'], **file_record) return err, 405 except orm.ORMException as e: err = _report_write_error('file', e, **file_record) return err, 500 return file_record
def get_study_by_id(studyId): """ :param studyId: required identifier :return: a single specified study """ db_session = orm.get_session() study = orm.models.Study try: validate_uuid_string('studyID', studyId) specified_study = db_session.query(study)\ .get(studyId) except IdentifierFormatError as e: err = Error(message=str(e), code=404) return err, 404 if not specified_study: err = Error(message="Study not found: " + studyId, code=404) return err, 404 return orm.dump(specified_study), 200
def search_projects(tags=None, version=None): """ :param tags: :param version: :return: """ db_session = orm.get_session() project = orm.models.Project try: projects = db_session.query(project) if version: projects = projects.filter( project.version.like('%' + version + '%')) if tags: # return any project that matches at least one tag projects = projects.filter( or_(*[project.tags.contains(tag) for tag in tags])) except orm.ORMException as e: err = _report_search_failed('project', e) return err, 500 return [orm.dump(x) for x in projects], 200
def get_file(fileID): """ :param fileID: required identifier :return: a single specified file download URL """ db_session = orm.get_session() file = orm.models.File try: validate_uuid_string('fileID', fileID) file_q = db_session.query(file).get(fileID) except IdentifierFormatError as e: err = Error(message=str(e), code=404) return err, 404 except orm.ORMException as e: err = _report_search_failed('file', e, file_id=fileID) return err, 500 if not file_q: err = Error(message="File not found: " + fileID, code=404) return err, 404 return orm.dump(file_q), 200