【FastAPI】アップロード・ダウンロードファイルの操作
FastAPI
のAPI
でのファイルの
- アップロード
- ダウンロード
方法についてご紹介いたします。
サーバーにある静的ファイルの配信方法や、エンドポイントでの認証を含めた配信方法です。
FastAPIの基礎についての記事まとめ
File
ファイルを受け取るためのクラスは主に2種類あり
File
UploadFile
があります。UploadFile
はFile
のラッパークラスです。より使いやすく、大きなファイルでも操作可能にしたものです。両方見ていきます。
File
ファイルを受け取るには、bytes
を宣言し、デフォルトとしてFile
を受け取るように記述します。
def file(file: bytes = File(...)):
@router.post('/')
def get_file(file: bytes = File(...)):
content = file.decode('utf-8')
lines = content.split('\n')
return {'lines': lines}
ファイルをアップロードできるエンドポイントを作成しました。
テキストファイルをサンプルとしてアップロードしてみましょう。テキストの中身を返すようにしています。
Hello FastAPI
txt file
UploadFile
前述の通り、File
の他にUploadFile
があります。
File
と比較するとより多くの機能を持つほか、大きいファイルサイズの画像やビデオが扱えるようになります。
def upload_file(file: UploadFile = File(...)):
アップロードされたファイル名を返すエンドポイントを作成しました。
@router.post('uploadfile')
def get_uploadfile(upload_file: UploadFile = File(...)):
return {
'filename': upload_file.filename
}
class UploadFile:
"""
An uploaded file included as part of the request data.
"""
spool_max_size = 1024 * 1024
def __init__(
self, filename: str, file: typing.IO = None, content_type: str = ""
) -> None:
self.filename = filename
self.content_type = content_type
if file is None:
file = tempfile.SpooledTemporaryFile(max_size=self.spool_max_size)
self.file = file
アップロードファイルの保存
アップロードファイルをローカルに保存します。
https://docs.python.org/ja/3/library/functions.html#open
https://docs.python.org/ja/3/library/shutil.html
from fastapi import UploadFile
import shutil
@router.post('uploadfile')
def get_uploadfile(upload_file: UploadFile = File(...)):
path = f'files/{upload_file.filename}'
with open(path, 'w+b') as buffer:
shutil.copyfileobj(upload_file.file, buffer)
return {
'filename': path,
'type': upload_file.content_type
}
shutil.coyfileobj()
でローカル上の指定フォルダにファイルがコピーされます。
ファイルアップロードのAPIを叩いてみると・・・
下記の様に、ローカル上のfile/
ディレクトリに保存されていることが確認できました。
静的ファイルを外部に配信する
アップロードしたファイルを外部に公開できるようにします。
例えば、127.0.0.1:8000/files/fastapi.png
のような形式で見れたら良いですね。
pip install aiofiles
次にmain.py
に追記していきます。
fastapi.staticfiles
からStaticFiles
をインポートし、app.mount()
を記述します。
from fastapi.staticfiles import StaticFiles
~~~
app.mount('/files', StaticFiles(directory="files"), name='files')
http://127.0.0.1:8000/files/
のアップロードしたファイル名のパスにブラウザからアクセスすると閲覧できるようになっているはずです。
ダウンロード
前述のように、ただファイルを公開するだけではなく、ダウンロードリンクとして実装します。
https://fastapi.tiangolo.com/ja/advanced/custom-response/?h=fileresponse#fileresponse
エンドポイント経由となるため、認証機能を追加したりすることが可能です。
エンドポイントの作成
fastapi.responses
からFileResponse
をインポートし、response_class
に指定します。
from fastapi.responses import FileResponse
~~~
@router.get('/download/{name}', response_class=FileResponse)
def get_file(name: str):
path = f'files/{name}'
return path
FileResponse
の通り、file
が配信されています。
認証機能の追加
この状態ですと、誰でも閲覧できてしまうので認証機能をAPI
に追加します。
@router.get('/download2/{name}', response_class=FileResponse)
def get_file(name: str, current_user: str = Depends(get_current_user)):
path = f'files/{name}'
return path
確認してみると・・・
きちんと保護されていますね!
FastAPIの基礎についての記事まとめ
コメント