banesullivan / scooby

🐶 🕵️ Great Dane turned Python environment detective
MIT License
47 stars 12 forks source link

Feature request: detect whether in script/jupyter/ipython #5

Closed leouieda closed 5 years ago

leouieda commented 5 years ago

I imagine this is something that a lot of visualization libraries would want. There are some ways of telling if the kernel is IPython but I'm not sure if there is any robust way of knowing if on a notebook. It might expand the usage of Scooby beyond capturing an environment metadata in a notebook.

banesullivan commented 5 years ago

We actually figured this out in PyVista with this little snippet:

def run_from_ipython():
    """ returns True when run from IPython """
    try:
        py = __IPYTHON__
        return True
    except NameError:
        return False

notebook = None
if run_from_ipython():
    try:
        notebook = type(get_ipython()).__module__.startswith('ipykernel.')
    except NameError:
        pass

The variable notebook will let you know if you are in a notebook - or at least this works for PyVista so that we can default to use different viewing styles if a user is calling from normal python, IPython, or a Jupyter notebook.

I image we could clean this up and make it a bit more general/useful

banesullivan commented 5 years ago

And proof that it works:

Screen Shot 2019-06-25 at 6 55 16 PM Screen Shot 2019-06-25 at 6 55 08 PM
leouieda commented 5 years ago

Ooh nice! Just confirmed that it works on JupyterLab as well. How would you feel about having this in Scooby as a function? I'd love to use it in PyGMT and wouldn't mind adding Scooby as a dependency.

banesullivan commented 5 years ago

Sounds good to me (and it requires true detective work so it fits well with scooby's goals)! I'll see if I can generalize this snippet later tonight then implement it

how should it be called? Suggestions?

Perhaps:

import scooby
scooby.in_ipython()
scooby.in_jupyter()

Then you could step through the three possible scenarios with the following logic:

import scooby

if scooby.in_jupyter():
    # Do Jupyter stuff
elif scooby.in_ipython():
    # Do IPython stuff
else:
    # Do normal, boring Python stuff
leouieda commented 5 years ago

That looks good to me :)

prisae commented 5 years ago

Just saw that now, after opening issue https://github.com/banesullivan/scooby/issues/8 . This method does not always work, and so far I do not know a method that can say absolutely that you are in a notebook. The thing is, notebooks use the kernel, but a kernel can also be used by other things... So scooby.in_jupyter yields True if you are, in fact, in a QtConsole (or other tools making use of the kernel).

leouieda commented 5 years ago

Ah, that was my main concern. I always forget about the console. The whole "frontend agnostic" approach of Jupyter seems good in principle but I haven't able to make it work reliably in practice. I'll take the guess of maybe being in a notebook over not having a clue. But maybe we should rename the function is_ipykernel?

banesullivan commented 5 years ago

Bummer...

Fair to rename that function to is_ipykernel instead

prisae commented 5 years ago

There might be a trick... So in jupyter, the output will be html, right. In the console, it will be text. Could we do a test scooby.investigate and see if the output has any html-tags?

banesullivan commented 5 years ago

Ah yup, I went down that path and dived into IPython's source code to figure out how they decide to use the HTML repo method... which is how I made: https://github.com/banesullivan/scooby/issues/8#issuecomment-505768933

prisae commented 5 years ago

Nope, I don't think so.

Here, from a core-dev: https://github.com/bokeh/bokeh/issues/1895#issuecomment-74453564

Citing

Technically you can not know if you are in the notebook!

leouieda commented 5 years ago

Yeah, I figured that was the case. Thanks for the references @prisae. It is still useful to know if using ipykernel out of ipython since even in the qt gui we probably don't want pop up windows but pngs