跳转到主要内容

一个不出所料的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单值类型(intstrfloat等):首先路径,然后是查询

  • Python集合类型(list[int]等):仅查询,隐式地将单个或多个值转换为列表

  • hatchway.Schema/Pydantic BaseModel子类:仅正文(见以下模型来源)

  • django.core.files.File:仅文件

您可以通过使用PathQueryBodyFileQueryOrBodyPathOrQueryBodyDirect注解之一来覆盖Hatchway拉取参数的位置

from hatchway import api_view, Path, QueryOrBody

@api_view.post
def my_api_endpoint(request, id: Path[int], limit: QueryOrBody[int] = 100) -> dict:
    ...

虽然PathQueryBodyFile强制参数仅从该来源获取,但其中还有一些更复杂的选项

  • 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 正文,尽管当然您不需要它们在那里;不过,出于兼容性原因,它们仍然有效。

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解有关 安装包 的更多信息。

源代码分发

django-hatchway-0.5.2.tar.gz (13.7 kB 查看哈希值)

上传日期 源代码

构建分发

django_hatchway-0.5.2-py3-none-any.whl (13.2 kB 查看哈希值)

上传日期 Python 3

由以下机构支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页面