Пример #1
0
def add_sample_metadata(resp):  # pylint: disable=unused-argument
    """Update metadata for sample."""
    try:
        post_data = request.get_json()
        sample_name = post_data['sample_name']
        metadata = post_data['metadata']
    except TypeError:
        raise ParseError('Missing Sample metadata payload.')
    except KeyError:
        raise ParseError('Invalid Sample metadata payload.')

    try:
        sample = Sample.objects.get(name=sample_name)
    except DoesNotExist:
        raise NotFound('Sample does not exist.')

    try:
        sample.metadata = metadata
        sample.save()
        result = sample_schema.dump(sample).data
        return result, 200
    except ValidationError as validation_error:
        current_app.logger.exception('Sample metadata could not be updated.')
        raise ParseError(
            f'Invalid Sample metadata payload: {str(validation_error)}')
Пример #2
0
def add_sample_group(authn):  # pylint: disable=too-many-locals
    """Add sample group."""
    # Validate input
    try:
        data = request.get_json()
        name = data['name']
        organization = Organization.query.filter_by(
            name=data['organization_name']).first()
    except TypeError as exc:
        current_app.logger.exception(f'Sample Group creation error:\n{exc}')
        raise ParseError(f'Missing Sample Group creation payload.\n{exc}')
    except KeyError:
        raise ParseError('Invalid Sample Group creation payload.')
    authn_user = User.query.filter_by(uuid=authn.sub).first()
    if authn_user.uuid not in organization.writer_uuids():
        raise PermissionDenied(
            'You do not have permission to write to that organization.')

    # Create Sample Group
    try:
        sample_group = SampleGroup(
            name=name,
            organization_uuid=organization.uuid,
            description=data.get('description', False),
            is_library=data.get('is_library', False),
            is_public=data.get('is_public', False),
        ).save()
        return sample_group.serializable(), 201
    except IntegrityError as integrity_error:
        current_app.logger.exception('Sample Group could not be created.')
        raise ParseError('Duplicate group name.')
Пример #3
0
def add_organization_user(authn, organization_uuid):     # pylint: disable=too-many-return-statements
    """Add user to organization."""
    try:
        post_data = request.get_json()
        organization = Organization.from_uuid(UUID(organization_uuid))
        admin = User.from_uuid(authn.sub)
    except TypeError:
        raise ParseError('Missing membership payload.')
    except ValueError:
        raise ParseError('Invalid organization UUID.')
    except NoResultFound:
        raise NotFound('Organization does not exist')
    try:
        user = User.from_uuid(post_data['user_uuid'])
    except KeyError:
        raise ParseError('Invalid membership payload.')
    except NoResultFound:
        raise NotFound('User does not exist')

    if admin.uuid in organization.admin_uuids():
        if user.uuid in organization.reader_uuids():
            raise InvalidRequest('User is already part of organization.')
        role = post_data.get('role', 'read')
        try:
            organization.add_user(user, role_in_org=role)
            result = {'message': f'${user.username} added to ${organization.name}'}
            return result, 200
        except IntegrityError as integrity_error:
            current_app.logger.exception('IntegrityError encountered.')
            raise InternalError(str(integrity_error))
    raise PermissionDenied('You do not have permission to add a user to that organization.')
Пример #4
0
def add_sample_group(resp):  # pylint: disable=unused-argument
    """Add sample group."""
    try:
        post_data = request.get_json()
        name = post_data['name']
    except TypeError:
        raise ParseError('Missing Sample Group creation payload.')
    except KeyError:
        raise ParseError('Invalid Sample Group creation payload.')

    sample_group = SampleGroup.query.filter_by(name=name).first()
    if sample_group is not None:
        raise InvalidRequest('Sample Group with that name already exists.')

    try:
        analysis_result = AnalysisResultMeta().save()
        sample_group = SampleGroup(name=name, analysis_result=analysis_result)
        db.session.add(sample_group)
        db.session.commit()
        result = sample_group_schema.dump(sample_group).data
        return result, 201
    except IntegrityError as integrity_error:
        current_app.logger.exception('Sample Group could not be created.')
        db.session.rollback()
        raise InternalError(str(integrity_error))
Пример #5
0
 def view_function(resp, uuid):
     """Wrap receive_upload to provide class."""
     if issubclass(cls, SampleToolResultModule):
         return receive_sample_tool_upload(cls, resp, uuid)
     elif issubclass(cls, GroupToolResultModule):
         return receive_group_tool_upload(cls, resp, uuid)
     raise ParseError('Tool Result of unrecognized type.')
Пример #6
0
def add_samples_to_group(authn, group_uuid):
    """Add samples to a sample group."""
    try:
        post_data = request.get_json()
        sample_group = SampleGroup.query.filter_by(uuid=UUID(group_uuid)).one()
    except ValueError:
        raise ParseError('Invalid Sample Group UUID.')
    except NoResultFound:
        raise NotFound('Sample Group does not exist')
    authn_user = User.query.filter_by(uuid=authn.sub).first()
    organization = Organization.query.filter_by(
        uuid=sample_group.organization_uuid).first()
    if authn_user.uuid not in organization.writer_uuids():
        raise PermissionDenied(
            'You do not have permission to write to that organization.')
    for sample_uuid in [UUID(uuid) for uuid in post_data.get('sample_uuids')]:
        try:
            sample = Sample.query.filter_by(uuid=sample_uuid).first()
            sample_group.samples.append(sample)
        except NoResultFound:
            raise InvalidRequest(
                f'Sample UUID \'{sample_uuid}\' does not exist')
        except IntegrityError as integrity_error:
            current_app.logger.exception(
                f'Sample \'{sample_uuid}\' could not be added to Sample Group.'
            )
            raise InternalError(str(integrity_error))
    sample_group.save()
    result = sample_group.serializable()
    return result, 200
Пример #7
0
def add_samples_to_group(resp, group_uuid):  # pylint: disable=unused-argument
    """Add samples to a sample group."""
    try:
        post_data = request.get_json()
        sample_group_id = UUID(group_uuid)
        sample_group = SampleGroup.query.filter_by(id=sample_group_id).one()
    except ValueError:
        raise ParseError('Invalid Sample Group UUID.')
    except NoResultFound:
        raise NotFound('Sample Group does not exist')

    try:
        sample_uuids = [UUID(uuid) for uuid in post_data.get('sample_uuids')]
        for sample_uuid in sample_uuids:
            sample = Sample.objects.get(uuid=sample_uuid)
            sample_group.sample_ids.append(sample.uuid)
        db.session.commit()
        result = sample_group_schema.dump(sample_group).data
        return result, 200
    except NoResultFound:
        db.session.rollback()
        raise InvalidRequest(f'Sample UUID \'{sample_uuid}\' does not exist')
    except IntegrityError as integrity_error:
        current_app.logger.exception('Samples could not be added to Sample Group.')
        db.session.rollback()
        raise InternalError(str(integrity_error))
Пример #8
0
def get_single_sample_group(group_uuid):
    """Get single sample group model."""
    try:
        sample_group = SampleGroup.query.filter_by(uuid=UUID(group_uuid)).one()
        return sample_group.serializable(), 200
    except ValueError:
        raise ParseError('Invalid Sample Group UUID.')
    except NoResultFound:
        raise NotFound('Sample Group does not exist')
Пример #9
0
def get_single_organization(organization_uuid):
    """Get single organization details."""
    try:
        org = Organization.from_uuid(UUID(organization_uuid))
        return org.serializable(), 200
    except ValueError:
        raise ParseError('Invalid organization UUID.')
    except NoResultFound:
        raise NotFound('Organization does not exist')
Пример #10
0
def add_organization(authn):
    """Add organization."""
    try:
        post_data = request.get_json()
        org_name = post_data['name']
        primary_admin = User.from_uuid(authn.sub)
        is_public = post_data.get('is_public', True)
    except NoResultFound:
        raise NotFound('User does not exist')
    except TypeError:
        raise ParseError('Missing organization payload.')
    except KeyError:
        raise ParseError('Invalid organization payload.')
    try:
        org = Organization.from_user(primary_admin, org_name, is_public=is_public)
        return org.serializable(), 201
    except IntegrityError:
        current_app.logger.exception('There was a problem adding an organization.')
        raise InternalError(str(integrity_error))
Пример #11
0
def get_metadata_from_request(request):
    try:
        metadata_file = request.files['metadata']
    except KeyError:
        raise ParseError('Missing metadata file attachment.')
    if metadata_file.filename == '':
        raise ParseError('Missing metadata file attachment.')
    try:
        extension = metadata_file.filename.split('.')[1]
    except KeyError:
        raise ParseError('Metadata file missing extension.')
    stream = StringIO(metadata_file.stream.read().decode('UTF8'), newline=None)
    if extension == 'csv':
        metadata = DictReader(stream)
    elif 'xls' in extension:
        metadata = XLSDictReader(stream)
    else:
        raise ParseError('Missing valid metadata file attachment.')
    return metadata
Пример #12
0
def login_user():
    """Log user in."""
    try:
        post_data = request.get_json()
        email = post_data['email']
        password = post_data['password']
    except TypeError:
        raise ParseError('Missing login payload.')
    except KeyError:
        raise ParseError('Invalid login payload.')

    # Fetch the user data
    user = User.query.filter_by(email=email).first()
    if user and bcrypt.check_password_hash(user.password, password):
        auth_token = user.encode_auth_token(user.id)
        if auth_token:
            result = {'auth_token': auth_token.decode()}
            return result, 200
    raise NotFound('User does not exist.')
Пример #13
0
def get_all_analysis_results():
    """Get all analysis result models."""
    try:
        analysis_results = AnalysisResultMeta.objects.all()
        result = analysis_result_schema.dump(analysis_results, many=True).data
        return result, 200
    except ValueError:
        raise ParseError('Invalid UUID provided.')
    except DoesNotExist:
        raise NotFound('Analysis Result does not exist.')
Пример #14
0
def get_single_result(group_uuid):
    """Get single sample group model."""
    try:
        sample_group_id = UUID(group_uuid)
        sample_group = SampleGroup.query.filter_by(id=sample_group_id).one()
        result = sample_group_schema.dump(sample_group).data
        return result, 200
    except ValueError:
        raise ParseError('Invalid Sample Group UUID.')
    except NoResultFound:
        raise NotFound('Sample Group does not exist')
Пример #15
0
def get_single_result(result_uuid):
    """Get single analysis result."""
    try:
        uuid = UUID(result_uuid)
        analysis_result = AnalysisResultMeta.objects.get(uuid=uuid)
        result = analysis_result_schema.dump(analysis_result).data
        return result, 200
    except ValueError:
        raise ParseError('Invalid UUID provided.')
    except DoesNotExist:
        raise NotFound('Analysis Result does not exist.')
Пример #16
0
def get_single_sample(sample_uuid):
    """Get single sample details."""
    try:
        uuid = UUID(sample_uuid)
        sample = Sample.objects.get(uuid=uuid)
        fields = ('uuid', 'name', 'analysis_result_uuid', 'created_at')
        result = SampleSchema(only=fields).dump(sample).data
        return result, 200
    except ValueError:
        raise ParseError('Invalid UUID provided.')
    except DoesNotExist:
        raise NotFound('Sample does not exist.')
Пример #17
0
def get_samples_for_group_by_name(group_name):
    """Get single sample group's list of samples."""
    try:
        sample_group = SampleGroup.from_name(group_name)
        result = {
            'samples':
            [sample.serializable() for sample in sample_group.samples],
        }
        return result, 200
    except ValueError:
        raise ParseError('Invalid Sample Group UUID.')
    except NoResultFound:
        raise NotFound('Sample Group does not exist')
Пример #18
0
def get_samples_for_group(group_uuid):
    """Get single sample group's list of samples."""
    try:
        sample_group = SampleGroup.query.filter_by(uuid=UUID(group_uuid)).one()
        result = {
            'samples':
            [sample.serializable() for sample in sample_group.samples],
        }
        return result, 200
    except ValueError:
        raise ParseError('Invalid Sample Group UUID.')
    except NoResultFound:
        raise NotFound('Sample Group does not exist')
Пример #19
0
def get_samples_for_group(group_uuid):
    """Get single sample group's list of samples."""
    try:
        sample_group_id = UUID(group_uuid)
        sample_group = SampleGroup.query.filter_by(id=sample_group_id).one()
        samples = sample_group.samples
        current_app.logger.info(f'Found {len(samples)} samples for group {group_uuid}')
        result = SampleSchema(only=('uuid', 'name')).dump(samples, many=True).data
        return result, 200
    except ValueError:
        raise ParseError('Invalid Sample Group UUID.')
    except NoResultFound:
        raise NotFound('Sample Group does not exist')
Пример #20
0
def receive_sample_tool_upload(cls, resp, uuid):
    """Define handler for receiving uploads of analysis tool results."""
    try:
        safe_uuid = UUID(uuid)
        sample = Sample.objects.get(uuid=safe_uuid)
    except ValueError:
        raise ParseError('Invalid UUID provided.')
    except DoesNotExist:
        raise NotFound('Sample does not exist.')

    # gh-21: Write actual validation:
    try:
        auth_user = User.query.filter_by(id=resp).one()
        print(auth_user)
    except NoResultFound:
        raise PermissionDenied('Authorization failed.')

    try:
        payload = request.get_json()
        payload = cls.run_upload_hooks(payload)

        tool_result = cls.make_result_model(payload).save()
        setattr(sample, cls.name(), tool_result)
        sample.save()
    except ValidationError as validation_error:
        raise ParseError(str(validation_error))

    # Kick off middleware tasks
    dryrun = request.args.get('dryrun', False)
    if not dryrun:
        try:
            downstream_modules = SampleConductor.downstream_modules(cls)
            SampleConductor(safe_uuid, downstream_modules).shake_that_baton()
        except Exception:  # pylint: disable=broad-except
            current_app.logger.exception(
                'Exception while coordinating display modules.')

    # Return payload here to avoid per-class JSON serialization
    return payload, 201
Пример #21
0
def add_sample(resp):  # pylint: disable=unused-argument
    """Add sample."""
    try:
        post_data = request.get_json()
        sample_group_uuid = post_data['sample_group_uuid']
        sample_name = post_data['name']
    except TypeError:
        raise ParseError('Missing Sample creation payload.')
    except KeyError:
        raise ParseError('Invalid Sample creation payload.')

    try:
        sample_group = SampleGroup.query.filter_by(id=sample_group_uuid).one()
    except NoResultFound:
        raise InvalidRequest('Sample Group does not exist!')

    sample = Sample.objects(name=sample_name).first()
    if sample is not None:
        raise InvalidRequest('A Sample with that name already exists.')

    try:
        analysis_result = AnalysisResultMeta().save()
        sample = Sample(name=sample_name,
                        analysis_result=analysis_result,
                        metadata={
                            'name': sample_name
                        }).save()
        sample_group.sample_ids.append(sample.uuid)
        db.session.commit()
        result = sample_schema.dump(sample).data
        return result, 201
    except ValidationError as validation_error:
        current_app.logger.exception('Sample could not be created.')
        raise InternalError(str(validation_error))
    except IntegrityError as integrity_error:
        current_app.logger.exception(
            'Sample could not be added to Sample Group.')
        db.session.rollback()
        raise InternalError(str(integrity_error))
Пример #22
0
def run_sample_group_display_modules(uuid):  # pylint: disable=invalid-name
    """Run display modules for sample group."""
    try:
        safe_uuid = UUID(uuid)
        _ = SampleGroup.query.filter_by(uuid=safe_uuid).first()
    except ValueError:
        raise ParseError('Invalid UUID provided.')
    except NoResultFound:
        raise NotFound('Sample Group does not exist.')

    analysis_names = request.args.getlist('analysis_names')
    TaskConductor(uuid, analysis_names).shake_that_baton()
    result = {'middleware': analysis_names}
    return result, 202
Пример #23
0
def register_user():
    """Register user."""
    try:
        post_data = request.get_json()
        username = post_data['username']
        email = post_data['email']
        password = post_data['password']
    except TypeError:
        raise ParseError('Missing registration payload.')
    except KeyError:
        raise ParseError('Invalid registration payload.')

    # Check for existing user
    user = User.query.filter(
        or_(User.username == username, User.email == email)).first()
    if user is not None:
        raise InvalidRequest('Sorry. That user already exists.')

    try:
        # Add new user to db
        new_user = User(
            username=username,
            email=email,
            password=password,
        )
        db.session.add(new_user)
        db.session.commit()
    except IntegrityError as integrity_error:
        current_app.logger.exception('There was a problem with registration.')
        db.session.rollback()
        raise InternalError(str(integrity_error))

    # Generate auth token
    auth_token = new_user.encode_auth_token(new_user.id)
    result = {'auth_token': auth_token.decode()}
    return result, 201