如何在FastAPI中上传CSV文件并将其转换为Pandas数据帧



我想将文件上传到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}

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

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

选项1

由于pandas.read_csv()可以接受file-like对象,因此可以直接传递UploadFilefile-like对象。UploadFile公开了一个实际的PythonSpooledTemporaryFile,您可以使用.file属性获得它。示例如下。注意:pd.read_csv()不是async方法,因此,如果要使用async def端点,最好使用async方法读取文件的内容,如本文所述,然后使用下面的一个reamining选项将内容传递给pd.read_csv()。或者,您可以使用Starlette的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}

选项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}

选项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}

相关内容

  • 没有找到相关文章

最新更新