Extending Flask with Flask-Script

Flask Extensions

Flask Extensions refers to the packages you can install to extend Flask. The idea behind Flask extensions is to provide a consistent and predictable way to integrate packages with Flask. To view, all the available extensions visit http://flask.pocoo.org/extensions/. The page contains packages ranging from sending mail to building full-fledged admin interfaces. Remember that you are not limited to Flask Extensions to extend Flask, In fact, you can use any package from Python standard library or PyPI. The rest of the lesson discusses how to install and integrate a useful Flask extension named Flask-Script.

Flask-Script Extension

Flask-Script is a nice little extension which allows us to create command line interfaces, run server, start Python shell within the application context, make certain variables available inside the shell automatically and so on.

Recall that in lesson Flask Basics we have discussed that in order to run the development server on a specific host and port, we need to pass them as keyword arguments to the run() method as follows:

The problem is that this approach is not very flexible, a better way would be to pass host and port as command line options while starting the server. The Flask-Script extension allows us to do just that. Without further ado, let’s install Flask-Script by entering the following command:

To use Flask-Script first import Manager class from flask_script package and instantiate Manager object by passing application instance to it. That’s how you integrate Flask Extensions, you import the necessary class from the extension package and instantiate it by passing application instance to it. Open main2.py and modify the file as follows:

flask_app/main2.py

The Manager object we just created also provides the run() method but in addition to starting the development server it can also parse command line arguments. Replace the line app.run(debug=True) with manager.run(). At this point, main2.py should look like this:

flask_app/main2.py

Our application now has access to some basic commands. To see the commands available, run main2.py as follows:

As the output shows, currently we have two commands: shell and runserver. Let’s start with the runserver command.

The runserver command starts the web server. By default, it starts the development server at 127.0.0.1 on port 5000. To see the available options for any command. Type --help followed by the command name. For example:

The most commonly used options for runserver command are --host and --post, which allows us to start development server at a specific interface and port. For example:

The runserver command by default starts the server without debugger and reloader. We could turn on debugger and reloader manually as follows:

A much simpler way to start the debugger and reloader is to set debug attribute of the application instance (app) to True. Open main2.py and modify the file as follows:

flask_app/main2.py

Let’s now explore the shell command.

The shell command starts the Python shell inside Flask application context. This simply means that all objects provided by the application and request context are available to you inside the console without creating application or request context. To start shell enter the following command.

Now let’s try accessing some objects.

As expected, we can access the desired object without creating application or request context.

Creating Commands

Once Manager instance is created, we are ready to create our own commands. There are two ways to create commands:

  1. Using Command class.
  2. Using @command decorator.

Creating Commands using Command class

Open main2.py and add the Faker class as follows:

flask_app/main2.py

Here we have created a command Faker by inheriting the Command class. The run() method is called when the command is executed. Now to run this command from the command line, add it to the Manager instance using the add_command() method as follows:

flask_app/main2.py

Now head back to terminal and run main2.py again:

Note that in addition to shell and runserver, we now have an entry for faker command as well. The description in front of the faker command comes from doc string in the Faker class. To run it enter the following command:

Creating commands using @command decorator

Creating commands using Command class is slightly verbose. Alternatively, we can use @command decorator of the Manager instance. Open main2.py and modify the file as follows:

flask_app/main2.py

We have created a simple command foo which prints foo command executed when called. The @command decorator automatically adds the command to the existing Manager instance, so we don’t need to call add_command() method. Head back to the terminal again and run main2.py file to see command usage.

As you can see our foo command is now available, we can execute it by entering the following command.

Importing Objects Automatically

Importing lots of objects inside a shell can be tedious. Using Flask-Script, we can make objects available inside the shell without explicitly importing them.

The Shell command starts a shell. The Shell constructor function accepts a keyword argument named make_context. The argument passed to make_context must be a callable returning a dictionary. By default, the callable returns a dictionary containing just the application instance i.e app. That means, by default in the shell you only have access to application instance (app) without explicitly importing it. To override this default, assign a new callable (function) to make_context which returns a dictionary of objects that you want to access inside the shell.

Open main2.py and add the following code after the foo() function.

flask_app/main2.py

Here we are assigning a callable named shell_context to the make_context keyword argument. The shell_context() function returns a dictionary containing three objects: app, os and sys. As a result, inside the shell we will have access to these objects without explicitly importing them.

Leave a Comment