Skip to content

Commit

Permalink
Encoders embed in the responses (#52)
Browse files Browse the repository at this point in the history
* Add encoders to responses
* Fix encoders position in responses
  • Loading branch information
tarsil authored Apr 18, 2024
1 parent ca0464b commit cd16fae
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 3 deletions.
4 changes: 2 additions & 2 deletions lilya/_internal/_encoders.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,10 @@ def serialize(self, obj: Any) -> Any:
}


def register_encoder(encoder: Encoder[Any]) -> None:
def register_encoder(encoder: Encoder[Any] | type[Encoder[Any]]) -> None:
if is_class_and_subclass(encoder, Encoder):
encoder = encoder() # type: ignore
ENCODER_TYPES.add(encoder)
ENCODER_TYPES.add(cast(Encoder[Any], encoder))


def json_encoder(value: Any) -> Any:
Expand Down
32 changes: 31 additions & 1 deletion lilya/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
Literal,
Mapping,
NoReturn,
Sequence,
Union,
)
from urllib.parse import quote
Expand All @@ -31,6 +32,7 @@
from lilya.compat import md5_hexdigest
from lilya.concurrency import iterate_in_threadpool
from lilya.datastructures import URL, Header
from lilya.encoders import Encoder, register_encoder
from lilya.enums import Event, HTTPMethod, MediaType
from lilya.types import Receive, Scope, Send

Expand All @@ -53,13 +55,19 @@ def __init__(
cookies: Mapping[str, str] | Any | None = None,
media_type: str | None = None,
background: Task | None = None,
encoders: Sequence[Encoder[Any]] | Sequence[type[Encoder[Any]]] | None = None,
) -> None:
if status_code is not None:
self.status_code = status_code
if media_type is not None:
self.media_type = media_type
self.background = background
self.cookies = cookies
self.encoders = encoders or []

for encoder in self.encoders:
register_encoder(encoder)

self.body = self.make_response(content)
self.raw_headers: list[Any] = []
self.make_headers(headers)
Expand Down Expand Up @@ -252,13 +260,15 @@ def __init__(
headers: Mapping[str, str] | None = None,
media_type: str | None = None,
background: Task | None = None,
encoders: Sequence[Encoder[Any]] | Sequence[type[Encoder[Any]]] | None = None,
) -> None:
super().__init__(
content=content,
status_code=status_code,
headers=headers,
media_type=media_type,
background=background,
encoders=encoders,
)

def make_response(self, content: Any) -> bytes:
Expand All @@ -282,9 +292,14 @@ def __init__(
status_code: int = status.HTTP_307_TEMPORARY_REDIRECT,
headers: Mapping[str, str] | None = None,
background: Task | None = None,
encoders: Sequence[Encoder[Any]] | Sequence[type[Encoder[Any]]] | None = None,
) -> None:
super().__init__(
content=b"", status_code=status_code, headers=headers, background=background
content=b"",
status_code=status_code,
headers=headers,
background=background,
encoders=encoders,
)
self.headers["location"] = quote(str(url), safe=":/%#?=@[]!$&'()*+,;")

Expand All @@ -299,7 +314,12 @@ def __init__(
headers: Mapping[str, str] | None = None,
media_type: str | None = None,
background: Task | None = None,
encoders: Sequence[Encoder[Any]] | Sequence[type[Encoder[Any]]] | None = None,
) -> None:
self.encoders = encoders or []
for encoder in self.encoders:
register_encoder(encoder)

if isinstance(content, AsyncIterable):
self.body_iterator = content
else:
Expand Down Expand Up @@ -353,6 +373,7 @@ def __init__(
stat_result: os.stat_result | None = None,
method: str | None = None,
content_disposition_type: str = "attachment",
encoders: Sequence[Encoder[Any]] | Sequence[type[Encoder[Any]]] | None = None,
) -> None:
self.path = path
self.status_code = status_code
Expand All @@ -362,6 +383,11 @@ def __init__(
media_type = guess_type(filename or path)[0] or MediaType.TEXT
self.media_type = media_type
self.background = background

self.encoders = encoders or []
for encoder in self.encoders:
register_encoder(encoder)

self.make_headers(headers)

if self.filename is not None:
Expand Down Expand Up @@ -430,6 +456,7 @@ def __init__(
background: Task | None = None,
headers: dict[str, Any] | None = None,
media_type: MediaType | str = MediaType.HTML,
encoders: Sequence[Encoder[Any]] | Sequence[type[Encoder[Any]]] | None = None,
):
self.template = template
self.context = context or {}
Expand All @@ -440,6 +467,7 @@ def __init__(
headers=headers,
media_type=media_type,
background=background,
encoders=encoders,
)

async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
Expand All @@ -461,6 +489,7 @@ def make_response(
status_code: int = status.HTTP_200_OK,
headers: Mapping[str, str] | None = None,
background: Task | None = None,
encoders: Sequence[Encoder[Any]] | Sequence[type[Encoder[Any]]] | None = None,
) -> Response:
"""
Build JSON responses from a given content and
Expand All @@ -474,4 +503,5 @@ def make_response(
headers=headers,
media_type=MediaType.JSON,
background=background,
encoders=encoders,
)

0 comments on commit cd16fae

Please sign in to comment.