Skip to content

Commit

Permalink
Add name to handlers for lookup
Browse files Browse the repository at this point in the history
  • Loading branch information
tarsil committed Jan 19, 2025
1 parent 2dadbd6 commit edae183
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 14 deletions.
3 changes: 2 additions & 1 deletion esmerald/openapi/openapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,8 @@ def get_openapi_operation(
if route.handler.summary:
operation.summary = route.handler.summary
else:
operation.summary = route.handler.name.replace("_", " ").replace("-", " ").title()
name = route.handler.name or route.name
operation.summary = name.replace("_", " ").replace("-", " ").title()

# Handle the handler description
if route.handler.description:
Expand Down
15 changes: 8 additions & 7 deletions esmerald/routing/gateways.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ def handle_middleware(


class GatewayUtil:

def is_class_based(
self, handler: Union["HTTPHandler", "WebSocketHandler", "ParentType"]
) -> bool:
Expand Down Expand Up @@ -286,7 +285,8 @@ def __init__(

if not name:
if not isinstance(handler, View):
name = clean_string(handler.fn.__name__)
if not handler.name:
name = clean_string(handler.fn.__name__)
else:
name = clean_string(handler.__class__.__name__)

Expand Down Expand Up @@ -328,17 +328,17 @@ def __init__(
self.operation_id = operation_id

if self.is_handler(self.handler): # type: ignore
self.handler.name = self.name

if self.operation_id or handler.operation_id is not None:
handler_id = self.generate_operation_id(
name=self.name, handler=self.handler # type: ignore
name=self.name,
handler=self.handler, # type: ignore
)
self.operation_id = f"{operation_id}_{handler_id}" if operation_id else handler_id

elif not handler.operation_id:
handler.operation_id = self.generate_operation_id(
name=self.name, handler=self.handler # type: ignore
name=self.name,
handler=self.handler, # type: ignore
)

async def handle_dispatch(self, scope: "Scope", receive: "Receive", send: "Send") -> None:
Expand Down Expand Up @@ -691,5 +691,6 @@ def __init__(

if not handler.operation_id:
handler.operation_id = self.generate_operation_id(
name=self.name, handler=self.handler # type: ignore
name=self.name,
handler=self.handler, # type: ignore
)
90 changes: 90 additions & 0 deletions esmerald/routing/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ def get(
),
] = None,
*,
name: Annotated[
Optional[str],
Doc(
"""
The name for the Gateway. The name can be reversed by `path_for()`.
"""
),
] = None,
summary: Annotated[
Optional[str],
Doc(
Expand Down Expand Up @@ -397,6 +405,7 @@ async def get() -> str:
def wrapper(func: Any) -> HTTPHandler:
handler = HTTPHandler(
path=path,
name=name,
methods=[HttpMethod.GET],
summary=summary,
description=description,
Expand Down Expand Up @@ -441,6 +450,14 @@ def head(
),
] = None,
*,
name: Annotated[
Optional[str],
Doc(
"""
The name for the Gateway. The name can be reversed by `path_for()`.
"""
),
] = None,
summary: Annotated[
Optional[str],
Doc(
Expand Down Expand Up @@ -666,6 +683,7 @@ def head(
def wrapper(func: Any) -> HTTPHandler:
handler = HTTPHandler(
path=path,
name=name,
methods=[HttpMethod.HEAD],
summary=summary,
description=description,
Expand Down Expand Up @@ -722,6 +740,14 @@ def post(
),
] = None,
*,
name: Annotated[
Optional[str],
Doc(
"""
The name for the Gateway. The name can be reversed by `path_for()`.
"""
),
] = None,
summary: Annotated[
Optional[str],
Doc(
Expand Down Expand Up @@ -1074,6 +1100,7 @@ async def create() -> None:
def wrapper(func: Any) -> HTTPHandler:
handler = HTTPHandler(
path=path,
name=name,
status_code=status_code,
content_encoding=content_encoding,
content_media_type=content_media_type,
Expand Down Expand Up @@ -1130,6 +1157,14 @@ def put(
),
] = None,
*,
name: Annotated[
Optional[str],
Doc(
"""
The name for the Gateway. The name can be reversed by `path_for()`.
"""
),
] = None,
summary: Annotated[
Optional[str],
Doc(
Expand Down Expand Up @@ -1477,6 +1512,7 @@ async def update() -> str:
def wrapper(func: Any) -> HTTPHandler:
handler = HTTPHandler(
path=path,
name=name,
methods=[HttpMethod.PUT],
summary=summary,
description=description,
Expand Down Expand Up @@ -1533,6 +1569,14 @@ def patch(
),
] = None,
*,
name: Annotated[
Optional[str],
Doc(
"""
The name for the Gateway. The name can be reversed by `path_for()`.
"""
),
] = None,
summary: Annotated[
Optional[str],
Doc(
Expand Down Expand Up @@ -1880,6 +1924,7 @@ async def update_partial() -> str:
def wrapper(func: Any) -> HTTPHandler:
handler = HTTPHandler(
path=path,
name=name,
methods=[HttpMethod.PATCH],
summary=summary,
description=description,
Expand Down Expand Up @@ -1936,6 +1981,14 @@ def delete(
),
] = None,
*,
name: Annotated[
Optional[str],
Doc(
"""
The name for the Gateway. The name can be reversed by `path_for()`.
"""
),
] = None,
summary: Annotated[
Optional[str],
Doc(
Expand Down Expand Up @@ -2283,6 +2336,7 @@ async def remove() -> None:
def wrapper(func: Any) -> HTTPHandler:
handler = HTTPHandler(
path=path,
name=name,
methods=[HttpMethod.DELETE],
summary=summary,
description=description,
Expand Down Expand Up @@ -2327,6 +2381,14 @@ def options(
),
] = None,
*,
name: Annotated[
Optional[str],
Doc(
"""
The name for the Gateway. The name can be reversed by `path_for()`.
"""
),
] = None,
summary: Annotated[
Optional[str],
Doc(
Expand Down Expand Up @@ -2552,6 +2614,7 @@ def options(
def wrapper(func: Any) -> HTTPHandler:
handler = HTTPHandler(
path=path,
name=name,
methods=[HttpMethod.OPTIONS],
summary=summary,
description=description,
Expand Down Expand Up @@ -2596,6 +2659,14 @@ def trace(
),
] = None,
*,
name: Annotated[
Optional[str],
Doc(
"""
The name for the Gateway. The name can be reversed by `path_for()`.
"""
),
] = None,
summary: Annotated[
Optional[str],
Doc(
Expand Down Expand Up @@ -2822,6 +2893,7 @@ def trace(
def wrapper(func: Any) -> HTTPHandler:
handler = HTTPHandler(
path=path,
name=name,
methods=[HttpMethod.TRACE],
summary=summary,
description=description,
Expand Down Expand Up @@ -2878,6 +2950,14 @@ def route(
),
] = None,
*,
name: Annotated[
Optional[str],
Doc(
"""
The name for the Gateway. The name can be reversed by `path_for()`.
"""
),
] = None,
methods: Annotated[
List[str],
Doc(
Expand Down Expand Up @@ -3259,6 +3339,7 @@ async def operate() -> str:
def wrapper(func: Any) -> HTTPHandler:
handler = HTTPHandler(
path=path,
name=name,
methods=methods,
summary=summary,
description=description,
Expand Down Expand Up @@ -3316,6 +3397,14 @@ def websocket(
),
] = None,
*,
name: Annotated[
Optional[str],
Doc(
"""
The name for the Gateway. The name can be reversed by `path_for()`.
"""
),
] = None,
dependencies: Annotated[
Optional["Dependencies"],
Doc(
Expand Down Expand Up @@ -3356,6 +3445,7 @@ def wrapper(func: Any) -> WebSocketHandler:
exception_handlers=exception_handlers,
permissions=permissions,
middleware=middleware,
name=name,
)
handler.fn = func
handler.handler = func
Expand Down
26 changes: 20 additions & 6 deletions esmerald/routing/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -481,9 +481,9 @@ async def another(request: Request) -> str:
path = "/"
else:
assert path.startswith("/"), "A path prefix must start with '/'"
assert not path.endswith("/"), (
"A path must not end with '/', as the routes will start with '/'"
)
assert not path.endswith(
"/"
), "A path must not end with '/', as the routes will start with '/'"

new_routes: list[Any] = []
for route in routes or []:
Expand Down Expand Up @@ -511,9 +511,9 @@ async def another(request: Request) -> str:
)
new_routes.append(route)

assert lifespan is None or (on_startup is None and on_shutdown is None), (
"Use either 'lifespan' or 'on_startup'/'on_shutdown', not both."
)
assert lifespan is None or (
on_startup is None and on_shutdown is None
), "Use either 'lifespan' or 'on_startup'/'on_shutdown', not both."

super().__init__(
redirect_slashes=redirect_slashes,
Expand Down Expand Up @@ -1929,6 +1929,7 @@ class HTTPHandler(Dispatcher, OpenAPIFieldInfoMixin, LilyaPath):
"_dependencies",
"_response_handler",
"_middleware",
"name",
"methods",
"status_code",
"content_encoding",
Expand Down Expand Up @@ -1958,6 +1959,7 @@ def __init__(
path: Optional[str] = None,
handler: Callable[..., Any] = None,
*,
name: Optional[str] = None,
methods: Optional[Sequence[str]] = None,
status_code: Optional[int] = None,
content_encoding: Optional[str] = None,
Expand Down Expand Up @@ -1991,6 +1993,7 @@ def __init__(
handler=handler,
include_in_schema=include_in_schema,
exception_handlers=exception_handlers,
name=name,
)

self._permissions: Union[List[Permission], VoidType] = Void
Expand All @@ -2002,6 +2005,7 @@ def __init__(
self.path = path
self.handler = handler
self.summary = summary
self.name = name
self.tags = tags or []
self.include_in_schema = include_in_schema
self.deprecated = deprecated
Expand Down Expand Up @@ -2379,6 +2383,7 @@ class WebSocketHandler(Dispatcher, LilyaWebSocketPath):
"permissions",
"middleware",
"parent",
"name",
"__type__",
)

Expand All @@ -2391,6 +2396,14 @@ def __init__(
exception_handlers: Optional[ExceptionHandlerMap] = None,
permissions: Optional[List[Permission]] = None,
middleware: Optional[List[Middleware]] = None,
name: Annotated[
Optional[str],
Doc(
"""
The name for the Gateway. The name can be reversed by `path_for()`.
"""
),
] = None,
):
if not path:
path = "/"
Expand All @@ -2411,6 +2424,7 @@ def __init__(
self.fn: Optional[AnyCallable] = None
self.tags: Sequence[str] = []
self.__type__: Union[str, None] = None
self.name = name

def validate_reserved_words(self, signature: Signature) -> None:
"""
Expand Down

0 comments on commit edae183

Please sign in to comment.