Python: interactive shell and shell context processor decorator.

behainguyen

Be Hai Nguyen

Posted on July 16, 2022

Python: interactive shell and shell context processor decorator.

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.

The

$ flask shell
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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\
Enter fullscreen mode Exit fullscreen mode
Updated file f:\flask_restx_demo\app.py
Enter fullscreen mode Exit fullscreen mode
"""Flask Application entry point."""

from flask_restx_demo import (
    create_app,
    db,
)   

app = create_app()

@app.shell_context_processor
def shell():
    return {
        "db": db,
    }
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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():
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
>>>
Enter fullscreen mode Exit fullscreen mode

❷ 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 )
Enter fullscreen mode Exit fullscreen mode

We should get:

<Flask 'flask-restx-demo'>
>>>
Enter fullscreen mode Exit fullscreen mode

❸ Let's look at the db object:

>>> print( db )
Enter fullscreen mode Exit fullscreen mode

This is the output on my configuration:

<SQLAlchemy engine=sqlite:///F:\flask_restx_demo\flask_restx_demo.db>
>>>
Enter fullscreen mode Exit fullscreen mode

❹ 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
Enter fullscreen mode Exit fullscreen mode

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')
>>>
Enter fullscreen mode Exit fullscreen mode

❺ 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
Enter fullscreen mode Exit fullscreen mode
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
Enter fullscreen mode Exit fullscreen mode

Then:

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

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

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

❻ To exit the interactive shell:

>>> exit()
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.

💖 💪 🙅 🚩
behainguyen
Be Hai Nguyen

Posted on July 16, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related