Litestar 是一个功能强大、灵活且高性能的 Python ASGI 框架。它的设计灵感来源于 NestJS(一个流行的 NodeJS 框架),并大量借鉴了 FastAPI 的成功经验,但在架构和功能上做出了自己的选择和优化。
Litestar 框架简介
核心特性与优势
- 极致性能:Litestar 从底层就为高性能而设计,在许多基准测试中表现优于其他主流 ASGI 框架。
- 强类型与 Pydantic 集成:与 FastAPI 类似,Litestar 深度集成 Pydantic,利用 Python 的类型提示进行自动请求数据验证、反序列化和响应数据序列化,极大地提升了代码的健壮性和开发效率。
- 清晰的架构:通过引入控制器(Controllers)、**依赖注入(Dependency Injection)**等概念,鼓励开发者编写分层清晰、高内聚、低耦合的代码,非常适合构建大型、可维护的应用。
- 开箱即用:内置了 OpenAPI(Swagger UI & Redoc)文档生成、中间件支持、后台任务、插件系统等现代化 Web 框架所需的各种功能。
- 灵活性和可扩展性:提供了丰富的配置选项和强大的插件系统,允许开发者根据需求进行深度定制。
与 FastAPI 相比,Litestar 在组织大型项目上提供了更明确的指导(通过控制器),并在某些底层实现上追求更高的性能。
核心概念解析
Litestar
应用实例: 这是你应用的核心,类似于 Flask(__name__)
或 FastAPI()
。你将路由处理器注册到这个实例上。
- 路由处理器 (Route Handlers): 一个被
@get
, @post
, @put
, @delete
等装饰器修饰的函数。它负责处理特定路径和 HTTP 方法的请求。
- 控制器 (Controllers): 一个类,用于组织一组相关的路由处理器。例如,一个
BookController
可以包含所有与图书
资源相关的操作(获取、创建、更新图书等)。这使得代码结构更加清晰。
- Pydantic 模型集成: 你可以使用 Pydantic
BaseModel
来定义请求体(Request Body)和响应体(Response Body)的数据结构。Litestar 会自动完成:
- 请求校验:如果传入的 JSON 数据不符合模型定义,自动返回 400 错误。
- 数据解析:将合法的请求数据解析为你定义的 Pydantic 对象。
- 响应序列化:将你返回的 Pydantic 对象自动转换为 JSON 响应。
- OpenAPI 文档生成:根据模型定义生成精确的 API schema。
- 依赖注入 (Dependency Injection): 一种设计模式,允许你将服务或资源(如数据库连接)
注入
到你的路由处理器中,而无需在函数内部手动创建它们。这有助于解耦和测试。
安装 litestar
首先,你需要安装 Litestar、一个 ASGI 服务器(如 Uvicorn),以及 python-multipart
(用于文件上传)。
pip install "litestar[standard]" multipart python-multipart
litestar[standard]
会自动安装 uvicorn
和其他常用依赖。
实战代码示例:图书管理 API
我们将所有代码放在一个名为 main.py
的文件中。这个 API 将提供对内存中存储的图书列表进行增删改查以及上传封面的功能。
启动服务
-
运行以下命令启动服务:
uvicorn litestar-demo:app --reload
litestar-demo
: 指的是 litestar-demo.py
文件。
app
: 指的是文件中创建的 Litestar
实例 app
。
--reload
: 当你修改代码时,服务器会自动重启,非常适合开发阶段。
你将看到类似以下的输出,表示服务已在 http://127.0.0.1:8000
上运行:
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [xxxxx]
INFO: Started server process [xxxxx]
INFO: Waiting for application startup.
应用启动,填充初始数据...
INFO: Application startup complete.
如何使用 curl
测试每个 API
打开一个新的终端,使用以下命令与你的 API 进行交互。
1. GET /books - 获取所有图书
curl -X GET http://127.0.0.1:8000/books
预期输出:
[
{
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"title": "The Hitchhiker's Guide to the Galaxy",
"author": "Douglas Adams",
"year": 1979
},
{
"id": "8f8b8a0a-3b3c-4b0c-8e1a-9a8b7c6d5e4f",
"title": "1984",
"author": "George Orwell",
"year": 1949
}
]
2. POST /books - 创建一本新书
curl -X POST http://127.0.0.1:8000/books \
-H "Content-Type: application/json" \
-d '{"title": "Dune", "author": "Frank Herbert", "year": 1965}'
预期输出 (ID 是动态生成的):
{
"id": "a1b2c3d4-e5f6-a7b8-c9d0-e1f2a3b4c5d6",
"title": "Dune",
"author": "Frank Herbert",
"year": 1965
}
3. GET /books/{book_id} - 获取指定 ID 的图书
使用初始数据中的一个 ID:
curl -X GET http://127.0.0.1:8000/books/f47ac10b-58cc-4372-a567-0e02b2c3d479
预期输出:
{
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"title": "The Hitchhiker's Guide to the Galaxy",
"author": "Douglas Adams",
"year": 1979
}
4. PUT /books/{book_id} - 更新图书信息
更新 “1984” 的出版年份。
curl -X PUT http://127.0.0.1:8000/books/8f8b8a0a-3b3c-4b0c-8e1a-9a8b7c6d5e4f \
-H "Content-Type: application/json" \
-d '{"title": "1984", "author": "George Orwell", "year": 1950}'
预期输出:
{
"id": "8f8b8a0a-3b3c-4b0c-8e1a-9a8b7c6d5e4f",
"title": "1984",
"author": "George Orwell",
"year": 1950
}
5. DELETE /books/{book_id} - 删除图书
删除我们刚刚创建的 “Dune” (你需要替换为你收到的实际 ID)。假设 ID 是 a1b2c3d4-...
。
# 首先获取Dune的ID
# curl http://127.0.0.1:8000/books
# 假设你拿到的Dune的ID是 a1b2c3d4-e5f6-a7b8-c9d0-e1f2a3b4c5d6
curl -X DELETE http://127.0.0.1:8000/books/a1b2c3d4-e5f6-a7b8-c9d0-e1f2a3b4c5d6
预期输出:
这个请求没有输出内容,HTTP 状态码为 204 No Content,表示成功。你可以再次 GET /books
来确认它已被删除。
6. POST /upload-cover - 上传文件
首先,创建一个测试文件,例如 my_cover.txt
,内容为 hello world
。
echo "hello world" > my_cover.txt
然后执行上传命令:
curl -X POST http://127.0.0.1:8000/upload-cover \
-T "file=@my_cover.txt;type=text/plain"
预期输出:
{
"filename": "my_cover.txt",
"content_type": "text/plain",
"size_in_bytes": 12
}
Swagger UI (OpenAPI) 自动文档
这是 Litestar 的一大亮点。在你运行服务后,直接在浏览器中打开以下两个 URL 中的任意一个:
你将看到一个漂亮的、可交互的 API 文档页面。
在这个页面上,你可以:
- 查看所有的 API 端点、HTTP 方法、路径参数等。
- 了解每个端点所需的请求体(Request Body)和可能的响应(Responses)。
- 直接在浏览器中测试 API!点击一个 endpoint,选择 “Try it out”,填写参数,然后点击 “Execute”,它会向你的本地服务发送请求并显示结果。
这个文档是根据你的 Python 代码(类型提示、Pydantic 模型、函数的 docstring、summary
和 description
参数)自动生成的。代码即文档!