Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

change default media_type of Response to None to match LilyaResponse #458

Merged
merged 2 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/en/docs/release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ hide:

- Allow passing extensions as string.

### Changed

- Change `media_type` parameter of `Response` from `MediaType.JSON` to `None` to match the default of the underlying lilya Response.

### Fixed

- OpenAPI responses.
Expand Down
4 changes: 3 additions & 1 deletion docs/en/docs/responses.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ This will allow you to use the [ORJSON](#orjson) and [UJSON](#ujson) as well as

### Response

Classic and generic `Response` that fits almost every single use case out there.
Classic and generic `Response` that fits almost every single use case out there. It behaves like lilya `Response` by default.
It has a special mode for `media_type="application/json"` (used by handlers) in which it behaves like `make_response` (encodes content).
This special mode is required for encoding data like datetimes, ...

```python
{!> ../../../docs_src/responses/response.py !}
Expand Down
16 changes: 13 additions & 3 deletions esmerald/responses/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def __init__(
The media type used in the response.
"""
),
] = MediaType.JSON,
] = None,
background: Annotated[
Optional[Union["BackgroundTask", "BackgroundTasks"]],
Doc(
Expand Down Expand Up @@ -175,18 +175,27 @@ def __init__(
self.cookies = cookies or []

@staticmethod
def transform(value: Any) -> Dict[str, Any]:
def transform(
value: Any, *, encoders: Union[Sequence[Encoder], None] = None
) -> Dict[str, Any]:
"""
The transformation of the data being returned.

Supports all the default encoders from Lilya and custom from Esmerald.
"""
return cast(
Dict[str, Any], json_encoder(value, json_encode_fn=dumps, post_transform_fn=loads)
Dict[str, Any],
json_encoder(
value,
json_encode_fn=partial(dumps, option=OPT_SERIALIZE_NUMPY | OPT_OMIT_MICROSECONDS),
post_transform_fn=loads,
with_encoders=encoders,
),
)

def make_response(self, content: Any) -> Union[bytes, str]:
# here we need lilyas encoders not only esmerald encoders
# in case no extra encoders are defined use the default by passing None
encoders = (
(
(
Expand All @@ -208,6 +217,7 @@ def make_response(self, content: Any) -> Union[bytes, str]:
)
):
return b""
# switch to a special mode for MediaType.JSON
if self.media_type == MediaType.JSON:
return cast(
bytes,
Expand Down
4 changes: 2 additions & 2 deletions tests/routing/test_proxy_load.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ def test_can_load_from_proxy(test_client_factory):
response = client.get("/child/home")

assert response.status_code == 200
assert response.json() == "Hello, from proxy"
assert response.text == '"Hello, from proxy"'

response = client.get("/esmerald")

assert response.status_code == 200
assert response.json() == "Hello, esmerald"
assert response.text == "Hello, esmerald"
2 changes: 1 addition & 1 deletion tests/routing/test_routing.py
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ def test_protocol_switch(test_client_factory):
with create_client(routes=mixed_protocol_app) as client:
response = client.get("/")
assert response.status_code == 200
assert response.json() == "URL: http://testserver/"
assert response.text == "URL: http://testserver/"

with client.websocket_connect("/") as session:
assert session.receive_json() == {"URL": "ws://testserver/"}
Expand Down
14 changes: 7 additions & 7 deletions tests/test_responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,23 +52,23 @@ def test_override(test_client_factory):
with create_client(routes=[Gateway(handler=route_three)]) as client:
response = client.get("/three")

assert response.text == '"Ok"'
assert response.text == "Ok"
assert response.status_code == status.HTTP_103_EARLY_HINTS


def test_default(test_client_factory):
with create_client(routes=[Gateway(handler=route_four)]) as client:
response = client.get("/four")

assert response.text == '"Ok"'
assert response.text == "Ok"
assert response.status_code == status.HTTP_200_OK


def test_default_decorator(test_client_factory):
with create_client(routes=[Gateway(handler=route_five)]) as client:
response = client.get("/five")

assert response.text == '"Ok"'
assert response.text == "Ok"
assert response.status_code == status.HTTP_207_MULTI_STATUS


Expand All @@ -92,20 +92,20 @@ def test_multiple(test_client_factory):
) as client:
response = client.get("/multi")

assert response.text == '"Ok"'
assert response.text == "Ok"
assert response.status_code == status.HTTP_207_MULTI_STATUS

response = client.get("/multi/test")

assert response.text == '"Ok"'
assert response.text == "Ok"
assert response.status_code == status.HTTP_401_UNAUTHORIZED

response = client.get("/multi/esmerald")

assert response.text == '"Ok"'
assert response.text == "Ok"
assert response.status_code == status.HTTP_300_MULTIPLE_CHOICES

response = client.get("/multi/other")

assert response.text == '"Ok"'
assert response.text == "Ok"
assert response.status_code == status.HTTP_207_MULTI_STATUS
Loading