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

feat: make 302 the default status_code for redirect responses #2189

Merged
merged 15 commits into from
Sep 7, 2023
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
6 changes: 3 additions & 3 deletions docs/usage/responses.rst
Original file line number Diff line number Diff line change
Expand Up @@ -575,12 +575,12 @@ In Litestar, a redirect response looks like this:

.. code-block:: python

from litestar.status_codes import HTTP_307_TEMPORARY_REDIRECT
from litestar.status_codes import HTTP_302_FOUND
from litestar import get
from litestar.response import Redirect


@get(path="/some-path", status_code=HTTP_307_TEMPORARY_REDIRECT)
@get(path="/some-path", status_code=HTTP_302_FOUND)
def redirect() -> Redirect:
# do some stuff here
# ...
Expand All @@ -589,7 +589,7 @@ In Litestar, a redirect response looks like this:

To return a redirect response you should do the following:

- set an appropriate status code for the route handler (301, 302, 303, 307, 308)
- optionally: set an appropriate status code for the route handler (301, 302, 303, 307, 308). If not set the default of 302 will be used.
- annotate the return value of the route handler as returning :class:`Redirect <.response.Redirect>`
- return an instance of the :class:`Redirect <.response.Redirect>` class with the desired redirect path

Expand Down
6 changes: 4 additions & 2 deletions litestar/response/redirect.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from litestar.enums import MediaType
from litestar.exceptions import ImproperlyConfiguredException
from litestar.response.base import ASGIResponse, Response
from litestar.status_codes import HTTP_307_TEMPORARY_REDIRECT
from litestar.status_codes import HTTP_302_FOUND
from litestar.utils import url_quote
from litestar.utils.helpers import filter_cookies, get_enum_string_value

Expand Down Expand Up @@ -40,7 +40,7 @@ def __init__(
) -> None:
headers = {**(headers or {}), "location": url_quote(path)}
media_type = media_type or MediaType.TEXT
status_code = status_code or HTTP_307_TEMPORARY_REDIRECT
status_code = status_code or HTTP_302_FOUND

if status_code not in REDIRECT_STATUS_CODES:
raise ImproperlyConfiguredException(
Expand Down Expand Up @@ -95,6 +95,8 @@ def __init__(
supported.
"""
self.url = path
if status_code is None:
status_code = HTTP_302_FOUND
super().__init__(
background=background,
content=b"",
Expand Down
17 changes: 17 additions & 0 deletions tests/unit/test_openapi/test_responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,23 @@ def handler() -> Stream:


def test_create_success_response_redirect() -> None:
@get(path="/test", name="test")
def redirect_handler() -> Redirect:
return Redirect(path="/target")

handler = get_registered_route_handler(redirect_handler, "test")

response = create_success_response(handler, SchemaCreator(generate_examples=True))
assert response.description == "Redirect Response"
assert response.headers
location = response.headers["location"]
assert isinstance(location, OpenAPIHeader)
assert isinstance(location.schema, Schema)
assert location.schema.type == OpenAPIType.STRING
assert location.description


def test_create_success_response_redirect_override() -> None:
@get(path="/test", status_code=HTTP_307_TEMPORARY_REDIRECT, name="test")
def redirect_handler() -> Redirect:
return Redirect(path="/target")
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/test_response/test_redirect_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ def handler() -> Redirect:
def test_redirect(handler_status_code: Optional[int]) -> None:
@get("/", status_code=handler_status_code)
def handler() -> Redirect:
return Redirect(path="/something-else", status_code=301)
return Redirect(path="/something-else", status_code=handler_status_code) # type: ignore[arg-type]

with create_test_client([handler]) as client:
res = client.get("/", follow_redirects=False)
assert res.status_code == 301
assert res.status_code == 302 if handler_status_code is None else handler_status_code