Is there a way to find out if my code is running inside a jupyter notebook or jupyter lab?
More specifically, is it possible to find out if wherever my code runs it is possible to get HTML rendered or not?
I want to implement a function to display an object. The way how the object is displayed should be configurable so I need to invoke a function like myobject.show(options...) instead of just doing display(myobject).
But I want this function to work well both when displaying HTM is possible, like in a notebook or lab, and e.g. within IPython or the qtconsole or just a plain python interpreter, where this is not possible and I would fall back to some kind of pretty printing instead.
Update: I read that as āIs there a way to find out if my code is running inside a jupyter notebook vs. jupyter lab?ā Sorry. After you posted a valid solution for a notebook vs. a script, I then posted & linked below what I should have posted here. But Iām leaving my original response here addressing detecting if running in the classic notebook vs. JupyterLab because how to determine that has been raised as a question a few times.
I havenāt found the answer to that yet; however, to encourage one, Iāll point out by listing the examples I found that this question (or very similar variants) has been raised on StackOverflow & on this discourse in the past a few times with no clear answer. We should then update these to maybe point to such an answer:
try:
from IPython import get_ipython
ip = get_ipython()
if ip is None:
# we have IPython installed but not running from IPython
return False
else:
from IPython.core.interactiveshell import InteractiveShell
format = InteractiveShell.instance().display_formatter.format
if len(format(_checkhtml, include="text/html")[0]):
# TODO: need to check for qtconsole here!
return True
else:
return False
except:
# We do not even have IPython installed
return False
I think this incorrectly returns true if we are running in a qtconsole, but qtconsole can NOT show HTML, so we should check for that separately.
I ignored this for now, cause, how is really using qtconsole?
Otherwise I think it does what I need.
Feedback welcome!
Oops, I totally misread your point. You were looking to find out if it was running in a Jupyter notebook vs. a script /other. For that, in the past I had used a variant of what you have posted now from here (Indeed, I make a comment below that one under my āWayneā Stackoverflow user name). The StackOverflow question that was in response to is How can I check if code is executed in the IPython notebook?. (This question I misread as well while researching is also asking that but in relation to a particular package, tqdm, that gets imported differently depending, or at least did at that time.)
I thought you were trying to answer the question posed at the links I posted earlier for detecting which specific front-end is being used, Jupyter classic vs. JupyterLab. I still would like to know the answer to that question as others asked it and I have collected the occurrences of that in my response earlier in this thread.
I can see how my question is ambiguous, sorry.
What I basically need to know if wherever my script is running, an object can be rendered as HTML or not.
I thought that actually letting the backend give me the HTML rendered representation of a small object should work, but strangely I still get a text/html representation even if I am in the qtconsole which is not able to render it.
The name __IPYTHON__ is defined in Jupyter or IPython but not a basic Python interpreter.
As to the HTML rendering, look at how Pandas dataframes work. Did you ever notice how when you are using the IPython console and print a Pandas dataframe, it prints a nicely formatted text table, but the identical code in a Jupyter notebok displays a nice HTML table? Thatās because the dataframe has a special method _repr_html_ that the Jupyter Notebooks for. Only Jupyter looks for it, and only when the front-end is capable of displaying HTML. So the front end decides if it can display HTML, and if so, calls _repr_html_().
Bottom line, what you need to do is create a method called _repr_html_ and let Jupyter decide for you to display HTML or not. I donāt think your code needs to figure out if it is actually in Jupyter.
Quick clarification - it is not that smart. Using the IPython display method to show such an object will always generate the HTML, regardless of what frontend is being used. In general, the kernel does not know what frontends will be displaying the information, so it cannot make such decisions.
Thatās essentially correct. And in general, it gets all mimetypes available and sends all of those to the client, then the client decides which to show the user.
So if we have a fixed number of possible clients, and we know which of the clients is capable of showing html, then the way to figure this out could maybe be to check which client we have?
The method I use so far already distinguishes everything I care about but qtconsole where it thinks HTML can be displayed but it cannot.
So I guess the question that remains is: is there a way to find out that I am running qtconsole and not notebook/lab?
Thanks!
I have seen a number of answers based on checking the process we are running in but I was hoping for a solution based on just the code of the client or kernel we are running in, especially as this should work on all operating systems.
TBH this is now just curiosity, as the main cases are solved anyways and nobody really uses qtconsole I think. It is just interesting that such a simple task is not something already dealt with in the API in the first place.
I think a client should know what it can and cannot do and tell the module that wants to display something which then can provide the data as needed, rather than the module generating all the diferent versions and the client picking what it can deal with.
There was probably a good reason to do it that way but: still weird.
I donāt think that is universal @CatChenal. To get your function to return True, I needed to change jupyter-lab-script to jupyter-notebook inside a notebook running in JupyterLab that was running via MyBinder, which is a fancy JupyterHub.
Hereās what psutil.Process().parent().cmdline() returns inside my current JupyterLab session with the token anonymized:
For completeness, I should add that I got back the same from psutil.Process().parent().cmdline(), whether I was running in classic notebook or JupyterLab notebook interface on that hub.
Possible the indentation got messed up in what you pasted in discourse?
Or it matters what MyBinder host it runs from? Here it is running on the gke host.
Your original statement is correct, @fomightez: my āsolutionā is not universal (actually, I had never tested it for binder bundles).
From your last test, I donāt even think this is the right approach since there is nothing in the psutil command output that can identify a ānativeā JupyterLab string with ālabā in it (as the user-defined base_url may be totally different than yours).
The function I gave, with the wrong indentation, which you caught, is part of another one which I use as a reminder depending on how I open an existing notebook:
def is_lab_notebook():
import re
import psutil
return any(re.search('jupyter-lab-script', x)
for x in psutil.Process().parent().cmdline())
def check_notebook():
"""
Util to check a Jupyter notebook environment:
a markdown cell in a jupyter lab notebook cannot render
variables: the cell text needs to be created with
IPython.display.Markdown.
"""
if is_lab_notebook():
# need to use Markdown if referencing variables:
from IPython.display import Markdown
msg = "This is a <span style=\"color:red;\">JupyterLab notebook </span>:<br>"
msg += "* Use `IPython.display.Markdown(F'x = {n}')` if referencing variables. "
msg += "Using {{n}} directly in a Markdown cell will not work."
return Markdown('### {}'.format(msg))
check_notebook()
Bonus question: does anyone know how to find out if we are running under Google Colab?
It turns out that some of the things I use for loading javascript from within the generated HTML do not work with Google Colab, so I need yet another approach to correctly render the object there, and of course it would be nice for the code to figure out when that is necessary automatically!
This is what Iām using in JupySQL to display user feedback, Itāll take care of displaying HTML if running Jupyter and the text version if running IPython.