概要
Fast APIで何かしら作ってみたかったのでファイルを入力として受け付けるAPIでも作成してみようかと思います
(ユースケースは正直あまり思い浮かんでいないですが、形式の決まっているデータをファイルにまとめてたくさん送ることができるとかでしょうか?)
材料
Fast APIでファイルの入力を受け付ける方法について調べます
File
とForm
を同時に使うことで実現が可能になるそうです(リファレンス)
※またファイルやフォームデータを受け取るためにpython-multipartのインストールが必要でした
公式のリファレンスをコードに起こして、docsを確認してみた結果が以下になります
実際にリクエストしてみると渡されたファイルのサイズ、種類、そして文字列それぞれをjson形式でレスポンスする形となっています
import uvicorn
from fastapi import FastAPI, File, Form, UploadFile
from typing import Annotated
app = FastAPI()
@app.post("/files/")
async def create_file(
file: Annotated[bytes, File()],
fileb: Annotated[UploadFile, File()],
token: Annotated[str, Form()],
):
return {
"file_size": len(file),
"token": token,
"fileb_content_type": fileb.content_type,
}
if __name__ == "__main__":
uvicorn.run("main:app", reload=True)
想定されるユースケース
どういったタイミングで使うか考えてみましたが、やはりまとまったデータの一括注入とかでしょうか?
例えば、以前作成した動画リンクからダウンロードするAPIを一括で取り扱うなどいかがでしょうか?(参考)
@app.post("/files/donwloader/")
async def from_file_download(
file: UploadFile = File(...)
):
URL_PATTERN = re.compile(r'http.*')
content = await file.read()
data = json.loads(content)
for i in data:
try:
ytdlp_opts = {
"format": "mp4",
}
with YoutubeDL(ytdlp_opts) as ydl:
if re.match(URL_PATTERN, i["link"]):
ydl.download(i["link"])
else:
raise Exception
except Exception as e:
print(e)
if __name__ == "__main__":
uvicorn.run("main:app", reload=True)
上記のようなコードにすれば、一回のリクエストでファイルに記載したリンク先のものを随時ダウンロードしてくれるようになります
また、引き渡しの際に使用するファイルの形式はjson形式で以下を想定しております(titleについてはあってもなくても可です)
[
{
"title": "title_1",
"link": "https://www.example.com/"
},
{
"title": "title_2",
"link": "https://www.example.com/"
}
]
あとはcurlでリクエストをしてみると、jsonファイルで指定したリンクのものがダウンロードできます
curl -X 'POST' \
'http://localhost:8080/files/donwloader/' \
-H 'accept: application/json' \
-H 'Content-Type: multipart/form-data' \
-F 'file=@sample.json;type=application/json'
おわりに
こんな感じでファイルの入力ができるようになると一気にデータの取り扱う量が増えたように見えますね
今後もこの調子で扱える領域増やしていきたいと思います