def delete_project(request, project_guid): """Delete project Args: project_guid (string): GUID of the project to delete """ project = _get_project_and_check_permissions(project_guid, request.user, permission_level=IS_OWNER) _deprecated_delete_original_project(project) for family in Family.objects.filter(project=project): for individual in Individual.objects.filter(family=family): individual.delete() family.delete() project.delete() # TODO delete PhenoTips, etc. and other objects under this project return create_json_response({ 'projectsByGuid': { project.guid: None }, })
def variant_search_page(request, project_guid): """Generates the dashboard page, with initial variant_search_page json embedded.""" # check project permissions project = _get_project_and_check_permissions(project_guid, request.user) initial_json = json.loads(variant_search_page_data(request).content) return render_with_initial_json('variant_search.html', initial_json)
def project_page_data(request, project_guid): """Returns a JSON object containing information used by the project page: :: json_response = { 'user': {..}, 'familiesByGuid': {..}, 'individualsByGuid': {..}, 'samplesByGuid': {..}, 'sampleBatchesByGuid': {..}, } Args: project_guid (string): GUID of the Project to retrieve data for. """ project = _get_project_and_check_permissions(project_guid, request.user) cursor = connection.cursor() families_by_guid, individuals_by_guid = _retrieve_families_and_individuals( cursor, project.guid) samples_by_guid, sample_batches_by_guid = _retrieve_samples( cursor, project.guid, individuals_by_guid) cursor.close() project_json = _get_json_for_project(project, request.user) project_json['collaborators'] = _get_json_for_collaborator_list(project) project_json['locusLists'] = _get_json_for_locus_lists(project) project_json['variantTagTypes'] = _get_json_for_variant_tag_types(project) #project_json['referencePopulations'] = _get_json_for_reference_populations(project) # gene search will be deprecated once the new database is online. project_json['hasGeneSearch'] = _has_gene_search(project) user_json = _get_json_for_user(request.user) user_json[ 'hasEditPermissions'] = request.user.is_staff or request.user.has_perm( CAN_EDIT, project) user_json['hasViewPermissions'] = user_json[ 'hasEditPermissions'] or request.user.has_perm(CAN_VIEW, project) json_response = { 'user': user_json, 'project': project_json, 'familiesByGuid': families_by_guid, 'individualsByGuid': individuals_by_guid, 'samplesByGuid': samples_by_guid, 'sampleBatchesByGuid': sample_batches_by_guid, } return create_json_response(json_response)
def save_individuals_table(request, project_guid, token): """Handler for 'save' requests to apply Individual tables previously uploaded through receive_individuals_table(..) Args: request (object): Django request object project_guid (string): project GUID token (string): a token sent to the client by receive_individuals_table(..) """ project = _get_project_and_check_permissions(project_guid, request.user) serialized_file_path = _compute_serialized_file_path(token) with gzip.open(serialized_file_path) as f: records = json.load(f) families = {} for record in records: family, created = Family.objects.get_or_create(project=project, family_id=record['familyId']) if created: if not family.display_name: family.display_name = family.family_id family.save() logger.info("Created family: %s" % str(family)) individual, created = Individual.objects.get_or_create(family=family, individual_id=record['individualId']) update_individual_from_json(individual, record, allow_unknown_keys=True) individual.phenotips_eid = individual.guid # use this instead of individual_id to avoid chance of collisions if created: patient_record = create_patient(project, individual.phenotips_eid) individual.phenotips_patient_id = patient_record['id'] logger.info("Created phenotips record with patient id %s and external id %s" % ( str(individual.phenotips_patient_id), str(individual.phenotips_eid))) if not individual.case_review_status: individual.case_review_status = Individual.CASE_REVIEW_STATUS_IN_REVIEW if not individual.display_name: individual.display_name = individual.individual_id individual.save() _deprecated_update_original_individual_data(project, individual) families[family.family_id] = family # update pedigree images for family in families.values(): update_pedigree_image(family) # sync events os.remove(serialized_file_path) return create_json_response({})
def export_project_families_handler(request, project_guid): """Export project Families table. Args: project_guid (string): GUID of the project for which to export family data """ format = request.GET.get('file_format', 'tsv') project = _get_project_and_check_permissions(project_guid, request.user) # get all families in this project families = Family.objects.filter(project=project).order_by('family_id') filename_prefix = "%s_families" % _slugify(project.name) return export_families(filename_prefix, families, format, include_case_review_columns=False)
def case_review_page_data(request, project_guid): """Returns a JSON object containing information used by the case review page: :: json_response = { 'user': {..}, 'project': {..}, 'familiesByGuid': {..}, 'individualsByGuid': {..}, } Args: project_guid (string): GUID of the project being case-reviewed. """ # get all families in this project project = _get_project_and_check_permissions(project_guid, request.user) json_response = { 'user': _get_json_for_user(request.user), 'project': _get_json_for_project(project, request.user), 'familiesByGuid': {}, 'individualsByGuid': {}, } for i in Individual.objects.select_related('family').filter( family__project=project): # filter out individuals that were never in case review if not i.case_review_status: continue # process family record if it hasn't been added already family = i.family if family.guid not in json_response['familiesByGuid']: json_response['familiesByGuid'][ family.guid] = _get_json_for_family(family, request.user) json_response['familiesByGuid'][ family.guid]['individualGuids'] = [] json_response['individualsByGuid'][i.guid] = _get_json_for_individual( i, request.user) json_response['familiesByGuid'][family.guid]['individualGuids'].append( i.guid) return create_json_response(json_response)
def export_project_individuals_handler(request, project_guid): """Export project Individuals table. Args: project_guid (string): GUID of the project for which to export individual data """ format = request.GET.get('file_format', 'tsv') include_phenotypes = bool(request.GET.get('include_phenotypes')) project = _get_project_and_check_permissions(project_guid, request.user) # get all individuals in this project individuals = Individual.objects.filter(family__project=project).order_by('family__family_id', 'affected') filename_prefix = "%s_individuals" % _slugify(project.name) return export_individuals(filename_prefix, individuals, format, include_phenotips_columns=include_phenotypes)
def delete_project_handler(request, project_guid): """Delete project - request handler. Args: project_guid (string): GUID of the project to delete """ project = _get_project_and_check_permissions(project_guid, request.user, permission_level=IS_OWNER) delete_project(project) return create_json_response({ 'projectsByGuid': { project.guid: None }, })
def save_individuals_table_handler(request, project_guid, token): """Handler for 'save' requests to apply Individual tables previously uploaded through receive_individuals_table(..) Args: request (object): Django request object project_guid (string): project GUID token (string): a token sent to the client by receive_individuals_table(..) """ project = _get_project_and_check_permissions(project_guid, request.user) serialized_file_path = _compute_serialized_file_path(token) with gzip.open(serialized_file_path) as f: json_records = json.load(f) add_or_update_individuals_and_families(project, individual_records=json_records) os.remove(serialized_file_path) return create_json_response({})
def export_case_review_families(request, project_guid): """Export case review Families table. Args: project_guid (string): GUID of the project for which to export case review family data """ format = request.GET.get('file_format', 'tsv') project = _get_project_and_check_permissions(project_guid, request.user) # get all families in this project that have at least 1 individual in case review. families = set() for i in Individual.objects.filter( family__project=project, case_review_status__regex="[\w].*").order_by('family__family_id'): families.add(i.family) filename_prefix = "%s_case_review_families" % _slugify(project.name) return export_families(filename_prefix, families, format, include_case_review_columns=True)
def export_case_review_individuals(request, project_guid): """Export case review Individuals table. Args: project_guid (string): GUID of the project for which to export case review individual data """ format = request.GET.get('file_format', 'tsv') project = _get_project_and_check_permissions(project_guid, request.user) individuals = Individual.objects.filter( family__project=project, case_review_status__regex="[\w].*").order_by('family__family_id', 'affected') filename_prefix = "%s_case_review_individuals" % _slugify(project.name) return export_individuals(filename_prefix, individuals, format, include_case_review_columns=True, include_phenotips_columns=True)
def receive_individuals_table_handler(request, project_guid): """Handler for the initial upload of an Excel or .tsv table of individuals. This handler parses the records, but doesn't save them in the database. Instead, it saves them to a temporary file and sends a 'token' representing this file back to the client. If/when the client then wants to 'apply' this table, it can send the token to the save_individuals_table(..) handler to actually save the data in the database. Args: request (object): Django request object project_guid (string): project GUID """ project = _get_project_and_check_permissions(project_guid, request.user) if len(request.FILES) != 1: return create_json_response({ 'errors': ["Received %s files instead of 1" % len(request.FILES)] }) # parse file stream = request.FILES.values()[0] filename = stream._name #file_size = stream._size #content_type = stream.content_type #content_type_extra = stream.content_type_extra #for chunk in value.chunks(): # destination.write(chunk) json_records, errors, warnings = parse_pedigree_table(filename, stream) if errors: return create_json_response({'errors': errors, 'warnings': warnings}) # save json to temporary file token = hashlib.md5(str(json_records)).hexdigest() serialized_file_path = _compute_serialized_file_path(token) with gzip.open(serialized_file_path, "w") as f: json.dump(json_records, f) # send back some stats num_families = len(set(r['familyId'] for r in json_records)) num_individuals = len(set(r['individualId'] for r in json_records)) num_families_to_create = len([ family_id for family_id in set(r['familyId'] for r in json_records) if not Family.objects.filter(family_id=family_id, project=project) ]) num_individuals_to_create = len( set(r['individualId'] for r in json_records if not Individual.objects.filter(individual_id=r['individualId'], family__family_id=r['familyId'], family__project=project))) info = [ "%(num_families)s families, %(num_individuals)s inidividuals parsed from %(filename)s" % locals(), "%d new families, %d new individuals will be added to the project" % (num_families_to_create, num_individuals_to_create), "%d existing individuals will be updated" % (num_individuals - num_individuals_to_create), ] return create_json_response({ 'token': token, 'errors': errors, 'warnings': warnings, 'info': info, })