Skip to content

Commit 8505b37

Browse files
Warn on unexpected header, use HTTPException
1 parent f8d2fc4 commit 8505b37

File tree

4 files changed

+52
-11
lines changed

4 files changed

+52
-11
lines changed

src/daq_config_server/app.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from typing import Annotated
66

77
import uvicorn
8-
from fastapi import FastAPI, Header
8+
from fastapi import FastAPI, Header, HTTPException
99
from fastapi.middleware.cors import CORSMiddleware
1010
from fastapi.responses import JSONResponse, Response
1111

@@ -43,7 +43,7 @@ def get_configuration(
4343
Read a file and return its contents in a format specified by the accept header.
4444
"""
4545
if not file_path.is_file():
46-
raise FileNotFoundError(f"File {file_path} cannot be found")
46+
raise HTTPException(status_code=404, detail=f"File {file_path} cannot be found")
4747

4848
file_name = os.path.basename(file_path)
4949

src/daq_config_server/client.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import json
21
from enum import StrEnum
32
from logging import Logger, getLogger
43
from typing import Any, TypeVar
@@ -36,10 +35,16 @@ def _get(
3635

3736
content_type = r.headers["content-type"].split(";")[0].strip()
3837

38+
if content_type != headers["Accept"]:
39+
self._log.warning(
40+
f"Server failed to parse the file as requested. Requested \
41+
{headers['Accept']} but response came as content-type {content_type}"
42+
)
43+
3944
try:
4045
match content_type:
4146
case ValidAcceptHeaders.JSON:
42-
content = json.loads(r.content)
47+
content = r.json()
4348
case ValidAcceptHeaders.PLAIN_TEXT:
4449
content = r.text
4550
case _:

tests/unit_tests/test_api.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,8 @@ async def test_get_configuration_on_plain_text_file(mock_app: TestClient):
5757

5858
def test_get_configuration_exception_on_invalid_file(mock_app: TestClient):
5959
file_path = f"{TEST_DATA_DIR}/nonexistent_file.yaml"
60-
61-
with pytest.raises(FileNotFoundError):
62-
mock_app.get(f"{ENDPOINTS.CONFIG}/{file_path}", headers=HEADER_DEFAULTS)
60+
response = mock_app.get(f"{ENDPOINTS.CONFIG}/{file_path}", headers=HEADER_DEFAULTS)
61+
assert response.status_code == status.HTTP_404_NOT_FOUND
6362

6463

6564
async def test_get_configuration_on_json_file(mock_app: TestClient):

tests/unit_tests/test_client.py

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,56 @@ def test_get_file_contents(mock_request: MagicMock):
2626
def test_get_file_contents_warns_and_gives_bytes_on_invalid_json(
2727
mock_request: MagicMock,
2828
):
29+
content_type = ValidAcceptHeaders.JSON
2930
bad_json = "bad_dict}"
3031
mock_request.return_value = Response(
3132
status_code=status.HTTP_200_OK,
3233
json="test",
3334
headers={
34-
"accept": ValidAcceptHeaders.JSON,
35-
"content-type": ValidAcceptHeaders.JSON,
35+
"content-type": content_type,
3636
},
3737
content=bad_json,
3838
)
3939
file_path = "test"
4040
url = "url"
4141
server = ConfigServer(url)
4242
server._log.warning = MagicMock()
43-
assert server.get_file_contents(file_path) == bad_json.encode()
44-
server._log.warning.assert_called_once()
43+
assert (
44+
server.get_file_contents(
45+
file_path, requested_response_format=RequestedResponseFormats.DICT
46+
)
47+
== bad_json.encode()
48+
)
49+
assert (
50+
f"Failed trying to convert to content-type {content_type} due to "
51+
in server._log.warning.call_args[0][0]
52+
)
53+
54+
55+
@patch("daq_config_server.client.requests.get")
56+
def test_logger_warning_if_content_type_doesnt_match_requested_type(
57+
mock_request: MagicMock,
58+
):
59+
headers = {"Accept": RequestedResponseFormats.DICT}
60+
content_type = ValidAcceptHeaders.PLAIN_TEXT
61+
text = "text"
62+
mock_request.return_value = Response(
63+
status_code=status.HTTP_200_OK,
64+
json="test",
65+
headers={
66+
"content-type": content_type,
67+
},
68+
content=text,
69+
)
70+
file_path = "test"
71+
url = "url"
72+
server = ConfigServer(url)
73+
server._log.warning = MagicMock()
74+
server.get_file_contents(
75+
file_path, requested_response_format=RequestedResponseFormats.DICT
76+
)
77+
78+
server._log.warning.assert_called_once_with(
79+
f"Server failed to parse the file as requested. Requested \
80+
{headers['Accept']} but response came as content-type {content_type}"
81+
)

0 commit comments

Comments
 (0)