LeoRochael
LeoRochael

Reputation: 15187

How can I call `IPython.start_ipython()` with my own banner?

What works

When calling IPython.embed(), one can pass banner1, banner2 or header to customize the message that appears before the interactive session, like this:

import IPython
IPython.embed(banner2="*** Welcome! ***")

With the result:

Python 2.7.6 (default, Jun 22 2015, 17:58:13) 
Type "copyright", "credits" or "license" for more information.

IPython 3.2.1 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

*** Welcome! ***
In [1]: 

What doesn't work

When using IPython.start_ipython(), instead of IPython.embed() in the invocation above, I couldn't find any parameters that would influence the banner, except display_banner=False to omit the it entirely.

The best I could do was to mangle argv, to change the configuration, like:

import sys, IPython
argv = (
    sys.argv[1:] + 
    ['--TerminalInteractiveShell.banner2=*** Welcome! ***']
)
IPython.start_ipython(argv=argv)

This is usable but looks contrived.

I suppose I could also inherit from IPython.ipapp.TerminalInteractiveShell in my code and override .banner1 or .banner2, but this feels like overkill.

The Question

All I want is a way to pass banner2 into IPython.start_ipython().

Is there a more straightforward way?

More Technical details

The use case is to create a script that starts an IPython console session with some pre-defined variables for controlling an application with a fairly involved setup. And explain how to use the setup.

Something like:

import sys, myapp, IPython

explain_usage_of_session = """
You can use session.blah() to frobnicate the foobaringo
"""

session = myapp.MyComplicatedSessionFactory(including=
    configuration.params(from_file))

sys.exit(
    IPython.start_ipython(user_ns=dict(session=session),
                          banner2=explain_usage_of_session)
)

Constraints

The more specific use-case is that this script is being generated automatically by buildout's zc.recipe.egg, which locates IPython.start_ipython using IPython [console_scripts] entry point, so I'm limited in the amount of customization I can actually pass into the script, and I can't use IPython.embed() directly.

The super duper plus specific use-case is that I'm actually using anybox.recipe.odoo, which wraps zc.recipe.egg. The end result is that I'm even more limited in how the script is built.

Basically I can just set the parameters that are passed into IPython.start_ipython() call as with the arguments option of zc.recipe.egg, and nothing else. In particular, I can't use the initialization option of zc.recipe.egg.

And I'd rather not have to write my own entry-point.

Upvotes: 6

Views: 1835

Answers (1)

dtk
dtk

Reputation: 2536

As @Thomas K said, you can create an IPython.Config instance and set the banner2:

from IPython import start_ipython
from traitlets.config.loader import Config

c = Config()
c.TerminalInteractiveShell.banner2 = '*** Welcome! ***'

start_ipython(config=c)

The result:

$ python start_with_banner.py
Python 2.7.11+ (default, Mar 30 2016, 21:00:42) 
Type "copyright", "credits" or "license" for more information.

IPython 2.4.1 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

*** Welcome! ***
In [1]: 

Ftr: the Config constructor accepts kwargs:

c = Config(TerminalInteractiveShell={'banner2': '*** Welcome! ***'})

Hth, dtk

Update: For versions before ipython 5.x, you could directly from IPython import Config.

Upvotes: 3

Related Questions