def mendelian_variant_search(request): # TODO: how about we move project getter into the form, and just test for authX here? # esp because error should be described in json, not just 404 project, family = get_project_and_family_for_user(request.user, request.GET) form = api_forms.MendelianVariantSearchForm(request.GET) if form.is_valid(): search_spec = form.cleaned_data['search_spec'] search_spec.family_id = family.family_id variants = api_utils.calculate_mendelian_variant_search(search_spec, family.xfamily()) search_hash = cache_utils.save_results_for_spec(project.project_id, search_spec.toJSON(), [v.toJSON() for v in variants]) add_extra_info_to_variants_family(get_reference(), family, variants) return_type = request.GET.get('return_type', 'json') if return_type == 'json': return JSONResponse({ 'is_error': False, 'variants': [v.toJSON() for v in variants], 'search_hash': search_hash, }) elif return_type == 'csv': return '' else: return HttpResponse("Return type not implemented") else: return JSONResponse({ 'is_error': True, 'error': server_utils.form_error_string(form) })
def mendelian_variant_search_spec(request): project, family = get_project_and_family_for_user(request.user, request.GET) # TODO: use form search_hash = request.GET.get('search_hash') search_spec_dict, variants = cache_utils.get_cached_results(project.project_id, search_hash) search_spec = MendelianVariantSearchSpec.fromJSON(search_spec_dict) if variants is None: variants = api_utils.calculate_mendelian_variant_search(search_spec, family.xfamily()) else: variants = [Variant.fromJSON(v) for v in variants] add_extra_info_to_variants_family(get_reference(), family, variants) return_type = request.GET.get('return_type') if return_type == 'json' or not return_type: return JSONResponse({ 'is_error': False, 'variants': [v.toJSON() for v in variants], 'search_spec': search_spec_dict, }) elif request.GET.get('return_type') == 'csv': response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename="results_{}.csv"'.format(search_hash) writer = csv.writer(response) indiv_ids = family.indiv_ids_with_variant_data() headers = xbrowse_displays.get_variant_display_headers(get_mall(project.project_id), project, indiv_ids) writer.writerow(headers) for variant in variants: fields = xbrowse_displays.get_display_fields_for_variant(get_mall(project.project_id), project, variant, indiv_ids) writer.writerow(fields) return response
def mendelian_variant_search_spec(request): project, family = get_project_and_family_for_user(request.user, request.GET) search_hash = request.GET.get('search_hash') search_spec_dict, variants = cache_utils.get_cached_results(project.project_id, search_hash) search_spec = MendelianVariantSearchSpec.fromJSON(search_spec_dict) if variants is None: variants = api_utils.calculate_mendelian_variant_search(search_spec, family.xfamily()) else: variants = [Variant.fromJSON(v) for v in variants] add_extra_info_to_variants_family(get_reference(), family, variants) return_type = request.GET.get('return_type') if return_type == 'json' or not return_type: return JSONResponse({ 'is_error': False, 'variants': [v.toJSON() for v in variants], 'search_spec': search_spec_dict, }) elif request.GET.get('return_type') == 'csv': response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename="results_{}.csv"'.format(search_hash) writer = csv.writer(response) indiv_ids = family.indiv_ids_with_variant_data() headers = xbrowse_displays.get_variant_display_headers(get_mall(project.project_id), project, indiv_ids) writer.writerow(headers) for variant in variants: fields = xbrowse_displays.get_display_fields_for_variant(get_mall(project.project_id), project, variant, indiv_ids) writer.writerow(fields) return response
def mendelian_variant_search(request): # TODO: how about we move project getter into the form, and just test for authX here? # esp because error should be described in json, not just 404 request_dict = request.GET or request.POST project, family = get_project_and_family_for_user(request.user, request_dict) form = api_forms.MendelianVariantSearchForm(request_dict) if form.is_valid(): search_spec = form.cleaned_data['search_spec'] search_spec.family_id = family.family_id try: variants = api_utils.calculate_mendelian_variant_search( search_spec, family.xfamily()) except Exception as e: return JSONResponse({ 'is_error': True, 'error': str(e.args[0]) if e.args else str(e) }) sys.stderr.write("done fetching %s variants. Adding extra info..\n" % len(variants)) hashable_search_params = search_spec.toJSON() hashable_search_params['family_id'] = family.family_id search_hash = cache_utils.save_results_for_spec( project.project_id, hashable_search_params, [v.toJSON() for v in variants]) add_extra_info_to_variants_family(get_reference(), family, variants) sys.stderr.write( "done adding extra info to %s variants. Sending response..\n" % len(variants)) return_type = request_dict.get('return_type', 'json') if return_type == 'json': return JSONResponse({ 'is_error': False, 'variants': [v.toJSON() for v in variants], 'search_hash': search_hash, }) elif return_type == 'csv': return '' else: return HttpResponse("Return type not implemented") else: return JSONResponse({ 'is_error': True, 'error': server_utils.form_error_string(form) })
def add_variant_note(request): """ """ family = None if 'family_id' in request.GET: project, family = get_project_and_family_for_user(request.user, request.GET) else: project = utils.get_project_for_user(request.user, request.GET) form = api_forms.VariantNoteForm(project, request.GET) if form.is_valid(): note = VariantNote.objects.create( user=request.user, date_saved=datetime.datetime.now(), project=project, note=form.cleaned_data['note_text'], xpos=form.cleaned_data['xpos'], ref=form.cleaned_data['ref'], alt=form.cleaned_data['alt'], ) if family: note.family = family note.save() variant = get_datastore(project.project_id).get_single_variant( project.project_id, family.family_id, form.cleaned_data['xpos'], form.cleaned_data['ref'], form.cleaned_data['alt'], ) add_extra_info_to_variants_family(get_reference(), family, [variant,]) ret = { 'is_error': False, 'variant': variant.toJSON(), } else: ret = { 'is_error': True, 'error': server_utils.form_error_string(form) } return JSONResponse(ret)
def add_variant_note(request): """ """ family = None if 'family_id' in request.GET: project, family = get_project_and_family_for_user( request.user, request.GET) else: project = utils.get_project_for_user(request.user, request.GET) form = api_forms.VariantNoteForm(project, request.GET) if form.is_valid(): note = VariantNote.objects.create( user=request.user, date_saved=datetime.datetime.now(), project=project, note=form.cleaned_data['note_text'], xpos=form.cleaned_data['xpos'], ref=form.cleaned_data['ref'], alt=form.cleaned_data['alt'], ) if family: note.family = family note.save() variant = get_datastore(project.project_id).get_single_variant( project.project_id, family.family_id, form.cleaned_data['xpos'], form.cleaned_data['ref'], form.cleaned_data['alt'], ) add_extra_info_to_variants_family(get_reference(), family, [ variant, ]) ret = { 'is_error': False, 'variant': variant.toJSON(), } else: ret = {'is_error': True, 'error': server_utils.form_error_string(form)} return JSONResponse(ret)
def edit_variant_tags(request): family = None if 'family_id' in request.GET: project, family = get_project_and_family_for_user( request.user, request.GET) else: project = utils.get_project_for_user(request.user, request.GET) form = api_forms.VariantTagsForm(project, request.GET) if form.is_valid(): VariantTag.objects.filter(family=family, xpos=form.cleaned_data['xpos'], ref=form.cleaned_data['ref'], alt=form.cleaned_data['alt']).delete() for project_tag in form.cleaned_data['project_tags']: VariantTag.objects.create( project_tag=project_tag, family=family, xpos=form.cleaned_data['xpos'], ref=form.cleaned_data['ref'], alt=form.cleaned_data['alt'], ) variant = get_datastore(project.project_id).get_single_variant( project.project_id, family.family_id, form.cleaned_data['xpos'], form.cleaned_data['ref'], form.cleaned_data['alt'], ) add_extra_info_to_variants_family(get_reference(), family, [ variant, ]) ret = { 'is_error': False, 'variant': variant.toJSON(), } else: ret = {'is_error': True, 'error': server_utils.form_error_string(form)} return JSONResponse(ret)
def edit_variant_tags(request): family = None if 'family_id' in request.GET: project, family = get_project_and_family_for_user(request.user, request.GET) else: project = utils.get_project_for_user(request.user, request.GET) form = api_forms.VariantTagsForm(project, request.GET) if form.is_valid(): VariantTag.objects.filter(family=family, xpos=form.cleaned_data['xpos'], ref=form.cleaned_data['ref'], alt=form.cleaned_data['alt']).delete() for project_tag in form.cleaned_data['project_tags']: VariantTag.objects.create( user=request.user, date_saved=datetime.datetime.now(), project_tag=project_tag, family=family, xpos=form.cleaned_data['xpos'], ref=form.cleaned_data['ref'], alt=form.cleaned_data['alt'], ) variant = get_datastore(project.project_id).get_single_variant( project.project_id, family.family_id, form.cleaned_data['xpos'], form.cleaned_data['ref'], form.cleaned_data['alt'], ) add_extra_info_to_variants_family(get_reference(), family, [variant,]) ret = { 'is_error': False, 'variant': variant.toJSON(), } else: ret = { 'is_error': True, 'error': server_utils.form_error_string(form) } return JSONResponse(ret)
def mendelian_variant_search(request): # TODO: how about we move project getter into the form, and just test for authX here? # esp because error should be described in json, not just 404 project, family = get_project_and_family_for_user(request.user, request.GET) form = api_forms.MendelianVariantSearchForm(request.GET) if form.is_valid(): search_spec = form.cleaned_data['search_spec'] search_spec.family_id = family.family_id variants = api_utils.calculate_mendelian_variant_search( search_spec, family.xfamily()) search_hash = cache_utils.save_results_for_spec( project.project_id, search_spec.toJSON(), [v.toJSON() for v in variants]) add_extra_info_to_variants_family(get_reference(), family, variants) return_type = request.GET.get('return_type', 'json') if return_type == 'json': return JSONResponse({ 'is_error': False, 'variants': [v.toJSON() for v in variants], 'search_hash': search_hash, }) elif return_type == 'csv': return '' else: return HttpResponse("Return type not implemented") else: return JSONResponse({ 'is_error': True, 'error': server_utils.form_error_string(form) })
def add_or_edit_variant_tags(request): family = None if 'family_id' in request.GET: project, family = get_project_and_family_for_user(request.user, request.GET) else: project = utils.get_project_for_user(request.user, request.GET) form = api_forms.VariantTagsForm(project, request.GET) if not form.is_valid(): ret = { 'is_error': True, 'error': server_utils.form_error_string(form) } return JSONResponse(ret) variant = get_datastore(project.project_id).get_single_variant( project.project_id, family.family_id, form.cleaned_data['xpos'], form.cleaned_data['ref'], form.cleaned_data['alt'], ) if not variant: variant = Variant(form.cleaned_data['xpos'], form.cleaned_data['ref'], form.cleaned_data['alt']) variant_tags_to_delete = { variant_tag.id: variant_tag for variant_tag in VariantTag.objects.filter( family=family, xpos=form.cleaned_data['xpos'], ref=form.cleaned_data['ref'], alt=form.cleaned_data['alt']) } project_tag_events = {} for project_tag in form.cleaned_data['project_tags']: # retrieve tags tag, created = VariantTag.objects.get_or_create( project_tag=project_tag, family=family, xpos=form.cleaned_data['xpos'], ref=form.cleaned_data['ref'], alt=form.cleaned_data['alt'], ) if not created: # this tag already exists so just keep it (eg. remove it from the set of tags that will be deleted) del variant_tags_to_delete[tag.id] continue # this a new tag, so update who saved it and when project_tag_events[project_tag] = "add_variant_tag" tag.user = request.user tag.date_saved = timezone.now() tag.search_url = form.cleaned_data['search_url'] tag.save() # delete the tags that are no longer checked. for variant_tag in variant_tags_to_delete.values(): project_tag_events[variant_tag.project_tag] = "delete_variant_tag" variant_tag.delete() # add the extra info after updating the tag info in the database, so that the new tag info is added to the variant JSON add_extra_info_to_variants_family(get_reference(), family, [variant,]) # log tag creation for project_tag, event_type in project_tag_events.items(): try: settings.EVENTS_COLLECTION.insert({ 'event_type': event_type, 'date': timezone.now(), 'project_id': ''.join(project.project_id), 'family_id': family.family_id, 'tag': project_tag.tag, 'title': project_tag.title, 'xpos':form.cleaned_data['xpos'], 'pos':variant.pos, 'chrom': variant.chr, 'ref':form.cleaned_data['ref'], 'alt':form.cleaned_data['alt'], 'gene_names': ", ".join(variant.extras['gene_names'].values()), 'username': request.user.username, 'email': request.user.email, 'search_url': form.cleaned_data.get('search_url'), }) except Exception as e: logging.error("Error while logging add_variant_tag event: %s" % e) return JSONResponse({ 'is_error': False, 'variant': variant.toJSON(), })
def add_or_edit_variant_note(request): """Add a variant note""" family = None if 'family_id' in request.GET: project, family = get_project_and_family_for_user(request.user, request.GET) else: project = utils.get_project_for_user(request.user, request.GET) form = api_forms.VariantNoteForm(project, request.GET) if not form.is_valid(): return JSONResponse({ 'is_error': True, 'error': server_utils.form_error_string(form) }) variant = get_datastore(project.project_id).get_single_variant( project.project_id, family.family_id, form.cleaned_data['xpos'], form.cleaned_data['ref'], form.cleaned_data['alt'], ) if not variant: variant = Variant.fromJSON({ 'xpos' : form.cleaned_data['xpos'], 'ref': form.cleaned_data['ref'], 'alt': form.cleaned_data['alt'], 'genotypes': {}, 'extras': {}, }) if 'note_id' in form.cleaned_data and form.cleaned_data['note_id']: event_type = "edit_variant_note" notes = VariantNote.objects.filter( id=form.cleaned_data['note_id'], project=project, xpos=form.cleaned_data['xpos'], ref=form.cleaned_data['ref'], alt=form.cleaned_data['alt'], ) if not notes: return JSONResponse({ 'is_error': True, 'error': 'note id %s not found' % form.cleaned_data['note_id'] }) note = notes[0] note.user = request.user note.note = form.cleaned_data['note_text'] note.date_saved = timezone.now() if family: note.family = family note.save() else: event_type = "add_variant_note" VariantNote.objects.create( user=request.user, project=project, xpos=form.cleaned_data['xpos'], ref=form.cleaned_data['ref'], alt=form.cleaned_data['alt'], note=form.cleaned_data['note_text'], date_saved=timezone.now(), family=family, ) add_extra_info_to_variants_family(get_reference(), family, [variant,]) try: settings.EVENTS_COLLECTION.insert({ 'event_type': event_type, 'date': timezone.now(), 'project_id': ''.join(project.project_id), 'family_id': family.family_id, 'note': form.cleaned_data['note_text'], 'xpos':form.cleaned_data['xpos'], 'pos':variant.pos, 'chrom': variant.chr, 'ref':form.cleaned_data['ref'], 'alt':form.cleaned_data['alt'], 'gene_names': ", ".join(variant.extras['gene_names'].values()), 'username': request.user.username, 'email': request.user.email, }) except Exception as e: logging.error("Error while logging %s event: %s" % (event_type, e)) return JSONResponse({ 'is_error': False, 'variant': variant.toJSON(), })