[IPython-dev] Detecting ipython notebook on the browser

Matthias BUSSONNIER bussonniermatthias at gmail.com
Fri May 23 09:00:29 EDT 2014


Le 23 mai 2014 à 14:11, Tiago Antao a écrit :

> 
>> There are non way to know that a kernel is run from a notebook, 
>> and actually the question does not make sense, to retake example 
>> i have already use, it's like a book authors wondering the eye color
>> of its reader. 
> 
> [Changing context a bit here]

I understand the use case, and the metaphor I chose are of course different
that what will actually happen with the kernel. But I can make the explanation
purely technical. 

I will re-explain why it is technically impossible then point out how other external project are 
making use of IPython rich display system without knowing they are in the notebook (or in IPython) 
without impacting usability on pure python script.


TLDR: 

There are technically no reliable way when executing a piece of code to know what the 
frontend is.

You should not try to display the object by yourself, define a _repr_*_ and leave lets it be computed 
when needed.

The kernel is unaware of the environment :
	
	 From the kernel perspective, it receive a message through ZMQ, and reply to it. 
	The message contains a string of code to execute[1], and reply with a mime bundle. 

	What is on the other side of ZMQ 
		- does not matter.
		- might be changing.
		- might be many things at once.
	For example what is on the other side of ZMQ can be the console, 
	or the qtconsole, or the tornado web server, a run-ipynb.
	Already there are no way to know, they all make use of the same subclass. 

	Taking the example of Tornado, it forward the messages from zmq to web socket.
	Which arrives on the other side. What can connect to web socket ? 
		- Single cell example, there are no ipynb involve, pure javascript. 
		- eLisp, Yes, Emacs connect to IPython through websocket
		- The notebook app you know.

So from the kernel point of view there is **no way** to reliably know if you are on a notebook, 
the kernel is a writer that wrote things on a book and someone might read over its shoulder (command 
line IPyhon) but the little green martian can be watching it through their telescope (tornado + websocket).

I won't go into details with the file format and the mime bundle, and storing on disk, kernel/server on different
 machines and language agnosticity, but as until know, we have not came across real use case where 
the ability to reliably know that you are in notebooks (or even in IPython) are needed, 

Pandas is defining _repr_html_ to work magically on notebooks : 

https://github.com/pydata/pandas/blob/2e1b092085ee49109b3d68b3cda05732316525ba/pandas/core/frame.py#L468

IPython blocks too : 

https://github.com/jiffyclub/ipythonblocks/blob/b1785f471ee46917673abae1320e2953e0da0072/ipythonblocks/ipythonblocks.py#L325

And sympy prefer the display hook approach not to duplicate the _repr_png_ everywhere, but the result is the same :
https://github.com/sympy/sympy/blob/423d51c458c8cc14baa4adcf4e1598e46936e73e/sympy/interactive/printing.py#L87-L93


The case of sympy is probably closer to yours as they are actually calling an external program to render the PNG, 
but prefer to disable it by default. 

So I believe, the approach of defying a _repr_pgn_ into abjad score class 
(or registering a display hook, but that's nitpicking) should allow you to do transparently
 what you ask.

ie here :

https://github.com/Abjad/abjad/blob/d6a5ce051482371d0c37ae287b13bd4afb9ec015/abjad/tools/scoretools/Score.py#L55

define a method :

def _repr_png_(self):
	return #png data created by smith like this : https://github.com/tiagoantao/abjad-ipython/blob/master/src/abjad-nb.py#L22



Note that Julia has defined this mime bundle thing on the language itself, 
library not define how to show object, then there is no more1 show/display/draw
methods per library, you just have a global julia "show()" that knows what to do. 

Same goes with IPython, user should just have to use IPython.display.display(object)
and it should work. 

If you use display_* in library or try to guess wether or not you are in IPython/ IPython notebook, 
you are <del>probably</del> certainly doing things wrong.

Hope this make things a little clearer.

[1] actually little more complicated, but a string will do it

> 
> At least in my work flow, it is starting to get more common that
> IPython notebooks get "promoted" to modules. ie some piece of code that
> was initially ad-hoc, graduates to some abstract function and gets
> inside a module.
> 
> Another use-case is when one wants to run several instances of a
> notebook from the command line(e.g. to run many simulation replicates).
> i.e., to use a notebook as a script.
> 
> One alternative, of course is just to convert mature/reusable
> code from .ipynb to .py.
> 
> But another alternative is to use notebooks directly as
> scripts/modules. In this view, having a way to understand the
> context can be really interesting: in front of the users eyes or as a
> re-usable piece of code.
> 
> Now, I understand that this is not the original intent of the notebook
> and that this is going off-script here. But a vision of things might be
> to develop everything inside the notebook. The whole code as ipython
> notebooks.
> 
> I just note that there is no performance penalty in this vision (after
> import the speed would be the same) and the machinery to do this is
> already very well documented:
> 
> http://nbviewer.ipython.org/github/ipython/ipython/blob/1.x/examples/notebooks/Importing%20Notebooks.ipynb
> 
> I do understand the argument that this is a bit crazy, but it is a
> possible use-case nonetheless.
> 
> Tiago

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/ipython-dev/attachments/20140523/0bcbe9d0/attachment.html>


More information about the IPython-dev mailing list