Пример #1
0
async def update_sample(sample_id: str, sample: SampleResult, db: Session = Depends(get_db), current_user: Auth0ClaimsPatched = Depends(get_current_user)):
    sample_dict = sample.dict()
    new_sample = db.query(Sample).get(sample_id)
    if not new_sample or new_sample.is_deleted:
        raise HTTPException(status_code=404, detail='Sample not found')
    if not change_allowed(run_to_sample(new_sample), sample_dict):
        raise HTTPException(status_code=403, detail='Insufficient Permissions')
    new_sample_version = SampleVersion(data=strip_metadata(sample_dict), server_version=settings.server_version)
    new_sample_version.sample = new_sample
    add_updator(new_sample_version, current_user.username)
    new_sample.current = new_sample_version
    db.session.add(new_sample_version)
    db.session.commit()
    return run_to_sample(new_sample)
Пример #2
0
async def update_run_sample(
    run_id: int,
    sample_id: str,
    sample: SampleResult,
    enforcer: casbin.Enforcer = Depends(get_enforcer),
    db: Session = Depends(get_db),
    current_user: Auth0ClaimsPatched = Depends(get_current_user)):
    if not check_access(enforcer,
                        user=current_user.username,
                        path=f"/run/{str(run_id)}",
                        method="PUT"):
        raise HTTPException(status_code=403, detail='Insufficient Permissions')

    run = db.query(Run).get(run_id)
    if not run or run.is_deleted:
        raise HTTPException(status_code=404, detail='Run Not Found')

    sample_dict = sample.dict()
    new_sample = db.query(Sample).filter(
        Sample.sample_version_id == new_sample.version_id).filter(
            Sample.sample_id == sample_id).first()
    if not new_sample or new_sample.is_deleted:
        raise HTTPException(status_code=404, detail='Sample Not Found')
    if not change_allowed(run_to_dict(run, run.current), {}):
        raise HTTPException(status_code=403, detail='Insufficient Permissions')
    new_sample_version = SampleVersion(data=strip_metadata(sample_dict),
                                       server_version=settings.server_version)
    new_sample_version.sample = new_sample
    add_updator(new_sample_version, current_user.username)
    new_sample.current = new_sample_version
    db.add(new_sample_version)
    db.commit()
    return run_to_sample(new_sample)
Пример #3
0
async def get_samples(
    protocol: Optional[int] = None,
    run: Optional[int] = None,
    plate: Optional[str] = None,
    reagent: Optional[str] = None,
    sample: Optional[str] = None,
    creator: Optional[str] = None,
    archived: Optional[bool] = None,
    page: Optional[int] = None,
    per_page: Optional[int] = None,
    enforcer: casbin.Enforcer = Depends(get_enforcer),
    db: Session = Depends(get_db),
    current_user: Auth0ClaimsPatched = Depends(get_current_user)
):
    return crud_get_samples(
        item_to_dict=lambda sample: run_to_sample(sample),

        enforcer=enforcer,
        db=db,
        current_user=current_user,
        
        protocol=protocol,
        run=run,
        plate=plate,
        reagent=reagent,
        sample=sample,
        creator=creator,
        archived=archived,
        page=page,
        per_page=per_page,
    )
Пример #4
0
 def put(self, sample_id):
     sample_dict = request.json
     sample = Sample.query.get(sample_id)
     if not sample or sample.is_deleted:
         abort(404)
         return
     if not change_allowed(run_to_sample(sample), sample_dict):
         abort(403)
         return
     sample_version = SampleVersion(
         data=strip_metadata(sample_dict),
         server_version=app.config['SERVER_VERSION'])
     sample_version.sample = sample
     add_updator(sample_version)
     sample.current = sample_version
     db.session.add(sample_version)
     db.session.commit()
     return run_to_sample(sample)
Пример #5
0
    def get(self, sample_id):
        version_id = int(request.args.get('version_id')) if request.args.get(
            'version_id') else None

        if version_id:
            sample_version = SampleVersion.query\
                .filter(SampleVersion.id == version_id)\
                .filter(Sample.id == sample_id)\
                .first()
            if (not sample_version) or sample_version.sample.is_deleted:
                abort(404)
                return
            return run_to_sample(sample_version.sample)

        sample = Sample.query.get(sample_id)
        if (not sample) or sample.is_deleted:
            abort(404)
            return
        return run_to_sample(sample)
Пример #6
0
async def export_run_samples_csv(
    run_id: Optional[int] = None,
    protocol: Optional[int] = None,
    plate: Optional[str] = None,
    reagent: Optional[str] = None,
    creator: Optional[str] = None,
    archived: Optional[bool] = None,
    enforcer: casbin.Enforcer = Depends(get_enforcer),
    db: Session = Depends(get_db),
    current_user: Auth0ClaimsPatched = Depends(get_current_user)):
    if not check_access(enforcer,
                        user=current_user.username,
                        path=f"/run/{str(run_id)}",
                        method="GET"):
        raise HTTPException(status_code=403, detail='Insufficient Permissions')
    run = db.query(Run).get(run_id)
    if not run or run.is_deleted:
        raise HTTPException(status_code=404, detail='Run Not Found')

    samples = crud_get_run_samples(
        item_to_dict=lambda sample: run_to_sample(sample),
        enforcer=enforcer,
        db=db,
        current_user=current_user,
        run_id=run_id,
        protocol=protocol,
        plate=plate,
        reagent=reagent,
        creator=creator,
        archived=archived,
    )

    # Process each sample and add in flattened run data (with a filter).
    flattened_run = flatten_list_or_dict(
        run_to_dict(run, run.current, False),
        '(attachments|type|definition|protocol|plates|plateSequencingResults|plateMarkers)'
    )
    flattened_samples = []
    sample_headers = set()
    for sample in samples['samples']:
        flattened_sample = {**flattened_run, **flatten_list_or_dict(sample)}
        flattened_samples.append(flattened_sample)
        sample_headers.update(flattened_sample.keys())

    sample_headers = list(sample_headers)
    sample_headers.sort()
    csvfile = io.StringIO()
    writer = csv.writer(csvfile, quoting=csv.QUOTE_NONNUMERIC)
    writer.writerow(sample_headers)
    for flattened_sample in flattened_samples:
        writer.writerow(
            [flattened_sample.get(header, '') for header in sample_headers])

    return Response(csvfile.getvalue(), media_type='text/csv')
Пример #7
0
 def get(self, run_id, sample_id):
     if not check_access(path=f"/run/{str(run_id)}", method="GET"):
         abort(403)
         return
     run = Run.query.get(run_id)
     if not run or run.is_deleted:
         abort(404)
         return
     sample = Sample.query.filter(
         Sample.run_version_id == run.version_id).filter(
             Sample.sample_id == sample_id).first()
     # sample = get_samples(run=run, run_version=run.current, sample_id=sample_id).first()
     return run_to_sample(sample)
Пример #8
0
async def get_run_sample(
    run_id: int,
    sample_id: str,
    version_id: Optional[int] = None,
    enforcer: casbin.Enforcer = Depends(get_enforcer),
    db: Session = Depends(get_db),
    current_user: Auth0ClaimsPatched = Depends(get_current_user)):
    return crud_get_run_sample(
        item_to_dict=lambda sample: run_to_sample(sample),
        enforcer=enforcer,
        db=db,
        current_user=current_user,
        run_id=run_id,
        sample_id=sample_id,
        version_id=version_id,
    )
Пример #9
0
 def put(self, run_id, sample_id):
     sample_dict = request.json
     # This field shouldn't be updated by users.
     # sample_dict.pop('protocol', None)
     sample = Sample.query.filter(
         Sample.sample_version_id == sample.version_id).filter(
             Sample.sample_id == sample_id).first()
     if not sample or sample.is_deleted:
         abort(404)
         return
     if not change_allowed(run_to_dict(run, run.current), {}):
         abort(403)
         return
     sample_version = SampleVersion(
         data=strip_metadata(sample_dict),
         server_version=app.config['SERVER_VERSION'])
     sample_version.sample = sample
     add_updator(sample_version)
     sample.current = sample_version
     db.session.add(sample_version)
     db.session.commit()
     return run_to_sample(sample)
Пример #10
0
    def get(self):
        protocol = int(request.args.get('protocol')) if request.args.get(
            'protocol') else None
        run = int(request.args.get('run')) if request.args.get('run') else None
        plate = request.args.get('plate')
        reagent = request.args.get('reagent')
        sample = request.args.get('sample')
        creator = request.args.get('creator')
        archived = request.args.get('archived') == 'true' if request.args.get(
            'archived') else False

        samples_queries = []

        # Add filter specific queries. These will be intersected later on.
        if protocol:
            samples_queries.append(
                all_samples(archived)\
                    .join(ProtocolVersion, ProtocolVersion.id == Sample.protocol_version_id)\
                    .filter(ProtocolVersion.protocol_id == protocol)
            )
        if run:
            samples_queries.append(
                all_samples(archived)\
                    .join(RunVersion, RunVersion.id == Sample.run_version_id)\
                    .filter(RunVersion.run_id == run)
            )
        if plate:
            samples_queries.append(
                all_samples(archived)\
                    .filter(Sample.plate_id == plate)
            )
        if reagent:
            run_version_query = all_samples(archived)\
                .join(RunVersion, RunVersion.id == Sample.run_version_id)
            samples_subquery = filter_by_reagent_label(run_version_query,
                                                       reagent)
            samples_queries.append(samples_subquery)
        if sample:
            samples_queries.append(
                all_samples(archived)\
                    .filter(Sample.sample_id == sample)
            )
        if creator:
            samples_queries.append(
                all_samples(archived)\
                    .filter(Sample.created_by == creator)
            )

        # Add a basic non-deleted items query if no filters were specified.
        if len(samples_queries) == 0:
            samples_queries.append(all_samples(archived))

        # Only return the intersection of all queries.
        samples_query = reduce(lambda a, b: a.intersect(b), samples_queries)

        results = {}
        if request.args.get('page') is not None or request.args.get(
                'per_page') is not None:
            page = int(
                request.args.get('page')) if request.args.get('page') else 1
            per_page = int(request.args.get('per_page')) if request.args.get(
                'per_page') else 20
            page_query = samples_query.distinct().order_by(
                Sample.created_on.desc()).paginate(page=page,
                                                   per_page=per_page)
            results['page'] = page_query.page
            results['pageCount'] = page_query.pages
            query = page_query.items
        else:
            query = samples_query.distinct().order_by(Sample.created_on.desc())

        results['samples'] = [
            run_to_sample(sample) for sample in query
            if check_access(path=f"/run/{str(sample.run_version.run_id)}",
                            method="GET") and sample and sample.current
        ]
        return results