如何在 FastAPI 中上传 CSV 文件并将其转换为 Pandas Dataframe?

Abh*_*hth -2 python csv dataframe pandas fastapi

我想将文件上传到 FastAPI 后端并将其转换为 Pandas DataFrame。但是,我似乎不明白如何使用 FastAPI 的UploadFile对象来做到这一点。更具体地说,我应该将什么传递给该pd.read_csv()函数?

这是我的 FastAPI 端点:

@app.post("/upload")
async def upload_file(file: UploadFile):
    df = pd.read_csv("")
    print(df)
    return {"filename": file.filename}
Run Code Online (Sandbox Code Playgroud)

Chr*_*ris 5

下面给出了如何将上传的 FastAPI 文件转换为 Pandas DataFrame 的各种选项。如果您还想将 DataFrame 转换为 JSON 并将其返回给客户端,请查看此答案。如果您想使用async def端点而不是def,请查看此答案,了解如何以某种async方式读取文件内容,以及此答案def以了解使用和 之间的区别async def。最好将 I/O 操作(在下面的示例中)包含在一个try-except-finally块中(如此处和此处所示以便您可以捕获/引发任何可能的异常并close正确file地释放对象记忆并避免潜在的错误。

关于如何上传和读取 CSV 文件的相关答案可以在这里找到(给出使用 Jinja2 模板的示例),以及这里(将上传的 CSV 文件转换为 JSON 并将其返回给客户端)和这里(提供不使用外部的解决方案)图书馆)。

选项1

既然pandas.read_csv()可以接受一个file-like对象,就可以直接传递该file-like对象UploadFile。公开了您可以使用该属性获取的UploadFile实际 Python 。下面给出示例。注意:这不是一种方法,因此,如果您要使用端点,最好使用一种方法读取文件的内容,如此处所述然后使用其中一种方法将内容传递给下面的选项。或者,您可以使用 Starlette (如此处所述,它将在单独的线程中运行,以确保主线程(运行协程的地方)不会被阻塞。SpooledTemporaryFile.filepd.read_csv()asyncasync defasyncpd.read_csv()run_in_threadpool()pd.read_csv(file.file)

from fastapi import FastAPI, File, UploadFile
import pandas as pd

app = FastAPI()

@app.post("/upload")
def upload_file(file: UploadFile = File(...)):
    df = pd.read_csv(file.file)
    file.file.close()
    return {"filename": file.filename}
Run Code Online (Sandbox Code Playgroud)

选项2

将字节转换为字符串,然后将其加载到内存中的文本缓冲区(即StringIO)中,该缓冲区可以转换为数据帧:

from fastapi import FastAPI, File, UploadFile
import pandas as pd
from io import StringIO

app = FastAPI()

@app.post("/upload")
def upload_file(file: UploadFile = File(...)):
    contents = file.file.read()
    s = str(contents,'utf-8')
    data = StringIO(s) 
    df = pd.read_csv(data)
    data.close()
    file.file.close()
    return {"filename": file.filename}
Run Code Online (Sandbox Code Playgroud)

选项3

请改用内存中的字节缓冲区(即BytesIO),从而节省将字节转换为字符串的步骤,如选项 2 所示:

from fastapi import FastAPI, File, UploadFile
import pandas as pd
from io import BytesIO
import uvicorn

app = FastAPI()

@app.post("/upload")
def upload_file(file: UploadFile = File(...)):
    contents = file.file.read()
    data = BytesIO(contents)
    df = pd.read_csv(data)
    data.close()
    file.file.close()
    return {"filename": file.filename}
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

6254 次

最近记录:

2 年,7 月 前