LoginSignup
7
8

More than 1 year has passed since last update.

2. FlaskでOpenAPI定義の自動出力、Swagger UIページの作成

Last updated at Posted at 2022-01-21

Flask-RESTX の導入

1. Flask 環境構築、簡単なバックエンドサーバー実装では
エンドポイントの実装の例を挙げてきましたが、ここでFlaskをもう少し簡潔に記述するために Flask-RESTX を導入します。

まずはFlask-RESTXのインストールです。

pip install flask-restx

app.pyを編集します。

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/を開いてみてください。

1.png

Flask-RESTXがPythonコードを基に自動でSwagger UI生成までやってくれます。
超便利です。
ですが、この段階ではPOSTリクエストにBodyを付けることはできません。

2.png


POSTリクエストにBodyを指定できるように修正

コードは以下になります。

app.py
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欄が表示されています。

3.png


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,
        }

ページを更新すると少し充実したドキュメントになっていると思います。


7
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
8