def create_saved_variant_handler(request): variant_json = json.loads(request.body) family_guid = variant_json['familyGuid'] family = Family.objects.get(guid=family_guid) check_project_permissions(family.project, request.user) variants_json = variant_json['variant'] if not isinstance(variant_json['variant'], list): variants_json = [variants_json] saved_variants = [] for single_variant_json in variants_json: try: parsed_variant_json = _get_parsed_variant_args(single_variant_json, family) except ValueError as e: return create_json_response({'error': str(e)}, status=400) saved_variant, _ = get_or_create_model_from_json( SavedVariant, create_json=parsed_variant_json, update_json={'saved_variant_json': single_variant_json}, user=request.user) saved_variants.append(saved_variant) if variant_json.get('note'): _create_variant_note(saved_variants, variant_json, request.user) elif variant_json.get('tags'): _create_new_tags(saved_variants, variant_json, request.user) return create_json_response(get_json_for_saved_variants_with_tags(saved_variants, add_details=True))
def update_policies(request): request_json = json.loads(request.body) if not request_json.get('acceptedPolicies'): message = 'User must accept current policies' return create_json_response({'error': message}, status=400, reason=message) get_or_create_model_from_json(UserPolicy, {'user': request.user}, update_json={ 'privacy_version': SEQR_PRIVACY_VERSION, 'tos_version': SEQR_TOS_VERSION, }, user=request.user) return create_json_response({'currentPolicies': True})
def _get_or_create_results_model(search_hash, search_context, user): results_model = VariantSearchResults.objects.filter(search_hash=search_hash).first() if not results_model: if not search_context: raise Exception('Invalid search hash: {}'.format(search_hash)) project_families = search_context.get('projectFamilies') if project_families: all_families = set() for project_family in project_families: all_families.update(project_family['familyGuids']) families = Family.objects.filter(guid__in=all_families) elif _is_all_project_family_search(search_context): omit_projects = [p.guid for p in ProjectCategory.objects.get(name='Demo').projects.only('guid').all()] project_guids = [project_guid for project_guid in get_project_guids_user_can_view(user) if project_guid not in omit_projects] families = Family.objects.filter(project__guid__in=project_guids) elif search_context.get('projectGuids'): families = Family.objects.filter(project__guid__in=search_context['projectGuids']) else: raise Exception('Invalid search: no projects/ families specified') search_dict = search_context.get('search', {}) search_model = VariantSearch.objects.filter(search=search_dict).filter( Q(created_by=user) | Q(name__isnull=False)).first() if not search_model: search_model = create_model_from_json(VariantSearch, {'search': search_dict}, user) # If a search_context request and results request are dispatched at the same time, its possible the other # request already created the model results_model, _ = get_or_create_model_from_json( VariantSearchResults, {'search_hash': search_hash, 'variant_search': search_model}, update_json=None, user=user) results_model.families.set(families) return results_model
def create_saved_search_handler(request): request_json = json.loads(request.body) name = request_json.pop('name', None) if not name: error = '"Name" is required' return create_json_response({'error': error}, status=400, reason=error) if (request_json.get('inheritance') or {}).get('filter', {}).get('genotype'): error = 'Saved searches cannot include custom genotype filters' return create_json_response({'error': error}, status=400, reason=error) try: saved_search, _ = get_or_create_model_from_json( VariantSearch, {'search': request_json, 'created_by': request.user}, {'name': name}, request.user) except MultipleObjectsReturned: # Can't create a unique constraint on JSON field, so its possible that a duplicate gets made by accident dup_searches = VariantSearch.objects.filter( search=request_json, created_by=request.user, ).order_by('created_date') saved_search = dup_searches.first() VariantSearch.bulk_delete(request.user, queryset=dup_searches.exclude(guid=saved_search.guid)) update_model_from_json(saved_search, {'name': name}, request.user) except IntegrityError: error = 'Saved search with name "{}" already exists'.format(name) return create_json_response({'error': error}, status=400, reason=error) return create_json_response({ 'savedSearchesByGuid': { saved_search.guid: get_json_for_saved_search(saved_search, request.user) } })
def edit_families_handler(request, project_guid): """Edit or one or more Family records. Args: project_guid (string): GUID of project that contains these individuals. """ project = get_project_and_check_pm_permissions(project_guid, request.user) request_json = json.loads(request.body) if request_json.get('uploadedFileId'): modified_families = load_uploaded_file( request_json.get('uploadedFileId')) else: modified_families = request_json.get('families') if modified_families is None: return create_json_response({}, status=400, reason="'families' not specified") updated_families = [] for fields in modified_families: if fields.get('familyGuid'): family = Family.objects.get(project=project, guid=fields['familyGuid']) elif fields.get(PREVIOUS_FAMILY_ID_FIELD): family = Family.objects.get( project=project, family_id=fields[PREVIOUS_FAMILY_ID_FIELD]) else: family, _ = get_or_create_model_from_json( Family, { 'project': project, 'family_id': fields[FAMILY_ID_FIELD] }, update_json=None, user=request.user) update_family_from_json(family, fields, user=request.user, allow_unknown_keys=True) updated_families.append(family) updated_families_by_guid = { 'familiesByGuid': { family.guid: _get_json_for_family(family, request.user, add_individual_guids_field=True) for family in updated_families } } return create_json_response(updated_families_by_guid)
def update_individual_igv_sample(request, individual_guid): individual = Individual.objects.get(guid=individual_guid) project = individual.family.project check_project_permissions(project, request.user, can_edit=True) request_json = json.loads(request.body) try: file_path = request_json.get('filePath') if not file_path: raise ValueError('request must contain fields: filePath') suffix = '.'.join(file_path.split('.')[1:]) sample_type = SAMPLE_TYPE_MAP.get(suffix) if not sample_type: raise Exception( 'Invalid file extension for "{}" - valid extensions are {}'. format(file_path, ', '.join(SAMPLE_TYPE_MAP.keys()))) if not does_file_exist(file_path): raise Exception('Error accessing "{}"'.format(file_path)) sample, created = get_or_create_model_from_json( IgvSample, create_json={ 'individual': individual, 'sample_type': sample_type }, update_json={ 'file_path': file_path, 'sample_id': request_json.get('sampleId') }, user=request.user) response = { 'igvSamplesByGuid': { sample.guid: get_json_for_sample(sample, individual_guid=individual_guid, project_guid=project.guid) } } if created: response['individualsByGuid'] = { individual.guid: { 'igvSampleGuids': [s.guid for s in individual.igvsample_set.all()] } } return create_json_response(response) except Exception as e: error = str(e) return create_json_response({'error': error}, status=400, reason=error)
def _update_locus_list_items(locus_list, genes_by_id, intervals, request_json, user): # Update genes LocusList.bulk_delete(user, queryset=locus_list.locuslistgene_set.exclude( gene_id__in=genes_by_id.keys())) for gene_id in genes_by_id.keys(): get_or_create_model_from_json(LocusListGene, { 'locus_list': locus_list, 'gene_id': gene_id }, update_json=None, user=user) # Update intervals genome_version = request_json.get( 'intervalGenomeVersion') or GENOME_VERSION_GRCh37 interval_guids = set() for interval in intervals: interval_model, _ = get_or_create_model_from_json( LocusListInterval, { 'locus_list': locus_list, 'chrom': interval['chrom'], 'start': interval['start'], 'end': interval['end'], 'genome_version': genome_version, }, update_json=None, user=user) interval_guids.add(interval_model.guid) LocusList.bulk_delete(user, queryset=locus_list.locuslistinterval_set.exclude( guid__in=interval_guids))
def update_mme_contact_note(request, institution): """ Looks for matches for the given individual. Expects a single patient (MME spec) in the POST data field under key "patient_data" Args: project_id,indiv_id and POST all data in POST under key "patient_data" Returns: Status code and results """ institution = institution.strip().lower() request_json = json.loads(request.body) note, _ = get_or_create_model_from_json( MatchmakerContactNotes, create_json={'institution': institution}, update_json={'comments': request_json.get('comments', '')}, user=request.user) return create_json_response({ 'mmeContactNotes': {institution: _get_json_for_model(note, user=request.user)}, })
def update_analysis_group_handler(request, project_guid, analysis_group_guid=None): project = get_project_and_check_permissions(project_guid, request.user, can_edit=True) request_json = json.loads(request.body) missing_fields = [ field for field in REQUIRED_FIELDS.keys() if not request_json.get(field) ] if missing_fields: return create_json_response( {}, status=400, reason='Missing required field(s): {missing_field_names}'.format( missing_field_names=', '.join( [REQUIRED_FIELDS[field] for field in missing_fields]))) families = Family.objects.filter( guid__in=request_json['familyGuids']).only('guid') if len(families) != len(request_json['familyGuids']): return create_json_response( {}, status=400, reason='The following families do not exist: {missing_families}'. format(missing_families=', '.join( set(request_json['familyGuids']) - set([family.guid for family in families])))) if analysis_group_guid: analysis_group = AnalysisGroup.objects.get(guid=analysis_group_guid, project=project) update_model_from_json(analysis_group, request_json, user=request.user, allow_unknown_keys=True) else: analysis_group, created = get_or_create_model_from_json( AnalysisGroup, { 'project': project, 'name': request_json['name'], 'description': request_json.get('description'), 'created_by': request.user, }, update_json=None, user=request.user) if not created: return create_json_response( {}, status=400, reason= 'An analysis group named "{name}" already exists for project "{project}"' .format(name=request_json['name'], project=project.name)) analysis_group.families.set(families) return create_json_response({ 'analysisGroupsByGuid': { analysis_group.guid: get_json_for_analysis_group(analysis_group, project_guid=project_guid) }, })