下面提供了有关如何将 FastAPI 中上传的文件转换为 Pandas DataFrame 的各种选项。如果您想将 DataFrame 转换为 JSON 并将其返回给客户端,请查看 this answer。如果您想使用async def 端点而不是def,请查看this answer 了解如何以async 方式读取文件内容,以及this answer 以了解两者之间的区别使用def 和async def。最好将 I/O 操作(在下面的选项中描述)包含在 try-except-finally 块中,以便您可以正确捕获/引发任何可能的异常和 close file 对象(如图所示 @987654324 @ 和 here)。
选项1
由于pandas.read_csv()可以接受file-like对象,所以可以直接传递UploadFile的file-like对象。 UploadFile 公开了一个实际的 Python SpooledTemporaryFile,您可以使用 .file 属性获得它。下面给出示例。注意:pd.read_csv() isn't an async method,因此,如果您要使用async def 端点,最好使用async 方法读取文件的内容,如here 所述,然后传递内容到pd.read_csv() 使用下面的扩孔选项之一。或者,您可以使用 Starlette 的run_in_threadpool()(如here 所述),它将在单独的线程中运行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}