diff --git a/CHANGELOG.md b/CHANGELOG.md index c72e03c..1f95f62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## [unreleased] +### Changed +- Expand the output of validate endpoint to return the link for downloading json file containing evantual submission errors + ## [2.5.2] ### Fixed - Upload to Codecov step in `tests_n_coverage.yml` action diff --git a/preClinVar/main.py b/preClinVar/main.py index 77158ab..80fb147 100644 --- a/preClinVar/main.py +++ b/preClinVar/main.py @@ -34,15 +34,15 @@ async def root(): @app.post("/validate") -async def validate(api_key: str = Form(), json_file: UploadFile = File(...)): - """A proxy to the validate submission ClinVar API endpoint""" +async def validate(api_key: str = Form(), json_file: UploadFile = File(...)) -> JSONResponse: + """A proxy to the apitest submission ClinVar API endpoint. Returns the ID of the submission and the data summary report with eventual errors.""" # Create a submission header header = build_header(api_key) # Get json file content as dict: submission_obj = json.load(json_file.file) - # And use it in POST request to API + # And use it as data in a POST request to API data = { "actions": [ { @@ -52,10 +52,23 @@ async def validate(api_key: str = Form(), json_file: UploadFile = File(...)): } ] } - resp = requests.post(VALIDATE_SUBMISSION_URL, data=json.dumps(data), headers=header) + apitest_resp = requests.post(VALIDATE_SUBMISSION_URL, data=json.dumps(data), headers=header) + apitest_json: dict = apitest_resp.json() + + # If submission was created, return eventual link for downloading json file with data-specific errors + if apitest_resp.status_code == 201: + + apitest_actions_url = f"{VALIDATE_SUBMISSION_URL}/{apitest_json.get('id')}/actions/" + apitest_actions_resp = requests.get(apitest_actions_url, headers=header) + + return JSONResponse( + status_code=apitest_actions_resp.status_code, + content=apitest_actions_resp.json(), + ) + return JSONResponse( - status_code=resp.status_code, - content=resp.json(), + status_code=apitest_resp.status_code, + content=apitest_json, ) diff --git a/tests/test_main.py b/tests/test_main.py index c209c05..8165afa 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -312,22 +312,56 @@ def test_validate_wrong_api_key(): @responses.activate -def test_validate(): +def test_validate_error(): """Test the validated API proxy endpoint (with a mocked ClinVar API response)""" - # GIVEN a json submission file - json_file = {"json_file": open(subm_json_path, "rb")} - - # AND a mocked ClinVar API + # GIVEN a mocked POST response from CLinVar apitest endpoint responses.add( responses.POST, VALIDATE_SUBMISSION_URL, json={"id": DEMO_SUBMISSION_ID}, - status=201, # The ClinVar API returs code 201 when request is successful (created) + status=201, # The ClinVar API returns code 201 when request is successful (created) + ) + + # GIVEN a mocked error response from apitest actions endpoint + actions: list[dict] = [ + { + "id": "SUB14404390-1", + "targetDb": "clinvar-test", + "status": "error", + "updated": "2024-04-26T06:41:04.533900Z", + "responses": [ + { + "status": "error", + "message": { + "severity": "error", + "errorCode": "2", + "text": 'Your ClinVar submission processing status is "Error". Please find the details in the file referenced by actions[0].responses[0].files[0].url.', + }, + "files": [ + { + "url": "https://submit.ncbi.nlm.nih.gov/api/2.0/files/vxgc6vtt/sub14404390-summary-report.json/?format=attachment" + } + ], + "objects": [], + } + ], + } + ] + + responses.add( + responses.GET, + f"{VALIDATE_SUBMISSION_URL}/{DEMO_SUBMISSION_ID}/actions/", + json={"actions": actions}, + status=200, # The ClinVar API returns code 201 when request is successful (created) ) + # GIVEN a json submission file + json_file = {"json_file": open(subm_json_path, "rb")} + response = client.post("/validate", data={"api_key": DEMO_API_KEY}, files=json_file) - # THEN the ClinVar API proxy should return "success" - assert response.status_code == 201 # Created - assert response.json()["id"] == DEMO_SUBMISSION_ID + # THEN the ClinVar API proxy should return the expected data + assert response.status_code == 200 + assert response.json()["actions"][0]["id"] + assert response.json()["actions"][0]["responses"][0]["files"]