Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

176
Vistas
Use Flask's Click CLI with the app factory pattern

I define my Flask application using the app factory pattern. When using Flask-Script, I can pass the factory function to the Manager. I'd like to use Flask's built-in Click CLI instead. How do I use the factory with Click?

My current code uses Flask-Script. How do I do this with Click?

from flask import Flask
from flask_script import Manager, Shell

def create_app():
    app = Flask(__name__)
    ...
    return app

manager = Manager(create_app)

def make_shell_context():
    return dict(app=app, db=db, User=User, Role=Role)

manager.add_command('shell', Shell(make_context=make_shell_context))

if __name__ == '__main__':
    manager.run()
over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

The flask command is a click interface built 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 will get the Click interface using its factory.

 FLASK_DEBUG=1 python app.py run

Ideally, create an entry point and install your package into your env. You can then 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 is not affected by errors in your module.

over 4 years ago · Santiago Trujillo Denunciar

0

To pass arguments to your app factory, you need to make use of script_info like this...

manage.py

 #!/usr/bin/env python import click import config from flask import Flask from flask.cli import FlaskGroup, pass_script_info def create_app(script_info): app = Flask(__name__) if script_info.config_mode: obj = getattr(config, script_info.config_mode) flask_config.from_object(obj) ... return app @click.group(cls=FlaskGroup, create_app=create_app) @click.option('-m', '--config-mode', default="Development") @pass_script_info def manager(script_info, config_mode): script_info.config_mode = config_mode if __name__ == "__main__": manager()

config.py

 class Config(object): TESTING = False class Production(Config): DATABASE_URI = 'mysql://user@localhost/foo' class Development(Config): DATABASE_URI = 'sqlite:///app.db' class Testing(Config): TESTING = True DATABASE_URI = 'sqlite:///:memory:'

now, on the command line, you can manage -m Production run (after adding the setup.py entry_points mentioned in @davidism, or run pip install manage.py ).

over 4 years ago · Santiago Trujillo Denunciar

0

Newly updated for Flask >= 2.1. See my other answer for Flask < 2.1.

In order to pass arguments to our app, we store them in script_info. And in order to do that, we create a custom Click interface using flask.cli.FlaskGroup.

However, passing script_info directly to app factories is deprecated in Flask 2, so we use Click's get_current_context function to get the current context and then access script_info from that context.

manage.py

#!/usr/bin/env python

import click
import config

from click import get_current_context
from flask import Flask
from flask.cli import FlaskGroup, pass_script_info


def create_app(*args, **kwargs):
    app = Flask(__name__)
    ctx = get_current_context(silent=True)

    if ctx:
        script_info = ctx.obj
        config_mode = script_info.config_mode
    elif kwargs.get("config_mode"):
        # Production server, e.g., gunincorn 
        # We don't have access to the current context, so must
        # read kwargs instead.
        config_mode = kwargs["config_mode"]

    ...    
    return app


@click.group(cls=FlaskGroup, create_app=create_app)
@click.option('-m', '--config-mode', default="Development")
@pass_script_info
def manager(script_info, config_mode):
    script_info.config_mode = config_mode
    ...


if __name__ == "__main__":
    manager()

Now you can run the dev server and set your desired config_mode by using either -m or --config-mode. Note, until Flask 2.1 drops you have to install Flask@aa13521d42bfdb

pip install git+https://github.com/pallets/flask.git@aa13521d42bfdb
python manage.py -m Production run

Production servers like gunincorn don't have access to the current context, so we pass what we need via kwargs.

gunicorn app:create_app\(config_mode=\'Production\'\) -w 3 -k gevent
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda