【徹底解説】Flask VS FastAPI
はじめに
今回の記事では、PythonでWeb開発を進める際に使われるWebフレームワークである「FastAPI」と「Flask」について、両者それぞれの特徴と強みを具体的なソースコードを用いて解説する。
この記事の対象とする読者
- これからPythonでWeb開発を進めることを検討している人
- APIを開発したいものの、どのような技術を使うべきが迷っている人
- FlaskとFastAPI両方とも、あるいはどちらか一方に興味を持っている人
- 社内あるいは個人開発の技術選定で、FastAPIあるいはFlaskの導入を検討している人
Flaskとは
FlaskはPythonで開発された軽量のWSGI(Web Server Gateway Interface)製のWebフレームワークである。
Flaskの説明に入る前に、WSGIについて簡潔に説明させてほしい。WSGIを完結に説明すると、Pythonにおいて、Web ServerとWebアプリケーションを接続するための標準化されたインターフェイスの定義である。WSGIが開発される以前は、Pythonに多種多様なWebフレームワークが存在しており、Web開発で問題になっていた。というのは、Webフレームワークを選択することで、使えるWebサーバーが制限されたり、その逆の制限が発生したりするからである。
WSGIが登場したことで、アプリケーション側がWSGIに対応していればアプリケーションのコードに修正を加える必要がなく、WSGIに対応したサーバを自由に選択できるのだ。そのため、高いポータビリティが得られる。
特徴
Flaskのアプリケーションは簡単に始められるので、初心者でも学びやすい。特定のツールやライブラリを必要とせず、コアな部分をシンプルに保ちつつ拡張性を高めることを目的として設計されている。ルーティングやリクエスト処理など、開発に必要なコンポーネントだけを提供している。
Flaskで強調しておきたい特徴は以下の通り。
- 軽量でシンプル: Flaskは最小限の機能を持っており、必要な機能は拡張ライブラリやプラグインで追加できる。これにより、開発者は必要な機能だけを選択してアプリケーションを構築できる。
- 学習コストの低さ: Flaskのシンプルさとわかりやすいドキュメントにより、Pythonの基本的な知識があればすぐに使い始められる。
- 柔軟性: Flaskはプロジェクト構造や機能に関して制約が少なく、開発者が自由にカスタマイズできるため、さまざまなニーズに対応できる。
- 大規模なコミュニティ: Flaskは広く使われており、豊富なリソースや拡張機能が使える。また、多くの開発者がコミュニティに参加しており、サポートや質問に対する回答が簡単に得られる。
FlaskはWebサイト等を構築する上で重宝する。Pythonで開発されているので、機械学習のモデルをデプロイするのに重宝する。主に、NetflixやMozilla等の大企業でも活用されている。
サンプルコード
Flaskは次のコマンドでインストールされる。
pip install flask
Flaskでリクエスト処理を行うプログラムは、以下のように記述する。下記のコードの例は、HTTPのGET
リクエストで送られた名前(name
)を受け取り、リテラル文字列でHello, {name}!
というメッセージを出力するAPIを作成している。
from flask import Flask, request
app = Flask(__name__)
@app.route('/hello', methods=['GET'])
def hello():
name = request.args.get('name', 'World') # 'name'パラメータが存在しない場合、デフォルトで'World'を使用
return f"Hello, {name}!"
if __name__ == '__main__':
app.run(debug=True)
上述のプログラムを実行するには、コマンドラインで以下のコマンドを実行する。
py app.py
プログラムが実行されると、http://127.0.0.1:5000/hello
にアクセスすることで、APIにリクエストを送れる。nameパラメータを指定して、http://127.0.0.1:5000/hello?name=John
にアクセスすれば、"Hello, John!"
というレスポンスが返される。
FastAPIとは
FastAPIは、pydantic
ライブラリでPythonに型定義の概念を取り入れながら、Python製のAPIを開発するWebフレームワークである。Flask同様に、軽量でモジュール化されている。文法もFlaskに多少類似医しているので、Flaskの基本的な文法の仕組みや知識を理解できていれば学習コストはそこまで高くない。
特徴
FastAPIは、非同期処理に対応し、高いパフォーマンスを提供することを目的として設計されている。また、API開発に特化しており、データ検証や自動ドキュメント生成などの便利な機能が含まれているのが強みとして挙げられる。
FastAPIが持つ特徴は以下の通りである。
- 高いパフォーマンス: FastAPIは非同期I/Oをサポートし、ASGI (Asynchronous Server Gateway Interface) フレームワークであるStarletteをベースにしています。これにより、高いパフォーマンスと並行性が実現されます。
- 型ヒントとデータ検証: FastAPIはPythonのタイプヒントを利用し、Pydanticを使ったデータ検証を行います。これにより、APIの入出力の型チェックや自動的なデータ検証が可能になり、エラーを減らすことができます。言い換えれば、動的型付け言語のPythonでもTypeScriptのような静的型付け言語に対応した開発ができるのだ。
- 自動ドキュメント生成: FastAPIは、APIの定義に基づいて自動的にOpenAPIとJSON Schemaのドキュメントを生成する。Swagger UIやReDocなどのツールを使って、インタラクティブなAPIドキュメントを提供できる。
- 依存性注入: FastAPIは依存性注入システムをサポートしており、コンポーネントの再利用やテストが容易になる。
- 学習コストの低さ: FastAPIはドキュメントが充実しており、Pythonの基本的な知識があれば比較的短時間で学習できる。文法構造がFlaskと似通っており、Flaskの開発経験があればより簡単に習得できる。
サンプルコード
まずは、FastAPIとサーバを立ち上げるのに必要なライブラリ(ASGIサーバ)をインストールする。
pip install fastapi[all] uvicorn
次に、以下のコードをmain.py
という名前のファイルに保存する。
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
return {"item_id": item_id, "q": q}
次に、Uvicorn(FastAPIアプリケーションを立ち上げる際に必要なサーバ)を使ってアプリケーションを起動する。以下はUvicornの例である。
uvicorn main:app --reload
上述のコマンドを入力し終えた後は、APIのテストを行う。ブラウザでhttp://127.0.0.1:8000
およびhttp://127.0.0.1:8000/items/5?q=test
にアクセスして、APIが正しく動作していることを確認します。
さらに、FastAPIは自動でAPIドキュメントを生成できる。以下のURLにアクセスすると、Swagger UIとReDocを確認できる。
- Swagger UI:
http://127.0.0.1:8000/docs
- ReDoc:
http://127.0.0.1:8000/redoc
ソースコードの比較
ここで、FlaskとFastAPIのソースコードを比較してみよう。
# Flask
from flask import Flask, request
app = Flask(__name__)
@app.route('/hello', methods=['GET'])
def hello():
name = request.args.get('name', 'World')
return f"Hello, {name}!"
if __name__ == '__main__':
app.run(debug=True)
# FastAPI
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
return {"item_id": item_id, "q": q}
上述の2つのソースコードを比較すると、FastAPIのほうがFlaskよりも少ないコード量で同じ処理を実現できていることがわかる。
# インスタンス変数appの書き方。
app = Flask(__name__) # Flask
app = FastAPI() # FastAPI
# デコレータの書き方。
@app.route('/hello', methods=['GET']) # Flask
@app.get("/") # FastAPI。引数にmethodを書く必要がなく、コンパクトにまとめられている
# サーバの立ち上げ方
# (1) Flaskの場合
if __name__ == '__main__':
app.run(debug=True)
# (2) FastAPIの場合。サーバを立ち上げる場合はuvicornを使ってコマンド入力するので、
# 上述のコードを書く必要がない。
Flask VS FastAPI
パフォーマンス
FastAPIは高性能なASGI(Asynchronous Server Gateway Interface)フレームワークであるStarletteを基盤として開発されている。一方で、FlaskはWSGIサーバとJinja2テンプレートエンジンを基盤として開発されている。これらを簡単に言えば、FastAPIは非同期処理やWebSocketを使った通信を得意としており、高速な処理が要求されるWeb開発ではFastAPIのほうに軍配が上がる。
さらに、FastAPIにあってFlaskにはない特徴が次の2点存在する。
- 型定義
- ドキュメントの自動生成
(1)において、動的型付け言語のPythonで型定義を使うメリットは以下の4つ存在する。
- コードの可読性の向上: 型ヒントは、関数や変数がどのような型を扱っているかを明示的に示せる。これにより、コードの可読性が向上し、他の開発者がコードの理解や保守がしやすくなる。
- IDEのサポート:型ヒントが適用されたコードは、IDEによる補完や検証が効果的に機能する。これにより、開発速度や生産性が上がる。
- 静的型チェック: 型ヒントを使用することで、静的型チェッカー(例: mypy, Pyright)が、実行前に型エラーや不整合を検出できる。これにより、バグの発見や修正が早まり、品質の高いコードが実現される。
- リファクタリングの容易さ:型ヒントが適用されたコードは、リファクタリングが容易になる。型ヒントにより、変更によって生じる型の不整合を早期に検出できるので、安全なリファクタリングができる。
(2)では、FastAPIはデフォルトでSwaggerとRedocをサポートしているので、サーバを立ち上げるだけで自動でAPIドキュメントが出力される。FastAPIは、特にAPI開発を中心に据えたプロジェクトが得意であり、データ検証や自動でドキュメントの生成等の機能を通して開発の効率を上げられるのだ。
FastAPIが最適な場面
- 高いパフォーマンスや非同期処理が必要な場合
- 型ヒントとデータ検証を利用した堅牢なAPI開発が必要な場合
- 自動生成されるドキュメントによる開発効率向上が期待される場合
Flaskが最適な場面
- シンプルで学習曲線が緩やかなフレームワークが求められる場合
- 豊富なプラグインや拡張機能によって柔軟な開発が行いたい場合
- 非同期処理が不要であり、パフォーマンスが最優先でない場合
両方とも最適な場面
FlaskやFastAPIが両方とも扱うのが得意な場面は機械学習である。ほとんどの場合、機械学習のコードはPythonで書かれているので、同じ言語を使っているFlaskやFastAPIとの相性が非常に抜群である。
まとめ
今回の記事では、Python製の軽量WebフレームワークFlaskとFastAPIの両方の特徴をそれぞれ比較した。
- Flask:Python製のWSGIベースのWebフレームワーク。非常に軽量で、リクエスト処理やエラーハンドリング等の必要最低限の機能しか備わっていない。
- FastAPI:Python製のASGIベースのWebフレームワーク。文法構造がFlaskに類似している。Flaskにはない独自の強みとして、型定義とSwaggerやReDocによるAPIドキュメントの自動生成にデフォルトで対応している点が挙げられる。
- 複雑な処理が不要で、パフォーマンスを優先しないWeb開発を行うならFlask、効率的にAPIの開発を進めたり、非同期処理を積極的に活用したいならFastAPI
両者の共通点として、以下のの2点が考えられる。
- Pythonの文法に関する知識があれば学習コストが高くないこと
- 同じ言語を用いる機械学習との相性が抜群であること
技術に優劣はないので、自分が開発したいプロジェクトに応じて最適な技術を選ぶことが最も重要になる。技術選択が常にトレードオフであることは忘れないように。
参考記事
Discussion
まさに読みたかった纏め記事ありがとうございます!もしかしたらですが「Flaskが最適な場面」と「FastAPIが最適な場面」のタイトルと内容が逆になっていませんか?
それぞれの最適な場面が逆?ですかね。