ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

FastAPI 进阶:在 JSON 中用 Base64 传输二进制数据(bytes 字段实战)

FastAPI 进阶:在 JSON 中用 Base64 传输二进制数据(bytes 字段实战) FastAPI 进阶在 JSON 中用 Base64 传输二进制数据bytes 字段实战【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi本篇指南讲解 FastAPI 中一个进阶但非常实用的场景当你的接口必须接收和发送 JSON 数据、其中又需要携带二进制内容bytes时如何利用 Pydantic 的val_json_bytes与ser_json_bytes配置把二进制数据安全地以 base64 编码嵌入 JSON 请求体与响应体。读完本文你将掌握 base64 方案与文件上传/下载方案的取舍原则、bytes字段模型配置的完整写法以及 FastAPI 源码中 OpenAPI Schema 是如何自动生成contentEncoding: base64声明的底层机制。何时需要用 Base64 而不是文件如果你的应用需要接收和发送 JSON 数据但其中必须包含二进制数据就可以把这些二进制数据编码为 base64 字符串来传输。在选择方案之前先评估是否可以直接使用 请求文件 来上传二进制数据、使用 自定义响应 – FileResponse 来下发二进制数据而不是把二进制内容编码进 JSON。两者的取舍依据如下JSON 只能包含 UTF-8 编码的字符串因此它无法承载原始字节raw bytesBase64 可以把二进制数据编码成字符串但代价是需要比原始二进制数据更多的字符通常膨胀约 1/3因此在传输效率上一般不如直接传文件只有当你确实必须把二进制数据内嵌在 JSON 中、且无法改用文件方案时才使用 base64。用 Pydanticbytes字段接收输入数据声明一个带bytes字段的 Pydantic 模型并在模型配置中设置val_json_bytes即可告诉 Pydantic在校验validate输入的 JSON 数据时使用 base64。校验过程中base64 字符串会被自动解码为字节对象。完整示例见 docs_src/json_base64_bytes/tutorial001_py310.py其中接收端模型为from fastapi import FastAPI from pydantic import BaseModel class DataInput(BaseModel): description: str data: bytes model_config {val_json_bytes: base64} app FastAPI() app.post(/data) def post_data(body: DataInput): content body.data.decode(utf-8) return {description: body.description, content: content}启动应用后访问/docsSwagger UI 会展示字段data期望接收 base64 编码的字节此时可以发送如下请求{ description: Some data, data: aGVsbG8 }提示aGVsbG8就是字符串hello的 base64 编码。Pydantic 会解码这个 base64 字符串并在模型的data字段中把原始字节交给你。随后你会收到类似这样的响应{ description: Some data, content: hello }这里的关键点在于端点函数拿到的body.data已经是解码后的bytes类型示例中再用.decode(utf-8)转回字符串base64 编解码完全由 Pydantic 在模型边界处自动完成业务代码无需手动调用任何base64模块。用 Pydanticbytes字段输出数据对于输出数据可以在模型配置中使用ser_json_bytes。Pydantic 在生成 JSON 响应时会把字节序列化serialize为 base64 字符串class DataOutput(BaseModel): description: str data: bytes model_config {ser_json_bytes: base64} app.get(/data) def get_data() - DataOutput: data hello.encode(utf-8) return DataOutput(descriptionA plumbus, datadata)响应体中data字段就会以aGVsbG8这样的 base64 字符串形式返回。仓库中的测试 tests/test_tutorial/test_json_base64_bytes/test_tutorial001.py 正是如此断言的def test_get_data(client: TestClient): response client.get(/data) assert response.status_code 200, response.text assert response.json() {description: A plumbus, data: aGVsbG8}测试同时覆盖了输入方向发送SGVsbG8sIFdvcmxkIQ解码为Hello, World!验证了这套机制在真实请求/响应链路中的端到端行为。同一模型同时处理输入和输出当然你也可以配置同一个模型让 base64 同时用于输入校验和输出序列化class DataInputOutput(BaseModel): description: str data: bytes model_config { val_json_bytes: base64, ser_json_bytes: base64, } app.post(/data-in-out) def post_data_in_out(body: DataInputOutput) - DataInputOutput: return body此时请求体里的 base64 字符串会被解码成bytes传入端点端点把同一个模型对象返回后bytes又会以 base64 形式序列化进响应。上述测试文件中的test_post_data_in_out验证了这一回环发送SGVsbG8sIFdvcmxkIQ响应体中data原样返回同一 base64 字符串。源码视角OpenAPI Schema 是怎么知道要声明 base64 的一个值得注意的细节是配置val_json_bytes/ser_json_bytes后OpenAPI 文档会自动为bytes字段生成contentEncoding: base64和contentMediaType: application/octet-stream声明/docs界面因此能正确提示该字段期望 base64 字符串。从上面的测试快照test_openapi_schema可以看到生成的 Schema 片段data: { type: string, contentEncoding: base64, contentMediaType: application/octet-stream, title: Data }这一行为来自 FastAPI 对 Pydantic JSON Schema 生成器的定制覆盖位于 fastapi/_compat/v2.pyclass GenerateJsonSchema(_GenerateJsonSchema): def bytes_schema(self, schema: CoreSchema) - JsonSchemaValue: json_schema {type: string, contentMediaType: application/octet-stream} bytes_mode ( self._config.ser_json_bytes if self.mode serialization else self._config.val_json_bytes ) if bytes_mode base64: json_schema[contentEncoding] base64 self.update_with_validations(json_schema, schema, self.ValidationsMapping.bytes) return json_schema从这段源码可以看出两个要点FastAPI 重写了 Pydantic 的bytes_schema方法先按bytes的默认语义生成type: stringcontentMediaType: application/octet-stream然后根据当前模式校验模式读val_json_bytes、序列化模式读ser_json_bytes当配置值为base64时追加contentEncoding: base64声明。也就是说Schema 声明与实际的数据编解码行为是同一份模型配置驱动的两面同一组model_config既决定运行时如何解码/编码字节也决定 OpenAPI 文档如何向调用方描述字段格式。小结与适用边界优先用文件上传二进制用请求文件、下发二进制用FileResponseJSON 无法承载原始字节base64 是可嵌入 JSON 的通用编码但字符膨胀使其通常不如直接传文件高效输入方向用model_config {val_json_bytes: base64}输出方向用{ser_json_bytes: base64}两者可同时配置在同一个模型上配置生效后/docs中的 OpenAPI Schema 会自动带上contentEncoding: base64声明调用方包括自动生成的客户端能据此正确编码请求体参考实现示例应用、端到端测试、Schema 生成定制。【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表