FastAPI从入门到实战(11)——表单请求与上传文件

本文主要记录表单的数据请求以及上传不同大小的文件、上传多个文件、获取文件信息等相关内容。

表单请求

@app07.post("/stu07/form")
def stu07_form(
        param1: str = Form(),
        param2: str = Form(),
        param3: int = Form()
):
    return {
        "param1": param1,
        "param2": param2,
        "param3": param3
    }

同路径参数和查询参数一致,利用fastapi内置的Form方法进行声明即可;

image-20221202182310041

上传一个bytes文件

@app07.post("/stu07/files")
def stu07_files(
        file: bytes = File()
):
    return {
        "files_size": len(file)
    }

上传文件都是以Form形式进行上传,上面代码中的File也是继承至Form;

如果把路径操作函数参数的类型声明为 bytes,FastAPI 将以 bytes 形式读取和接收文件内容。

这种方式把文件的所有内容都存储在内存里,适用于小型文件。

image-20221202182443372

使用UploadFile上传文件

@app07.post("/stu07/uploadfile/")
def stu07_uploadfile(
        file: UploadFile
):
    return {
        "文件名": file.filename,
        "内容类型": file.content_type
    }

UploadFilebytes 相比有更多优势;更适于处理图像、视频、二进制文件等大型文件,好处是不会占用所有内存;

使用UploadFile 也可以直接利用属性获取相关信息:

  • filename:上传文件名字符串(str),例如, myimage.jpg
  • content_type:内容类型(MIME 类型 / 媒体类型)字符串(str),例如,image/jpeg
  • fileSpooledTemporaryFilefile-like 对象)。其实就是 Python文件,可直接传递给其他预期 file-like 对象的函数或支持库。

UploadFile 支持以下 async 方法,(使用内部 SpooledTemporaryFile)可调用相应的文件方法。

  • write(data):把 data (str 或 bytes)写入文件;
  • read(size):按指定数量的字节或字符(size (int))读取文件内容;
  • 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()

image-20221202182630119

可选文件上传

@app07.post("/stu07/optionalfile")
def stu07_optional_file(
        file: Optional[bytes] = File(None)
):
    if not file:
        return {"message": "未上传文件"}
    else:
        return {"filesize": len(file)}

同样利用Optional或者Union进行设置即可;

image-20221202182723271

设置元数据

@app07.post("/stu07/uploadfile/metadata/")
def stu07_uploadfile_metadata(
        file: UploadFile = File(None, description="一个UploadFile文件")
):
    if not file:
        return {"message": "未上传文件"}
    else:
        return {"filename": file.filename}

这部分内容和路径参数和查询参数一致,根据需求进行设置即可;

image-20221202182807495

上传多文件

@app07.post("/stu07/fileslist")
def stu07_files_list(
        byteslist: List[bytes] = File(...),
        uploadfilelist: List[UploadFile] = File(...)
):
    return {
        "bytes_files_size": [len(file) for file in byteslist],
        "upload_filesname": [file.filename for file in uploadfilelist]
    }

上传多个文件,设置对应参数为List类型即可;

image-20221202182933070

同时上传表单参数和文件

@app07.post("/stu07/form_file/")
def stu07_form_file(
        file: UploadFile,
        form: str = Form()
):
    return {
        "filename": file.filename,
        "form": form
    }

混合上传,即在对应的路径函数中声明不同的参数即可;

image-20221202183039266

源码

# -*- coding: utf-8 -*-
# @Time: 2022/11/30 18:09
# @Author: MinChess
# @File: stu07.py
# @Software: PyCharm
from fastapi import APIRouter, Form, File, UploadFile
from typing import List, Optional
from fastapi.encoders import jsonable_encoder
from pydantic import BaseModel
from datetime import datetime

app07 = APIRouter()


# 一个form请求
@app07.post("/stu07/form")
def stu07_form(
        param1: str = Form(),
        param2: str = Form(),
        param3: int = Form()
):
    return {
        "param1": param1,
        "param2": param2,
        "param3": param3
    }


# 上传一个bytes类型的文件
@app07.post("/stu07/files")
def stu07_files(
        file: bytes = File()
):
    return {
        "files_size": len(file)
    }


# 使用UploadFile
@app07.post("/stu07/uploadfile/")
def stu07_uploadfile(
        file: UploadFile
):
    return {
        "文件名": file.filename,
        "内容类型": file.content_type
    }


# 可选文件上传
@app07.post("/stu07/optionalfile")
def stu07_optional_file(
        file: Optional[bytes] = File(None)
):
    if not file:
        return {"message": "未上传文件"}
    else:
        return {"filesize": len(file)}


# 设置UploadFile元数据
@app07.post("/stu07/uploadfile/metadata/")
def stu07_uploadfile_metadata(
        file: UploadFile = File(None, description="一个UploadFile文件")
):
    if not file:
        return {"message": "未上传文件"}
    else:
        return {"filename": file.filename}


# 多文件上传
@app07.post("/stu07/fileslist")
def stu07_files_list(
        byteslist: List[bytes] = File(...),
        uploadfilelist: List[UploadFile] = File(...)
):
    return {
        "bytes_files_size": [len(file) for file in byteslist],
        "upload_filesname": [file.filename for file in uploadfilelist]
    }


# 同时上传表单和文件
@app07.post("/stu07/form_file/")
def stu07_form_file(
        file: UploadFile,
        form: str = Form()
):
    return {
        "filename": file.filename,
        "form": form
    }


感谢阅读!

九陌斋地址:https://blog.jiumoz.com/archives/fastapi-cong-ru-men-dao-shi-zhan-biao-dan-qing-qiu-yu-shang-chuan-wen-jian

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spring是一个开源的Java框架,它提供了一种简化Java开发的方式。它的目标是通过依赖注入(DI)和向切面编程(AOP)来降低代码的耦合性,提高开发效率和系统的可维护性。从入门实战,你可以按照以下步骤进行学习和应用Spring框架: 1. 学习基础知识:了解Spring框架的核心概念,包括依赖注入、控制反转、面向切面编程等。可以通过阅读官方文档、参考书籍或在线教程来学习。 2. 搭建开发环境:安装Java开发环境(JDK)和集成开发环境(IDE),如Eclipse、IntelliJ IDEA等。然后下载并配置Spring框架。 3. 创建项目:使用Spring框架创建一个简单的Java项目。可以使用Spring Initializr(Spring的快速启动工具)创建一个基本的Spring Boot项目。 4. 配置和使用Spring的核心功能:学习如何通过注解或XML配置来使用Spring的核心功能,如依赖注入、Bean的生命周期管理、AOP等。 5. 数据访问与持久化:学习如何使用Spring框架进行数据库操作和持久化,可以使用Spring JDBC、Spring Data JPA或MyBatis等。 6. Web开发:学习如何使用Spring MVC构建Web应用程序。了解基本的请求处理、页面渲染、表单处理等。 7. 集成其他技术:学习如何集成其他常用的技术和框架,如Spring Security(安全认证和授权)、Spring Cloud(构建分布式系统)、Spring Integration(集成不同系统之间的数据交互)等。 8. 测试和调试:学习如何使用Spring框架进行单元测试和集成测试,并掌握调试技巧。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

九陌斋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值