简体   繁体   中英

blueprint of blueprints (Flask)

I have a series of blueprints I'm using, and I want to be able to bundle them further into a package I can use as seamlessly as possible with any number of other applications. A bundle of blueprints that provides an entire engine to an application. I sort of created my own solution, but it is manual and requires too much effort to be effective. It doesn't seem like an extension, and it is more than one blueprint(several that provide a common functionality).

Is this done? How?

(Application dispatching methods of tying together several programs might work isn't what I'm looking for)

I wish the Blueprint object has a register_blueprint function just as the Flask object does. It would automatically place and registered blueprints under the current Blueprints' url.

The simplest way would be to create a function that takes an instance of a Flask application and registers all your blueprints on it in one go. Something like this:

# sub_site/__init__.py
from .sub_page1 import bp as sb1bp
from .sub_page2 import bp as sb2bp
# ... etc. ...

def register_sub_site(app, url_prefix="/sub-site"):
    app.register_blueprint(sb1bp, url_prefix=url_prefix)
    app.register_blueprint(sb2bp, url_prefix=url_prefix)
    # ... etc. ...


# sub_site/sub_page1.py
from flask import Blueprint

bp = Blueprint("sub_page1", __name__)

@bp.route("/")
def sub_page1_index():
    pass

Alternately, you could use something like HipPocket 's autoload function (full disclosure: I wrote HipPocket ) to simplify the import handling:

# sub_site/__init__.py
from hip_pocket.tasks import autoload

def register_sub_site(app,
                          url_prefix="/sub-site",
                          base_import_name="sub_site"):
    autoload(app, base_import_name, blueprint_name="bp")

However, as it currently stands you couldn't use the same structure as example #1 (HipPocket assumes you are using packages for each Blueprint). Instead, your layout would look like this:

# sub_site/sub_page1/__init__.py
# This space intentionally left blank

# sub_site/sub_page1/routes.py
from flask import Blueprint

bp = Blueprint("sub_page1", __name__)

@bp.route("/")
def sub_page1_index():
    pass

Check this out: Nesting Blueprintshttps://flask.palletsprojects.com/en/2.0.x/blueprints/#nesting-blueprints

parent = Blueprint('parent', __name__, url_prefix='/parent')
child = Blueprint('child', __name__, url_prefix='/child')
parent.register_blueprint(child)
app.register_blueprint(parent)

I have solution for myself how to load blueprints defined in configuration, so then you can have something like CORE_APPS = ('core', 'admin', 'smth') in config and when you construct app you can register those apps (of course those strings in CORE_APPS must be the names of the files you want to import in your python path).

So I'm using function to create app:

app = create_app()

def create_app():
  app = Flask(__name__)

  # I have class for my configs so configuring from object
  app.config.from_object('configsClass')

  # does a lot of different stuff but the main thing could help you:
  from werkzeug.utils import import_string
  for app in app.config['CORE_APPS']
    real_app = import_string(app)
    app.register_blueprint(real_app)

After that your blueprint should be registered. Of course you can have different format in configs to support custom url prefixes and so on and so on :)

Of course you can also do something like this in your main blueprint, so in the application creation you will need to register that one main blueprint.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM