FastAPI(46)- JSONResponse

本文介绍了在FastAPI中如何返回响应数据,特别是使用Pydantic模型和JSONResponse的方式。通过示例代码展示了基础的路径操作函数返回PydanticModel,以及等价的使用jsonable_encoder和JSONResponse的方法。强调了直接将PydanticModel传递给JSONResponse会导致错误,因为对象不可序列化,并提示了JSONResponse可以自定义状态码、头信息和媒体类型。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

  • 创建 FastAPI 路径操作函数时,通常可以从中返回任何数据:字典、列表、Pydantic 模型、数据库模型等
  • 默认情况下,FastAPI 会使用 jsonable_encoder 自动将该返回值转换为 JSON 字符串
  • 然后,FastAPI 会将与 JSON 兼容的数据(例如 dict)放在 JSONResponse 中,然后将 JSONResponse 返回给客户端
  • 总结:默认情况下,FastAPI 将使用 JSONResponse 返回响应
  • 但是可以直接从路径操作函数中返回自定义的 JSONResponse
返回响应数据的常见方式(基础版)

https://www.cnblogs.com/poloyy/p/15364635.html

最简单的栗子

路径操作函数返回一个 Pydantic Model

#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
# author: 小菠萝测试笔记
# blog:  https://www.cnblogs.com/poloyy/
# time: 2021/10/3 3:26 下午
# file: 38_responses.py
"""
from typing import Optional

import uvicorn
from fastapi import FastAPI
from fastapi.encoders import jsonable_encoder
from fastapi.responses import JSONResponse

from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    id: str
    name: str
    title: Optional[str] = None


@app.post("/item")
async def get_item(item: Item):
    # 打印看看传进来的数据是什么
    print(item, type(item))

    # 直接返回传进来的数据
    return item

if __name__ == '__main__':
    uvicorn.run(app="38_responses:app", reload=True, host="127.0.0.1", port=8080)
正常传参的请求结果

Response Header 的显示 content-type 是 JSON 

console 打印结果
id='string' name='string' title='string' <class '38_responses.Item'>
INFO:     127.0.0.1:51856 - "POST /item HTTP/1.1" 200 OK 
  • item 类型的确是 Pydantic Model 类
  • 但最终返回给客户端的是一个 JSON 数据
等价写法
@app.post("/item")
async def get_item(item: Item):
    return item

这样写也能返回 JSON 数据,是因为FastAPI 是自动帮忙做了转换的

等价写法如下

from fastapi.encoders import jsonable_encoder

@app.post("/item")
async def get_item(item: Item):
    json_body = jsonable_encoder(item)
    return JSONResponse(content=json_body)
打印数据,来看看细节
@app.post("/item2")
async def get_item(item: Item):
    json_body = jsonable_encoder(item)
    
    print(json_body, type(json_body))
    
    return JSONResponse(content=json_body) 

console 打印结果

{'id': 'string', 'name': 'string', 'title': 'string'} <class 'dict'>
INFO:     127.0.0.1:52880 - "POST /item2 HTTP/1.1" 200 OK
假设将 item Pydantic Model 类型直接传给 JSONResponse 呢?
@app.post("/item3")
async def get_item(item: Item):
    return JSONResponse(content=item)

访问该接口就会报错

    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type Item is not JSON serializable
  • 类型错误:项目类型的对象不是 JSON 可序列化的
  • 因为它无法转换为 JSON 数据,所以报错了

看看 JSONResponse 源码

会调用 json.dumps() 方法

看看 Response 源码

看到其实可以自定义 status_code、headers、media_type 哦

headers 后面再用单独的篇幅来讲

修改 status_code 响应码

@app.post("/item2")
async def get_item(item: Item):
    json_item = jsonable_encoder(item)
    return JSONResponse(content=json_item, status_code=status.HTTP_201_CREATED)
正确传参的请求结果

更多自定义响应类型

### 如何在 FastAPI 中实现会话管理 为了实现在 FastAPI 应用程序中的会话管理,可以采用多种方法来存储和检索用户的会话数据。一种常见的做法是利用依赖注入机制以及第三方库如 `fastapi-session` 或者基于令牌的身份验证方案。 #### 使用 fastapi-session 实现基本的会话功能 通过安装并配置 `fastapi-session` 可以简化创建与维护 HTTP 会话的过程: 1. 安装所需的 Python 包: ```bash pip install fastapi-session[aiofiles] ``` 2. 创建一个简单的 FastAPI 应用实例,并设置会话中间件: ```python from fastapi import FastAPI, Depends, Request from fastapi.responses import JSONResponse from fastapi_sessions.backends.implementations import InMemoryBackend from fastapi_sessions.session_verifier import SessionVerifier import uuid app = FastAPI() class CustomSessionData(BaseModel): username: Optional[str] = None backend = InMemoryBackend[UUID, CustomSessionData]() verifier = SessionVerifier[uuid.UUID, CustomSessionData]( identifier="general_verifier", auto_error=True, backend=backend, auth_http_exception=HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Invalid session" ), ) @app.post("/create_session", response_model=CustomSessionData) async def create_session(data: dict, request: Request): session_id = await verifier.create_session(CustomSessionData(username=data.get('username'))) response = JSONResponse({"session": "created"}) response.set_cookie(key="session_id", value=session_id.hex) return response @app.get("/whoami") def read_root(session_data: CustomSessionData = Depends(verifier)): return {"message": f"Hello {session_data.username}"} ``` 此代码片段展示了如何定义自定义会话模型、初始化内存后端用于保存会话信息、建立会话校验器来进行身份验证检查[^1]。 对于更复杂的应用场景,还可以考虑使用 Redis 等分布式缓存作为持久化层替代内置的记忆体后端;另外也可以集成 JWT (JSON Web Token) 来增强安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小菠萝测试笔记

来支持下测试小锅锅

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

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

打赏作者

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

抵扣说明:

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

余额充值