def put_call(call_id, call): """ Update a single individual by call id (in URL) and new Call api dict (passed in body) """ db_session = orm.get_session() try: q = db_session.query(Call).get(call_id) except orm.ORMException as e: err = _report_search_failed('call', e, call_id=str(call_id)) return err, 500 if not q: err = Error(message="No call found: "+str(call_id), code=404) return err, 404 if 'id' in call: del call['id'] if 'created' in call: del call['created'] call['updated'] = datetime.datetime.utcnow() try: row = db_session.query(Individual).filter(Call.id == call_id).first() for key in call: setattr(row, key, call[key]) db_session.commit() except orm.ORMException as e: err = _report_update_failed('call', e, call_id=str(call_id)) return err, 500 return None, 204, {'Location': '/calls/'+str(call_id)}
def put_individual(individual_id, individual): """ Update a single individual by individual id (in URL) and new api.models.Invididual object (passed in body) """ db_session = orm.get_session() try: q = db_session.query(Individual).get(individual_id) except orm.ORMException as e: err = _report_search_failed('individual', e, ind_id=str(individual_id)) return err, 500 if not q: err = Error(message="No individual found: "+str(individual_id), code=404) return err, 404 if 'id' in individual: del individual['id'] if 'created' in individual: del individual['created'] individual['updated'] = datetime.datetime.utcnow() try: row = db_session.query(Individual).filter(Individual.id == individual_id).first() for key in individual: setattr(row, key, individual[key]) db_session.commit() except orm.ORMException as e: err = _report_update_failed('individual', e, ind_id=str(individual_id)) return err, 500 return None, 204, {'Location': BASEPATH+'/individuals/'+str(individual_id)}
def get_variants_by_individual(individual_id): """ Return variants that have been called in an individual """ db_session = orm.get_session() ind_id = individual_id try: ind = db_session.query(orm.models.Individual)\ .filter(orm.models.Individual.id == ind_id)\ .one_or_none() except orm.ORMException as e: err = _report_search_failed('individual', e, individual_id=individual_id) return err, 500 if not ind: err = Error(message="No individual found: "+str(ind_id), code=404) return err, 404 try: variants = [call.variant for call in ind.calls if call.variant] except orm.ORMException as e: err = _report_search_failed('variants', e, by_individual_id=individual_id) return err, 500 return [orm.dump(v) for v in variants], 200
def get_individuals_by_variant(variant_id): """ Return variants that have been called in an individual """ db_session = orm.get_session() try: var = db_session.query(orm.models.Variant)\ .filter(orm.models.Variant.id == variant_id)\ .one_or_none() except orm.ORMException as e: err = _report_search_failed('variant', e, variant_id=variant_id) return err, 500 if not var: err = Error(message="No variant found: "+str(variant_id), code=404) return err, 404 try: individuals = [call.individual for call in var.calls if call.individual is not None] except orm.ORMException as e: err = _report_search_failed('individuals', e, by_variant_id=variant_id) return err, 500 return [orm.dump(i) for i in individuals], 200
def put_variant(variant_id, variant): """ Update a single variant by variant id (in URL) and new Variant dict object (passed in body) """ db_session = orm.get_session() try: q = db_session.query(Variant).get(variant_id) except orm.ORMException as e: err = _report_search_failed('variant', e, var_id=str(variant_id)) return err, 500 if not q: err = Error(message="No variant found: "+str(variant_id), code=404) return err, 404 if 'id' in variant: del variant['id'] if 'created' in variant: del variant['created'] variant['updated'] = datetime.datetime.utcnow() try: row = db_session.query(Variant).filter(Variant.id == variant_id).first() for key in variant: setattr(row, key, variant[key]) db_session.commit() except orm.ORMException as e: err = _report_update_failed('variant', e, var_id=str(variant_id)) return err, 500 return None, 204, {'Location': BASEPATH+'/individuals/'+str(variant_id)}
def simple_db(db_filename="ormtest.db"): # pylint: disable=too-many-locals """ Create a DB with a small number of objects for testing """ # delete db if already exists try: os.remove(db_filename) except OSError: pass init_db('sqlite:///'+db_filename) session = get_session(expire_on_commit=False) ind_ids = [uuid.uuid1() for _ in range(2)] var_ids = [uuid.uuid1() for _ in range(3)] call_ids = [uuid.uuid1() for _ in range(4)] ind1 = Individual(id=ind_ids[0], description='Subject X') ind2 = Individual(id=ind_ids[1], description='Subject Y') individuals = [ind1, ind2] session.add_all(individuals) session.commit() variant1 = Variant(id=var_ids[0], name='rs699', chromosome='chr1', start=230710048, ref='C', alt='T') variant2 = Variant(id=var_ids[1], name='rs900', chromosome='chr1', start=218441563, ref='A', alt='T') variant3 = Variant(id=var_ids[2], name='rs5714', chromosome='chr1', start=53247055, ref='A', alt='G') variants = [variant1, variant2, variant3] session.add_all(variants) session.commit() call1 = Call(id=call_ids[0], individual_id=ind_ids[0], variant_id=var_ids[0], genotype='0/1') call2 = Call(id=call_ids[1], individual_id=ind_ids[0], variant_id=var_ids[1], genotype='0/0') call3 = Call(id=call_ids[2], individual_id=ind_ids[1], variant_id=var_ids[1], genotype='1/1') call4 = Call(id=call_ids[3], individual_id=ind_ids[1], variant_id=var_ids[2], genotype='0/1') calls = [call1, call2, call3, call4] session.add_all(calls) session.commit() session.expunge_all() session.close() return individuals, variants, calls, db_filename
def get_variants(chromosome, start, end): """ Return all variants between [chrom, start) and (chrom, end] """ db_session = orm.get_session() try: q = db_session.query(orm.models.Variant)\ .filter(models.Variant.chromosome == chromosome)\ .filter(and_(models.Variant.start >= start, models.Variant.start <= end)) except orm.ORMException as e: err = _report_search_failed('variant', e, chromosome=chromosome, start=start, end=end) return err, 500 return [orm.dump(p) for p in q], 200
def test_search_individuals(simple_db): """ Perform simple individual searches on the DB fixture """ inds, _, _, _ = simple_db db_session = get_session() # Test simple individual queries # By ID: for ind in inds: indquery = db_session.query(Individual).filter(Individual.id == ind.id).all() assert len(indquery) == 1 assert are_equivalent(indquery[0], ind) db_session.close()
def get_one_variant(variant_id): """ Return single variant object """ db_session = orm.get_session() try: q = db_session.query(models.Variant).get(variant_id) except orm.ORMException as e: err = _report_search_failed('variant', e, var_id=str(variant_id)) return err, 500 if not q: err = Error(message="No variant found: "+str(variant_id), code=404) return err, 404 return orm.dump(q), 200
def test_search_calls(simple_db): """ Perform simple call searches on the DB fixture """ _, _, calls, _ = simple_db db_session = get_session() # Test simple call queries # By ID: for call in calls: callquery = db_session.query(Call).filter(Call.id == call.id).all() assert len(callquery) == 1 assert are_equivalent(callquery[0], call) # By individual + variant IDs for call in calls: callquery = db_session.query(Call).\ filter_by(individual_id=call.individual_id, variant_id=call.variant_id).all() assert len(callquery) == 1 assert are_equivalent(callquery[0], call) db_session.close()
def post_variant(variant): """ Add a new variant """ db_session = orm.get_session() # Does this variant already exist, by ID or by content? try: found_variant = variant_exists(**variant) except orm.ORMException as e: err = _report_search_failed('variant', e, **variant) return err if found_variant: err = _report_object_exists('variant', **variant) return err, 405 vid = uuid.uuid1() variant['id'] = vid variant['created'] = datetime.datetime.utcnow() variant['updated'] = variant['created'] # convert to ORM representation try: orm_variant = models.Variant(**variant) except orm.ORMException as e: err = _report_conversion_error('variant', e, **variant) return err, 400 try: db_session.add(orm_variant) db_session.commit() except orm.ORMException as e: err = _report_write_error('variant', e, **variant) return err, 400 logger().info(struct_log(action='variant_created', **variant)) return variant, 201, {'Location': BASEPATH+'/variants/'+str(vid)}
def test_search_variants(simple_db): """ Perform simple variant searches on the DB fixture """ _, variants, _, _ = simple_db db_session = get_session() # Test simple variant queries # By ID: for var in variants: varquery = db_session.query(Variant).filter(Variant.id == var.id).all() assert len(varquery) == 1 assert are_equivalent(varquery[0], var) # By chrom/start/ref/alt for var in variants: varquery = db_session.query(Variant).\ filter_by(chromosome=var.chromosome, start=var.start, ref=var.ref, alt=var.alt).all() assert len(varquery) == 1 assert are_equivalent(varquery[0], var) db_session.close()
def test_relationships(simple_db): """ Test the individual <-> call <-> variant relationship """ inds, variants, calls, _ = simple_db db_session = get_session() # note: currenly only testing relationship outwards from call # TODO: add testing starting from individual and variant for call in calls: ormcalls = db_session.query(Call).filter_by(id=call.id).all() assert len(ormcalls) == 1 ormcall = ormcalls[0] assert ormcall.variant.id == call.variant_id calledvar = [var for var in variants if var.id == call.variant_id][0] assert are_equivalent(ormcall.variant, calledvar) assert ormcall.individual.id == call.individual_id calledind = [ind for ind in inds if ind.id == call.individual_id][0] assert are_equivalent(ormcall.individual, calledind) db_session.close()
def post_individual(individual): """ Add a new individual """ db_session = orm.get_session() try: found_individual = individual_exists(db_session, **individual) except orm.ORMException as e: err = _report_search_failed('variant', e, **individual) return err if found_individual: err = _report_object_exists('individual', **individual) return err, 405 iid = uuid.uuid1() individual['id'] = iid individual['created'] = datetime.datetime.utcnow() individual['updated'] = individual['created'] try: orm_ind = orm.models.Individual(**individual) except orm.ORMException as e: err = _report_conversion_error('individual', e, **individual) return err, 400 try: db_session.add(orm_ind) db_session.commit() except orm.ORMException as e: err = _report_write_error('individual', e, **individual) return err, 500 logger().info(struct_log(action='individual_created', ind_id=str(iid), **individual)) return individual, 201, {'Location': BASEPATH+'/individuals/'+str(iid)}
def delete_call(call_id): """ Delete a single call by call id (in URL) """ db_session = orm.get_session() try: q = db_session.query(Call).get(call_id) except orm.ORMException as e: err = _report_search_failed('call', e, call_id=str(call_id)) return err, 500 if not q: err = Error(message="No call found: "+str(call_id), code=404) return err, 404 try: row = db_session.query(Call).filter(Call.id == call_id).first() db_session.delete(row) db_session.commit() except orm.ORMException as e: err = _report_update_failed('call', e, call_id=str(call_id)) return err, 500 return None, 204, {'Location': BASEPATH+'/calls/'+str(call_id)}
def post_call(call): """ Add a new call """ db_session = orm.get_session() try: found_call = call_exists(**call) except orm.ORMException as e: err = _report_search_failed('call', e, **call) return err if found_call: err = _report_object_exists('call', **call) return err, 405 cid = uuid.uuid1() call['id'] = cid call['created'] = datetime.datetime.utcnow() call['updated'] = call['created'] try: orm_call = orm.models.Call(**call) except orm.ORMException as e: err = _report_conversion_error('call', e, **call) return err try: db_session.add(orm_call) db_session.commit() except orm.ORMException as e: err = _report_write_error('call', e, **call) return err logger().info(struct_log(action='call_post', status='created', call_id=str(cid), **call)) # noqa501 return call, 201, {'Location': BASEPATH+'/calls/'+str(cid)}
def delete_individual(individual_id): """ Delete a single individual by individual id (in URL) """ db_session = orm.get_session() try: q = db_session.query(Individual).get(individual_id) except orm.ORMException as e: err = _report_search_failed('individual', e, ind_id=str(individual_id)) return err, 500 if not q: err = Error(message="No individual found: "+str(individual_id), code=404) return err, 404 try: row = db_session.query(Individual).filter(Individual.id == individual_id).first() db_session.delete(row) db_session.commit() except orm.ORMException as e: err = _report_update_failed('individual', e, ind_id=str(individual_id)) return err, 500 return None, 204, {'Location': BASEPATH+'/individuals/'+str(individual_id)}