
究極の対決:Flask vs. FastAPI
フレームワークを選ぶのは簡単なことではない。
両者は似ている。どちらもPythonのマイクロフレームワークで、肥大化したベルやホイッスルがない。また、どちらもAPIやウェブアプリケーションの構築に使われる。
両者はまた違う。Flaskはよりテストされたフレームワークであるため、信頼性が若干高く、広く使われている。FastAPIはより新しくモダンなフレームワークで、PydanticやSwaggerUIのようなビルトインサポートがたくさんあり、そのスピードで知られています。
各フレームワークについて理解を深めたところで、対決を始めよう!
インストール
新しいことを学ぶ上で最も難しいのは、実際に始めることだったりします。だからこそ、まずはインストールから始めよう。
Pythonのお気に入りのインストーラであるpipを使ってFlaskとFastAPIの両方をインストールするのは比較的簡単です。Pythonプロジェクトごとに隔離された環境である仮想環境内に両方をインストールするのも良い方法です。
フラスコ
$ pip install flask ファストAPI
$ pip install fastapi uvicorn結論:Uvicornと一緒にFastAPIをインストールすることに注意してください。Uvicornは、アプリケーションを高速に実行させる光速のサーバーだと考えてください。
ハロー・ワールド・アプリケーション
もしあなたがこれまでの人生でコードを1行しか書いたことがないとしたら、それはきっとこんな感じだろう:
print(“Hello World”)
他の言語、例えば北京語を学ぶようなものだ。ピンインと呼ばれるシステムがあり、これは中国語の文字を英語に書き起こし、人々が発音できるようにするものだ。これは、Hello Worldアプリケーションのように、すぐに使えるように設計されています。
FlaskとFastAPIの両方でhello worldアプリケーションがどのように見えるか見てみましょう。
フラスコ < 2.0
# inside of a Python .py file
from flask import Flask
app = Flask(__name__)
@app.route("/", methods=\[“GET”])
def home():
return {"Hello": "World"}
if __name__ == "__main__":
app.run() フラスコ2.0
from flask import Flask
app = Flask(__name__)
@app.get("/")
def home():
return {"Hello": "World"}
if __name__ == "__main__":
app.run() ファストAPI
# inside of a Python .py file
import uvicorn
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def home():
return {"Hello": "World"}
if __name__ == "__main__":
uvicorn.run("main:app")結論:Flaskの新しいバージョンでは @app.get()と @app.post()デコレータをルーティングのショートカットとして使うことができます。以前の @app.route()を使うには、HTTP動詞をメソッドリストに渡す必要がありました: methods=\[“GET”, “POST”].
注意:Flaskはデフォルトで
GETをデフォルトで使用するので、メソッドリストに指定する必要はありません。
これらのメソッドは、FastAPIでも各HTTPメソッドに対して以下のようなデコレートされたルートをサポートしています:
@app.get()@app.post()@app.put()@app.delete()
開発中のランニング
Hello World "アプリを書いたら、全世界に公開する前に、まず開発環境で、あるいは自分のマシンのローカル環境で動かしてみましょう。もしアプリケーションが期待通りに動かなかったら、人々は間違いなくパニックになるでしょう。そのパニックは最小限に抑えたいものです。
ターミナルで以下のコマンドを実行する:
フラスコ
$ export FLASK_APP=app.py
$ export FLASK_ENV=development
$ flask run ファストAPI
$ uvicorn main:app --reload結論:FastAPIはホット・リロードを使用し、コード変更中もアプリを実行し続けます。そのため、開発サーバーを再起動し続ける必要はありません。Flaskでは、追加のターミナルコマンドが必要です: export FLASK_ENV=developmentこれにより、開発サーバを再起動することなくコード変更を行うことができます。
HTTPメソッド
Hello Worldの例では、FlaskとFastAPIでGETがどのように見えるかを見ました。
フラスコ < 2.0
@app.route("/teams", methods=["POST"])
def create_team():
team = {
"team_name": "Phoenix Suns",
"players": [
{
"name": "Chris Paul",
"age": 36
}
]
}
teams.append(team)
return (jsonify(teams)) フラスコ2.0
@app.post("/teams")
def create_team():
team = {
"team_name": "Phoenix Suns",
"players": [
{
"name": "Chris Paul",
"age": 36
}
]
}
teams.append(team)
return (jsonify(teams)) ファストAPI
@app.post("/teams")
def create_team():
team = {
"team_name": "Phoenix Suns",
"players": [
{
"name": "Chris Paul",
"age": 36
}
]
}
teams.append(team)
return {'teams':teams}結論:Flask2.0とFastAPIは、POSTメソッドを実行すると非常によく似ている。トリックは、新しいデータがどのように作成されるかを見ることだ。
Flaskでは、Postmanのようなツールをクライアントとして使用する必要があり、POSTリクエストや作成したデータをJSON形式で確認することができます。
FastAPIにはPydanticとSwaggerUIが付属しており、POSTリクエストを含むブラウザからのリクエストに対して、自動ドキュメンテーションを使って対話することができます。
Flaskも自動ドキュメンテーションを使うことができるが、flask-swaggerを使ってインストールする必要がある。また、動作させるには多くの設定が必要です。次のセクションでは、FastAPI で POST リクエストを見る方法を見てみましょう。
自動ドキュメンテーション
マジックを信じるなら、間違いなく『オートマティック・ドキュメンテーション』が気に入るだろう。
FastAPIは、オブジェクトのモデリングと検証を簡単に行うためのフレームワークであるPydanticをベースにしています。Pydanticは、オブジェクトを簡単にモデル化し、検証するためのフレームワークです。Pydanticはコンストラクタを書く手間を省き、魔法のようなメソッドをすべて手に入れることができます。また、Pydanticはデータ検証を行い、より親しみやすいエラーを表示し、pythonの型ヒントを使用することで、デバッグ時間を短縮します。自動ドキュメントにアクセスするには、開発用サーバーが起動していることを確認し、localhostとアプリケーションが動作しているポートにアクセスしてください:
http://127.0.0.1:8000/docs他のHTTPメソッドを使用している場合は、これらも表示されます。
FastAPI Python automatic documentation POST request using Pydantic
自動ドキュメンテーションの素晴らしさを知るために、もっとクールなことをしてみましょう。FastAPIにこんなコードがあるとします:
ファストAPI
from pydantic import BaseModel
app = FastAPI()
class Player(BaseModel):
player_name: str
player_team: str
player_age: int
@app.post("/teams")
def create_team(request: Player):
return {'teams':request}Pydanticを使用するためには、Pydanticをインポートする必要があります。 BaseModelをインポートしなければならないことに注意してください。 Playerをインポートしなければならないことに注意してください。また、クラス内部で変数を型ヒントとして宣言し、POSTリクエストで辞書を返しています。
自動ドキュメントを表示すると、スキーマが表示されます。このスキーマは変数を持つモデルのスケルトンで、どのフィールドが必須で、どのフィールドがオプションなのかを見ることができます。
FastAPI Python automatic documentation with Pydantic POST request and schema
変数に値を渡すことで、APIエンドポイントを "Try it out "してテストすることもできる。例えば、ここでは変数に “Michael Jordan”を渡しています。 player_nameを渡しています。
FastAPI Python automatic documentation with Pydantic POST request and request body
そして実行をクリックすると、レスポンス・ボディが表示される。Postmanのような余計なツールを使う必要はない。
FastAPI Python automatic documentation with Pydantic POST request and response body
対話型ドキュメントはcurlコマンドも生成してくれるので、ゼロから書く必要はない:
FastAPI Python automatic documentation with Pydantic POST request and Curl
結論:Automatic DocumentationはPydanticとSwagger UIと一緒にFastAPIに付属しているので、これらの機能は間違いなく開発時間を短縮します。リクエストをテストするために外部ツールをインストールする必要はありません。
データ検証
Pydanticにはインストール時にFastAPIが付属しているので、コードに問題が発生すると、親切なエラーメッセージが表示されます。
ファストAPI
from pydantic import BaseModel
from typing import Optional
class Login(BaseModel):
username: str
password: str
agree_to_terms: Optional\[bool]
@app.post("/login")
def login(request: Login):
if request.username == "janedoe" and request.password == "password12345":
return {"message": "Success"}
return {"message": "Authentication Failed"}ここではPydantic BaseModelを継承したLoginクラスを作成し、その中に型ヒントを持つ変数を作成しています。最初に usernameが janedoeと passwordが passworld12345であるかどうかをチェックし、それに応じて成功または失敗のメッセージを返します。
自動ドキュメントに目を向け、リクエスト・ボディをテストする。 Noneを渡すことでリクエストボディをテストします:
FastAPI Python automatic documentation with Pydantic POST request and change request body
Pydanticが魔法をかけ、エラーの内容を正確に伝える親切なメッセージを表示します。この場合、エラー Expecting Valueを返します。 Noneを username.
FastAPI Python automatic documentation with Pydantic error message
結論:Flaskは社内でデータ検証をサポートしていません。データ検証のための強力な Pydantic パッケージは Flask-Pydantic.
URLまたはパス・パラメータ
パスまたはURLパラメータは、1つの単一アイテムをフェッチします。例えば、1人の選手を取得したいとします。URLに渡したものと同じidを持つ選手がユーザーに返されます。
辞書のリストがあり、このJSONファイルから1人の選手を取得したいとしよう:
players = [
{
"player_id": 1,
"name": "Giannis"
},
{
"player_id": 2,
"name": "Luka"
}
] フラスコ
@app.get('/players/<int:player_id>')
def get_player_details(player_id):
for player in players:
if player["player_id"] == player_id:
return jsonify(player)
ここでは、ポート5000のlocalhostにidが2のルートを渡しています。
Flask Python url or path parameters running on localhost returning JSON as response body
ファストAPI
@app.get("/player/{player_id}")
def get_player_details(player_id: int):
for player in players:
if player['player_id'] == player_id:
return {'player':player['name']}ここでは、ポート8000のlocalhostにidが1のルートを渡しています。
FastAPI Python url or path parameters running on localhost returning JSON as response body
結論:FastAPI では、Python の型ヒンティングを使っているので、Django のような他のフレームワークにコードを移植できます。Flaskの場合は、Pythonの型ヒンティングではなく、フレームワーク固有の型ヒンティングを使っているため、移植性がありません。
テンプレートフォルダ
Templates フォルダには、Flask や FastAPI で Web アプリケーションを構築しているときの HTML ファイルが保存され、変数を HTML で表示するには Jinja を使う必要があります。Jinja はテンプレートエンジンで、HTML を表示する Python のようなコードを書くことができます。
フラスコ
デフォルトでは、Flask は "templates" フォルダにあるテンプレートを探します。ファイル構造の中にテンプレートを作る必要があります。
Flask Python templates folder in file structure to render HTML files
Flask Python templates folder in file structure to render HTML files
そして、Jinjaを使って変数を二重中括弧で囲んで表示することができます:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Players</title>
</head>
<body>
<h1>Display Players</h1>
{{ player.name }}
{{ player.jersey_number }}
</body>
</html>
結論:JijnjaをインストールするとFlaskが付属してくる。FastAPIでは、Jinjaをインストールし、コード内にテンプレートフォルダを定義する必要があります。
プロダクション・サーバー
ある時点で、あなたはアプリケーションをデプロイし、世界に公開したいと思うだろう。
フラスコ
FlaskはWSGIと呼ばれるWebサーバーを使う。WSGIはWeb Server Gateway Interfaceの略で、長年Pythonの標準として使われてきた。難点は同期型であることだ。つまり、リクエストがたくさんあると、キューが完了するまで順番に待たなければならない。
ファストAPI
FastAPIは、ASGI(Asynchronous Server Gateway Interface)と呼ばれるウェブサーバーを使用します。つまり、大量のリクエストが来ても、他のリクエストが処理完了するまで待つ必要がないのだ。
結論:ASGIはリクエストを非同期に処理するため、Webアプリケーションのパフォーマンスを高速化します。
ドラムロールをお願いします。
優勝は......まあ、場合によるね。
こうして選ぶことができる。
使用方法 フラスコを使う:
長く使われているフレームワークであるため、実戦的である。
迅速なプロトタイプの開発
ウェブアプリケーション開発
使用方法 FastAPIを使用します:
開発期間とパフォーマンスにおけるスピード
コードのバグやエラーを減らすために
APIをゼロから構築する
さて、FlaskとFastAPIの両方を実際に見てきましたね。これで両方の理解が深まり、次のプロジェクトにはどちらが適しているかがわかったでしょう。