diff --git a/htsget_server/authz.py b/htsget_server/authz.py index 42c0ca87..45648130 100644 --- a/htsget_server/authz.py +++ b/htsget_server/authz.py @@ -25,6 +25,8 @@ def is_authed(id_, request): if obj is not None and 'cohort' in obj: if is_cohort_authorized(request, obj['cohort']): return 200 + else: + return 404 else: return 401 return 403 diff --git a/htsget_server/htsget_openapi.yaml b/htsget_server/htsget_openapi.yaml index 96f943c1..d28a8539 100644 --- a/htsget_server/htsget_openapi.yaml +++ b/htsget_server/htsget_openapi.yaml @@ -405,9 +405,25 @@ paths: schema: $ref: '#/components/schemas/SampleTicket' /samples: + get: + summary: Get metadata about samples in a cohort + operationId: htsget_operations.get_cohort_samples + description: Get MoH-relevant genomic information about all samples in a cohort + parameters: + - $ref: '#/components/parameters/authHeaderParam' + - $ref: '#/components/parameters/cohortParam' + responses: + 200: + description: Success + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/SampleTicket' post: summary: Get metadata about multiple samples - operationId: htsget_operations.get_samples + operationId: htsget_operations.get_multiple_samples description: Get MoH-relevant genomic information about a list of samples parameters: - $ref: '#/components/parameters/authHeaderParam' @@ -855,6 +871,9 @@ components: sample_id: type: string description: MoH submitter_sample_id from a Sample Registration associated with a specimen. + cohort: + type: string + description: MoH cohort ID genome: type: array description: An array of associated GenomicDrsObjects that describe reads, e.g. bams. @@ -1068,6 +1087,13 @@ components: name: Range schema: $ref: '#/components/schemas/Range' + cohortParam: + in: query + name: cohort + description: name of cohort + required: false + schema: + type: string requestBodies: ReadsRequestBody: description: Specify desired file format, fields, tags, and regions from an alignment file diff --git a/htsget_server/htsget_operations.py b/htsget_server/htsget_operations.py index 6de864b0..f37ba6e9 100644 --- a/htsget_server/htsget_operations.py +++ b/htsget_server/htsget_operations.py @@ -247,6 +247,7 @@ def get_sample(id_=None): # Each of those GenomicDrsObjects will have a description that is either 'wgs' or 'wts'. sample_drs_obj, result_code = drs_operations.get_object(id_) if result_code == 200 and "contents" in sample_drs_obj and sample_drs_obj["description"] == "sample": + result["cohort"] = sample_drs_obj["cohort"] for contents_obj in sample_drs_obj["contents"]: drs_obj = database.get_drs_object(contents_obj["id"]) if drs_obj is not None: @@ -265,7 +266,7 @@ def get_sample(id_=None): return {"message": f"Could not find sample {id_}"}, 404 -def get_samples(): +def get_multiple_samples(): req = connexion.request.json result = [] for sample in req["samples"]: @@ -275,6 +276,20 @@ def get_samples(): return result, 200 +def get_cohort_samples(cohort=None): + if cohort is None: + sample_drs_objs = database.list_drs_objects() + else: + sample_drs_objs = database.list_drs_objects(cohort) + samples = list(map(lambda y: y["id"], filter(lambda x: x["description"] == "sample", sample_drs_objs))) + result = [] + for sample in samples: + res, status_code = get_sample(sample) + if status_code == 200: + result.append(res) + return result, 200 + + def _get_htsget_url(id, reference_name, slice_start, slice_end, file_type, data=True): """ Creates single slice for a region in a file. Returns an HTSGetURL object. diff --git a/tests/test_htsget_server.py b/tests/test_htsget_server.py index 6ffdb887..097301c9 100644 --- a/tests/test_htsget_server.py +++ b/tests/test_htsget_server.py @@ -26,6 +26,9 @@ def get_headers(): headers = {} + if TEST_KEY is not None: + headers["Authorization"] = f"Bearer {TEST_KEY}" + return headers try: token = get_site_admin_token() headers["Authorization"] = f"Bearer {token}" @@ -307,13 +310,14 @@ def test_add_sample_drs(input, program_id): response = requests.post(post_url, json=genomic_drs_obj, headers=get_headers()) print(response.text) - response = requests.request("GET", get_url, headers=headers) + response = requests.request("GET", get_url, headers=get_headers()) if response.status_code == 200: assert response.status_code == 200 assert len(genomic_drs_obj["contents"]) == contents_count + 1 verify_url = f"{HOST}/htsget/v1/variants/{input['genomic_id']}/verify" - response = requests.get(verify_url) + response = requests.get(verify_url, headers=get_headers()) + print(response.text) assert response.status_code == 200 @@ -326,12 +330,23 @@ def test_sample_stats(input, program_id): # look for the sample get_url = f"{HOST}/htsget/v1/samples/{sample[list(sample.keys()).pop()]}" response = requests.request("GET", get_url, headers=headers) - if response.status_code == 200: - assert response.status_code == 200 + assert response.status_code == 200 assert input['genomic_id'] in response.json()['genomes'] +def test_cohort_samples(): + headers = get_headers() + + get_url = f"{HOST}/htsget/v1/samples" + response = requests.request("GET", get_url, headers=headers) + print(response.json()) + response = requests.request("GET", get_url, headers=headers, params={"cohort": "1000genomes"}) + assert response.status_code == 200 + print(response.json()) + assert len(response.json()) == 1 + + def invalid_start_end_data(): return [(17123456, 23588), (9203, 42220938)] @@ -446,7 +461,7 @@ def get_beacon_post_search(): return [ ( # 6 variations, corresponding to three variant records in multisample_1 and multisample_2 - # first variation, corresponding to "NC_000021.8:g.5030551=", should contain two cases + # first variation, corresponding to "NC_000021.9:g.5030847=", should contain two cases { "query": { "requestParameters": {