概要
過去に flasgger を使って Swagger2.0 の定義ファイルを作成する方法を紹介しました
しかし flasgger では OpenAPI3 に完全に対応しておらず components.schame
など自動で出力してくれません
今回は apispec を使って OpenAPI3 の定義ファイルを自動生成してみました
環境
- macOS 11.1
- Python 3.8.7
- apispec 4.0.0
- apispec-webframeworks 0.5.2
- flask 1.1.2
- marshmallow 3.10.0
インストール
pipenv install apispec apispec-webframeworks flask marshmallow
サンプルコード
vim app.py
import uuid
from apispec import APISpec
from apispec.ext.marshmallow import MarshmallowPlugin
from apispec_webframeworks.flask import FlaskPlugin
from flask import Flask
from marshmallow import Schema, fields
spec = APISpec(
title="Swagger Petstore",
version="1.0.0",
openapi_version="3.0.2",
plugins=[FlaskPlugin(), MarshmallowPlugin()],
)
class CategorySchema(Schema):
id = fields.Int()
name = fields.Str(required=True)
class PetSchema(Schema):
categories = fields.List(fields.Nested(CategorySchema))
name = fields.Str()
api_key_scheme = {"type": "apiKey", "in": "header", "name": "X-API-Key"}
spec.components.security_scheme("ApiKeyAuth", api_key_scheme)
app = Flask(__name__)
@app.route("/random")
def random_pet():
"""A cute furry animal endpoint.
---
get:
description: Get a random pet
security:
- ApiKeyAuth: []
responses:
200:
description: Return a pet
content:
application/json:
schema: PetSchema
"""
pet_data = {
"name": "sample_pet_" + str(uuid.uuid1()),
"categories": [{"id": 1, "name": "sample_category"}],
}
return PetSchema().dump(pet_data)
with app.test_request_context():
spec.path(view=random_pet)
if __name__ == "__main__":
import json
print(json.dumps(spec.to_dict(), indent=2))
print(print(spec.to_yaml()))
app.run(debug=True)
pipenv run python app.py
or
FLASK_APP=app.py pipenv run flask run
説明
基本は APISpec
を作成してこれに必要な属性を追加していく感じです
今回は Flask + Marshmallow と連携するので plugins でそれぞれのプラグインを追加しています
components.schemas
はデフォルトで表示してくれますが components.securitySchemes
は表示してくれないので spec.components.security_scheme
で追加しています
Flask のルーティングのコメント部分に各パスのパラメータやレスポンスの定義を直接記載します
MethodView を使う
MethodView を使うとルーティングをクラスとして管理することができます
こちらの方が管理しやすくなると思います
vim app.py
import uuid
from apispec import APISpec
from apispec.ext.marshmallow import MarshmallowPlugin
from apispec_webframeworks.flask import FlaskPlugin
from flask import Flask
from flask.views import MethodView
from marshmallow import Schema, fields
spec = APISpec(
title="Swagger Petstore",
version="1.0.0",
openapi_version="3.0.2",
plugins=[FlaskPlugin(), MarshmallowPlugin()],
)
class CategorySchema(Schema):
id = fields.Int()
name = fields.Str(required=True)
class PetSchema(Schema):
categories = fields.List(fields.Nested(CategorySchema))
name = fields.Str()
api_key_scheme = {"type": "apiKey", "in": "header", "name": "X-API-Key"}
spec.components.security_scheme("ApiKeyAuth", api_key_scheme)
app = Flask(__name__)
class RandomPet(MethodView):
def get(self):
"""A cute furry animal endpoint.
---
description: Get a random pet
security:
- ApiKeyAuth: []
responses:
200:
description: Return a pet
content:
application/json:
schema: PetSchema
"""
pet_data = {
"name": "sample_pet_" + str(uuid.uuid1()),
"categories": [{"id": 1, "name": "sample_category"}],
}
return PetSchema().dump(pet_data)
random_pet_view = RandomPet.as_view("random")
app.add_url_rule(
"/random",
view_func=random_pet_view
)
with app.test_request_context():
spec.path(view=random_pet_view)
if __name__ == "__main__":
import json
print(json.dumps(spec.to_dict(), indent=2))
print(print(spec.to_yaml()))
app.run(debug=True)
pipenv run python app.py
最後に
apispec と flask を組み合わせて OpenAPI3 のドキュメントを flask 内で定義し自動生成する方法を紹介しました
今回はすべて 1 つのファイルに記載しましたが MVC は分割して管理したほうが良いかなと思います
OpenAPI3 の定義ファイルも今回は標準出力に出しているだけなので、別のメインファイルを作成してそちらで spec の情報をファイルに出力するようにしても良いかなと思います
0 件のコメント:
コメントを投稿