Using async def
终点
如果一个对象是协同例程,则需要等待它。FastAPI实际上是底层的Starlette https://fastapi.tiangolo.com/advanced/using-request-directly/, and 星光法 https://www.starlette.io/requests/#body用于返回请求body
are async
方法(见源码here https://github.com/encode/starlette/blob/212fa46b23be0701a5963cdeff14f05ed352e22a/starlette/requests.py#L231以及);因此,人们需要await
他们(在一个async def
终点)。例如:
from fastapi import Request
@app.post("/input")
async def input_request(request: Request):
return await request.body()
更新 1 - 使用def
终点
或者,如果您确信传入的数据是有效的JSON
,您可以定义您的端点def
相反,并使用Body https://fastapi.tiangolo.com/tutorial/body-fields/字段,如下所示(有关如何发布的更多选项JSON
数据,参见这个答案 https://stackoverflow.com/a/70636163/17865804):
from fastapi import Body
@app.post("/input")
def input_request(payload: dict = Body(...)):
return payload
但是,如果传入数据位于XML
格式,如您提供的示例中所示,一种选择是使用传递它们Files https://fastapi.tiangolo.com/tutorial/request-files/相反,如下所示 - 只要您可以控制客户端数据发送到服务器的方式(看看here https://stackoverflow.com/a/70657621/17865804以及)。例子:
from fastapi import File
@app.post("/input")
def input_request(contents: bytes = File(...)):
return contents
更新 2 - 使用def
终点和async
依赖性
如中所述这个帖子 https://github.com/tiangolo/fastapi/issues/2574#issuecomment-751787209,你可以使用async
依赖性 https://fastapi.tiangolo.com/tutorial/dependencies/函数来拉出body
来自请求。您可以使用async
依赖于non-async
(i.e., def
) 端点也是如此。因此,如果此端点中存在某种阻止您使用的阻止代码async/await https://fastapi.tiangolo.com/async/——我猜这可能是你的情况的原因——这就是要走的路。
注意:我还应该提到这个答案 https://stackoverflow.com/a/71517830/17865804- 这解释了之间的区别def
and async def
端点(您可能知道)——当您需要使用时还提供解决方案async def
(因为你可能需要await
对于路线内的协程),但也有一些同步昂贵的 CPU 密集型操作可能会阻塞服务器。请看一看。
下面可以找到前面描述的方法的示例。您可以取消注释time.sleep()
行,如果您想确认自己的请求不会阻止其他请求通过,如当您使用正常声明端点时def代替async def,它在外部线程池中运行 https://fastapi.tiangolo.com/async/#path-operation-functions(不管async def
依赖函数)。
from fastapi import FastAPI, Depends, Request
import time
app = FastAPI()
async def get_body(request: Request):
return await request.body()
@app.post("/input")
def input_request(body: bytes = Depends(get_body)):
print("New request arrived.")
#time.sleep(5)
return body