Python Flask interactive shell enables us to explore our application data. shell_context_processor decorator makes application objects available in the Python Flask interactive shell. In this post, we focus on shell_context_processor decorator and how to use Python Flask interactive shell.

028-feature-image.png
Python: interactive shell and shell_context_processor() decorator.

The

$ flask shell

command starts a Python interactive command prompt where we can explore our application data. To quote from the link Command Line Interface:

To explore the data in your application, you can start an interactive Python shell with the shell command. An application context will be active, and the app instance will be imported.

Use shell_context_processor() to add other automatic imports.

In this short post, we're focusing on the shell_context_processor() decorator and how it works with the “flash shell” command.

The code for this post is built upon the code created for this post Python: Flask-RESTX and the Swagger UI automatic documentation. This code can be cloned from GitHub using:

E:\>git clone -b v1.0.0 https://github.com/behai-nguyen/flask-restx-demo.git

To recap, the layout of the project from the above git clone is as below -- ☆ marks the file we're going to update for this post:

f:\flask_restx_demo
|
|-- .env
|-- app.py ☆
|-- setup.py
|
|-- src\
|   |
|   |-- flask_restx_demo\
|       |
|       |-- __init__.py 
|       |-- config.py
|       |
|       |-- api\
|       |   |       
|       |   |-- __init__.py
|       |   |
|       |   |-- trees\
|       |       |
|       |       |-- bro.py
|       |       |-- dto.py
|       |       |-- routes.py 
|       |       |-- __init__.py
|       |
|       |-- models\
|           |       
|           |-- tree.py
|
|-- venv\
Updated file f:\flask_restx_demo\app.py
"""Flask Application entry point."""

from flask_restx_demo import (
    create_app,
    db,
)	

app = create_app()

@app.shell_context_processor
def shell():
    return {
        "db": db,
    }

The complete code for this post can be downloaded from GitHub using:

E:\>git clone -b v1.0.1 https://github.com/behai-nguyen/flask-restx-demo.git

Basically, we import the db object, and making it available to the Python interactive shell via the @app.shell_context_processor decorator. We list all objects we want to make available to the shell one after another, separated by comma ( , ). Please note that the method does not have to be:

def shell():

We could name it whatever we like, for so long it makes sense. What's important is the @app.shell_context_processor decorator.

❶ Now we can try opening a Python interactive shell with:

(venv) F:\flask_restx_demo>venv\Scripts\flask.exe shell

We'll get the following:

Python 3.10.1 (tags/v3.10.1:2cd268a, Dec  6 2021, 19:10:37) [MSC v.1929 64 bit (AMD64)] on win32
App: flask-restx-demo [development]
Instance: F:\flask_restx_demo\instance
>>>

❷ Remember an earlier quote from Command Line Interface?

An application context will be active, and the app instance will be imported.

We'd expect the app object to be available:

>>> print( app )

We should get:

<Flask 'flask-restx-demo'>
>>>

❸ Let's look at the db object:

>>> print( db )

This is the output on my configuration:

<SQLAlchemy engine=sqlite:///F:\flask_restx_demo\flask_restx_demo.db>
>>>

❹ Similar to other Python interactive shells, we can also use the db object in an interactive manner:

>>> conn = db.engine.connect()
>>> res = conn.execute( 'select * from tree' )
>>> for r in res:
...    print( r )
... press Enter key

It'll print out the... entire tree table:

(1, 'Acer palmatum', 'Japanese maple', 'https://en.wikipedia.org/wiki/Acer_palmatum')
(2, 'Liquidambar', 'Sweetgums', 'https://en.wikipedia.org/wiki/Liquidambar')
(3, 'Lagerstroemia', 'Crepe myrtle', 'https://en.wikipedia.org/wiki/Lagerstroemia')
(4, 'Pinus Thunbergii', 'Black Pine', 'https://en.wikipedia.org/wiki/Pinus_thunbergii')
(5, 'Pinus parviflora', 'Japanese White Pine', 'https://en.wikipedia.org/wiki/Pinus_parviflora')
>>>

❺ I did run the same application on my Synology DS218 box. It's not different to the Windows 10 Pro environment:

(venv) behai@omphalos-nas-01:/var/services/web/flask_restx_demo$ sudo venv/bin/flask shell
Python 3.9.6 (default, Jan  5 2022, 15:50:31)
[GCC 8.5.0] on linux
App: flask-restx-demo [development]
Instance: /volume1/web/flask_restx_demo/instance

Then:

>>> conn = db.engine.connect()
>>> res = conn.execute( 'select * from tree' )
>>> for r in res:
...     print( r )
... press Enter key

I've only one record in the tree table on this environment:

(1, 'Acer Buergerianum', 'Trident Maple', 'https://en.wikipedia.org/wiki/Acer_buergerianum')
>>>

❻ To exit the interactive shell:

>>> exit()

We'll be returned to the Python virtualenv prompt.

The complete code for this post can be downloaded from GitHub using:

E:\>git clone -b v1.0.1 https://github.com/behai-nguyen/flask-restx-demo.git

For such small addition, we've such rich functionalities... I find this feature very enticing. I hope you find this post helpful in some manner. And thank you for reading.