17.FastAPI 表单数据

17.FastAPI 表单数据

如果接收的数据不是JSON格式,而是表单字段,则需要使用Form。在FastAPI中,要使用Form,需要事先安装python-multipart,执行如下命令:

pip install python-multipart 

Form参数与Path、Query、Body一样,从fastapi导入。其使用方法相同。

17.1使用Form参数

from fastapi import FastAPI
from fastapi import Form
​
app = FastAPI()
​
@app.post(path='/login')
async def login(uacc: str = Form(...), upwd: str = Form(...)):
    res = False
    if uacc == 'admin' and upwd == 'admin':
        res = True
    return {'res': res}

执行请求:

curl -d "uacc=admin&upwd=123" -X POST http://127.0.0.1:8000/login
{"res":false}
curl -d "uacc=admin&upwd=admin" -X POST http://127.0.0.1:8000/login
{"res":true}

在使用Form参数时,需要注意:可以在一个路由操作中声明多个 Form 参数,但不能同时声明要接收 JSON 的 Body 字段。因为此时请求体的编码是 application/x-www-form-urlencoded,不是 application/json;这不是 FastAPI 的问题,而是 HTTP 协议的规定。

17.2使用File参数

在web开发中,文件上传的需求是肯定会出现的,FastAPI通过多种方式支持文件上传操作。首先可以使用与Form、Body等相同的File,File直接继承自Form类。代码如下:

from fastapi import FastAPI
from fastapi import File
​
app = FastAPI()
​
@app.post(path='/upload')
async def login(file: bytes = File(...)):
    with open('test.png', 'wb') as f:
        f.write(file)
    return {'file_size': len(file)}

执行请求:

curl -F "file=@demo.png" -X POST http://127.0.0.1:8000/upload
{"file_size":10731}

通过查看项目所在文件夹,其下的test.png文件与demo.png文件相同。

在FastAPI中,声明文件体必须使用 File,否则,FastAPI 会把该参数当作查询参数或请求体(JSON)参数;文件作为表单数据上传;如果路由操作函数参数的类型声明为 bytes,FastAPI 将以 bytes 形式读取和接收文件内容,这种方式把文件的所有内容都存储在内存里,适用于小文件。所以,在大多数情况下,我们会使用 UploadFile。

17.3UploadFile类型

定义 File 参数时使用 UploadFile 类型,UploadFile 的属性如下:

  • filename:上传文件的文件名字符串;

  • content_type:内容类型(MIME 类型 / 媒体类型)字符串(str),如:image/jpeg;

  • file: 文件,可直接传递给其他file对象的函数或支持库。

UploadFile 支持以下 async 方法:

  • write(data):把 data (str 或 bytes)写入文件;

  • read(size):按指定数量的字节或字符(size (int))读取文件内容;

  • seek(offset):移动至文件 offset (int)字节处的位置;例如,await myfile.seek(0) 移动到文件开头;执行 await myfile.read() 后,需再次读取已读取内容时,这种方法特别好用;

  • close():关闭文件。

因为上述方法都是 async 方法,要搭配 await 使用。

代码如下:

from fastapi import FastAPI
from fastapi import File
from fastapi import UploadFile
​
app = FastAPI()
​
@app.post(path='/upload')
async def login(file: UploadFile = File(...)):
    with open('test.png', 'wb') as f:
        f.write(await file.read())
    return {'file_name': file.filename}

执行请求:

curl -F "file=@demo.png" -X POST http://127.0.0.1:8000/upload
{"file_name":"demo.png"}

通过查看项目所在文件夹,其下的test.png文件与demo.png文件相同。

使用UploadFile与 bytes 相比,其优势:

  • 使用 spooled 文件:存储在内存的文件超出最大上限时,FastAPI 会把文件存入磁盘;

  • 这种方式更适于处理图像、视频、二进制文件等大型文件,好处是不会占用所有内存;

  • 可获取上传文件的元数据;

  • 自带 file-like async 接口;

  • 暴露的 Python SpooledTemporaryFile 对象,可直接传递给其他预期「file-like」对象的库。

17.4多文件上传

FastAPI支持同时上传多个文件,可以使用一个表单字段上传多个文件,此时,路由操作函数要声明为包含bytes或UploadFile的列表。代码如下:

from fastapi import FastAPI
from fastapi import File
from fastapi import UploadFile
from typing import List
​
app = FastAPI()
​
@app.post(path='/upload')
async def upload(files: List[bytes] = File(...)):
    sizes = [len(file) for file in files]
    index = 0
    for file in files:
        with open("{0}.png".format(index), 'wb') as f:
            f.write(file)
            index += 1
    return sizes
​
@app.post(path='/upload_file')
async def upload_file(files: List[UploadFile] = File(...)):
    names = [file.filename for file in files]
    for file in files:
        with open(file.filename, 'wb') as f:
            f.write(await file.read())
    return names

17.5同时请求表单与文件

在FastAPI中,支持同时使用表单和文件。但可以在一个路径操作中声明 File 和 Form 参数,但不能同时声明要接收 JSON 的 Body 字段。因为此时请求体的编码是 multipart/form-data,不是 application/json。

from fastapi import FastAPI
from fastapi import Form
from fastapi import File
from fastapi import UploadFile
from typing import List

app = FastAPI()

@app.post(path='/upload')
async def upload(files: List[bytes] = File(...), desc: str = Form(...)):
    print(desc)
    sizes = [len(file) for file in files]
    index = 0
    for file in files:
        with open("{0}.png".format(index), 'wb') as f:
            f.write(file)
            index += 1
    return sizes


@app.post(path='/upload_file')
async def upload_file(files: List[UploadFile] = File(...), desc: str = Form(...)):
    print(desc)
    names = [file.filename for file in files]
    for file in files:
        with open(file.filename, 'wb') as f:
            f.write(await file.read())
    return names

执行请求:

curl -F "desc=images" -F "files=@demo.png" -F "files=@elephant.png" -X POST http://127.0.0.1:8000/upload
[10731,50279]
curl -F "desc=images" -F "files=@demo.png" -F "files=@elephant.png" -X POST http://127.0.0.1:8000/upload_file
["demo.png","elephant.png"]

后台print输出:

images
INFO:     127.0.0.1:52608 - "POST /upload HTTP/1.1" 200 OK
images
INFO:     127.0.0.1:52611 - "POST /upload_file HTTP/1.1" 200 OK
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
FastAPI 是一种基于 Python 的现代 Web 框架,它提供了快速构建高性能 Web 应用的能力。它支持前后端数据交互,可以使用 JSON、FormData 或其他格式来发送数据。 下面是一个简单的 FastAPI后端数据交互的示例: 1. 首先,需要在前端编写一个表单,并在表单添加一个提交按钮: ```html <form id="my-form"> <input type="text" name="name"> <input type="email" name="email"> <button type="submit">提交</button> </form> ``` 2. 接下来,在 JavaScript 编写发送数据的代码: ```javascript const form = document.querySelector('#my-form'); form.addEventListener('submit', async (e) => { e.preventDefault(); const formData = new FormData(form); const response = await fetch('/api/my-endpoint', { method: 'POST', body: formData, }); const data = await response.json(); console.log(data); }); ``` 3. 在后端,我们可以使用 FastAPI 来处理请求并返回响应: ```python from fastapi import FastAPI, Form app = FastAPI() @app.post('/api/my-endpoint') async def my_endpoint(name: str = Form(...), email: str = Form(...)): # 处理请求数据 # ... # 返回响应数据 return {'success': True} ``` 在上面的代码,我们使用 FastAPI 的 `Form` 类型来解析表单数据,并将其作为参数传递给路由处理函数。在处理函数,我们可以使用解析后的数据来执行相应的操作,并返回响应数据。 以上就是一个简单的 FastAPI后端数据交互的示例,你可以根据自己的需求进行修改和扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Janeb1018

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

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

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

打赏作者

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

抵扣说明:

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

余额充值