我应该如何创建一个依赖于另一个扩展的Flask扩展?

时间:2017-03-14 17:34:14

标签: python flask

我想创建一个Flask扩展,它依赖于另一个Flask扩展。为了争论,说它是Flask-Foo,并且需要Flask-Redis将一些特定数据存储在Redis数据库中。

我知道我可以向Flask-Redis添加安装依赖项。但是我不明白我应该如何实例化和初始化Flask-Redis。

  1. Flask-Foo的设置设置了Flask-Redis对象。这样做的缺点是假设应用程序还没有使用Flask-Redis其他原因,在Flask-Foo之外明确配置。如果是,我们得到两个并排存在的对象,这似乎是错误的。

  2. 用户必须自己实例化并配置Flask-Redis。 Flask-Foo会检查它是否已为该应用初始化,否则会抱怨。这样做的问题在于它似乎对用户施加了样板 - 为什么他们必须设置Flask-Redis才能使用Flask-Foo,因为他们对Flask-Redis的配置没有其他知识或兴趣?此外,如果这意味着Flask-Foo.init_app()之后必须始终调用Flask-Redis.init_app(),我们是否会遇到麻烦?

  3. 不要使用Flask-Redis。直接使用Redis软件包,并在Flask-Foo代码中管理连接。这可能会避免上述问题。但它似乎不太优雅 - 我们基本上必须解决Flask-Redis解决的问题。如果Flask-Foo继续支持替代数据库,它将变得复杂,因为我们必须维护代码来管理不同类型的连接。

  4. 为了清楚起见,这不是一个特别关于Flask-Redis或它是如何工作的问题!我只想了解通常在扩展程序之上构建扩展的正确方法。

2 个答案:

答案 0 :(得分:0)

Flask扩展与python模块具有相同的结构。您应该在setup.py文件中指定所有要求。 例如flask-babel

install_requires=[
    'Flask',
    'Babel>=2.3',
    'Jinja2>=2.5'
],

答案 1 :(得分:0)

您可以将依赖扩展名传递给init_app。 http://flask.pocoo.org/docs/1.0/extensiondev/

flask_foo / init .py

class FooManager:

    def __init__(self, app=None, db=None, **kwargs):
        self.app = app
        if app is not None:
            self.init_app(app, db, **kwargs)

    def init_app(self, app, db, **kwargs):
        self.db = db

        app.config.setdefault('xxx', xxx)

        # Bind Flask-Foo to app
        app.foo_manager = self

现在,您可以像这样从foo_manager获取current_app对象:

models.py

from flask import current_app

db = current_app.foo_manager.db


class XXX(db.Model):
    pass

最后,也许您必须通过app_context()注册foo:

run.py

with app.app_context():
    FooManager(app, db)  # or xx = FooManager(); xx.init_app(app, db)

很棒的依赖扩展对我们很有用。

其他提示:https://stackoverflow.com/a/51739367/5204664