1#!/usr/bin/env python 2"""An example of how to embed an IPython shell into a running program. 3 4Please see the documentation in the IPython.Shell module for more details. 5 6The accompanying file embed_class_short.py has quick code fragments for 7embedding which you can cut and paste in your code once you understand how 8things work. 9 10The code in this file is deliberately extra-verbose, meant for learning.""" 11 12# The basics to get you going: 13 14# IPython injects get_ipython into builtins, so you can know if you have nested 15# copies running. 16 17# Try running this code both at the command line and from inside IPython (with 18# %run example-embed.py) 19 20from IPython.terminal.prompts import Prompts, Token 21 22class CustomPrompt(Prompts): 23 24 def in_prompt_tokens(self, cli=None): 25 26 return [ 27 (Token.Prompt, 'In <'), 28 (Token.PromptNum, str(self.shell.execution_count)), 29 (Token.Prompt, '>: '), 30 ] 31 32 def out_prompt_tokens(self): 33 return [ 34 (Token.OutPrompt, 'Out<'), 35 (Token.OutPromptNum, str(self.shell.execution_count)), 36 (Token.OutPrompt, '>: '), 37 ] 38 39 40from traitlets.config.loader import Config 41try: 42 get_ipython 43except NameError: 44 nested = 0 45 cfg = Config() 46 cfg.TerminalInteractiveShell.prompts_class=CustomPrompt 47else: 48 print("Running nested copies of IPython.") 49 print("The prompts for the nested copy have been modified") 50 cfg = Config() 51 nested = 1 52 53# First import the embeddable shell class 54from IPython.terminal.embed import InteractiveShellEmbed 55 56# Now create an instance of the embeddable shell. The first argument is a 57# string with options exactly as you would type them if you were starting 58# IPython at the system command line. Any parameters you want to define for 59# configuration can thus be specified here. 60ipshell = InteractiveShellEmbed(config=cfg, 61 banner1 = 'Dropping into IPython', 62 exit_msg = 'Leaving Interpreter, back to program.') 63 64# Make a second instance, you can have as many as you want. 65ipshell2 = InteractiveShellEmbed(config=cfg, 66 banner1 = 'Second IPython instance.') 67 68print('\nHello. This is printed from the main controller program.\n') 69 70# You can then call ipshell() anywhere you need it (with an optional 71# message): 72ipshell('***Called from top level. ' 73 'Hit Ctrl-D to exit interpreter and continue program.\n' 74 'Note that if you use %kill_embedded, you can fully deactivate\n' 75 'This embedded instance so it will never turn on again') 76 77print('\nBack in caller program, moving along...\n') 78 79#--------------------------------------------------------------------------- 80# More details: 81 82# InteractiveShellEmbed instances don't print the standard system banner and 83# messages. The IPython banner (which actually may contain initialization 84# messages) is available as get_ipython().banner in case you want it. 85 86# InteractiveShellEmbed instances print the following information every time they 87# start: 88 89# - A global startup banner. 90 91# - A call-specific header string, which you can use to indicate where in the 92# execution flow the shell is starting. 93 94# They also print an exit message every time they exit. 95 96# Both the startup banner and the exit message default to None, and can be set 97# either at the instance constructor or at any other time with the 98# by setting the banner and exit_msg attributes. 99 100# The shell instance can be also put in 'dummy' mode globally or on a per-call 101# basis. This gives you fine control for debugging without having to change 102# code all over the place. 103 104# The code below illustrates all this. 105 106 107# This is how the global banner and exit_msg can be reset at any point 108ipshell.banner2 = 'Entering interpreter - New Banner' 109ipshell.exit_msg = 'Leaving interpreter - New exit_msg' 110 111def foo(m): 112 s = 'spam' 113 ipshell('***In foo(). Try %whos, or print s or m:') 114 print('foo says m = ',m) 115 116def bar(n): 117 s = 'eggs' 118 ipshell('***In bar(). Try %whos, or print s or n:') 119 print('bar says n = ',n) 120 121# Some calls to the above functions which will trigger IPython: 122print('Main program calling foo("eggs")\n') 123foo('eggs') 124 125# The shell can be put in 'dummy' mode where calls to it silently return. This 126# allows you, for example, to globally turn off debugging for a program with a 127# single call. 128ipshell.dummy_mode = True 129print('\nTrying to call IPython which is now "dummy":') 130ipshell() 131print('Nothing happened...') 132# The global 'dummy' mode can still be overridden for a single call 133print('\nOverriding dummy mode manually:') 134ipshell(dummy=False) 135 136# Reactivate the IPython shell 137ipshell.dummy_mode = False 138 139print('You can even have multiple embedded instances:') 140ipshell2() 141 142print('\nMain program calling bar("spam")\n') 143bar('spam') 144 145print('Main program finished. Bye!') 146