I want to register a CLI command that's defined in a separate file from the Flask app factory. This command needs access to app.config
. However, accessing current_app.config
from the command raises RuntimeError: Working outside of application context.
app/__init__.py
from flask import Flask
from app.commands import my_command
def create_app():
app = Flask(__name__, instance_relative_config=True)
app.config.from_pyfile("config.py")
app.add_command(my_command)
return app
instance/config.py
TEST_VARIABLE = "TESTVALUE"
app/commands.py
from flask import current_app
@click.command()
def my_command():
click.echo(current_app.config["TEST_VARIABLE"])
I expect running flask my_command
to output TESTVALUE
. However, I get the following error:
RuntimeError: Working outside of application context.
This typically means that you attempted to use functionality that needed
to interface with the current application object in some way. To solve
this, set up an application context with app.app_context(). See the
documentation for more information.
I need to use with app.app_context():
for current_app
to work, but I don't have access to app
since it's defined in a factory. If I use @app.cli.command()
in the factory, this would be no problem, as there I have access to the app
variable, and wouldn't even need to push an app context.
def create_app():
...
@app.cli.command()
def my_command():
click.echo(current_app.config["TEST_VARIABLE"])
...
However, I want to define my commands in other files and have them use values from the app config, while this requires all the commands to be nested in the factory function.
I tried creating an app using the factory inside the command, and that worked, but I don't think doing that is a good idea just to have access to the config variables.
import click
import app
@click.command()
def my_command():
app_config = app.create_app().config
click.echo(app_config["TEST_VARIABLE"])
How can I define a command that has access to the application context when using the application factory pattern?
Flask's docs about the CLI discuss this.
@app.cli.command()
automatically ensures there's an app context when the command runs. However, this is less convenient to use when using an app factory because you don't have access to the app when defining the command.
When using the app factory, you use @click.command()
and app.cli.add_command()
to separate defining and registering the command, but @click.command
doesn't know about the app context. Use the @with_appcontext
decorator to ensure the command runs in an app context.
@click.command()
@with_appcontext
def my_command():
config = current_app.config
click.echo(config["TEST_VARIABLE"])
def create_app():
app = Flask(__name__)
...
app.cli.add_command(my_command)
...
return app
$ flask my-command
TESTVALUE
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With