python flask-restful blueprint и заводской шаблон работают вместе?

Я работаю над сервисом restful, используя flask-restful, и я хочу использовать как заводской шаблон, так и чертеж в своем проекте. в app/__init__.py у меня есть create_app функция для создания приложения колбы и возврата его внешнему вызывающему абоненту, чтобы вызывающий абонент мог запустить приложение.

def create_app():
    app = Flask(__name__)
    app.config.from_object('app.appconfig.DevelopmentConfig')
    from app.resource import resource
    app.register_blueprint(v1, url_prefix='/api')
    print app.url_map
    return app

внутри этой функции я намеревался зарегистрировать схему, указывающую на пакет реализации с префиксом url.

на app/resource/__init__.py есть следующий код

from flask import current_app, Blueprint, render_template
from flask.ext import restful
resource = Blueprint('resource', __name__, url_prefix='/api')

@resource.route('/')
def index():    
    api = restful.Api(current_app)
    from resource.HelloWorld import HelloWorld
    api.add_resource(HelloWorld, '/hello')

мой цель состоит в том, что я могу получить доступ к сервису HelloWorld rest по адресу url /api/hello , но я знаю, что приведенный выше код имеет что-то неправильно в часть @resource.route('/') .... Я получил некоторую ошибку, как AssertionError: A setup function was called after the first request was handled. This usually indicates a bug in the app ... at api.add_resource(HelloWorld, '/hello') . Не могли бы вы дать мне несколько советов по правильному подходу ? Спасибо!

1 ответов


Flask-Restful, как и все правильно реализованные расширения Flask, поддерживает два метода регистрации:

  1. С приложением при создании экземпляра (как вы пытаетесь сделать с Api(current_app))
  2. на более позднем этапе с помощью api.init_app(app)

канонический способ решения проблемы кругового импорта-использовать второй шаблон и импортировать созданное расширение в свой create_app функция и регистрация расширения с помощью the init_app способ:

# app/resource/__init__.py
from resource.hello_world import HelloWorld

api = restful.Api(prefix='/api/v1')  # Note, no app
api.add_resource(HelloWorld, '/hello')

# We could actually register our API on a blueprint
# and then import and register the blueprint as normal
# but that's an alternate we will leave for another day
# bp = Blueprint('resource', __name__, url_prefix='/api')
# api.init_app(bp)

и затем в create_app вызов вы бы просто загрузить и зарегистрировать api:

def create_app():
    # ... snip ...
    # We import our extension
    # and register it with our application
    # without any circular references
    # Our handlers can use `current_app`, as you already know
    from app.resource import api
    api.init_app(app)