LoginSignup
0
0

More than 1 year has passed since last update.

Flask-RESTX で作成した API を Postman のコレクション形式でエクスポートする

Last updated at Posted at 2021-08-11

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 を使って書き直す必要があるかもしれません。

色々調査して直したコードが書きになります。

postman.py
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.todosapi は、

api/todos.py
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 にインポートできるようなります。

postman-import.png

0
0
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
0
0