IPython embed and autoreload

1 minute read

IPython makes for very productive and effortless sessions working interactively with Python. From the numerous extensions for IPython, autoreload is one I use often. It’s very useful for working with existing code and being able to edit code from my code editor and have changes reflected automatically within the IPython terminal.

Enabling it is straightfoward:

%load_ext autoreload
%autoreload 2

Embedded shells

Unfortunately, this approach doesn’t work reliably when an IPython shell is embedded programatically using code. For example, shell which will initialise a Flask app’s factory method before embedding. This is a long standing issue on IPython’s Github project tracker.

After some searching, I found an elegant solution on Github

Custom shell.py

My shell.py now looks like this:

from IPython.terminal import embed

from app.models import *
from app.db import db


if __name__ == "__main__":
    terminal = embed.InteractiveShellEmbed()
    terminal.extension_manager.load_extension("autoreload")
    terminal.run_line_magic("autoreload", "2")

    db = get_db()

    terminal.mainloop()

In action

Small demo of this customised shell in action:

In action

Caveat

Autoreload will break reloading modules containing SQLAlchemy models because the models are registered in an SQLAlchemy namespace.