美文网首页fastapi学习文档fastapi
fastapi教程翻译(十七): Request Files(请

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

作者: warmsirius | 来源:发表于2019-11-08 17:07 被阅读0次

    客户端也可以上传文件到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的几种好处:

    • UploadFile文件使用脱机文件:
      • 文件存储在内存中有一个最大限制,如果超过了这个界限,会保存在硬盘中
    • 这意味着UploadFile将会对大文件,比如图片、视频、大二进制文件等,不会很快消耗掉所有内存
    • 可以从上传的文件中得到元数据】
    • UploadFilefile-like async 交互.
    • 它公开了一个实际的Python [SpooledTemporaryFile](https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile)对象,您可以将其直接传递给需要类似文件对象的其他库。

    3.1. UploadFile

    3.1.1 UploadFile 的属性:

    • filename: 具有上载原始文件名的str (例. myimage.jpg).
    • content_type: content type 的字符串 (MIME type / media type) (例. image/jpeg).
    • file: SpooledTemporaryFile (a file-like object). 这是实际的Python文件,您可以将其直接传递给需要“类文件”对象的其他函数或库。

    3.1.2 UploadFileasync 方法:

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

    • write(data): 写 data (str or bytes) 到文件.
    • read(size): 读 size (int) bytes/characters 文件.
    • seek(offset): 文件指针定位到文件中的字节offset (int)位置
      • 例., await myfile.seek(0) 文件将会定位到文件开始.
      • 如果您一次运行await myfile.read()然后需要再次读取内容,则此功能特别有用。
    • close(): 关闭文件句柄

    正如所有的方法都是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兼容。

    相关文章

      网友评论

        本文标题:fastapi教程翻译(十七): Request Files(请

        本文链接:https://www.haomeiwen.com/subject/qdyumctx.html