【发布时间】:2021-01-30 09:09:22
【问题描述】:
抱歉,不精通 Python。
我还没有找到该用例的文档。如何获取请求正文,确保它是有效的 Json(任何有效的 json,包括数字、字符串、布尔值和空值,不仅是对象和数组)并获取实际的 Json。 使用 pydantic 强制 Json 具有特定的结构。
【问题讨论】:
抱歉,不精通 Python。
我还没有找到该用例的文档。如何获取请求正文,确保它是有效的 Json(任何有效的 json,包括数字、字符串、布尔值和空值,不仅是对象和数组)并获取实际的 Json。 使用 pydantic 强制 Json 具有特定的结构。
【问题讨论】:
您几乎可以在 Request 对象中找到所有内容
您可以使用request.json() 获取请求正文,这会将解析后的 JSON 作为字典提供给您。
from fastapi import Request, FastAPI
@app.post("/dummypath")
async def get_body(request: Request):
return await request.json()
如果你想以字符串的形式访问正文,可以使用request.body()
【讨论】:
edit 历史中,request.body() 似乎只在代码块内被request.json() 取代:-)
如果您确信传入的数据是“有效的 JSON”,您可以创建一个简单的 类型注释 结构来接收任意 JSON 数据。
from fastapi import FastAPI
from typing import Any, Dict, AnyStr, List, Union
app = FastAPI()
JSONObject = Dict[AnyStr, Any]
JSONArray = List[Any]
JSONStructure = Union[JSONArray, JSONObject]
@app.post("/")
async def root(arbitrary_json: JSONStructure = None):
return {"received_data": arbitrary_json}
1. JSON 对象
curl -X POST "http://0.0.0.0:6022/" -H "accept: application/json" -H "Content-Type: application/json" -d "{\"test_key\":\"test_val\"}"
回复:
{
"received_data": {
"test_key": "test_val"
}
}
2。 JSON 数组
curl -X POST "http://0.0.0.0:6022/" -H "accept: application/json" -H "Content-Type: application/json" -d "[\"foo\",\"bar\"]"
回复:
{
"received_data": [
"foo",
"bar"
]
}
如果您不确定传入数据的内容类型,最好解析请求正文。
可以这样做,
from fastapi import FastAPI, Request
app = FastAPI()
@app.post("/")
async def root(request: Request):
return {"received_request_body": await request.body()}
这种方法的优点是body会包含任何类型的数据,JSON、form-data、multipart-form-data等。
【讨论】:
接受的 answer 也是有效的,但 FastAPI 提供了一种内置方式来执行此操作 - 请查看文档中的 Singular values in body 部分。
具有默认Body 的参数获取所有与传递的 Pydantic 类型参数不匹配的有效负载(在我们的例子中是整个有效负载)并将其转换为字典。如果 JSON 无效,则会产生标准验证错误。
from fastapi import Body, FastAPI
app = FastAPI()
@app.post('/test')
async def update_item(
payload: dict = Body(...)
):
return payload
【讨论】:
from fastapi import Request
async def synonyms__select(request: Request):
return await request.json()
将返回一个 JSON 对象。
【讨论】:
这是一个打印 Request 内容的示例,它将打印 json 正文(如果它是可解析的 json),否则只打印正文的原始字节。
async def print_request(request):
print(f'request header : {dict(request.headers.items())}' )
print(f'request query params : {dict(request.query_params.items())}')
try :
print(f'request json : {await request.json()}')
except Exception as err:
# could not parse json
print(f'request body : {await request.body()}')
@app.post("/printREQUEST")
async def create_file(request: Request):
try:
await print_request(request)
return {"status": "OK"}
except Exception as err:
logging.error(f'could not print REQUEST: {err}')
return {"status": "ERR"}
【讨论】: