zoukankan      html  css  js  c++  java
  • FastAPI(24)- 详解 File,上传文件

    前言

    可以使用 FastAPI 提供的 File 定义客户端要上传的文件

    学习 File 前最好先学习 Form:https://www.cnblogs.com/poloyy/p/15311533.html

    安装 python-multipart

    要用 File,需要先安装这个库

    pip install python-multipart

    FIle

    File 是继承 Form,所以可以定义和 Form 相同的元数据以及额外的验证

    上传单个文件的栗子

    #!usr/bin/env python
    # -*- coding:utf-8 _*-
    """
    # author: 小菠萝测试笔记
    # blog:  https://www.cnblogs.com/poloyy/
    # time: 2021/9/22 9:52 上午
    # file: 21_File.py
    """
    import uvicorn
    from fastapi import FastAPI, File, UploadFile
    
    app = FastAPI()
    
    
    # file 参数类型是字节 bytes
    @app.post("/files/")
    async def create_file(file: bytes = File(...)):
        return {"file_size": len(file)}
    
    
    # file 参数类型是 UploadFile
    @app.post("/uploadfile/")
    async def create_upload_file(file: UploadFile = File(...)):
        result = {
            "filename": file.filename,
            "content-type": file.content_type,
            "read": await file.read()
        }
        return result
    
    
    if __name__ == "__main__":
        uvicorn.run(app="21_File:app", host="127.0.0.1", port=8080, reload=True, debug=True)

    重点

    • 因为 UploadFile 对象提供的方法都是 async 异步的,所以调用的时候都要加 await 比如 await file.read() (后面会详解 async/await )
    • 当使用异步方法时,FastAPI 在线程池中运行文件方法并等待它们

    不加 await 调用 async 方法会报错

        raise ValueError(errors)
    ValueError: [TypeError("'coroutine' object is not iterable"), TypeError('vars() argument must have __dict__ attribute')]
    WARNING:  StatReload detected file change in '21_File.py'. Reloading...

    file: bytes 的请求结果

    file: UploadFile 的请求结果

    查看 Swagger API 文档

    这样就可以直接在 Swagger API 文档上测试上传文件功能啦

    file: bytes

    • FastAPI 将会读取文件,接收到的内容就是文件字节
    • 会将整个内容存储在内存中,更适用于小文件

    file: UploadFile

    FastAPI 的 UploadFile 直接继承了 Starlette 的 UploadFile,但增加了一些必要的部分,使其与 Pydantic 和 FastAPI 的其他部分兼容

    UploadFile 相比 bytes 的优势

    • 存储在内存中的文件达到最大大小限制,超过此限制后,它将存储在磁盘中,可以很好地处理大文件,如图像、视频、大型二进制文件等,而不会消耗所有内存
    • 可以从上传的文件中获取元数据
    • 有一个类似文件的 async 异步接口
    • 它公开了一个 Python SpooledTemporaryFile 对象,可以将它传递给其他需要文件的库

    UploadFile 具有以下属性

    • filename:str,上传的原始文件名,例如 myimage.jpg
    • content_type:str,包含 content-type(MIME type / media type),例如 image/jpeg
    • file:一个 SpooledTemporaryFile(一个类似文件的对象)。 这是实际的 Python 文件,可以将其直接传递给其他需要“类文件”对象的函数或库

    UploadFIle 具有以下 async 异步方法

    • write(data):写入data ( str 或 bytes ) 到文件
    • read(size):读取文件的 size (int) 个字节/字符
    • seek(offset):转到文件中的字节位置 offset(int),如: await myfile.seek(0)  将转到文件的开头
    • close():关闭文件

     

    上传多个文件的栗子

    from typing import List
    
    
    @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]}

    正确传参的请求结果

    查看 Swagger API 文档

  • 相关阅读:
    codevs1227 方格取数2 注意数组啊啊啊啊啊啊啊啊啊啊
    codevs1033 蚯蚓的游戏问题 裸最小费用最大流,注意要拆点
    模板题 codevs 1993 草地排水 想学习的请看链接
    java初级易错问题总结
    JAVA基本数据类型所占字节数是多少?
    forword和重定向有什么区别?
    Spring框架注解
    hibernate利用mysql的自增张id属性实现自增长id和手动赋值id并存
    eclispe中安装hibernate插件
    struts2使用模型传值
  • 原文地址:https://www.cnblogs.com/poloyy/p/15312290.html
Copyright © 2011-2022 走看看