Skip to content

Commit

Permalink
More 404 and 422 responses when failing to understand filename
Browse files Browse the repository at this point in the history
* 404 response for no files matching template ValueError

* Raise 422 error for unknown file format
  • Loading branch information
rjgildea authored Jun 8, 2023
1 parent e23574e commit 8470fab
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 6 deletions.
28 changes: 26 additions & 2 deletions src/dials_rest/routers/find_spots.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,15 +121,39 @@ async def find_spots(
else:
experiments = ExperimentListFactory.from_filenames([params.filename])
if params.scan_range and len(experiments) > 1:
# This means we've imported a sequence of still image: select
# This means we've imported a sequence of still images: select
# only the experiment, i.e. image, we're interested in
start, end = params.scan_range
experiments = experiments[start - 1 : end]
except FileNotFoundError as e:
logger.exception(e)
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"File not found: {params.filename}",
detail=str(e),
)
except ValueError as e:
logger.exception(e)
msg = str(e)
if "does not match any files" in msg:
logger.exception(e)
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=msg,
)
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail=msg,
)
except Exception as e:
logger.exception(e)
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail=str(e),
)
if not experiments:
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail=f"Could not find matching image format for {params.filename}",
)

phil_params = find_spots_phil_scope.fetch(source=phil.parse("")).extract()
Expand Down
21 changes: 20 additions & 1 deletion src/dials_rest/routers/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,26 @@ async def image_as_bitmap(
logger.exception(e)
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"File not found: {params.filename}",
detail=str(e),
)
except ValueError as e:
logger.exception(e)
msg = str(e)
if "does not match any files" in msg:
logger.exception(e)
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=msg,
)
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail=msg,
)
except Exception as e:
logger.exception(e)
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail=str(e),
)

phil_params = export_bitmaps.phil_scope.extract()
Expand Down
37 changes: 36 additions & 1 deletion tests/routers/test_find_spots.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,47 @@
from unittest import mock

import pytest
from fastapi import status


def test_find_spots_file_not_found_responds_404(client, authentication_headers):
data = {"filename": "/made/up/path.cbf"}
response = client.post("find_spots", json=data, headers=authentication_headers)
assert response.status_code == 404
assert response.status_code == status.HTTP_404_NOT_FOUND


def test_find_spots_template_no_matching_file_responds_404(
client, authentication_headers
):
data = {"filename": "/made/up/path_#####.cbf"}
response = client.post("find_spots", json=data, headers=authentication_headers)
assert response.status_code == status.HTTP_404_NOT_FOUND


def test_find_spots_fails_to_understand_h5_data_file_responds_422(
client, authentication_headers, dials_data
):
data = {
"filename": os.fspath(
# this is the data file rather than NeXus file, so dials should
# fail to understand
dials_data("vmxi_thaumatin", pathlib=True)
/ "image_15799_data_000001.h5"
),
}
response = client.post("find_spots", json=data, headers=authentication_headers)
assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY


def test_find_spots_fails_to_understand_text_file_responds_422(
client, authentication_headers, tmp_path
):
filename = tmp_path / "image_00001.cbf"
filename.touch()
for filename in {filename, tmp_path / "image_#####.cbf"}:
data = {"filename": os.fspath(filename)}
response = client.post("find_spots", json=data, headers=authentication_headers)
assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY


@pytest.mark.parametrize("filename", ["centroid_0001.cbf", "centroid_####.cbf"])
Expand Down
41 changes: 39 additions & 2 deletions tests/routers/test_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,55 @@
from io import BytesIO

import pytest
from fastapi import status
from PIL import Image


def test_export_bitmap_without_jwt_responds_403(client):
response = client.post("export_bitmap")
assert response.status_code == 403
assert response.status_code == status.HTTP_403_FORBIDDEN


def test_export_bitmap_file_not_found_responds_404(client, authentication_headers):
data = {"filename": "/made/up/path.cbf"}
response = client.post("export_bitmap", json=data, headers=authentication_headers)
assert response.status_code == 404
assert response.status_code == status.HTTP_404_NOT_FOUND


def test_export_bitmap_template_no_matching_file_responds_404(
client, authentication_headers
):
data = {"filename": "/made/up/path_#####.cbf"}
response = client.post("export_bitmap", json=data, headers=authentication_headers)
assert response.status_code == status.HTTP_404_NOT_FOUND


def test_export_bitmap_fails_to_understand_h5_data_file_responds_422(
client, authentication_headers, dials_data
):
data = {
"filename": os.fspath(
# this is the data file rather than NeXus file, so dials should
# fail to understand
dials_data("vmxi_thaumatin", pathlib=True)
/ "image_15799_data_000001.h5"
),
}
response = client.post("export_bitmap", json=data, headers=authentication_headers)
assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY


def test_export_bitmap_fails_to_understand_text_file_responds_422(
client, authentication_headers, tmp_path
):
filename = tmp_path / "image_00001.cbf"
filename.touch()
for filename in {filename, tmp_path / "image_#####.cbf"}:
data = {"filename": os.fspath(filename)}
response = client.post(
"export_bitmap", json=data, headers=authentication_headers
)
assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY


@pytest.mark.parametrize("filename", ["centroid_0001.cbf", "centroid_####.cbf"])
Expand Down

0 comments on commit 8470fab

Please sign in to comment.