fix(decisions): return 400 for bodies that are not JSON

This commit is contained in:
mateo-berri 2026-10-07 16:24:59 -07:00
parent 7ef132947a
commit b6bb885324
2 changed files with 26 additions and 2 deletions

View file

@ -40,6 +40,14 @@ async def _invalid_request(
) )
async def _request_data(request: Request, user_api_key_dict: UserAPIKeyAuth) -> dict[str, object]:
body: Final = await request.body()
try:
return _REQUEST_DATA_ADAPTER.validate_json(body)
except ValidationError as error:
raise await _invalid_request(raw_data={}, error=error, user_api_key_dict=user_api_key_dict)
async def _process_systemone( async def _process_systemone(
request: Request, request: Request,
fastapi_response: Response, fastapi_response: Response,
@ -133,7 +141,7 @@ async def systemone(
request=request, request=request,
fastapi_response=fastapi_response, fastapi_response=fastapi_response,
user_api_key_dict=user_api_key_dict, user_api_key_dict=user_api_key_dict,
raw_data=_REQUEST_DATA_ADAPTER.validate_json(await request.body()), raw_data=await _request_data(request, user_api_key_dict),
openai_body=None, openai_body=None,
) )
@ -155,7 +163,7 @@ async def decisions(
fastapi_response: Response, fastapi_response: Response,
user_api_key_dict: Annotated[UserAPIKeyAuth, Depends(user_api_key_auth)], user_api_key_dict: Annotated[UserAPIKeyAuth, Depends(user_api_key_auth)],
): ):
raw_data: Final = _REQUEST_DATA_ADAPTER.validate_json(await request.body()) raw_data: Final = await _request_data(request, user_api_key_dict)
try: try:
openai_body: Final = _OPENAI_DECISION_REQUEST_BODY_ADAPTER.validate_python(raw_data) openai_body: Final = _OPENAI_DECISION_REQUEST_BODY_ADAPTER.validate_python(raw_data)
except ValidationError as error: except ValidationError as error:

View file

@ -421,6 +421,22 @@ def test_openai_format_decisions_rejects_bodies_it_cannot_translate(
assert not upstream.called assert not upstream.called
@pytest.mark.parametrize("endpoint", ("/v1/systemone", "/v1/decisions"))
@pytest.mark.parametrize("raw_body", (b"", b"{not json"), ids=("empty", "malformed"))
def test_a_body_that_is_not_json_is_a_client_error(
client: TestClient,
respx_mock: respx.MockRouter,
endpoint: str,
raw_body: bytes,
) -> None:
upstream: Final = respx_mock.post("https://api.perplexity.ai/v1/decisions").respond(json=_RESPONSE)
response: Final = client.post(endpoint, content=raw_body, headers={"Content-Type": "application/json"})
assert response.status_code == 400, response.text
assert not upstream.called
def _decisions_feature() -> LazyFeature: def _decisions_feature() -> LazyFeature:
return next(feature for feature in LAZY_FEATURES if feature.name == "decisions") return next(feature for feature in LAZY_FEATURES if feature.name == "decisions")