-
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
152 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
from typing import Any, Iterator | ||
|
||
|
||
class BaseWrapper: | ||
""" | ||
Builds a wrapper middleware for all the classes. | ||
""" | ||
|
||
def __init__(self, cls_obj: type, **kwargs: Any) -> None: | ||
self.cls_obj = cls_obj | ||
self.kwargs = kwargs | ||
|
||
def __iter__(self) -> Iterator[Any]: | ||
return iter((self.cls_obj, self.kwargs)) | ||
|
||
def __repr__(self) -> str: | ||
class_name = self.__class__.__name__ | ||
option_strings = [f"{key}={value!r}" for key, value in self.kwargs.items()] | ||
args_repr = ", ".join([self.cls_obj.__name__] + option_strings) | ||
return f"{class_name}({args_repr})" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
from lilya._internal.iterables import BaseWrapper | ||
|
||
|
||
class Permission(BaseWrapper): | ||
""" | ||
Builds a wrapper permission for all the classes. | ||
""" | ||
|
||
... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
from __future__ import annotations | ||
|
||
import inspect | ||
from typing import Any, Callable, List, Sequence, Set, Tuple, Union | ||
|
||
from lilya.datastructures import URLPath | ||
from lilya.enums import HTTPMethod, Match | ||
from lilya.middleware.base import Middleware | ||
from lilya.permissions.base import Permission | ||
from lilya.types import Receive, Scope, Send | ||
|
||
|
||
def get_name(handler: Callable[..., Any]) -> str: | ||
""" | ||
Returns the name of a given handler. | ||
""" | ||
return ( | ||
handler.__name__ | ||
if inspect.isroutine(handler) or inspect.isclass(handler) | ||
else handler.__class__.__name__ | ||
) | ||
|
||
|
||
class BasePath: | ||
""" | ||
The base of all paths (routes) for any ASGI application | ||
with Lilya. | ||
""" | ||
|
||
def search(self, scope: Scope) -> Tuple[Match, Scope]: | ||
""" | ||
Searches for a matching route. | ||
""" | ||
raise NotImplementedError() # pragma: no cover | ||
|
||
def path_for(self, name: str, /, **path_params: Any) -> URLPath: | ||
""" | ||
Returns a URL of a matching route. | ||
""" | ||
raise NotImplementedError() # pragma: no cover | ||
|
||
async def dispatch(self, scope: Scope, receive: Receive, send: Send) -> None: | ||
""" | ||
Handles the matched ASGI route. | ||
""" | ||
raise NotImplementedError() # pragma: no cover | ||
|
||
|
||
class Path(BasePath): | ||
""" | ||
The way you can define a route in Lilya and apply the corresponding | ||
path definition. | ||
## Example | ||
```python | ||
from lilya.routing import Path | ||
Path('/home', callable=..., name="home") | ||
``` | ||
""" | ||
|
||
def __init__( | ||
self, | ||
path: str, | ||
handler: Callable[..., Any], | ||
*, | ||
methods: Union[List[str], None] = None, | ||
name: Union[str, None] = None, | ||
include_in_schema: bool = True, | ||
middleware: Union[Sequence[Middleware], None] = None, | ||
permissions: Union[Sequence[Permission], None] = None, | ||
) -> None: | ||
assert path.startswith("/"), "Paths must start with '/'" | ||
self.path = path | ||
self.handler = handler | ||
self.name = get_name(handler) if name is None else name | ||
self.include_in_schema = include_in_schema | ||
self.methods: Union[List[str], Set[str], None] = methods | ||
|
||
# Defition of the app | ||
self.app = handler | ||
|
||
# Execute the middlewares | ||
if middleware is not None: | ||
for cls, options in reversed(middleware): | ||
self.app = cls(app=self.app, **options) | ||
|
||
# Execute the permissions | ||
if permissions is not None: | ||
for cls, options in reversed(permissions): | ||
self.app = cls(app=self.app, **options) | ||
|
||
if self.methods is not None: | ||
self.methods = {method.upper() for method in methods} | ||
if HTTPMethod.GET in self.methods: | ||
self.methods.add(HTTPMethod.HEAD) |