You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI开发:如何像Jupyter Notebook一样逐行调试函数并检查变量?

如何在Jupyter中调试FastAPI端点的函数逻辑

当然有办法!我平时开发FastAPI的时候也经常遇到这种需求——不想每次都启动uvicorn服务器,只想像调试普通Python代码一样,逐行测试函数里的逻辑,熟悉每个变量的含义和接口。下面给你几个实用的方案,一步步解决你的问题:

方案1:把核心业务逻辑抽成独立函数

这是最推荐的做法,既方便调试,也利于后续写单元测试。你可以把upload_dataset_to_server里处理文件、生成DataFrame、保存数据的核心逻辑拆出来,变成一个不依赖FastAPI框架的普通函数:

import pandas as pd
from io import StringIO
import ml  # 假设你的ml模块已经存在

def process_file(raw_content: bytes, filename: str, encoding='utf-8', delimiter=',', sheets='Sheet1'):
    """独立的文件处理逻辑,和FastAPI框架解耦"""
    try:
        if 'xlsx' in filename.split('.')[-1]:
            df = pd.read_excel(io=raw_content, sheet_name=sheets)
            filename = filename.replace('xlsx', 'csv')
            filepath = ml.folder_path + f'\\datastore\\dataset\\{filename}'
        else:
            content = str(raw_content, encoding=encoding)
            data = StringIO(content)
            df = pd.read_csv(filepath_or_buffer=data, encoding=encoding, delimiter=delimiter)
            filepath = ml.folder_path + f'\\datastore\\dataset\\{filename}'
        
        df.to_csv(path_or_buf=filepath, index_label=False)
        resp = ml.store_dataframe(df)
        return resp, df  # 返回结果和DataFrame方便调试
    except UnicodeDecodeError as error:
        return str(error), None

然后在Jupyter Notebook里,你就可以随便构造测试数据,逐行或者整块运行这个函数了:

# 测试CSV文件
test_csv_content = b"id,name,age\n1,Alice,25\n2,Bob,30"
resp, df = process_file(test_csv_content, "test.csv")
print("处理结果:", resp)
display(df)  # 在Jupyter里直接展示DataFrame

# 测试XLSX文件(先准备一个本地的test.xlsx文件)
with open("test.xlsx", "rb") as f:
    test_xlsx_content = f.read()
resp, df = process_file(test_xlsx_content, "test.xlsx")
print("处理结果:", resp)
display(df)

这样你就能随时查看raw_content转成的content、data对象,以及生成的df是什么样的,完全不用启动服务器。

方案2:模拟FastAPI的UploadFile对象

如果你不想改动原函数,也可以直接在Jupyter里模拟FastAPI依赖的UploadFile对象,然后直接调用原函数。UploadFile是Starlette库提供的类,我们可以手动构造它:

from fastapi import UploadFile
from io import BytesIO
from your_module import upload_dataset_to_server  # 导入你的原函数

# 构造模拟的UploadFile
test_csv_file = UploadFile(
    filename="test.csv",
    file=BytesIO(b"id,name,age\n1,Alice,25\n2,Bob,30")
)

# 因为原函数是async的,在Jupyter里可以直接用await执行
result = await upload_dataset_to_server(file=test_csv_file)
print("接口返回结果:", result)

# 如果你的Jupyter环境不支持直接await,就用asyncio.run包裹
import asyncio
result = asyncio.run(upload_dataset_to_server(file=test_csv_file))
print("接口返回结果:", result)

这种方式可以完全模拟真实的请求场景,你甚至可以在原函数里加print语句或者断点,比如在raw = await file.read()后面加print(raw),就能看到读取到的文件内容了。

方案3:用FastAPI的TestClient发起测试请求

FastAPI官方提供了TestClient工具,本质是用requests库模拟HTTP请求,你可以在Jupyter里用它来调用你的端点,同时调试函数内部:

from fastapi.testclient import TestClient
from your_module import app  # 导入你的FastAPI app实例

client = TestClient(app)

# 上传本地的测试文件
with open("test.csv", "rb") as f:
    response = client.post(
        "/upload_dataset",
        files={"file": ("test.csv", f, "text/csv")},
        params={"encoding": "utf-8", "delimiter": ","}
    )

print("响应状态码:", response.status_code)
print("响应内容:", response.json())

如果想调试函数内部的细节,你可以在原函数里插入断点,比如:

async def upload_dataset_to_server(file: UploadFile = File(...), encoding='utf-8', delimiter=',', sheets='Sheet1'):
    raw = await file.read()
    print("读取到的原始字节:", raw)  # 打印原始数据
    import pdb; pdb.set_trace()  # 插入断点,运行到这里会暂停
    # 后续代码...

然后运行TestClient的请求,程序会在断点处暂停,你可以查看raw、file等变量的详细信息,还能逐行执行后续代码。

额外调试技巧

  • 在Jupyter里可以用%debug魔法命令,当代码抛出异常时,输入%debug就能进入调试模式,查看报错时的变量状态。
  • 用display()函数代替print(),可以在Jupyter里更友好地展示DataFrame、字典等复杂对象。

内容的提问来源于stack exchange,提问作者Della

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 15:27:48