如何在 fastAPI 中为 <input type="file"> 定义 REST 端点(并使其与 angular 一起工作)?

How to define a REST endpoint in fastAPI for <input type="file"> (and make it work with angular)?

我正在做这个 angular tutorial。我正在尝试使用 python fastAPI 创建一个后端端点,它通过 HttpClient POST 接收数据,但我正在努力这样做。 (angular 13.0.2,python 3.7,fastapi 0.70.0)

html模板代码:

<input type="file" class="file-input" (change)="onFileSelected($event)" #fileUpload> 

<div class="file-upload">

    {{fileName || "No file uploaded yet."}}

    <button mat-mini-fab color="primary" class="upload-btn" (click)="fileUpload.click()">
        <mat-icon>attach_file</mat-icon>
    </button>
</div>

对应组件ts代码:

  onFileSelected(event) {

    const file: File = event.target.files[0]
    console.log(`onFileSelected(${file.name})`)

    if (file) {
      this.fileName = file.name;
      const formData = new FormData();
      formData.append("thumbnail", file);
      const upload$ = this.http.post("http://localhost:8000/thumbnail-upload", formData);
      upload$.subscribe();
      console.log("upload done?")
  }

fastapi 代码: 灵感来自 this

@app.post("/thumbnail-upload")
def create_file(file: UploadFile = File(...)):
    print(file)
    return {"file_size": len(file)}

似乎正在进行一些正常的通信,但我被困在这里:

uvicorn 服务器的输出:

←[32mINFO←[0m:     127.0.0.1:18231 - "←[1mPOST /thumbnail-upload   HTTP/1.1←[0m" ←[31m422 Unprocessable Entity←[0m

浏览器调试控制台输出:

zone.js:2863 POST http://localhost:8000/thumbnail-upload 422 (Unprocessable Entity)
core.mjs:6495 ERROR HttpErrorResponse {headers: HttpHeaders, status: 422, statusText: 'Unprocessable Entity', url: 'http://localhost:8000/thumbnail-upload', ok: false, …}

我需要如何实施 fastAPI 端点才能获得此 运行? 免责声明:我是 angular/fastapi 的新手,如果我忘记包含必要的信息,请。告诉我缺少什么 ;)

422 错误消息的正文会告诉您到底缺少什么字段。从您的代码看来,您正在以 thumbnail 名称提交文件,但您在 FastAPI 路由中使用的是 file 名称。由于这两个不匹配,FastAPI 找不到您假定存在的文件。将表单参数重命名为 file 或将 FastAPI 参数重命名为 thumbnail:

@app.post("/thumbnail-upload")
def create_file(thumbnail: UploadFile = File(...)):
    print(thumbnail)
    return {"file_size": len(thumbnail.file.read())}

UploadFile 对象还公开了 file 以便在后台与假脱机文件进行交互。因为它不会直接给你字节,我认为调用 len 不会做你期望的事情。