はじめに
FastAPI Souce: https://github.com/tiangolo/fastapi
FastAPI Document: https://fastapi.tiangolo.com
Intro & First Step
FastAPIチュートリアルのメモ。
基本的にはFastAPIの公式チュートリアルを参考にしていますが、自身の学習のため一部分を省略したり順番を前後させています。
正しい詳細な情報は公式ドキュメントを参考いただければと思います。
Web & Python 初心者かつ翻訳はGoogleとDeepL頼りのため、間違い等ありましたらご指摘いただけますと幸いです。
開発環境
Ubuntu 20.04 LTS
Python 3.8.2
pipenv 2018.11.26
目標
FastAPIとは
FastAPIは、Pythonの型ヒントに基づいてAPIを構築するための高速・軽量・モダンなWebフレームワーク。
APIのオープンスタンダードであるOpenAPI(Swagger)とJSONスキーマに準拠しています。
詳しくは公式ドキュメントをご確認ください。
手順
FastAPIのインストール
FastAPIをpip
を使用しインストールします。
以下のコマンドでFastAPIで使用するすべての依存関係と機能をインストールできるので、開発環境ではとりあえずこのコマンドでインストールしてみましょう。
サーバとして使用するuvicorn
も一括でインストールできます。
$ pip install fastapi[all]
████████████████████████████████████████ 100%
pythonのインタラクティブシェルで確認してみます。
$ python
Python 3.8.2 (default, Apr 21 2020, 18:13:10)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> from fastapi import FastAPI
>>>
エラーが表示されなければインストールは成功です。
また、私の環境ではpipenvを使用しているため、pipenv install fastapi[all]
でインストールしましたが、今のところ問題はありません。
ここでは割愛しますがfastapi
やuvicorn
を別々にインストールすることも可能です。
サーバの起動
FastAPIをインストールしたところで、さっそくサーバを起動してみましょう。
まず、main.py
ファイルに簡単なFastAPIのコードを書きます。
(コードは基本的に公式ドキュメントから引用しています。参考をご確認ください。)
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
コードを保存したら、サーバを以下のコマンドで起動します。
$ uvicorn main:app --reload
以下のような表示が出力されればサーバが起動しています。
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [28720]
INFO: Started server process [28722]
INFO: Waiting for application startup.
INFO: Application startup complete.
出力にINFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
という行があります。
ローカルマシンでアプリが起動しているURL( http://127.0.0.1:8000 )とサーバの停止方法(Controlキー + C)を教えてくれているようです。
さっそく http://127.0.0.1:8000 をブラウザで表示してみましょう。
main.py
のroot
関数の返り値(return {"message": "Hello World"}
)が表示されるはずです。
uvicorn main:app --reload
について
-
main
はmain.py
ファイル(= Pythonモジュール)を参照- ファイル名は自由に設定することが可能です。
control.py
などに変更してみましょう。その場合はコマンドも変更する必要があります。
- ファイル名は自由に設定することが可能です。
-
app
はmain.py
ファイル内のapp = FastAPI
で生成されたオブジェクトを参照- これもファイル名同様に自由に設定することが可能です。
-
--reload
はコードが変更するたびにサーバを再起動するためのオプションです- このオプションは開発環境でのみ使用することが推奨されています。
Swagger UIの確認
FastAPIはOpenAPIに準拠にしており、Swagger UIによるインタラクティブなAPIドキュメントを自動生成してくれます。
http://127.0.0.1:8000/docs にアクセスして確認してみましょう。
また、その他にもhttp://127.0.0.1:8000/redoc にアクセスすることでReDocによるドキュメントも確認できます。
コードの確認
main.py
の内容を確認してみましょう。このコードは、FastAPIの基本のコードとなっています。
FastAPIのインポート
まず、FastAPI
クラスをインポートします。このFastAPI
によって作成するAPIのすべての機能が提供されています。
from fastapi import FastAPI
インスタンスの作成
次に、FastAPIのインスタンスとなる変数を作成します。この変数がFastAPIの実体となります。
from fastapi import FastAPI
app = FastAPI()
ここで作成したインスタンス変数app
がuvicorn
コマンドのオプションmain:app
に対応しています。
もし、ファイル名をcontrol.py
、インスタンス変数をmy_instance = FastAPI()
とした場合はuvicorn
コマンドは以下のようになるでしょう。
$ uvicorn control:my_instance --reload
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
Path Operationの作成
ここでのPathとはURLの最後、ドメイン名とポート名以降の/
から始まる部分を指します。
https://example.com/items/foo
というURLの場合は/items/foo
の箇所がFastAPIにおけるPathに該当します。
また、Pathは一般的なendpointやrouteと同じ意味と思っても良いでしょう。
FastAPIでは、Pathの役割は「API構築における"concerns"(関心)と"resource"(リソース)の分離」とされています。
プログラムを関心(目的、何をしたいか)という単位とリソース(資源、何を使用するか)という単位で分割するため、という意味でしょうか。詳しい方がいれば教えてください。
また、Path OperationのOperationはHTTPのメソッドと同義です。
主に使用されるメソッドは以下の通りです。
- POST: データの作成
- GET: データの読み込み
- PUT: データの更新
- DELETE: データの削除
HTTPはこれらのメソッドを使うことでWebサーバの各Pathと通信することができます。
APIを構築する際には、特定の処理を実行するためにこれらのHTTPメソッドを使用しています。
OpenAPIではHTTPメソッドはoperationと呼ばれており、FastAPIでもそれにならってoperationという用語が使用されています。
インスタンス変数を使用して path operation decoratorを定義しましょう。
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
デコレータ関数@app.get("/")
によって、FastAPIは以下のリクエストをすぐ下の関数を使用して処理することができます。
-
pathが
/
、かつ -
operationに
get
メソッドを使用
デコレータ関数については他の記事を参照してください。
ここでは、デコレータ関数の直下にある関数が**path/
に対応していることをFastAPIに伝えるため使用しています。また、このようなデコレータ関数をpath operation decorator(パス操作デコレータ)**と呼びます。
以下のようにget
以外のoperationも使用することができます。
- @app.post()
- @app.put()
- @app.delete()
path operation function(パス操作関数)の定義
コードの確認の最後に、パス操作関数の定義と戻り値の設定を行います。
path operation decorator(パス操作デコレータ)@app.get("/")
によって処理の起点となるHTTPリクエストを定義することができました。
次に、処理を行う関数をデコレータのすぐ下に定義します。
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
ここで使われるパス操作関数(async def root():
)は通常のPython関数と変わりません。
クライアントがget
operationでURL/
へリクエストを送信し、サーバがそれを受信する度にFastAPIによってこの関数が呼び出されます。
( http://127.0.0.1:8000 にアクセスした際にも、この関数が呼び出されたいました。)
また、async def
の代わりに通常の関数を定義することも可能です。
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def root():
return {"message": "Hello World"}
async
(非同期処理)についてはコチラの公式ドキュメントを参照してください。
後はreturn
で返り値を設定すれば、最初のコードの確認は終了します。
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
返り値に関して、複数の値ではdict
やlist
、単数の値ではstr
、int
などの型で返り値を設定できます。
その他にも、Pydantic
モデルを返すことも可能です。
以上の他にもJSONに自動変換されるオブジェクトやモデルは(ORMなども含めて)たくさんあるそうです。ぜひ調べてみてください。
終わりに OpenAPIについて
今回はFastAPIの公式チュートリアルのうち、IntroとFirst Stepsを取り上げました。
最後、OpenAPIとSchemaについての記述を取り上げます。
OpenAPIとは
OpenAPIはREST APIを記述するためのフォーマットのことであり、SwaggerはOpenAPIを記述する際に使用することオープンソースのツールセットのこと。
以下の記事に簡単にまとめられていました。
FastAPIでは、APIの定義がOpenAPIに準拠しており、すべてのAPIで"スキーマ"が生成されます。
スキーマとは
"スキーマ"とは何らかの定義や記述のことです。実装されたコードではなく、抽象的な概念を指しています。
APIスキーマ
APIにおける"スキーマ"を考える場合、OpenAPIは作成されたAPIのスキーマ定義の方法を規定する仕様になります。
このスキーマ定義には、APIへのパスやAPIが取得する可能性のあるパラメータなどが含まれます。
データスキーマ
"スキーマ"という言葉は、JSONコンテンツなどのような何らかのデータの形を指す場合もあります。
その場合は、JSONの属性やそれらが持つデータ型などを意味します。
OpenAPIとJSONスキーマの関係
OpenAPIは作成されたAPIの"APIスキーマ"を定義し、そのスキーマではJSONデータスキーマの標準である"JSONスキーマ"を使用してAPIが送受信するデータの定義(あるいは、その他の"スキーマ")が含まれています。
FastAPIでは、2種類のインタラクティブなドキュメントシステム(Swagger UI, ReDoc)を動かすためにOpenAPIスキーマを使用しています。