Litestar框架中的HTTP响应处理详解

Litestar框架中的HTTP响应处理详解

litestar Production-ready, Light, Flexible and Extensible ASGI API framework | Effortlessly Build Performant APIs litestar 项目地址: https://gitcode.com/gh_mirrors/li/litestar

响应基础概念

在Litestar框架中,处理HTTP响应有多种灵活的方式。最基本的模式非常简单:只需从路由处理函数返回一个值,框架会自动处理后续的响应构建过程。

from pydantic import BaseModel
from litestar import get

class Resource(BaseModel):
    id: int
    name: str

@get("/resources")
def retrieve_resource() -> Resource:
    return Resource(id=1, name="my resource")

在这个例子中,路由处理函数返回了一个Pydantic模型实例。Litestar会使用这个值构建响应对象,默认情况下会设置状态码为200,Content-Type头为application/json,并将Resource实例序列化为JSON作为响应体。

媒体类型处理

默认与自定义媒体类型

默认情况下,Litestar使用JSON作为响应格式,但你也可以指定其他媒体类型:

from litestar import MediaType, get

@get("/resources", media_type=MediaType.TEXT)
def retrieve_resource() -> str:
    return "The rumbling rabbit ran around the rock"

Litestar支持以下几种标准媒体类型:

  • JSON (application/json)
  • MessagePack (application/x-msgpack)
  • 纯文本 (text/plain)
  • HTML (text/html)

你也可以使用任何IANA注册的媒体类型字符串,但需要注意可能需要自定义序列化逻辑。

各媒体类型详解

JSON响应

作为默认格式,JSON支持序列化多种Python类型:

  • 标准库的dataclass
  • Pydantic模型和dataclass
  • UUID对象
  • 日期时间对象
  • msgspec.Struct
  • 包含上述类型的容器(字典、列表等)
MessagePack响应

MessagePack是一种高效的二进制序列化格式:

from litestar import get, MediaType

@get(path="/health-check", media_type=MediaType.MESSAGEPACK)
def health_check() -> dict[str, str]:
    return {"hello": "world"}
纯文本响应
from litestar import get, MediaType

@get(path="/health-check", media_type=MediaType.TEXT)
def health_check() -> str:
    return "healthy"
HTML响应
from litestar import get, MediaType

@get(path="/page", media_type=MediaType.HTML)
def health_check() -> str:
    return """
    <html>
        <body>
            <div>
                <span>Hello World!</span>
            </div>
        </body>
    </html>
    """

对于复杂HTML响应,建议使用模板引擎而非硬编码字符串。

内容协商

当处理程序可以返回多种媒体类型时,可以使用内容协商让客户端选择:

from litestar import get, MediaType, Request

@get("/resources")
def retrieve_resource(request: Request) -> str | dict:
    if request.accept == MediaType.TEXT:
        return "text response"
    return {"json": "response"}

状态码控制

可以通过status_code参数设置响应状态码:

from litestar import get
from litestar.status_codes import HTTP_202_ACCEPTED

@get("/resources", status_code=HTTP_202_ACCEPTED)
def retrieve_resource() -> dict:
    return {"id": 1, "name": "my resource"}

默认状态码规则:

  • POST: 201 (Created)
  • DELETE: 204 (No Content)
  • GET/PATCH/PUT: 200 (Ok)

注意:某些状态码不允许响应体,如204、304等。

高级响应处理

直接返回响应对象

除了返回数据让框架构建响应,你也可以直接返回响应对象:

from litestar import get, Response

@get("/")
def handler() -> Response[str]:
    return Response(content="hello world", media_type="text/plain")

返回ASGI应用

Litestar支持直接返回ASGI应用:

from litestar import get
from litestar.types import ASGIApp, Receive, Scope, Send

@get("/")
def handler() -> ASGIApp:
    async def my_asgi_app(scope: Scope, receive: Receive, send: Send) -> None:
        await send({
            "type": "http.response.start",
            "status": 200,
            "headers": [(b"content-type", b"text/plain")],
        })
        await send({
            "type": "http.response.body",
            "body": b"Hello, world!",
        })
    return my_asgi_app

响应头管理

静态头设置

可以在应用各层级设置响应头:

from litestar import get, ResponseHeader

@get(
    "/",
    response_headers={
        "my-header": ResponseHeader(value="header-value", description="A custom header")
    }
)
def handler() -> str:
    return "hello world"

动态头设置

有两种主要方式动态设置响应头:

  1. 通过返回响应对象直接设置
  2. 使用请求后钩子(after_request hook)
from litestar import get, Response
from litestar.datastructures import ResponseHeader

@get(
    "/random",
    response_headers={
        "Random-Header": ResponseHeader(
            description="a random number header",
            documentation_only=True
        )
    }
)
def handler() -> Response[str]:
    import random
    return Response(
        content=str(random.random()),
        headers={"Random-Header": str(random.randint(1, 100))}
    )

特殊响应头实现

缓存控制头

Litestar提供了专门的CacheControlHeader实现:

from litestar import get
from litestar.datastructures.headers import CacheControlHeader

@get(
    "/cached",
    cache_control=CacheControlHeader(max_age=3600, public=True)
)
def cached_handler() -> str:
    return "This response will be cached for 1 hour"

ETag头

from litestar import get
from litestar.datastructures.headers import ETag

@get("/etag")
def etag_handler() -> tuple[str, ETag]:
    return "content", ETag(value="unique-value")

响应Cookie设置

可以在应用各层级设置Cookie:

from litestar import get
from litestar.datastructures import Cookie

@get(
    "/",
    response_cookies=[
        Cookie(key="session-id", value="abc123", max_age=3600)
    ]
)
def handler() -> str:
    return "hello world"

Cookie设置遵循层级覆盖原则,低层级的定义会覆盖高层级的同名Cookie。

总结

Litestar提供了丰富而灵活的响应处理机制,从简单的数据返回到复杂的响应控制,能够满足各种Web开发场景的需求。通过合理使用这些特性,开发者可以构建出高效、规范的Web API和服务。

litestar Production-ready, Light, Flexible and Extensible ASGI API framework | Effortlessly Build Performant APIs litestar 项目地址: https://gitcode.com/gh_mirrors/li/litestar

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

黑河是我国西北干旱区最重要的内陆河流之一,灌区分布及水利工程体系直接关系到流域农业发展、水资源配置与生态安全。 本资源包含黑河流域范围内的灌区空间分布矢量数据(Shapefile格式)与干支渠分布栅格图(TIF格式),可广泛应用于农业水资源管理、流域水文模拟、灌溉工程布局分析及生态水文研究等领域。 【数据内容】 灌区分布数据(Shapefile) 数据类型:矢量多边形(Polygon) 坐标系统:WGS 84 或 CGCS2000(具体可查看 .prj 文件)。 干支渠分布图(GeoTIFF) 数据类型:栅格图像(TIF) 分辨率:通常为10–30米,满足中尺度制图与分析; 图像内容:表示黑河流域干渠与支渠的空间路径分布,可作为水利网络基础图层; 内容描述:标识黑河流域主要灌区边界,包括各县(如张掖、高台、临泽、肃南等)所辖的骨干灌区、支渠灌区分布; 属性字段:灌区名称等; 应用价值:可用于构建灌溉水流路径、流量估算、水资源调度仿真模型等。 【典型应用场景】 流域灌溉调度研究:用于构建灌区供水模型,估算引水量与灌溉效率; 遥感与地理建模:与MODIS、Sentinel遥感数据叠加进行土地覆被分类或作物监测; 农业统计分析:与统计年鉴灌溉面积核对比对,服务于灌溉政策评估; 地图制图与展示:支持ArcGIS、QGIS、Mapbox等平台加载使用,可生成专题图; 水文模型输入:可作为SWAT、MIKE SHE 等模型的空间输入因子。 【附加说明】 文件命名清晰,包含 .shp, .shx, .dbf, .prj 等标准矢量格式; TIF 文件配有 .tfw 文件及标准色带,可直接叠加到DEM、水系图等背景图上; 可适配常用 GIS 软件(ArcGIS/QGIS)及建模工具; 数据来源规范,具有较高的空间精度与现势性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

邢娣蝶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值