fastapi学习文档fastapi

fastapi教程翻译(十七): Request Files(请

2019-11-08  本文已影响0人  warmsirius

客户端也可以上传文件到Fastapi,只需要指定File格式即可。

解释
Form一样,想要接收上传的文件,需要先安装 python-multipart.

安装命令: pip install python-multipart.

原因
这是因为上传的文件会被解析为 "form data".

一、导入 File

fastapi中导入 FileUploadFile:

from fastapi import FastAPI, File, UploadFile 

二、定义 File 参数

创建文件参数:

from fastapi import FastAPI, File, UploadFile

app = FastAPI()

@app.post("/files/")
async def create_file(
    file: bytes = File(...)
):
    return {"file_size": len(file)}

解释

File 是直接继承自Form类的子类.

申明File请求体,你必须使用File,因为如果不使用该类,将会被解释为查询参数或者是请求体参数。

文件类型会被上传为 "form"数据类型.

如果你申明路由视图函数参数类型为bytesFastAPI将会把文件转化为bytes类型。

File类型的内容是将内容保存在内存中的,比较适合小型文件。

下面是使用UploadFile几种情况、

三、File 参数使用 UploadFile类型

将File参数定义为UploadFile类型:

from fastapi import FastAPI, File, UploadFile

app = FastAPI()

@app.post("/files/")
async def create_file(
file: bytes = File(...)
):
    return {"file_size": len(file)}

@app.post("/uploadfile/")
async def create_upload_file(
file: UploadFile = File(...)
):
    return {"filename": file.filename}

文件使用UploadFile类型比bytes的几种好处:

3.1. UploadFile

3.1.1 UploadFile 的属性:

3.1.2 UploadFileasync 方法:

其实都是下面调用相应的文件方法(使用内部的'SpooledTemporaryFile`)。

正如所有的方法都是async,您需要使用await调用上面的方法。

例如,
例如,在async路径操作函数中,您可以通过以下方式获取内容:

contents = await myfile.read()

如果您在常规的def路径操作功能中,则可以直接访问UploadFile.file,例如:

contents = myfile.file.read()

async 技术细节

当您使用async方法时,FastAPI在线程池中运行文件方法并等待它们。

Starlette技术细节

FastAPI的UploadFile继承自StarletteUploadFile,但是增加了一些必要的部分以使其与pydantic **和FastAPI的其他部分兼容。

四、"Form Data"?

HTML表单(<form> </ form>)将数据发送到服务器的方式通常对该数据使用“特殊”编码,这与JSON不同。

FastAPI将确保从正确的位置而不是JSON读取数据。

技术细节

  • 如果表单中的数据不包含文件,则通常使用“媒体类型” application / x-www-form-urlencoded编码。

  • 但是当表单包含文件时,它将被编码为multipart / form-data。 如果使用File,** FastAPI **将知道它必须从主体的正确部位获取文件。

如果您想了解更多有关这些编码和表单字段的信息,请转到MDN web docs for POST.

警告⚠️

您可以在路径操作中声明多个File和Form参数,但是您也不能声明希望以JSON形式接收的Body字段,因为请求的主体将使用multipart/form-data,而不是application/json

这并不是FastAPI的限制,而是HTTP协议的一部分。

五、多个文件上传

如果需要一次性上传多个文件,需要定义为bytesUploadFileList形式

from typing import List

from fastapi import FastAPI, File, UploadFile
from starlette.responses import HTMLResponse

app = FastAPI()

@app.post("/files/")
async def create_files(
    files: List[bytes] = File(...)
):
    return {"file_sizes": [len(file) for file in files]}

@app.post("/uploadfiles/")
async def create_upload_files(
    files: List[UploadFile] = File(...)
):
    return {"filenames": [file.filename for file in files]}

@app.get("/")
async def main():
    content = """
<body>
<form action="/files/" enctype="multipart/form-data" method="post">
<input name="files" type="file" multiple>
<input type="submit">
</form>
<form action="/uploadfiles/" enctype="multipart/form-data" method="post">
<input name="files" type="file" multiple>
<input type="submit">
</form>
</body>
 """
    return HTMLResponse(content=content)

你将会得到bytesUploadFile的列表。

注意

请注意,自2019年4月14日起,Swagger UI不支持在同一表单字段中上传多个文件。 有关更多信息,请检查#4276#3641

尽管如此,FastAPI已经使用标准OpenAPI与之兼容。

因此,只要Swagger UI支持多文件上传或任何其他支持OpenAPI的工具,它们都将与FastAPI兼容。

上一篇下一篇

猜你喜欢

热点阅读