Flask-RESTX には API を Postman のコレクションとしてエクスポートする機能がありますが、出力するのに苦労したので、調査の内容を記録しておきます。(出力したファイルを Postman にインポートするのにも変換が必要だったので、インポート手順もついでに記載します。)
Flask-RESTX で作成したアプリケーションは別記事で紹介しております。こちらのアプリケーションで作成した API を Postman のコレクションとして出力してみます。
Postman 用のコードを記載
公式の doc に Postman のコレクションとして出力するコードが紹介されていますが、コードをそのままコピーしてもエラーが出て動きません。。
This has to be executed when application context is available.
とでて application context
で実行されていないのでエラーが発生しているっぽいです。
return url_for(self.endpoint("root"), _scheme=self.url_scheme, _external=True)
File "C:\Users\kiyo27\.pyenv\pyenv-win\versions\3.8.10\lib\site-packages\flask\helpers.py", line 274, in url_for
raise RuntimeError(
RuntimeError: Attempted to generate a URL without the application context being pushed. This has to be executed when application context is available.
ネットで調べてみるとこちらの issue が出てきました。with app.app_context():
を追加して実行してみます。
from flask import Flask, json
from apis import api
app = Flask(__name__)
def see_json():
urlvars = False # Build query strings in URLs
swagger = True # Export Swagger specifications
data = api.as_postman(urlvars=urlvars, swagger=swagger)
# print(json.dumps(data))
f = open('postman_import.json', 'w')
f.write(json.dumps(data))
with app.app_context():
see_json()
url_for
でエラーが起きたりします。
return url_for(self.endpoint("root"), _scheme=self.url_scheme, _external=True)
File "C:\Users\kiyo27\.pyenv\pyenv-win\versions\3.8.10\lib\site-packages\flask\helpers.py", line 300, in url_for
raise RuntimeError(
RuntimeError: Application was not able to create a URL adapter for request independent URL generation. You might be able to fix this by setting the SERVER_NAME config variable.
エラーが発生しているコードを調べると、
def endpoint(self, name):
if self.blueprint:
return "{0}.{1}".format(self.blueprint.name, name)
else:
return name
...
@property
def base_path(self):
"""
The API path
:rtype: str
"""
return url_for(self.endpoint("root"), _external=False)
うーーん、api を分割して記述している場合は、 blueprint
を使って書き直す必要があるかもしれません。
色々調査して直したコードが書きになります。
from flask import Flask, json, url_for, Blueprint
from flask_restx import Api
from apis import api
from apis.todos import api as todos
app = Flask(__name__)
app.config['SERVER_NAME'] = 'localhost'
blueprint = Blueprint('api', __name__, url_prefix='/api')
api = Api(blueprint, doc='/doc/')
api.add_namespace(todos, path='/todos')
app.register_blueprint(blueprint)
def see_json():
# print(url_for('api.doc'))
urlvars = False # Build query strings in URLs
swagger = True # Export Swagger specifications
data = api.as_postman(urlvars=urlvars, swagger=swagger)
# print(json.dumps(data))
f = open('postman_import.json', 'w')
f.write(json.dumps(data))
with app.app_context():
see_json()
api.todos
の api
は、
from flask_restx import Namespace, Resource, fields
api = Namespace('todos', description='TODO operations')
こちらで実行したら、無事に出力されました。
Postman にインポートする
flask-restx で出力した postman のコレクションは v1 なので、インポートできませんでした。ですが幸いにも v1 から v2 に変換する方法が公式の doc に書いてありましたのでそちらを実行します。
Postman collection transformer をインストール:
sudo npm install -g postman-collection-transformer
v1 から v2 に変換:
postman-collection-transformer convert -i postman_import.json -o postman_v2.json -j 1.0.0 -p 2.0.0 -P
これで postman にインポートできるようなります。