How do I embed an IPython Interpreter into an application running in an IPython Qt Console
Asked Answered
S

2

24

There are a few topics on this, but none with a satisfactory answer.

I have a python application running in an IPython qt console

http://ipython.org/ipython-doc/dev/interactive/qtconsole.html

When I encounter an error, I'd like to be able to interact with the code at that point.

    try: 
      raise Exception()
    except Exception as e:
        try: # use exception trick to pick up the current frame
            raise None
        except:
            frame = sys.exc_info()[2].tb_frame.f_back
        namespace = frame.f_globals.copy()
        namespace.update(frame.f_locals)
        import IPython
        IPython.embed_kernel(local_ns=namespace)  

I would think this would work, but I get an error:

RuntimeError: threads can only be started once

Sigman answered 1/3, 2013 at 21:30 Comment(1)
For those coming to this question now, please see: #4235112. (There's an officially supported way of doing this from IPython.)Cormorant
S
83

I just use this:

from IPython import embed; embed()

works better than anything else for me :)


Update:

In celebration of this answer receiving 50 upvotes, here are the updates I've made to this snippet in the intervening six years since it was posted.

First, I now like to import and execute in a single statement, as I use black for all my python code these days and it reformats the original snippet in a way that doesn't make sense in this specific and unusual context. So:

 __import__("IPython").embed()

Given than I often use this inside a loop or a thread, it can be helpful to include a snippet that allows terminating the parent process (partly for convenience, and partly to remind myself of the best way to do it). os._exit is the best choice here, so my snippet includes this (same logic w/r/t using a single statement):

q = __import__("functools").partial(__import__("os")._exit, 0)

Then I can simply use q() if/when I want to exit the master process.

My full snippet (with # FIXME in case I would ever be likely to forget to remove it!) looks like this:

q = __import__("functools").partial(__import__("os")._exit, 0)  # FIXME
__import__("IPython").embed()  # FIXME  
Spoor answered 2/2, 2014 at 7:17 Comment(1)
I love using this to explore new projects. I have created a bit.ly URL j.mp/ipshell that I can curl into my code. It points to gist.github.com/RichardBronosky/570492Highkeyed
V
5

You can follow the following recipe to embed an IPython session into your program:

try:
    get_ipython
except NameError:
    banner=exit_msg=''
else:
    banner = '*** Nested interpreter ***'
    exit_msg = '*** Back in main IPython ***'

# First import the embed function
from IPython.frontend.terminal.embed import InteractiveShellEmbed
# Now create the IPython shell instance. Put ipshell() anywhere in your code
# where you want it to open.
ipshell = InteractiveShellEmbed(banner1=banner, exit_msg=exit_msg)

Then use ipshell() whenever you want to be dropped into an IPython shell. This will allow you to embed (and even nest) IPython interpreters in your code and inspect objects or the state of the program.

Valerlan answered 27/3, 2013 at 17:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.