如何在 fastAPI 中为 <input type="file"> 定义一个 REST 端点(并使其与 Angular 一起使用)?
Posted
技术标签:
【中文标题】如何在 fastAPI 中为 <input type="file"> 定义一个 REST 端点(并使其与 Angular 一起使用)?【英文标题】:How to define a REST endpoint in fastAPI for <input type="file"> (and make it work with angular)? 【发布时间】:2021-12-30 20:52:19 【问题描述】:我正在这样做angular tutorial。我正在尝试使用 python fastAPI 创建一个后端端点,该端点通过 HttpClient POST 接收数据,但我正在努力这样做。 (角度 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 很陌生,如果我忘记包含必要的信息,请。告诉我缺少什么;)
【问题讨论】:
【参考方案1】: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
不会达到您的预期。
【讨论】:
好的,这就行了。玩弄,我发现formData.append("file", file, file.name);
也适用于我的第一个实现(是的,len(file)
抛出了一个错误)。你能解释一下参数名称在 fastAPI 中的重要性吗?是不是因为 formdata 以键/值形式出现,然后被视为 kwarg?
一个表单可以包含多个文件,可以使用相同的名称或不同的名称。参数名称需要与 FastAPI 匹配,以了解数据与哪个文件相关,并知道它实际上是预期的参数,而不是随机的。如果您使用过查询参数,可能会更清楚; user_id=38
突然匹配 hits: int
会给你各种奇怪的结果。以上是关于如何在 fastAPI 中为 <input type="file"> 定义一个 REST 端点(并使其与 Angular 一起使用)?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Codeception 验收测试中为 <input type="email"> 获取 WebGuy->fillField?