概要
flasgger は内部的に apispec を使っています
apispec は OpenAPI-Specification ベースの定義ファイルをコードから生成することができるモジュールです
今回は flasgger 上のコードから apispec の機能を使って swagger の定義ファイルを生成してみました
環境
- macOS X 10.13.6
- Python 3.6.5
- flasgger 0.9.0
- apispec 0.38.0
インストール
pipenv install flasgger marshmallow apispec=="0.38.0"
サンプルコード
vim test_apispec.py
# coding: utf-8
from flask import Flask, jsonify
from flasgger import APISpec, Schema, Swagger, fields
# Create an APISpec
spec = APISpec(
title='Flasger Petstore',
version='1.0.10',
plugins=[
'apispec.ext.flask',
'apispec.ext.marshmallow',
],
)
app = Flask(__name__)
class CategorySchema(Schema):
id = fields.Int()
name = fields.Str(required=True)
class PetSchema(Schema):
category = fields.Nested(CategorySchema, many=True)
name = fields.Str()
@app.route('/random')
def random_pet():
"""A cute furry animal endpoint.
---
get:
description: Get a random pet
responses:
200:
description: A pet to be returned
schema:
$ref: '#/definitions/Pet'
"""
pet = {'category': [{'id': 1, 'name': 'rodent'}], 'name': 'Mickey'}
return jsonify(PetSchema().dump(pet).data)
template = spec.to_flasgger(
app,
definitions=[CategorySchema, PetSchema],
paths=[random_pet]
)
swag = Swagger(app, template=template)
print(spec.to_dict())
print(spec.to_yaml())
if __name__ == '__main__':
app.run(debug=True)
最後の print 文 2 つで dictionary 形式と YAML 形式の定義ファイルを出力しています
説明
最初に APISpec を使ってメタデータなどを定義します
plugings は定義ファイルには表示されませんが必須です
spec = APISpec(
title='Flasger Petstore',
version='1.0.10',
plugins=[
'apispec.ext.flask',
'apispec.ext.marshmallow',
],
)
その後に definitions 用のクラスの定義と paths に応じた処理が書いてあります
そしてその次に spec に対して定義した definitions と paths を登録します
template = spec.to_flasgger(
app,
definitions=[CategorySchema, PetSchema],
paths=[random_pet]
)
更にその後で swag = Swagger(app, template=template)
という設定がありますがこれは /apidocs
を表示するための設定なのでなくても問題ないです
動作確認
pipenv run python3 test_apispec.py
で
curl http://localhost:5000/random
という感じでリクエストすると動作します
また、サーバを動作させたターミナル上で dictionary と YAML の定義情報が表示されているのがわかると思います
definitions:
Category:
properties:
name: {type: string}
id: {format: int32, type: integer}
required: [name]
type: object
Pet:
properties:
name: {type: string}
category:
items: {$ref: '#/definitions/Category'}
type: array
type: object
info: {title: Flasger Petstore, version: 1.0.10}
parameters: {}
paths:
/random:
get:
description: Get a random pet
responses:
200:
description: A pet to be returned
schema: {$ref: '#/definitions/Pet'}
swagger: '2.0'
tags: []
今回の定義だと上記のような感じで表示されると思います
最後に
flasgger の APISpec の機能を使ってコードから swagger ファイルを出力してみました
おそらくこれがあるのは swagger ファイルからモデルを生成するのではなくコードから swagger ファイルを生成したいという需要があるからだと思います
普通に考えれば swagger-codegen などを使ってコードを生成しますが、それだと内部がブラックボックスなのと結局コードと swagger ファイルをメンテンスしなければならないので、それであればコードだけを書き続けて swagger ファイルを自動生成するほうが良いということなんだと思います
0 件のコメント:
コメントを投稿