python flask-restful blueprint和factory pattern一起工作?

时间:2014-02-12 04:23:30

标签: python rest flask blueprint flask-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')

我的目标是我可以在网址/api/hello访问HelloWorld休息服务,但我知道上面的代码在@resource.route('/') ...的部分内容有问题。我在AssertionError: A setup function was called after the first request was handled. This usually indicates a bug in the app ...收到了api.add_resource(HelloWorld, '/hello')之类的错误信息。 你能不能给我一些关于正确方法的提示?谢谢!

1 个答案:

答案 0 :(得分:20)

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

  1. 使用应用程序进行实例化(正如您尝试使用Api(current_app)
  2. 稍后使用api.init_app(app)
  3. 处理循环导入问题的规范方法是使用第二种模式并在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)