PythonのFlask-RESTPlusを使うとAPIサーバのコードにドキュメント(仕様書)を書けば自動でSwaggerUIで生成されるので色々試してみました。
1. テンプレート
ここで使うテンプレートです。
#!/usr/bin/env python3
from flask import Flask, request
from flask_restplus import Api, Resource, fields
app = Flask(__name__)
api = Api(app)
# ここにドキュメントとルートの処理を書く
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)
2. 接続先
上記テンプレートで起動すると http://flask server ip or FQDN:5000
へアクセスすれば自動でSwaggerUIでAPIドキュメントが表示されます。
3. APIドキュメント例
APIドキュメントについてですが、指定したドキュメントをSwaggerUIで表示させたい場合は対象の部分をデコレートするだけです。
例えばclassよりも前に書けばclass全体に指定したドキュメントが表示されます。
メソッドの前に書けば、書いたメソッドにだけ指定したドキュメントが表示されます。
何はともあれ、一先ずやってみます。
3-1. URLパラメーター説明
例えば id
param
というパラメーターのドキュメントを @api.doc
を使うことで自動生成可能です。
#!/usr/bin/env python3
from flask import Flask, request
from flask_restplus import Api, Resource, fields
app = Flask(__name__)
api = Api(app)
@api.route('/example/<id>/<param>')
@api.doc(params={'id': 'id of example','param':'param of example'})
class Example(Resource):
def get(self, id, param):
return {'id': id, 'param': param}
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)
結果
3-2. レスポンスの説明
ここでは、レスポンスの説明を付け加えてみます。
@api.marshal_with
を使えばレスポンス仕様を表示できます。
#!/usr/bin/env python3
from flask import Flask, request
from flask_restplus import Api, Resource, fields
app = Flask(__name__)
api = Api(app)
example_get_spec = api.model('Example GET', {
'id': fields.String(description='example id'),
'param': fields.String(description='example param')
})
@api.route('/example/<id>/<param>')
@api.doc(params={'id': 'id of example','param':'param of example'})
class Example(Resource):
@api.marshal_with(example_get_spec)
def get(self, id, param):
return {'id': id, 'param': param}
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)
結果
X-Fields
はマスクするフィールドを指定します。
例えば id
を入力して実行すると id
の情報しかレスポンスに返ってきません。
3-3. データリクエスト説明
例えばJSONデータをPOSTする時のデータ構造を説明するドキュメントを以下のように追加(example2)してみます。
@api.expect
を使うとJSONデータをSwaggerUIからリクエストとして出すことが出来ます。
#!/usr/bin/env python3
from flask import Flask, request
from flask_restplus import Api, Resource, fields
app = Flask(__name__)
api = Api(app)
example_get_spec = api.model('Example GET', {
'id': fields.String(description='example id'),
'param': fields.String(description='example param')
})
@api.route('/example/<id>/<param>')
@api.doc(params={'id': 'id of example','param':'param of example'})
class Example(Resource):
@api.marshal_with(example_get_spec)
def get(self, id, param):
return {'id': id, 'param': param}
example2_post_spec = api.model('Example POST', {
'name': fields.String(description='name of example2'),
'param': fields.String(description='param of example2')
})
@api.route('/example2')
@api.expect(example2_post_spec)
class Example2(Resource):
@api.marshal_with(example2_post_spec)
def post(self):
return {'name': request.json['name'], 'param': request.json['param']}
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)
結果
3-4. APIドキュメントのバージョンやタイトルを変更する
Api
の引数にバージョンやタイトルを指定すれば変更できます。
doc
はアクセスするURLを変更する事ができます。
以下の例では http://flask server ip or FQDN:5000/doc/
へアクセスすればドキュメントが表示されるようにしています。
#!/usr/bin/env python3
from flask import Flask, request
from flask_restplus import Api, Resource, fields
app = Flask(__name__)
api = Api(app, version='2.0', title='Example API Document', description='', doc='/doc/',
default='Example', default_label='default label')
(snip)
結果
3-5. NameSpaceを分ける
NameSpaceを分ける事で目的毎に仕様が書けたりします。
#!/usr/bin/env python3
from flask import Flask, request
from flask_restplus import Api, Resource, fields, Namespace
app = Flask(__name__)
api = Api(app, version='2.0', title='Example API Document', description='', doc='/doc/',
default='Example', default_label='default label')
api.add_namespace(Namespace('Example2', description='example2'))
api.add_namespace(Namespace('Example3', description='example3'))
(snip)
結果
以下のドキュメントに詳しく書いてあります。
4. 最後に
コードにドキュメントを書いてそのままSwaggerUIで表示されるのは便利ですね。
ブラウザでAPIの動作確認が簡単に出来るのもいいですね。
いちいち他(Wordとか)のドキュメントで残すというのはコストが高いので、なるべくコードに書いてそのままドキュメント化されるような効率化が必要だと感じる今日この頃です。
5. 参考
https://flask-restplus.readthedocs.io/en/stable/swagger.html
http://flask.pocoo.org/docs/1.0/api/