9

我正在使用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')

我的目标是我可以在 url 访问 HelloWorld 休息服务/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')。你能给我一些关于正确方法的提示吗?谢谢!

4

1 回答 1

24

Flask-Restful 和所有正确实现的 Flask 扩展一样,支持两种注册方法:

  1. 在实例化应用程序时(正如您尝试使用的那样Api(current_app)
  2. 稍后使用api.init_app(app)

处理循环导入问题的规范方法是使用第二种模式并在您的create_app函数中导入实例化的扩展,并使用以下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)
于 2014-02-12T05:18:00.767 回答