应用程序¶
应用对象¶
每个 Litestar 应用程序的核心是 Litestar 类的实例。通常,这段代码会放在项目根目录下名为 main.py、app.py、asgi.py 或类似的文件中。
这些入口点也会在 CLI 自动发现 期间使用。
创建应用程序很简单 - 唯一必需的 参数 是一个包含 控制器、路由器 或 路由处理器 的 列表:
# 你好世界示例
from litestar import Litestar, get
@get("/")
def hello_world() -> str:
return "你好,世界!"
app = Litestar(route_handlers=[hello_world])
应用实例是应用的根级别 - 它的基础路径为 /,所有根级别的 控制器、路由器 和 路由处理器 都应该在其上注册。
参见
要了解更多关于注册路由的信息,请查看文档中的这一章节:
路由 - 注册路由
启动和关闭¶
您可以向 应用实例 的 on_startup / on_shutdown 关键字参数 传递一个 可调用对象 列表 - 可以是同步或异步函数、方法或类实例。这些会在 ASGI 服务器(如 uvicorn、Hypercorn、Granian、Daphne 等)发出相应事件时按顺序调用。
flowchart LR
Startup[ASGI-事件: lifespan.startup] --> on_startup
Shutdown[ASGI-事件: lifespan.shutdown] --> on_shutdown
这方面的经典用例是数据库连接。通常,我们希望在应用启动时建立数据库连接,然后在关闭时优雅地关闭它。
例如,让我们使用 SQLAlchemy 的异步引擎创建数据库连接。我们创建两个函数,一个用于获取或建立连接,另一个用于关闭它,然后将它们传递给 Litestar 构造函数:
# 启动与关闭事件示例
from litestar import Litestar, on_startup, on_shutdown, get
@on_startup
async def startup() -> None:
print("应用启动!")
@on_shutdown
async def shutdown() -> None:
print("应用关闭!")
@get("/")
def index() -> str:
return "应用已启动!"
app = Litestar(route_handlers=[index], on_startup=[startup], on_shutdown=[shutdown])
生命周期上下文管理器¶
除了生命周期钩子之外,Litestar 还支持使用 异步上下文管理器 管理应用程序的生命周期。这在处理长时间运行的任务或需要保留某个上下文对象(如连接)时非常有用。
执行顺序¶
当指定多个生命周期上下文管理器和 on_shutdown 钩子时,Litestar 将在调用关闭钩子之前以相反的顺序调用 上下文管理器。
考虑这样一种情况,有两个生命周期上下文管理器 ctx_a 和 ctx_b 以及两个关闭钩子 hook_a 和 hook_b,如以下代码所示:
在关闭期间,它们按以下顺序执行:
flowchart LR
ctx_b --> ctx_a --> hook_a --> hook_b
如您所见,上下文管理器 以相反的顺序调用。另一方面,关闭钩子按照其指定的顺序调用。
使用应用程序状态¶
如 on_startup / on_shutdown 示例中所见,传递给这些钩子的 可调用对象 可以接收一个名为 app 的可选 关键字参数,通过它可以访问应用程序的状态对象和其他属性。使用应用程序 state 的优势在于它可以在连接的多个阶段访问,并且可以注入到依赖项和路由处理程序中。
应用程序状态是 datastructures.state.State 数据结构的实例,可以通过 state 属性访问。因此,它可以在应用实例可访问的任何地方访问。
state 是 保留的关键字参数 之一。
在此上下文中重要的是要理解,应用程序实例被注入到每个连接(即请求或 websocket 连接)的 ASGI scope 映射中,作为 scope["litestar_app"],并且可以使用 from_scope() 检索。这使得应用程序可以在 scope 映射可用的任何地方访问,例如在中间件、Request 和 WebSocket 实例上(作为 request.app / socket.app 访问)以及许多其他地方。
因此,state 提供了一种在应用程序的不同部分之间共享上下文数据的简单方法,如下所示:
初始化应用程序状态¶
要初始化应用程序状态,您可以将 State 对象传递给 Litestar 构造函数的 state 参数:
备注
State 可以使用 字典、ImmutableState 或 State 的实例,或包含键/值对的 元组 的 列表 进行初始化。
您可以指示 State 深度复制初始化数据,以防止从应用程序上下文外部进行修改。
将应用程序状态注入路由处理程序和依赖项¶
如上例所示,Litestar 提供了一种将状态注入路由处理程序和依赖项的简单方法 - 只需将 state 指定为处理程序或依赖函数的 kwarg。例如:
from litestar import get
from litestar.datastructures import State
@get("/")
def handler(state: State) -> None: ...
使用此模式时,您可以指定用于状态对象的类。此类型不仅用于类型检查器,Litestar 实际上会根据您在此处设置的类型实例化一个新的 state 实例。这允许用户使用自定义类作为 State。
虽然这非常强大,但它可能会鼓励用户遵循反模式:重要的是要强调,使用状态可能导致代码难以理解,并且由于不同 ASGI 上下文中的更改而导致难以理解的错误。因此,只有在这是最佳选择时才应使用此模式,并且应以有限的方式使用。为了不鼓励其使用,Litestar 还提供了内置的 ImmutableState 类。您可以使用此类来类型化状态并确保不允许对状态进行修改:
应用程序钩子¶
Litestar 包含几个应用程序级钩子,允许用户运行自己的同步或异步 可调用对象。虽然您可以根据需要使用这些钩子,但它们背后的设计意图是允许轻松地为可观察性(监控、跟踪、日志记录等)进行检测。
异常发生后¶
after_exception 钩子接受一个 同步或异步可调用对象,该可调用对象使用两个参数调用:发生的 exception 和请求或 websocket 连接的 ASGI scope。
注意
此钩子不用于处理异常 - 它只是接收它们以允许副作用。要处理异常,您应该定义 异常处理程序。
发送前¶
before_send 钩子接受一个 同步或异步可调用对象,该可调用对象在发送 ASGI 消息时调用。该钩子接收消息实例和 ASGI scope。
初始化¶
Litestar 包含一个钩子,用于拦截传递给 Litestar 构造函数 的参数,在它们用于实例化应用程序之前。
处理程序可以传递给应用程序构建时的 on_app_init 参数,并且每个处理程序将接收 AppConfig 的实例,并且必须返回相同的实例。
此钩子对于在应用程序之间应用通用配置以及供希望开发第三方应用程序配置系统的开发人员使用非常有用。
备注
on_app_init 处理程序不能是 Coroutine function definition 函数,因为它们在 __init__ 中调用,在异步上下文之外。
分层架构¶
Litestar 有一个由 4 层组成的分层架构:
有许多 参数 可以在每一层上定义,在这种情况下,在 最接近处理程序 的层上定义的 参数 优先。这允许在配置复杂应用程序时实现最大的灵活性和简单性,并实现参数的透明覆盖。
支持分层的参数有:
after_request
before_request
cache_control
include_in_schema
request_class
response_class
response_cookies
response_headers
securitytagswebsocket_class