Fastapi - UploadFile 在 Swagger /docs 中工作时无法使用 HTML 表单

Fastapi - UploadFile not working with HTML forms while it works in Swagger /docs

我正在尝试使用 Swagger/Fastapi 的 /docs 复制上传一个 有效 的文件,并使用 Pandas 处理它。但是,当我尝试使用 HTML 表单并且它不处理上传的文件时,我遇到了不同类型的错误。我尝试的最后一个代码如下,它返回一个 405 Method not Allowed 错误。

@app.get("/upload-test/")
def form_post(request: Request):
    """Displays the form to create a project"""
    return templates.TemplateResponse('upload-alerts.html', context={'request': request})


@app.get("/upload-test/file")
def form_post(request: Request):
    """Displays the form to create a project"""
    return {"message": "Upload success"}


@app.post("/upload-test/")
async def form_post(request: Request,
                    file: UploadFile = File(...)
                    ):
    """Uploads the file and processes it in Pandas"""
    contents = await file.read()
    test_data = io.BytesIO(contents)
    df = pd.read_csv(test_data, sep=";")
    df.to_sql("alert_test", if_exists="replace", con=database.SQLALCHEMY_DATABASE_URL, index=False)
    return {"filename":file.filename}

和 HTML:

<form action="file" enctype="multipart/form-data" method="post" autocomplete="off">
    <div class="mb-3">
        <div class="bg-light p-5 rounded-lg m-3">
            <label for="file" class="form-label">File Input</label>
            <input class="form-control" type="file" id="file" name="file">
        </div>
    </div>

    <div class="bg-light rounded-lg m-3">
        <div class="d-grid gap-2">
            <button class="btn btn-primary" type="button submit"><i class="bx bxs-cloud-upload"
                    style="font-size:1.4em;"></i> Upload Alerts</button>
        </div>
    </div>
</form>

不确定我在这里遗漏了什么.. :/

**更新**

感谢 fchancel 的回答,我发现我必须更改以下行:
@app.get("/upload-test")  # So remove the last forward slash in get
@app.post("/upload-test")  # Remove also the last forward slash in post

在 HTML 中将表单操作更改为“上传测试”以使其与 get/post:

相匹配
<form action="upload-test" enctype="multipart/form-data" method="post" autocomplete="off">

您收到 405 错误,因为 <form action="file" method='post'....> 具有 post 方法,而您的 "/upload-test/file " 端点是 GET。所以,确实,405 错误是有道理的。

因此,您需要匹配 form 和端点之间的方法。