一个不出所料的Django API框架
项目描述
Hatchway是一个受FastAPI等API框架启发的API框架,但在尽量保持API视图与标准Django视图尽可能相似的同时。
它是为了Takahē而构建的,并从中提取出来;如果您想查看它的使用示例,请浏览其api app。
安装
从PyPI安装Hatchway
pip install django-hatchway
并将其添加到您的 INSTALLED_APPS
INSTALLED_APPS = [ ... "hatchway", ]
使用方法
要将视图制作成API端点,您应编写一个标准的基于函数的视图,并用 @api_view.get、@api_view.post 或类似方式装饰它
from hatchway import api_view @api_view.get def my_api_endpoint(request, id: int, limit: int = 100) -> list[str]: ...
函数参数的类型很重要;Hatchway将使用它们来确定从哪里获取它们的值以及如何解析它们。所有标准的Python类型都受支持,加上 Pydantic风格的模型(理想情况下,您应基于 hatchway.Schema 基类构建它们,因为它了解如何从Django模型实例中加载数据)。
您的返回类型也很重要 - 这正是Hatchway用来确定如何格式化/验证返回值的。如果您不希望进行任何返回验证,可以省略它或将其设置为 Any。
URL模式
您可以在 urls.py 文件中添加API视图,就像添加其他视图一样
urlpatterns = [ ... path("api/test/", my_api_endpoint), ]
该视图仅接受装饰的相应方法(例如,对于 api_view.get,则为 GET)。
如果您想在同一URL上有两个或更多视图但响应不同方法,请使用Hatchway的 methods 对象
from hatchway import methods urlpatterns = [ ... path( "api/post/<id>/", methods( get=posts.post_get, delete=posts.posts_delete, ), ), ]
参数来源
输入参数可以从以下四个地方获取
路径:视图的URL,由URL解析器通过kwargs提供
查询:查询参数(request.GET)
正文:请求正文,可以是JSON、表单数据或multipart格式
文件:上传的文件,作为multipart正文的一部分
默认情况下,Hatchway将从这些来源拉取参数
标准Python单值类型(int、str、float等):首先路径,然后是查询
Python集合类型(list[int]等):仅查询,隐式地将单个或多个值转换为列表
hatchway.Schema/Pydantic BaseModel子类:仅正文(见以下模型来源)
django.core.files.File:仅文件
您可以通过使用Path、Query、Body、File、QueryOrBody、PathOrQuery或BodyDirect注解之一来覆盖Hatchway拉取参数的位置
from hatchway import api_view, Path, QueryOrBody @api_view.post def my_api_endpoint(request, id: Path[int], limit: QueryOrBody[int] = 100) -> dict: ...
虽然Path、Query、Body和File强制参数仅从该来源获取,但其中还有一些更复杂的选项
PathOrQuery首先尝试路径,然后尝试查询(简单类型的默认值)
QueryOrBody首先尝试查询,然后尝试正文
BodyDirect强制对模型进行顶级填充 - 请参阅以下模型来源。
模型来源
当您定义一个hatchway.Schema子类(或任何其他pydantic模型子类)时,Hatchway会假设它应该从POST/PUT等请求体中拉取它。
它如何拉取取决于您有多少个来自正文来源的参数
如果您只有一个,它将使用正文数据中的顶级键作为其内部值。
如果您有多个,它将查找其数据在一个与参数名称相同的子键中。
例如,这个函数有两个来自正文来源的东西(一个隐式的一个显式)
@api_view.post def my_api_endpoint(request, thing: schemas.MyInputSchema, limit: Body[int] = 100): ...
这意味着Hatchway将向schemas.MyInputSchema模型提供请求体中thing键下的内容作为其输入,而limit将来自limit键。
如果limit未指定,则只有一个来自正文来源的项,Hatchway将整个请求体作为其输入提供给schemas.MyInputSchema。
您可以使用其类型上的BodyDirect[MySchemaClass]注解来强制将整个请求体馈送到模式子类。
返回值
如果提供,API视图的返回值用于验证和强制响应类型
@api_view.delete def my_api_endpoint(request) -> int: ...
它可以是普通的Python类型,也可以是hatchway.Schema子类。如果是Schema子类,则将响应馈送到它以进行强制转换,并支持ORM对象 - 返回模型实例、包含模型实例值的字典或模式实例都是等效的。
类型检查器也将尊重这些,因此我们通常建议返回您的Schema的实例,以便您的整个视图都能从类型检查中受益,而不是依赖于强制转换。您将在Schema子类构造函数中获得类型检查,然后在视图中始终返回正确的东西时进行类型检查。
您还可以使用泛型如list[MySchemaClass]或dict[str, MySchemaClass]作为响应类型;通常,Pydantic允许的任何内容,我们都可以做到。
将标题/状态代码添加到响应中
如果您想对响应进行更多操作,而不仅仅是向客户端发送一些数据,您可以选择返回一个ApiResponse对象,而不是一个普通的值。
from hatchway import api_view, ApiResponse @api_view.delete def my_api_endpoint(request) -> ApiResponse[int]: ... return ApiResponse(42, headers={"X-Safe-Delete": "no"})
ApiResponse 是一个标准的 Django HTTPResponse 子类,因此接受几乎所有相同的参数,并且拥有大多数相同的方法。但是不要编辑其 .content 值;如果您想修改传递给它的数据,那么这些数据存储在 .data 中。
请注意,我们还更改了视图的返回类型,以便通过类型检查;ApiResponse 接受任何响应类型作为其参数,并将其传递到相同的验证层。
自动收集
Hatchway 允许您指定 Schema 子类可以从单个查询参数或正文值中提取它们的值;这些通常是扁平字符串,除非您正在查看 JSON 编码的正文,或者存在多个重复的查询参数。
但是,它会尊重 name[] 的使用来创建列表,以及 name[key] 来创建字典。以下是一些示例:
一个 a=Query[list[int]] 参数将把 url?a=1 视为 [1],url?a=1&a=2 视为 [1, 2],以及 url?a[]=1&a[]=2 视为 [1, 2]。
一个 b=Body[dict[str, int]] 参数将正确接受 POST 数据 b[age]=30&b[height]=180 并返回 {"age": 30, "height": 180}。
这些也适用于 JSON 正文,尽管当然您不需要它们在那里;不过,出于兼容性原因,它们仍然有效。
项目详情
下载文件
下载适合您平台的文件。如果您不确定选择哪个,请了解有关 安装包 的更多信息。