From f9ce39165d238eb0733e0be5617dfe0a4c8e9543 Mon Sep 17 00:00:00 2001 From: Hana Snow Date: Wed, 26 Jun 2024 10:58:00 -0400 Subject: [PATCH 1/3] validate no ambiguity for aip families --- seqr/views/apis/summary_data_api.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/seqr/views/apis/summary_data_api.py b/seqr/views/apis/summary_data_api.py index 2c8663b76d..6e94e7643c 100644 --- a/seqr/views/apis/summary_data_api.py +++ b/seqr/views/apis/summary_data_api.py @@ -184,17 +184,25 @@ def _load_aip_data(data: dict, user: User): category_map = data['metadata']['categories'] results = data['results'] - family_id_map = dict(Individual.objects.filter( + family_id_map = defaultdict(list) + for individual_id, family_id in Individual.objects.filter( family__project__in=get_internal_projects(), individual_id__in=results.keys(), - ).values_list('individual_id', 'family_id')) + ).values_list('individual_id', 'family_id'): + family_id_map[individual_id].append(family_id) + errors = [] missing_individuals = set(results.keys()) - set(family_id_map.keys()) if missing_individuals: - raise ErrorsWarningsException([f'Unable to find the following individuals: {", ".join(sorted(missing_individuals))}']) + errors.append(f'Unable to find the following individuals: {", ".join(sorted(missing_individuals))}') + multi_family_individuals = {individual_id for individual_id, families in family_id_map.items() if len(families) > 1} + if multi_family_individuals: + errors.append(f'The following individuals are found in multiple families: {", ".join(sorted(multi_family_individuals))}') + if errors: + raise ErrorsWarningsException(errors) family_variant_data = {} for family_id, variant_pred in results.items(): family_variant_data.update({ - (family_id_map[family_id], variant_id): pred for variant_id, pred in variant_pred.items() + (family_id_map[family_id][0], variant_id): pred for variant_id, pred in variant_pred.items() }) today = datetime.now().strftime('%Y-%m-%d') From 6a3bc72342151cf2825d4fe616f665b5a6500e0b Mon Sep 17 00:00:00 2001 From: Hana Snow Date: Wed, 26 Jun 2024 11:02:47 -0400 Subject: [PATCH 2/3] specify projects in the AIP metadata --- seqr/views/apis/summary_data_api.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/seqr/views/apis/summary_data_api.py b/seqr/views/apis/summary_data_api.py index 6e94e7643c..b279556c49 100644 --- a/seqr/views/apis/summary_data_api.py +++ b/seqr/views/apis/summary_data_api.py @@ -182,11 +182,15 @@ def bulk_update_family_external_analysis(request): def _load_aip_data(data: dict, user: User): category_map = data['metadata']['categories'] + projects = data['metadata'].get('projects') results = data['results'] + if not projects: + raise ErrorsWarningsException(['No projects specified in the metadata']) + family_id_map = defaultdict(list) for individual_id, family_id in Individual.objects.filter( - family__project__in=get_internal_projects(), individual_id__in=results.keys(), + family__project__in=get_internal_projects().filter(name__in=projects), individual_id__in=results.keys(), ).values_list('individual_id', 'family_id'): family_id_map[individual_id].append(family_id) errors = [] From afceec7ce37a6dbabca6b5915a4a83cb13c83920 Mon Sep 17 00:00:00 2001 From: Hana Snow Date: Wed, 26 Jun 2024 11:09:00 -0400 Subject: [PATCH 3/3] update tests --- seqr/views/apis/summary_data_api_tests.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/seqr/views/apis/summary_data_api_tests.py b/seqr/views/apis/summary_data_api_tests.py index 8785e361e0..fd999b9a6f 100644 --- a/seqr/views/apis/summary_data_api_tests.py +++ b/seqr/views/apis/summary_data_api_tests.py @@ -505,9 +505,19 @@ def test_bulk_update_family_external_analysis(self, mock_load_uploaded_file, moc body['dataType'] = 'AIP' response = self.client.post(url, content_type='application/json', data=json.dumps(body)) self.assertEqual(response.status_code, 400) + self.assertEqual(response.json()['errors'], ['No projects specified in the metadata']) + + aip_upload['metadata']['projects'] = ['1kg project nåme with uniçøde', 'Test Reprocessed Project'] + response = self.client.post(url, content_type='application/json', data=json.dumps(body)) + self.assertEqual(response.status_code, 400) self.assertEqual(response.json()['errors'], ['Unable to find the following individuals: SAM_123']) - aip_upload['results']['NA20889'] = aip_upload['results'].pop('SAM_123') + aip_upload['results']['NA20870'] = aip_upload['results'].pop('SAM_123') + response = self.client.post(url, content_type='application/json', data=json.dumps(body)) + self.assertEqual(response.status_code, 400) + self.assertEqual(response.json()['errors'], ['The following individuals are found in multiple families: NA20870']) + + aip_upload['results']['NA20889'] = aip_upload['results'].pop('NA20870') response = self.client.post(url, content_type='application/json', data=json.dumps(body)) self.assertEqual(response.status_code, 400) self.assertEqual(response.json()['errors'], [