Use Flask's Click CLI with the app factory pattern
The flask
command is a Click interface created with flask.cli.FlaskGroup
. Create your own group and pass it the factory function. Use app.shell_context_processor
to add objects to the shell.
from flask import Flask
from flask.cli import FlaskGroup
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
def create_app(script_info=None):
app = Flask(__name__)
db.init_app(app)
...
@app.shell_context_processor
def shell_context():
return {'app': app, 'db': db}
return app
cli = FlaskGroup(create_app=create_app)
@cli.command
def custom_command():
pass
if __name__ == '__main__':
cli()
Run your file instead of the flask
command. You'll get the Click interface using your factory.
FLASK_DEBUG=1 python app.py run
Ideally, create an entry point and install your package in your env. Then you can call the script as a command. Create a setup.py
file with at least the following.
project/
app/
__init__.py
setup.py
from setuptools import setup, find_packages
setup(
name='my_app',
version='1.0.0',
packages=find_packages(),
entry_points={
'console_scripts': [
'app=app:cli',
],
},
)
pip install -e /path/to/project
FLASK_DEBUG=1 app run
Using your own CLI is less robust than the built-in flask
command. Because your cli
object is defined with your other code, a module-level error will cause the reloader to fail because it can no longer import the object. The flask
command is separate from your project, so it's not affected by errors in your module.