-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added support for the Litestar framework (#48)
- Loading branch information
Showing
12 changed files
with
446 additions
and
4 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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
:mod:`asphalt.web.litestar` | ||
=========================== | ||
|
||
.. automodule:: asphalt.web.litestar | ||
:members: |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
.. highlight:: bash | ||
|
||
To install the prerequisites for this example:: | ||
|
||
pip install asphalt-web[litestar] | ||
|
||
To start the ``static`` example:: | ||
|
||
PYTHONPATH=. asphalt run config.yaml --service static | ||
|
||
To start the ``dynamic`` example:: | ||
|
||
PYTHONPATH=. asphalt run config.yaml --service dynamic | ||
|
||
Then, navigate to http://localhost:8000 in your browser. |
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,12 @@ | ||
services: | ||
static: | ||
component: | ||
type: litestar | ||
route_handlers: ["static:root"] | ||
|
||
dynamic: | ||
component: | ||
type: litestar | ||
components: | ||
myroot: | ||
type: dynamic:WebRootComponent |
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,12 @@ | ||
from asphalt.core import Component, Context, require_resource | ||
from litestar import Litestar, get | ||
|
||
|
||
@get("/") | ||
async def root() -> str: | ||
return "Hello, world!" | ||
|
||
|
||
class WebRootComponent(Component): | ||
async def start(self, ctx: Context) -> None: | ||
require_resource(Litestar).register(root) |
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,6 @@ | ||
from litestar import get | ||
|
||
|
||
@get("/") | ||
async def root() -> str: | ||
return "Hello, world!" |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
from __future__ import annotations | ||
|
||
from collections.abc import Callable, Sequence | ||
from dataclasses import dataclass | ||
from typing import Any | ||
|
||
from asgiref.typing import ASGI3Application, HTTPScope, WebSocketScope | ||
from asphalt.core import Context, require_resource, resolve_reference | ||
from litestar import Litestar, Request | ||
from litestar.middleware import AbstractMiddleware | ||
from litestar.types import ControllerRouterHandler, Receive, Scope, Send | ||
|
||
from asphalt.web.asgi3 import ASGIComponent | ||
|
||
|
||
@dataclass(frozen=True) | ||
class AsphaltProvide: | ||
""" | ||
Asphalt's version of Litestar's :func:`~litestar.di.Provide`. | ||
This should be marked as the default value on a parameter that should receive an | ||
Asphalt resource. | ||
:param cls: the type of the resource | ||
:param name: the name of the resource within its unique type | ||
""" | ||
|
||
cls: type | ||
name: str = "default" | ||
|
||
async def __call__(self) -> Any: | ||
return require_resource(self.cls, self.name) | ||
|
||
|
||
class AsphaltMiddleware(AbstractMiddleware): | ||
async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: | ||
async with Context() as ctx: | ||
if scope["type"] == "http": | ||
ctx.add_resource(scope, types=[HTTPScope]) | ||
ctx.add_resource(Request(scope)) | ||
elif scope["type"] == "websocket": | ||
ctx.add_resource(scope, types=[WebSocketScope]) | ||
ctx.add_resource(Request(scope)) | ||
|
||
await self.app(scope, receive, send) | ||
|
||
|
||
class LitestarComponent(ASGIComponent[Litestar]): | ||
""" | ||
A component that serves a Litestar application. | ||
:param host: the IP address to bind to | ||
:param port: the port to bind to | ||
:param route_handlers: list of callables or module:varname references that point | ||
to the routers / controolers / handlers that should be attached to the | ||
application | ||
:param middlewares: list of callables or dicts to be added as middleware using | ||
:meth:`add_middleware` | ||
.. note:: | ||
The following options are preset here: | ||
* ``debug``: set to the value of | ||
`__debug__ <https://docs.python.org/3/library/constants.html#debug__>`_; | ||
unless overridden | ||
* ``logging_config``: always set to ``None``, as Asphalt handles logging | ||
configuration | ||
If you supply the a pre-made application object that has route handlers already | ||
in it, know that any middleware added to it during the initialization of | ||
:class:`LitestarComponent` will **NOT** apply to the route handlers previously | ||
added to the application | ||
""" | ||
|
||
def __init__( | ||
self, | ||
components: dict[str, dict[str, Any] | None] | None = None, | ||
*, | ||
host: str = "127.0.0.1", | ||
port: int = 8000, | ||
route_handlers: Sequence[ControllerRouterHandler | str] = (), | ||
middlewares: Sequence[Callable[..., ASGI3Application] | dict[str, Any]] = (), | ||
config: dict[str, Any] | None = None, | ||
) -> None: | ||
config_ = config or {} | ||
config_.setdefault("debug", __debug__) | ||
config_["logging_config"] = None | ||
app = Litestar(**config_) | ||
super().__init__( | ||
components, app=app, middlewares=middlewares, host=host, port=port | ||
) | ||
|
||
for item in route_handlers: | ||
if isinstance(item, str): | ||
handler = resolve_reference(item) | ||
else: | ||
handler = item | ||
|
||
self.original_app.register(handler) | ||
|
||
def setup_asphalt_middleware(self, app: Litestar) -> ASGI3Application: | ||
return AsphaltMiddleware(app=app) |
Oops, something went wrong.