Flask-RESTX の導入
1. Flask 環境構築、簡単なバックエンドサーバー実装では
エンドポイントの実装の例を挙げてきましたが、ここでFlaskをもう少し簡潔に記述するために Flask-RESTX を導入します。
まずはFlask-RESTXのインストールです。
pip install flask-restx
app.pyを編集します。
from flask import Flask, request
from flask_restx import Resource, Api
app = Flask(__name__) # ここまでは同じ
api = Api(app) # Flask に Flask-RESTX を導入
@api.route('/hello/<name>/<email>')
class Hello(Resource):
def get(self, name, email):
return {
"name": name,
"email": email
}
def post(self, name, email):
body = request.json
return {
"name": name,
"email": email,
"body": body,
}
これでGET, POST 両方に/hello/{name}/{email}
に対応したエンドポイントを定義できました。
関数名はメソッド名と一致しなければいけません。
「get」ではない「my_get」のような名前に変えるとGETリクエストの定義がされません。
http://127.0.0.1:5000/hello/MyName001/aaa@bbb.ccc
をブラウザで開いてみましょう。json形式のBodyが返ってくるはずです。
{
"name": "MyName001",
"email": "aaa@bbb.ccc"
}
GETに続いて/hello/{name}/{email}
への POSTを試したいところですが
わざわざプログラムを書いて試すのはめんどくさいです。
Swaggerを使いましょう!
OpenAPI + Swagger UI
本来であれば OpenAPI 定義(json or yaml)を記述し、それをSwagger UIに読みこませることで静的Htmlファイルを生成することになりますが、
実は既に終わっています。
ブラウザでhttp://127.0.0.1:5000/を開いてみてください。
Flask-RESTXがPythonコードを基に自動でSwagger UI生成までやってくれます。
超便利です。
ですが、この段階ではPOSTリクエストにBodyを付けることはできません。
POSTリクエストにBodyを指定できるように修正
コードは以下になります。
from flask import Flask, request
from flask_restx import Resource, Api, fields # <- 追加
app = Flask(__name__)
api = Api(app)
# 追加 -------------------------------
resource_fields = api.model("Json Bodyです", {
"key1": fields.String,
"key2": fields.Integer,
"key3": fields.Boolean,
})
# -----------------------------------
@api.route('/hello/<name>/<email>')
class Hello(Resource):
def get(self, name, email):
return {
"name": name,
"email": email
}
@api.doc(body=resource_fields) # <- 追加
def post(self, name, email):
body = request.json
return {
"name": name,
"email": email,
"body": body,
}
ページを更新するとpayload欄が表示されています。
OpenAPIを充実させる
このように@api.doc()
などのデコレータを使って補足情報を追加していきます。
from flask import Flask, request
from flask_restx import Resource, Api, fields
app = Flask(__name__)
api = Api(app, version='1.0', title='Sample API Documentation', description='A sample API') # <- タイトルなどを変更
resource_fields = api.model("Json Bodyです", {
"key1": fields.String,
"key2": fields.Integer,
"key3": fields.Boolean,
})
@api.route('/hello/<name>/<email>')
@api.doc(params={'name': '名前です', 'email': 'E-mailです'}) # <- 各パラメータの補足を追加
class Hello(Resource):
def get(self, name, email):
return {
"name": name,
"email": email
}
@api.doc(body=resource_fields)
@api.doc(responses={400: '無効なBody'}) # <- HTTPコード, 補足を追加
def post(self, name, email):
body = request.json
# 追加 -------------------
if not body:
api.abort(400)
# -----------------------
return {
"name": name,
"email": email,
"body": body,
}
ページを更新すると少し充実したドキュメントになっていると思います。