将 pathlib.Path 数据发送到 FastAPI:PosixPath 不可 JSON 序列化
Send pathlib.Path data to FastAPI: PosixPath is not JSON serializable
我已经使用 FastAPI 构建了一个 API 并且正在尝试从客户端向它发送数据。
API 和客户端都对我要提交的数据使用类似的 Pydantic 模型。这包括一个包含文件路径的字段,我将其存储在 pathlib.path.
类型的字段中
然而,FastAPI 不接受提交,因为它显然无法处理路径对象:
TypeError: Object of type PosixPath is not JSON serializable
这是显示问题的最小测试文件:
import pathlib
from pydantic import BaseModel
from fastapi import FastAPI
from fastapi.testclient import TestClient
api = FastAPI()
client = TestClient(api)
class Submission(BaseModel):
file_path: pathlib.Path
@api.post("/", response_model=Submission)
async def add_submission(subm: Submission):
print(subm)
# add submission to database
return subm
def test_add_submission():
data = {"file_path": "/my/path/to/file.csv"}
print("original data:", data)
# create a Submission object, which casts filePath to pathlib.Path:
submission = Submission(**data)
print("submission object:", submission)
payload = submission.dict()
print("payload:", payload)
response = client.post("/", json=payload) # this throws the error
assert response.ok
test_add_submission()
当我将客户端的模型更改为使用字符串而不是 file_path
的路径时,事情就会发生。但是后来我失去了在创建 Submission 对象时将输入强制转换为 Path 的 pydantic 能力,然后拥有一个具有所有可能性的 Path 属性。当然,一定有更好的方法吗?
将 pathlib.PosixPath 对象作为负载的一部分发送到 FastAPI API 的正确方法是什么?
(这是 Python 3.8.9,fastapi 0.68.1,Ubuntu 上的 pydantic 1.8.2)
你的代码的问题是,你首先将 pydantic 模型转换成一个字典,然后将其传递给客户端,客户端使用它自己的 json 序列化器,而不是 pydantic 提供的序列化器。
submission.dict()
将任何 pydantic 模型转换为 dict 但保留任何其他数据类型。
使用client.post("/", json=payload)
requests
json序列化器,无法处理pathlib.Path
.
解决方法是,先不把pydantic模型转成dict,而是利用pydantic模型本身的json()
方法传给客户端。
response = client.post("/", data=submission.json())
请注意,您必须将参数 json
更改为 data
。
我已经使用 FastAPI 构建了一个 API 并且正在尝试从客户端向它发送数据。
API 和客户端都对我要提交的数据使用类似的 Pydantic 模型。这包括一个包含文件路径的字段,我将其存储在 pathlib.path.
类型的字段中然而,FastAPI 不接受提交,因为它显然无法处理路径对象:
TypeError: Object of type PosixPath is not JSON serializable
这是显示问题的最小测试文件:
import pathlib
from pydantic import BaseModel
from fastapi import FastAPI
from fastapi.testclient import TestClient
api = FastAPI()
client = TestClient(api)
class Submission(BaseModel):
file_path: pathlib.Path
@api.post("/", response_model=Submission)
async def add_submission(subm: Submission):
print(subm)
# add submission to database
return subm
def test_add_submission():
data = {"file_path": "/my/path/to/file.csv"}
print("original data:", data)
# create a Submission object, which casts filePath to pathlib.Path:
submission = Submission(**data)
print("submission object:", submission)
payload = submission.dict()
print("payload:", payload)
response = client.post("/", json=payload) # this throws the error
assert response.ok
test_add_submission()
当我将客户端的模型更改为使用字符串而不是 file_path
的路径时,事情就会发生。但是后来我失去了在创建 Submission 对象时将输入强制转换为 Path 的 pydantic 能力,然后拥有一个具有所有可能性的 Path 属性。当然,一定有更好的方法吗?
将 pathlib.PosixPath 对象作为负载的一部分发送到 FastAPI API 的正确方法是什么?
(这是 Python 3.8.9,fastapi 0.68.1,Ubuntu 上的 pydantic 1.8.2)
你的代码的问题是,你首先将 pydantic 模型转换成一个字典,然后将其传递给客户端,客户端使用它自己的 json 序列化器,而不是 pydantic 提供的序列化器。
submission.dict()
将任何 pydantic 模型转换为 dict 但保留任何其他数据类型。
使用client.post("/", json=payload)
requests
json序列化器,无法处理pathlib.Path
.
解决方法是,先不把pydantic模型转成dict,而是利用pydantic模型本身的json()
方法传给客户端。
response = client.post("/", data=submission.json())
请注意,您必须将参数 json
更改为 data
。