Skip to content

Commit

Permalink
feat: allow route_reverse params of type uuid to be passed as str (#3972
Browse files Browse the repository at this point in the history
)
  • Loading branch information
aedify-swi authored Jan 25, 2025
1 parent 1764dd7 commit e5340cf
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 3 deletions.
7 changes: 5 additions & 2 deletions litestar/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from itertools import chain
from pathlib import Path
from typing import TYPE_CHECKING, Any, AsyncGenerator, Callable, Iterable, Mapping, Sequence, TypedDict, cast
from uuid import UUID

from litestar._asgi import ASGIRouter
from litestar._asgi.utils import get_route_handlers, wrap_in_exception_handler
Expand Down Expand Up @@ -768,7 +769,9 @@ def get_membership_details(group_id: int, user_id: int) -> None:
Args:
name: A route handler unique name.
**path_parameters: Actual values for path parameters in the route.
**path_parameters: Actual values for path parameters in the route. Parameters of type
`datetime`, `date`, `time`, `timedelta`, `float`, `Path`, `UUID`
may be passed in their string representations.
Raises:
NoRouteMatchFoundException: If route with 'name' does not exist, path parameters are missing in
Expand All @@ -781,7 +784,7 @@ def get_membership_details(group_id: int, user_id: int) -> None:
if handler_index is None:
raise NoRouteMatchFoundException(f"Route {name} can not be found")

allow_str_instead = {datetime, date, time, timedelta, float, Path}
allow_str_instead = {datetime, date, time, timedelta, float, Path, UUID}
routes = sorted(
self.asgi_router.route_mapping[handler_index["identifier"]],
key=lambda r: len(r.path_parameters),
Expand Down
42 changes: 41 additions & 1 deletion tests/e2e/test_routing/test_route_reverse.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from datetime import time
from datetime import date, datetime, time, timedelta
from pathlib import Path
from typing import Type
from uuid import UUID

import pytest

Expand Down Expand Up @@ -102,3 +104,41 @@ def handler_two() -> None:

with pytest.raises(NoRouteMatchFoundException):
app.route_reverse("another-handler-name", param=1)


def test_route_reverse_allow_string_params() -> None:
@get(
"/strings-everywhere/{datetime_param:datetime}/{date_param:date}/"
"{time_param:time}/{timedelta_param:timedelta}/"
"{float_param:float}/{uuid_param:uuid}/{path_param:path}",
name="strings-everywhere-handler",
)
def strings_everywhere_handler(
datetime_param: datetime,
date_param: date,
time_param: time,
timedelta_param: timedelta,
float_param: float,
uuid_param: UUID,
path_param: Path,
) -> None:
return None

app = Litestar(route_handlers=[strings_everywhere_handler])

reversed_url_path = app.route_reverse(
"strings-everywhere-handler",
datetime_param="0001-01-01T01:01:01.000001Z", # datetime(1, 1, 1, 1, 1, 1, 1, tzinfo=UTC)
date_param="0001-01-01", # date(1,1,1)
time_param="01:01:01.000001Z", # time(1, 1, 1, 1, tzinfo=UTC)
timedelta_param="P8DT3661.001001S", # timedelta(1, 1, 1, 1, 1, 1, 1)
float_param="0.1",
uuid_param="00000000-0000-0000-0000-000000000000", # UUID(int=0)
path_param="/home/user", # Path("/home/user/"),
)

assert (
reversed_url_path == "/strings-everywhere/0001-01-01T01:01:01.000001Z/"
"0001-01-01/01:01:01.000001Z/P8DT3661.001001S/0.1/"
"00000000-0000-0000-0000-000000000000/home/user"
)

0 comments on commit e5340cf

Please sign in to comment.