def get(self): 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 return [{ 'id': attachment.id, 'name': attachment.name, } for attachment in run.attachments if check_access(path=f"/run/{str(run.id)}", method="GET") and attachment]
async def update_run( run_id: int, run: RunModel, 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_dict = run.dict() # This field shouldn't be updated by users. run_dict.pop('protocol', None) new_run = db.query(Run).get(run_id) if not new_run or new_run.is_deleted: raise HTTPException(status_code=404, detail='Run Not Found') if not change_allowed(run_to_dict(new_run, new_run.current), run_dict): raise HTTPException(status_code=403, detail='Insufficient Permissions') new_run_version = RunVersion(data=strip_metadata(run_dict), server_version=settings.server_version) new_run_version.run = new_run add_updator(new_run_version, current_user.username) new_run.current = new_run_version db.add(new_run_version) samples = get_samples(new_run_version, new_run.protocol_version) if samples: for sample in samples: db.merge(sample) db.commit() return run_to_dict(new_run, new_run.current)
def crud_get_run( item_to_dict, enforcer: casbin.Enforcer, db: Session, current_user: Auth0ClaimsPatched, run_id: int, version_id: Optional[int] = None, ) -> dict: 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') if version_id: run_version = db.query(RunVersion)\ .filter(RunVersion.id == version_id)\ .filter(Run.id == run_id)\ .first() if (not run_version) or run_version.run.is_deleted: raise HTTPException(status_code=404, detail='Run Not Found') return item_to_dict(run_version.run) run = db.query(Run).get(run_id) if (not run) or run.is_deleted: raise HTTPException(status_code=404, detail='Run Not Found') return item_to_dict(fix_plate_markers_run(db, run))
def crud_get_sample( item_to_dict, enforcer: casbin.Enforcer, db: Session, current_user: Auth0ClaimsPatched, sample_id: str, plate_id: str, run_version_id: int, protocol_version_id: int, version_id: Optional[int] = None, ) -> dict: sample = db.query(Sample).get(sample_id) if not check_access(enforcer, user=current_user.username, path=f"/run/{str(sample.run_version.run_id)}", method="GET"): raise HTTPException(status_code=403, detail='Insufficient Permissions') 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: raise HTTPException(status_code=404, detail='Sample Not Found') return item_to_dict(sample_version.sample) sample = db.query(Sample).get((sample_id, plate_id, run_version_id, protocol_version_id)) if (not sample) or sample.is_deleted: raise HTTPException(status_code=404, detail='Sample Not Found') return item_to_dict(sample)
def crud_get_user( item_to_dict, enforcer: casbin.Enforcer, db: Session, current_user: Auth0ClaimsPatched, user_id: int, version_id: Optional[int] = None, ) -> dict: user_id = urllib.parse.unquote(user_id) if user_id != current_user.username and not check_access( enforcer, user=current_user.username, path=f"/user/{str(user_id)}", method="GET"): raise HTTPException(status_code=403, detail='Insufficient Permissions') if version_id: user_version = db.query(UserVersion)\ .filter(UserVersion.id == version_id)\ .filter(User.id == user_id)\ .first() if (not user_version) or user_version.user.is_deleted: raise HTTPException(status_code=404, detail='User Not Found') return item_to_dict(user_version.user) user = db.query(User).get(user_id) if (not user) or user.is_deleted: raise HTTPException(status_code=404, detail='User Not Found') return item_to_dict(user)
async def patch_protocol( protocol_id: int, patch: list, 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"/protocol/{str(protocol_id)}", method="PUT"): raise HTTPException(status_code=403, detail='Insufficient Permissions') new_protocol = db.query(Protocol).get(protocol_id) if not new_protocol or new_protocol.is_deleted: raise HTTPException(status_code=404, detail='Protocol Not Found') protocol_dict = versioned_row_to_dict(new_protocol, new_protocol.current) json_patch = jsonpatch.JsonPatch(patch) protocol_dict = json_patch.apply(protocol_dict) if not change_allowed( versioned_row_to_dict(new_protocol, new_protocol.current), protocol_dict): raise HTTPException(status_code=403, detail='Insufficient Permissions') new_protocol_version = ProtocolVersion( data=strip_metadata(protocol_dict), server_version=settings.server_version) new_protocol_version.protocol = new_protocol add_updator(new_protocol_version, current_user.username) new_protocol.current = new_protocol_version db.add(new_protocol_version) db.commit() return versioned_row_to_dict(new_protocol, new_protocol.current)
async def delete_run_attachment( run_id: int, attachment_id: int, purge: bool = False, 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') attachment = db.query(Attachment).get(attachment_id) if not attachment or attachment.is_deleted: raise HTTPException(status_code=404, detail='Attachment Not Found') if purge: db.delete(attachment) else: attachment.is_deleted = True db.commit() return success
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)
def crud_get_protocol( item_to_dict, enforcer: casbin.Enforcer, db: Session, current_user: Auth0ClaimsPatched, protocol_id: int, version_id: Optional[int] = None, ) -> dict: if not check_access(enforcer, user=current_user.username, path=f"/protocol/{str(protocol_id)}", method="GET"): raise HTTPException(status_code=403, detail='Insufficient Permissions') if version_id: protocol_version = ProtocolVersion.query\ .filter(ProtocolVersion.id == version_id)\ .filter(Protocol.id == protocol_id)\ .first() if (not protocol_version) or protocol_version.protocol.is_deleted: raise HTTPException(status_code=404, detail='Protocol Not Found') return item_to_dict(protocol_version.protocol) protocol = db.query(Protocol).get(protocol_id) if (not protocol) or protocol.is_deleted: raise HTTPException(status_code=404, detail='Protocol Not Found') return item_to_dict(fix_plate_markers_protocol(db, protocol))
def decorated(*args, **kwargs): if check_access(path=f"/protocol/{kwargs.get('protocol_id')}", method=method): return f(*args, **kwargs) raise AuthError( { 'code': 'forbidden', 'description': 'User is not allowed to perform this action' }, 403)
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')
async def get_permissions( protocol_id: int, enforcer: casbin.Enforcer = Depends(get_enforcer), current_user: Auth0ClaimsPatched = Depends(get_current_user)): if not check_access(enforcer, user=current_user.username, path=f"/protocol/{str(protocol_id)}", method="GET"): raise HTTPException(status_code=403, detail='Insufficient Permissions') return get_policies(enforcer, path=f"/protocol/{protocol_id}")
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)
async def get_run_attachments( run_id: int, 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') return [ AttachmentModel(id=attachment.id, name=attachment.name) for attachment in run.attachments if check_access(enforcer, user=current_user.username, path=f"/run/{str(run.id)}", method="GET") and attachment ]
async def delete_permission( run_id: int, method: str, user_id: str, enforcer: casbin.Enforcer = Depends(get_enforcer), 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') delete_policy(enforcer, user=user_id, path=f"/run/{run_id}", method=method) return success
def get(self, run_id, attachment_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 attachment = Attachment.query.get(attachment_id) if not attachment or attachment.is_deleted: abort(404) return return app.response_class( attachment.data, mimetype=attachment.mimetype if attachment.mimetype else 'application/octet-stream')
def get(self): 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 = User.query.filter(User.is_deleted != True).paginate( page=page, per_page=per_page) results['page'] = page_query.page results['pageCount'] = page_query.pages query = page_query.items else: query = User.query.filter(User.is_deleted != True).all() results['users'] = [ add_role(versioned_row_to_dict(api, user, user.current)) for user in query if check_access(path=f"/user/{user.id}", method="GET") ] return results
async def delete_protocol( protocol_id: int, purge: bool = False, 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"/protocol/{str(protocol_id)}", method="DELETE"): raise HTTPException(status_code=403, detail='Insufficient Permissions') protocol = db.query(Protocol).get(protocol_id) if not protocol or protocol.is_deleted: raise HTTPException(status_code=404, detail='Protocol Not Found') if purge: db.delete(protocol) else: protocol.is_deleted = True db.commit() delete_policy(enforcer, path=f"/protocol/{str(protocol.id)}") return success
def crud_get_run_sample( item_to_dict, enforcer: casbin.Enforcer, db: Session, current_user: Auth0ClaimsPatched, run_id: int, sample_id: str, version_id: Optional[int] = None, ) -> dict: 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') sample = db.query(Sample)\ .filter(Sample.run_version_id == run.version_id)\ .filter(Sample.sample_id == sample_id)\ .first() return item_to_dict(sample)
async def get_run_attachment( run_id: int, attachment_id: int, 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') attachment = db.query(Attachment).get(attachment_id) if not attachment or attachment.is_deleted: raise HTTPException(status_code=404, detail='Attachment Not Found') return StreamingResponse( io.BytesIO(attachment.data), media_type=attachment.mimetype if attachment.mimetype else 'application/octet-stream')
def crud_get_users( item_to_dict, enforcer: casbin.Enforcer, db: Session, current_user: Auth0ClaimsPatched, archived: Optional[bool] = None, page: Optional[int] = None, per_page: Optional[int] = None, ) -> List[dict]: return paginatify( items_label='users', items=[ user for user in all_users(db, archived).order_by( User.created_on.desc()) if check_access(enforcer, user=current_user.username, path=f"/user/{str(user.id)}", method="GET") and user and user.current ], item_to_dict=item_to_dict, page=page, per_page=per_page, )
async def delete_run( run_id: int, purge: bool = False, 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="DELETE"): 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') if purge: db.delete(run) else: run.is_deleted = True # TODO: Mark all samples as deleted/archived? db.commit() delete_policy(enforcer, path=f"/run/{str(run.id)}") return success
async def create_run_attachment( run_id: int, file: UploadFile = File(...), 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') attachment = Attachment( name=file.filename, mimetype=file.content_type, data=await file.read(), ) db.add(attachment) db.commit() return AttachmentModel(id=attachment.id, name=attachment.name)
def delete(self, run_id, attachment_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 purge = request.args.get('purge') == 'true' if request.args.get( 'purge') else False attachment = Attachment.query.get(attachment_id) if not attachment or attachment.is_deleted: abort(404) return if purge: db.session.delete(attachment) else: attachment.is_deleted = True db.session.commit() return { 'success': True, }
def post(self, run_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 args = upload_parser.parse_args() uploaded_file = args['file'] attachment = Attachment( name=secure_filename(uploaded_file.filename), mimetype=uploaded_file.content_type, data=uploaded_file.read(), ) db.session.add(attachment) db.session.commit() return { 'id': attachment.id, 'name': attachment.name, }
def crud_get_runs( item_to_dict, enforcer: casbin.Enforcer, db: Session, current_user: Auth0ClaimsPatched, 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, ) -> List[dict]: runs_queries = [] # Add filter specific queries. These will be intersected later on. if protocol: runs_queries.append( all_runs(db, archived)\ .join(ProtocolVersion, ProtocolVersion.id == Run.protocol_version_id)\ .filter(ProtocolVersion.protocol_id == protocol) ) if run: runs_queries.append( all_runs(db, archived)\ .filter(Run.id == run) ) if plate: run_version_query = all_runs(db, archived)\ .join(RunVersion, RunVersion.id == Run.version_id) runs_subquery = filter_by_plate_label(run_version_query, plate) runs_queries.append(runs_subquery) if reagent: run_version_query = all_runs(db, archived)\ .join(RunVersion, RunVersion.id == Run.version_id) runs_subquery = filter_by_reagent_label(run_version_query, reagent) runs_queries.append(runs_subquery) if sample: run_version_query = all_runs(db, archived)\ .join(RunVersion, RunVersion.id == Run.version_id) runs_subquery = filter_by_sample_label(run_version_query, sample) runs_queries.append(runs_subquery) if creator: runs_queries.append( all_runs(db, archived)\ # .filter(Run.id == run) .filter(Run.created_by == creator) ) # Add a basic non-deleted items query if no filters were specified. if len(runs_queries) == 0: runs_queries.append(all_runs(db, archived)) # Only return the intersection of all queries. runs_query = reduce(lambda a, b: a.intersect(b), runs_queries) return paginatify( items_label='runs', items=[ run for run in runs_query.distinct().order_by(Run.created_on.desc()) if check_access(enforcer, user=current_user.username, path=f"/run/{str(run.id)}", method="GET") and run and run.current ], item_to_dict=lambda run: item_to_dict(fix_plate_markers_run(db, run)), page=page, per_page=per_page, )
def graphql_crud_get_samples( enforcer: casbin.Enforcer, current_user: Auth0CurrentUserPatched, info: ResolveInfo, # Search parameters 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, # Paging parameters page: Optional[int] = None, per_page: Optional[int] = None, ): # Calculate which top level fields to remove. top_level_ignore = { 'sample_id', 'plate_id', 'run_version_id', 'protocol_version_id', 'created_by', 'created_on', 'updated_by', 'updated_on', 'run_id', 'protocol_id' } # Flatten `info` parameter into jsonb_query_path statements. select_args = [] top_level = set() for result in graphql_ast_flatten_field(info.field_asts[0], info.fragments, info.return_type, info.schema): result_parts = result.split('.') if len(result_parts) > 3 and result_parts[3] not in top_level_ignore: top_level.add(result_parts[3]) jsonb_fields = [ 'sample_id', 'sampleID', 'plate_id', 'plateID', 'run_version_id', 'protocol_version_id', 'created_by', 'created_on', 'updated_by', 'updated_on', 'run_id', 'runID', 'protocol_id', 'protocolID', ] select_args = [ Sample.sample_id.label('sample_id'), Sample.sample_id.label('sampleID'), Sample.plate_id.label('plate_id'), Sample.plate_id.label('plateID'), Sample.run_version_id.label('run_version_id'), Sample.protocol_version_id.label('protocol_version_id'), Sample.created_by.label('created_by'), Sample.created_on.label('created_on'), SampleVersion.updated_by.label('updated_by'), SampleVersion.updated_on.label('updated_on'), RunVersion.run_id.label('run_id'), RunVersion.run_id.label('runID'), ProtocolVersion.protocol_id.label('protocol_id'), ProtocolVersion.protocol_id.label('protocolID'), ] for field in top_level: jsonb_fields.append(field) select_args.append(SampleVersion.data[field].label(field)) db = get_session(info) # Join with additional tables as necessary for search params. from_tables = OrderedDict() filters = [] if protocol: filters.append(ProtocolVersion.protocol_id == protocol) if run: filters.append(RunVersion.run_id == run) if plate: filters.append(Sample.plate_id.like(f"%{plate}%")) if reagent: filters.append(filter_by_reagent_label_filter(reagent)) if sample: filters.append(Sample.sample_id.like(f"%{sample}%")) if creator: filters.append(Sample.created_by == creator) if archived is None or archived == False: filters.append(Sample.is_deleted == False) query = db.query(*select_args)\ .select_from(Sample)\ .join(SampleVersion, SampleVersion.id == Sample.version_id)\ .join(RunVersion, RunVersion.id == Sample.run_version_id)\ .join(ProtocolVersion, ProtocolVersion.id == Sample.protocol_version_id) for join_cls, join_filter in from_tables.items(): query = query.join(join_cls, join_filter) # Apply search filters. for search_filter in filters: query = query.filter(search_filter) # Get results query = query.distinct().order_by(Sample.created_on.desc()) rows = [ sample for sample in query if check_access(enforcer, user=current_user.username, path=f"/run/{str(sample.run_id)}", method="GET") ] return paginatify( items_label='samples', items=rows, item_to_dict=lambda sample: SampleResult.parse_obj( add_sample_id(sample._asdict())), page=page, per_page=per_page, )
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
def crud_get_run_samples( item_to_dict, enforcer: casbin.Enforcer, db: Session, current_user: Auth0ClaimsPatched, 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, page: Optional[int] = None, per_page: Optional[int] = None, ) -> List[dict]: 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_queries = [] # Add filter specific queries. These will be intersected later on. if protocol: samples_queries.append( all_samples(db, run, archived)\ .join(ProtocolVersion, ProtocolVersion.id == Sample.protocol_version_id)\ .filter(ProtocolVersion.protocol_id == protocol) ) if plate: samples_queries.append( all_samples(db, run, archived)\ .filter(Sample.plate_id == plate) ) if reagent: run_version_query = all_samples(db, run, 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 creator: samples_queries.append( all_samples(db, run, 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(db, run, archived)) # Only return the intersection of all queries. samples_query = reduce(lambda a, b: a.intersect(b), samples_queries) return paginatify( items_label='samples', items=[ sample for sample in samples_query.distinct().order_by( Sample.sample_id.asc()) ], item_to_dict=item_to_dict, page=page, per_page=per_page, )
def get(self): 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 protocols_queries = [] if run: protocols_queries.append( all_protocols(archived)\ .join(ProtocolVersion, ProtocolVersion.protocol_id == Protocol.id)\ .join(Run, Run.protocol_version_id == ProtocolVersion.id)\ .filter(Run.id == run) ) if plate: run_version_query = all_protocols(archived)\ .join(ProtocolVersion, ProtocolVersion.protocol_id == Protocol.id)\ .join(Run, Run.protocol_version_id == ProtocolVersion.id)\ .join(RunVersion, RunVersion.id == Run.version_id) protocols_subquery = filter_by_plate_label(run_version_query, plate) protocols_queries.append(protocols_subquery) if reagent: run_version_query = all_protocols(archived)\ .join(ProtocolVersion, ProtocolVersion.protocol_id == Protocol.id)\ .join(Run, Run.protocol_version_id == ProtocolVersion.id)\ .join(RunVersion, RunVersion.id == Run.version_id) protocols_subquery = filter_by_reagent_label( run_version_query, reagent) protocols_queries.append(protocols_subquery) if sample: run_version_query = all_protocols(archived)\ .join(ProtocolVersion, ProtocolVersion.protocol_id == Protocol.id)\ .join(Run, Run.protocol_version_id == ProtocolVersion.id)\ .join(RunVersion, RunVersion.id == Run.version_id) protocols_subquery = filter_by_sample_label( run_version_query, sample) protocols_queries.append(protocols_subquery) if creator: protocols_queries.append( all_protocols(archived)\ # .filter(Protocol.id == protocol)\ .filter(Protocol.created_by == creator) ) # Add a basic non-deleted items query if no filters were specified. if len(protocols_queries) == 0: protocols_queries.append(all_protocols(archived)) # Only return the intersection of all queries. protocols_query = reduce(lambda a, b: a.intersect(b), protocols_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 = protocols_query.distinct().order_by( Protocol.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 = protocols_query.distinct().order_by( Protocol.created_on.desc()) results['protocols'] = [ versioned_row_to_dict(api, protocol, protocol.current) for protocol in query if check_access(path=f"/protocol/{str(protocol.id)}", method="GET") and protocol and protocol.current ] return results