フラスコユーザーのためのfastapi


フラスコが機械学習プロジェクトのAPI開発のための事実上の選択になっている間、FASTAPIと呼ばれる新しいフレームワークがあります.

私は最近FASAPIを生産フラスコプロジェクトを移植することによってスピンを与えることを決めた.Flatapiがフラスコから来るのを拾うのはとても簡単でした、そして、私はちょうど2、3時間でものを得て、走らせることができました.
自動データの検証、ドキュメントの生成とpydanticスキーマやPythonのタイピングなどのベストプラクティスで焼付けの追加の利点は、これは将来のプロジェクトのための強力な選択肢になります.
この記事では、FastAPIとFastAPIの両方の共通のユースケースの実装を対比してFastAPIを紹介します.
バージョン情報:
この文書の時点で、フラスコ版は1.1.2で、FastAPIバージョンは0.58.1です

インストール


両方のフラスコとfastapiはPYPIで利用可能です.Condaの場合は、conda-forge FASTAPIをインストールするには、デフォルトのチャネルで使用可能です.
フラスコ
pip install flask
conda install flask
FastAPI :
pip install fastapi uvicorn
conda install fastapi uvicorn -c conda-forge

" Hello World "の実行


フラスコ
# app.py
from flask import Flask

app = Flask(__name__)

@app.route('/')
def home():
    return {'hello': 'world'}

if __name__ == '__main__':
    app.run()
これで、次のコマンドを使用して開発サーバーを実行できます.デフォルトでポート5000で動作します.
python app.py
FastAPI
# app.py
import uvicorn
from fastapi import FastAPI

app = FastAPI()

@app.get('/')
def home():
    return {'hello': 'world'}

if __name__ == '__main__':
    uvicorn.run(app)
FastAPIディフェンダーと呼ばれる生産準備サーバにサービスuvicorn . 開発モードではデフォルトのポート8000で実行できます.
python app.py

生産サーバー


フラスコ
# app.py
from flask import Flask

app = Flask(__name__)

@app.route('/')
def home():
    return {'hello': 'world'}

if __name__ == '__main__':
    app.run()
生産サーバ用gunicorn フラスコの共通の選択です.
gunicorn app:app
FastAPI
# app.py
import uvicorn
from fastapi import FastAPI

app = FastAPI()

@app.get('/')
def home():
    return {'hello': 'world'}

if __name__ == '__main__':
    uvicorn.run(app)
FastAPIディフェンダーと呼ばれる生産準備サーバにサービスuvicorn . サーバを起動できます.
uvicorn app:app
また、実行してホットリロードモードで起動することができますて
uvicorn app:app --reload
また、ポートを変更することもできます.
uvicorn app:app --port 5000
労働者の数も同様に制御することができます.
uvicorn app:app --workers 2
使えますgunicorn Uvicornを管理するには、次のコマンドを使用します.労働者の数のようなすべての規則的なgunicorn旗-w ) 仕事.
gunicorn -k uvicorn.workers.UvicornWorker app:app

HTTPメソッド


フラスコ
@app.route('/', methods=['POST'])
def example():
    ...
FastAPI :
@app.post('/')
def example():
    ...
各HTTPメソッドの個々のデコレータメソッドがあります.
@app.get('/')
@app.put('/')
@app.patch('/')
@app.delete('/')

URL変数


URLからユーザIDを取得します./users/1 を返します.
フラスコ
@app.route('/users/<int:user_id>')
def get_user_details(user_id):
    return {'user_id': user_id}
FastAPI :
FastAPIでは、Pythonで型ヒントを使用して、すべてのデータ型を指定します.例えば、ここではuser_id は整数でなければなりません.URLパス内の変数もf文字列と同様に指定されます.
@app.get('/users/{user_id}')
def get_user_details(user_id: int):
    return {'user_id': user_id}

クエリ文字列


ユーザーがクエリ文字列を使用して検索項を指定できるようにします?q=abc URLで.
フラスコ
from flask import request

@app.route('/search')
def search():
    query = request.args.get('q')
    return {'query': query}
FastAPI :
@app.get('/search')
def search(q: str):
    return {'query': q}

ポストリクエスト


私たちがJSONポストリクエストをAと共に送りたいおもちゃの例を取りましょうtext キーと下位バージョンを取得します.
# Request
{"text": "HELLO"}

# Response
{"text": "hello"}
フラスコ
from flask import request

@app.route('/lowercase', methods=['POST'])
def lower_case():
    text = request.json.get('text')
    return {'text': text.lower()}
FastAPI :
あなたが単にフラスコから機能を複製するならば、あなたはFastAPIで以下のようにそれをすることができます.
from typing import Dict

@app.post('/lowercase')
def lower_case(json_data: Dict):
    text = json_data.get('text')
    return {'text': text.lower()}
しかし、これはFastAPIが受信されたJSONデータにマップするPydanticスキーマを作成する新しい概念を導入するところです.pydanticを使用して上記の例を再評価することができます.
from pydantic import BaseModel

class Sentence(BaseModel):
    text: str

@app.post('/lowercase')
def lower_case(sentence: Sentence):
    return {'text': sentence.text.lower()}
見られるように、辞書を得る代わりに、JSONデータは、スキーマのオブジェクトに変換されるSentence . このように、データ属性を使用してデータにアクセスできますsentence.text . これはまた、データ型の自動検証を提供します.ユーザーが文字列以外のデータを送信しようとすると、自動生成された検証エラーが与えられます.
無効なリクエスト例
{"text": null}
自動応答
{
    "detail": [
        {
            "loc": [
                "body",
                "text"
            ],
            "msg": "none is not an allowed value",
            "type": "type_error.none.not_allowed"
        }
    ]
}

ファイルアップロード


アップロードされたファイル名を返すAPIを作成しましょう.ファイルをアップロードする際に使用するキーはfile .
フラスコ
フラスコは、リクエストオブジェクトを介してアップロードされたファイルにアクセスすることができます.
# app.py

from flask import Flask, request
app = Flask(__name__)

@app.route('/upload', methods=['POST'])
def upload_file():
    file = request.files.get('file')
    return {'name': file.filename}
FastAPI :
FastAPIは関数キーを使用してファイルキーを指定します.
# app.py
from fastapi import FastAPI, UploadFile, File

app = FastAPI()

@app.post('/upload')
def upload_file(file: UploadFile = File(...)):
    return {'name': file.filename}

フォーム提出


以下に示すように定義されたテキストフォームフィールドにアクセスし、値をエコーします.
<input name='city' type='text'>
フラスコ
フラスコはリクエストオブジェクトを通してフォームフィールドにアクセスすることができます.
# app.py

from flask import Flask, request
app = Flask(__name__)

@app.route('/submit', methods=['POST'])
def echo():
    city = request.form.get('city')
    return {'city': city}
FastAPI :
関数フィールドを使用して、フォームフィールドのキーとデータ型を定義します.
# app.py
from fastapi import FastAPI, Form
app = FastAPI()

@app.post('/submit')
def echo(city: str = Form(...)):
    return {'city': city}
以下に示すように、フォームフィールドを省略することもできます
from typing import Optional

@app.post('/submit')
def echo(city: Optional[str] = Form(None)):
    return {'city': city}
同様に、次のようにフォームフィールドの既定値を設定できます.
@app.post('/submit')
def echo(city: Optional[str] = Form('Paris')):
    return {'city': city}

クッキー


クッキーにアクセスしたいname 要求から.
フラスコ
フラスコはリクエストオブジェクト経由でクッキーにアクセスできます.
# app.py

from flask import Flask, request
app = Flask(__name__)

@app.route('/profile')
def profile():
    name = request.cookies.get('name')
    return {'name': name}
FastAPI :
パラメータを使用してクッキーのキーを定義します.
# app.py
from fastapi import FastAPI, Cookie
app = FastAPI()

@app.get('/profile')
def profile(name = Cookie(None)):
    return {'name': name}

モジュールビュー


我々は、単一のアプリケーションからのビューを分解する.pyを別々のファイルにします.
- app.py
- views
  - user.py
フラスコ
フラスコでは、これを管理するために青写真と呼ばれる概念を使用します.まず、ユーザービューの青写真を作成します.
# views/user.py
from flask import Blueprint
user_blueprint = Blueprint('user', __name__)

@user_blueprint.route('/users')
def list_users():
    return {'users': ['a', 'b', 'c']}

そして、このビューはメインに登録されますapp.py ファイル.
# app.py
from flask import Flask
from views.user import user_blueprint

app = Flask(__name__)
app.register_blueprint(user_blueprint)
FastAPI :
FastAPIでは、青写真の等価物はルータと呼ばれます.まず、ユーザルータを作成します.
# routers/user.py
from fastapi import APIRouter
router = APIRouter()

@router.get('/users')
def list_users():
    return {'users': ['a', 'b', 'c']}
次に、このルータをメインアプリケーションオブジェクトに付けます.
# app.py
from fastapi import FastAPI
from routers import user

app = FastAPI()
app.include_router(user.router)

データ検証


フラスコ
フラスコは、ボックスから任意の入力データの検証機能を提供していません.カスタム検証ロジックを書くか、ライブラリを使用するかは一般的ですmarshmalllow or pydantic .
FastAPI :
FastAPIはPyDanticをそのフレームワークに包み、単にPydticスキーマとPythonのタイプヒントの組み合わせを使用してデータ検証を許可します.
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class User(BaseModel):
    name: str
    age: int

@app.post('/users')
def save_user(user: User):
    return {'name': user.name,
            'age': user.age}
このコードは自動検証を行いますname は文字列とage は整数です.他のデータ型が送られるならば、それは妥当なメッセージで妥当性検査エラーを生成します.
ここでは一般的なユースケースのためのpydanticスキーマの例を示します.

例1 :キー値ペア


{
  "name": "Isaac",
  "age": 60
}
from pydantic import BaseModel

class User(BaseModel):
    name: str
    age: int

例2:ものの収集


{
  "series": ["GOT", "Dark", "Mr. Robot"]
}
from pydantic import BaseModel
from typing import List

class Metadata(BaseModel):
    series: List[str]

例3 :入れ子オブジェクト


{
  "users": [
    {
      "name": "xyz",
      "age": 25
    },
    {
      "name": "abc",
      "age": 30
    }
  ],
  "group": "Group A"
}
from pydantic import BaseModel
from typing import List

class User(BaseModel):
    name: str
    age: int

class UserGroup(BaseModel):
    users: List[User]
    group: str
Pythonのタイプヒントについてはhere .

自動ドキュメント


フラスコ
フラスコは、ドキュメントの生成のための組み込み機能を提供していません.などの拡張機能がありますflask-swagger or flask-restful そのギャップを埋めるために、ワークフローは比較的複雑です.
FastAPI :
FastAPIは自動的にインタラクティブなswaggerドキュメントエンドポイントを生成する/docs とリファレンスドキュメント/redoc .
例えば、以下に示す単純なビューがあったとします.
# app.py
from fastapi import FastAPI

app = FastAPI()

@app.get('/search')
def search(q: str):
    return {'query': q}

swaggerドキュメント


サーバーを実行し、gotoを終了した場合http://127.0.0.1:8000/docs , 自動生成されたswaggerドキュメントを取得します.

対話的にブラウザ自体からAPIを試してみることができます.

redocドキュメント


あなたがエンドポイントをgotoする場合、swaggerに加えてhttp://127.0.0.01:8000/redoc , 自動生成されたリファレンスドキュメントを取得します.パラメータ、要求形式、応答形式、およびステータスコードに関する情報があります.

クロスオリジン資源共有


フラスコ
フラスコは、箱からコルズ支持を提供しません.このような拡張子を使用する必要がありますflask-cors 以下に示すようにCORSを設定します.
# app.py

from flask import Flask
from flask_cors import CORS

app_ = Flask(__name__)
CORS(app_)
FastAPI :
FastAPIはbuilt-in middleware を扱う.私たちは、どんな起源が我々のAPIにアクセスするのを許しているかについて、下記のCorsの例を示します.
# app.py
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=['*'],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

結論


したがって、FastAPIは、最高のプラクティスで焼かれた強固なAPIを構築するためのフラスコに優れた代替品です.あなたはdocumentation もっと学ぶ.

接続


あなたがこのブログ記事を楽しんだならば、私が毎週新しいブログ記事を共有するところで、私と連絡をとってください.