Skip to content

Commit

Permalink
refactor!: Remove deprecated app param of `Response.to_asgi_respons…
Browse files Browse the repository at this point in the history
…e` (#3393)

* Remove 'app' parameter from `.to_asgi_response`
  • Loading branch information
provinzkraut committed May 25, 2024
1 parent 149975c commit 4d95e8c
Show file tree
Hide file tree
Showing 10 changed files with 23 additions and 96 deletions.
8 changes: 8 additions & 0 deletions docs/release-notes/whats-new-3.rst
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,11 @@ the root path (``/``), in which case that plugin will be used.

For those previously using the ``root_schema_site`` attribute, the migration involves ensuring that the UI intended to
be served at the ``/schema`` endpoint is the first plugin listed in the :attr:`OpenAPIConfig.render_plugins`.


Deprecated ``app`` parameter for ``Response.to_asgi_response`` has been removed
-------------------------------------------------------------------------------

The parameter ``app`` for :meth:`~response.Response.to_asgi_response` has been removed.
If you need access to the app instance inside a custom ``to_asgi_response`` method,
replace the usages of ``app`` with ``request.app``.
6 changes: 1 addition & 5 deletions litestar/handlers/http_handlers/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
from litestar.types.builtin_types import NoneType

if TYPE_CHECKING:
from litestar.app import Litestar
from litestar.background_tasks import BackgroundTask, BackgroundTasks
from litestar.connection import Request
from litestar.datastructures import Cookie, ResponseHeader
Expand Down Expand Up @@ -59,7 +58,6 @@ def create_data_handler(
async def handler(
data: Any,
request: Request[Any, Any, Any],
app: Litestar,
**kwargs: Any,
) -> ASGIApp:
if isawaitable(data):
Expand All @@ -76,7 +74,7 @@ async def handler(
if after_request:
response = await after_request(response) # type: ignore[arg-type,misc]

return response.to_asgi_response(app=None, request=request, headers=normalize_headers(headers), cookies=cookies) # pyright: ignore
return response.to_asgi_response(request=request, headers=normalize_headers(headers), cookies=cookies) # pyright: ignore

return handler

Expand Down Expand Up @@ -144,13 +142,11 @@ def create_response_handler(

async def handler(
data: Response,
app: Litestar,
request: Request,
**kwargs: Any, # kwargs is for return dto
) -> ASGIApp:
response = await after_request(data) if after_request else data # type:ignore[arg-type,misc]
return response.to_asgi_response( # type: ignore[no-any-return]
app=None,
background=background,
cookies=cookie_list,
headers=normalized_headers,
Expand Down
7 changes: 3 additions & 4 deletions litestar/handlers/http_handlers/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ def resolve_tags(self) -> list[str]:

return self._resolved_tags

def get_response_handler(self, is_response_type_data: bool = False) -> Callable[[Any], Awaitable[ASGIApp]]:
def get_response_handler(self, is_response_type_data: bool = False) -> Callable[..., Awaitable[ASGIApp]]:
"""Resolve the response_handler function for the route handler.
This method is memoized so the computation occurs only once.
Expand Down Expand Up @@ -538,11 +538,10 @@ def get_response_handler(self, is_response_type_data: bool = False) -> Callable[
else self._response_handler_mapping["default_handler"],
)

async def to_response(self, app: Litestar, data: Any, request: Request) -> ASGIApp:
async def to_response(self, data: Any, request: Request) -> ASGIApp:
"""Return a :class:`Response <.response.Response>` from the handler by resolving and calling it.
Args:
app: The :class:`Litestar <litestar.app.Litestar>` app instance
data: Either an instance of a :class:`Response <.response.Response>`,
a Response instance or an arbitrary value.
request: A :class:`Request <.connection.Request>` instance
Expand All @@ -554,7 +553,7 @@ async def to_response(self, app: Litestar, data: Any, request: Request) -> ASGIA
data = return_dto_type(request).data_to_encodable_type(data)

response_handler = self.get_response_handler(is_response_type_data=isinstance(data, Response))
return await response_handler(app=app, data=data, request=request) # type: ignore[call-arg]
return await response_handler(data=data, request=request)

def on_registration(self, app: Litestar) -> None:
super().on_registration(app)
Expand Down
12 changes: 0 additions & 12 deletions litestar/response/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
if TYPE_CHECKING:
from typing import Optional

from litestar.app import Litestar
from litestar.background_tasks import BackgroundTask, BackgroundTasks
from litestar.connection import Request
from litestar.types import (
Expand Down Expand Up @@ -397,7 +396,6 @@ def render(self, content: Any, media_type: str, enc_hook: Serializer = default_s

def to_asgi_response(
self,
app: Litestar | None,
request: Request,
*,
background: BackgroundTask | BackgroundTasks | None = None,
Expand All @@ -412,7 +410,6 @@ def to_asgi_response(
"""Create an ASGIResponse from a Response instance.
Args:
app: The :class:`Litestar <.app.Litestar>` application instance.
background: Background task(s) to be executed after the response is sent.
cookies: A list of cookies to be set on the response.
encoded_headers: A list of already encoded headers.
Expand All @@ -427,15 +424,6 @@ def to_asgi_response(
An ASGIResponse instance.
"""

if app is not None:
warn_deprecation(
version="2.1",
deprecated_name="app",
kind="parameter",
removal_in="3.0.0",
alternative="request.app",
)

headers = {**headers, **self.headers} if headers is not None else self.headers
cookies = self.cookies if cookies is None else itertools.chain(self.cookies, cookies)

Expand Down
11 changes: 0 additions & 11 deletions litestar/response/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
from litestar.file_system import BaseLocalFileSystem, FileSystemAdapter
from litestar.response.base import Response
from litestar.response.streaming import ASGIStreamingResponse
from litestar.utils.deprecation import warn_deprecation
from litestar.utils.helpers import get_enum_string_value

if TYPE_CHECKING:
Expand All @@ -22,7 +21,6 @@

from anyio import Path

from litestar.app import Litestar
from litestar.background_tasks import BackgroundTask, BackgroundTasks
from litestar.connection import Request
from litestar.datastructures.cookie import Cookie
Expand Down Expand Up @@ -319,7 +317,6 @@ def __init__(

def to_asgi_response(
self,
app: Litestar | None,
request: Request,
*,
background: BackgroundTask | BackgroundTasks | None = None,
Expand Down Expand Up @@ -348,14 +345,6 @@ def to_asgi_response(
Returns:
A low-level ASGI file response.
"""
if app is not None:
warn_deprecation(
version="2.1",
deprecated_name="app",
kind="parameter",
removal_in="3.0.0",
alternative="request.app",
)

headers = {**headers, **self.headers} if headers is not None else self.headers
cookies = self.cookies if cookies is None else itertools.chain(self.cookies, cookies)
Expand Down
12 changes: 0 additions & 12 deletions litestar/response/redirect.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,9 @@
from litestar.response.base import ASGIResponse, Response
from litestar.status_codes import HTTP_302_FOUND
from litestar.utils import url_quote
from litestar.utils.deprecation import warn_deprecation
from litestar.utils.helpers import get_enum_string_value

if TYPE_CHECKING:
from litestar.app import Litestar
from litestar.background_tasks import BackgroundTask, BackgroundTasks
from litestar.connection import Request
from litestar.datastructures import Cookie
Expand Down Expand Up @@ -129,7 +127,6 @@ def __init__(

def to_asgi_response(
self,
app: Litestar | None,
request: Request,
*,
background: BackgroundTask | BackgroundTasks | None = None,
Expand All @@ -145,15 +142,6 @@ def to_asgi_response(
cookies = self.cookies if cookies is None else itertools.chain(self.cookies, cookies)
media_type = get_enum_string_value(self.media_type or media_type or MediaType.TEXT)

if app is not None:
warn_deprecation(
version="2.1",
deprecated_name="app",
kind="parameter",
removal_in="3.0.0",
alternative="request.app",
)

return ASGIRedirectResponse(
path=self.url,
background=self.background or background,
Expand Down
12 changes: 0 additions & 12 deletions litestar/response/streaming.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,10 @@
from litestar.enums import MediaType
from litestar.response.base import ASGIResponse, Response
from litestar.types.helper_types import StreamType
from litestar.utils.deprecation import warn_deprecation
from litestar.utils.helpers import get_enum_string_value
from litestar.utils.sync import AsyncIteratorWrapper

if TYPE_CHECKING:
from litestar.app import Litestar
from litestar.background_tasks import BackgroundTask, BackgroundTasks
from litestar.connection import Request
from litestar.datastructures.cookie import Cookie
Expand Down Expand Up @@ -177,7 +175,6 @@ def __init__(

def to_asgi_response(
self,
app: Litestar | None,
request: Request,
*,
background: BackgroundTask | BackgroundTasks | None = None,
Expand All @@ -192,7 +189,6 @@ def to_asgi_response(
"""Create an ASGIStreamingResponse from a StremaingResponse instance.
Args:
app: The :class:`Litestar <.app.Litestar>` application instance.
background: Background task(s) to be executed after the response is sent.
cookies: A list of cookies to be set on the response.
encoded_headers: A list of already encoded headers.
Expand All @@ -206,14 +202,6 @@ def to_asgi_response(
Returns:
An ASGIStreamingResponse instance.
"""
if app is not None:
warn_deprecation(
version="2.1",
deprecated_name="app",
kind="parameter",
removal_in="3.0.0",
alternative="request.app",
)

headers = {**headers, **self.headers} if headers is not None else self.headers
cookies = self.cookies if cookies is None else itertools.chain(self.cookies, cookies)
Expand Down
12 changes: 0 additions & 12 deletions litestar/response/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,10 @@
from litestar.exceptions import ImproperlyConfiguredException
from litestar.response.base import ASGIResponse, Response
from litestar.status_codes import HTTP_200_OK
from litestar.utils.deprecation import warn_deprecation
from litestar.utils.empty import value_or_default
from litestar.utils.scope.state import ScopeState

if TYPE_CHECKING:
from litestar.app import Litestar
from litestar.background_tasks import BackgroundTask, BackgroundTasks
from litestar.connection import Request
from litestar.datastructures import Cookie
Expand Down Expand Up @@ -99,7 +97,6 @@ def create_template_context(self, request: Request) -> dict[str, Any]:

def to_asgi_response(
self,
app: Litestar | None,
request: Request,
*,
background: BackgroundTask | BackgroundTasks | None = None,
Expand All @@ -111,15 +108,6 @@ def to_asgi_response(
status_code: int | None = None,
type_encoders: TypeEncodersMap | None = None,
) -> ASGIResponse:
if app is not None:
warn_deprecation(
version="2.1",
deprecated_name="app",
kind="parameter",
removal_in="3.0.0",
alternative="request.app",
)

if not (template_engine := request.app.template_engine):
raise ImproperlyConfiguredException("Template engine is not configured")

Expand Down
2 changes: 1 addition & 1 deletion litestar/routes/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ async def _call_handler_function(
route_handler=route_handler, parameter_model=parameter_model, request=request
)

response: ASGIApp = await route_handler.to_response(app=scope["app"], data=response_data, request=request)
response: ASGIApp = await route_handler.to_response(data=response_data, request=request)

if cleanup_group:
await cleanup_group.cleanup()
Expand Down
37 changes: 10 additions & 27 deletions tests/unit/test_response/test_response_to_asgi_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,7 @@ async def handler(data: DataclassPerson) -> DataclassPerson:

response = await handler.to_response(
data=handler.fn(data=person_instance),
app=Litestar(route_handlers=[handler]),
request=RequestFactory().get(route_handler=handler),
request=RequestFactory(app=Litestar(route_handlers=[handler])).get(route_handler=handler),
)
assert loads(response.body) == msgspec.to_builtins(person_instance) # type: ignore[attr-defined]

Expand All @@ -103,9 +102,7 @@ def handler() -> Response:
with create_test_client(handler) as client:
http_route: HTTPRoute = client.app.routes[0]
route_handler = http_route.route_handlers[0]
response = await route_handler.to_response(
data=route_handler.fn(), app=client.app, request=RequestFactory().get()
)
response = await route_handler.to_response(data=route_handler.fn(), request=RequestFactory().get())
assert isinstance(response, ASGIResponse)


Expand All @@ -128,9 +125,7 @@ def handler() -> StarletteResponse:
with create_test_client(handler) as client:
http_route: HTTPRoute = client.app.routes[0]
route_handler = http_route.route_handlers[0]
response = await route_handler.to_response(
data=route_handler.fn(), app=client.app, request=RequestFactory().get()
)
response = await route_handler.to_response(data=route_handler.fn(), request=RequestFactory().get())
assert isinstance(response, StarletteResponse)
assert response is expected_response # type: ignore[unreachable]

Expand All @@ -155,9 +150,7 @@ def handler() -> Redirect:
with create_test_client(handler) as client:
route: HTTPRoute = client.app.routes[0]
route_handler = route.route_handlers[0]
response = await route_handler.to_response(
data=route_handler.fn(), app=client.app, request=RequestFactory().get()
)
response = await route_handler.to_response(data=route_handler.fn(), request=RequestFactory().get())
encoded_headers = response.encode_headers() # type: ignore[attr-defined]

assert isinstance(response, ASGIResponse)
Expand Down Expand Up @@ -209,9 +202,7 @@ def handler() -> File:
with create_test_client(handler) as client:
route: HTTPRoute = client.app.routes[0]
route_handler = route.route_handlers[0]
response = await route_handler.to_response(
data=route_handler.fn(), app=client.app, request=RequestFactory().get()
)
response = await route_handler.to_response(data=route_handler.fn(), request=RequestFactory().get())
assert isinstance(response, ASGIFileResponse)
assert response.file_info
if iscoroutine(response.file_info):
Expand Down Expand Up @@ -267,11 +258,9 @@ def handler() -> Stream:
route_handler = route.route_handlers[0]
if should_raise:
with pytest.raises(TypeError):
await route_handler.to_response(data=route_handler.fn(), app=client.app, request=RequestFactory().get())
await route_handler.to_response(data=route_handler.fn(), request=RequestFactory().get())
else:
response = await route_handler.to_response(
data=route_handler.fn(), app=client.app, request=RequestFactory().get()
)
response = await route_handler.to_response(data=route_handler.fn(), request=RequestFactory().get())
assert isinstance(response, ASGIStreamingResponse)
encoded_headers = response.encode_headers()
assert (b"local-header", b"123") in encoded_headers
Expand Down Expand Up @@ -315,9 +304,7 @@ def handler() -> Template:
) as client:
route: HTTPRoute = client.app.routes[0]
route_handler = route.route_handlers[0]
response = await route_handler.to_response(
data=route_handler.fn(), app=client.app, request=RequestFactory(app=app).get()
)
response = await route_handler.to_response(data=route_handler.fn(), request=RequestFactory(app=app).get())
assert isinstance(response, ASGIResponse)
encoded_headers = response.encode_headers()

Expand Down Expand Up @@ -366,9 +353,7 @@ def handler() -> ServerSentEvent:
with create_test_client(handler) as client:
route: HTTPRoute = client.app.routes[0]
route_handler = route.route_handlers[0]
response = await route_handler.to_response(
data=route_handler.fn(), app=client.app, request=RequestFactory().get()
)
response = await route_handler.to_response(data=route_handler.fn(), request=RequestFactory().get())
encoded_headers = response.encode_headers() # type: ignore[attr-defined]

assert isinstance(response, ASGIStreamingResponse)
Expand Down Expand Up @@ -411,9 +396,7 @@ def handler() -> ServerSentEvent:
with create_test_client(handler) as client:
route: HTTPRoute = client.app.routes[0]
route_handler = route.route_handlers[0]
response = await route_handler.to_response(
data=route_handler.fn(), app=client.app, request=RequestFactory().get()
)
response = await route_handler.to_response(data=route_handler.fn(), request=RequestFactory().get())
assert isinstance(response, ASGIStreamingResponse)
async for value in response.iterator:
events.append(cast("bytes", value))
Expand Down

0 comments on commit 4d95e8c

Please sign in to comment.