Uduse
Uduse

Reputation: 1591

How to write a wrapper of IPython shell?

I want to create a custom shell that wraps around IPython interactive shell. It should has most things a IPython shell has, and on top of that, I want to preprocess some custom commands like "dance" or "knock knock" before it goes to IPython shell beneath it.

Visually it should looks like:

>>> print("IPython will handle this")
"IPython will handle this"
>>> dance
"I will handle this myself"

I look around and tried few ways that might do it, but I am really not sure...

Here're the things I tried:

  1. subclass IPython.kernel or something like that. It seems more complicated that I need and I've tried it with no success (can't really understand what is it doing...)
  2. use IPython.get_ipython() to get an instance of an interactive IPython shell and ping-pong with it. I can't really find helpful documentation on this one. The run_cell() function that I found might be useful can't do things like run_cell("for i in range(10):") and waits for an indented next line. It simply throws.
  3. use Popen to open up an IPython session and ping-pong with it. I followed few tutorials on working with pipes but I either get broken pipes or something wired. Definitely need to review my OS class before I dive deeper into this.

I am not really sure what's the correct way to go. I remember SageMath does similar thing, but can't really understand their source code very well.

Any comment will be helpful. Thanks in advance :)

Upvotes: 0

Views: 337

Answers (1)

Matt
Matt

Reputation: 27853

Is your preprocessing in Python ? If so you want to have a look at inputtransformers, which allows you to transform the user input into whatever you like. This is how magics are working. There are different level of input transformation depending on the kind of work you'd like to do.

Note that if no variable shadow a magic, and you define a magic called dance, then In[1]: dance will trigger the code of your magic instead of a syntax error, it could be way easier than a custom syntax transformer. IN you case a magic names knock and dance should be enough. The % in front of magics is necessary only to disambiguate in some case and is otherwise unnecessary. That is how cd, ls, pwd... work in IPython (well technically they are aliases, but the technical distinction is not relevant here). Here is how to define custom magics.

If you really have to overwrite, you need to subclass TerminalInteractiveShell, and you can tell IPython to swap it with your custom class via this option. Once you get it to work with the terminal it should be easy to make it into a kernel, but that require juggling also with IPykernel, which complicate things as a first step.

Upvotes: 1

Related Questions