How can I check if code is executed in the IPython notebook?

PythonIpythonIpython Notebook

Python Problem Overview


I have some Python code example I'd like to share that should do something different if executed in the terminal Python / IPython or in the IPython notebook.

How can I check from my Python code if it's running in the IPython notebook?

Python Solutions


Solution 1 - Python

The following worked for my needs:

get_ipython().__class__.__name__

It returns 'TerminalInteractiveShell' on a terminal IPython, 'ZMQInteractiveShell' on Jupyter (notebook AND qtconsole) and fails (NameError) on a regular Python interpreter. The method get_ipython() seems to be available in the global namespace by default when IPython is started.

Wrapping it in a simple function:

def isnotebook():
    try:
        shell = get_ipython().__class__.__name__
        if shell == 'ZMQInteractiveShell':
            return True   # Jupyter notebook or qtconsole
        elif shell == 'TerminalInteractiveShell':
            return False  # Terminal running IPython
        else:
            return False  # Other type (?)
    except NameError:
        return False      # Probably standard Python interpreter

The above was tested with Python 3.5.2, IPython 5.1.0 and Jupyter 4.2.1 on macOS 10.12 and Ubuntu 14.04.4 LTS

Solution 2 - Python

To check if you're in a notebook, which can be important e.g. when determining what sort of progressbar to use, this worked for me:

def in_ipynb():
    try:
        cfg = get_ipython().config 
        if cfg['IPKernelApp']['parent_appname'] == 'ipython-notebook':
            return True
        else:
            return False
    except NameError:
        return False

Solution 3 - Python

You can check whether python is in interactive mode with the following snippet [1]:

def is_interactive():
    import __main__ as main
    return not hasattr(main, '__file__')

I have found this method very useful because I do a lot of prototyping in the notebook. For testing purposes, I use default parameters. Otherwise, I read the parameters from sys.argv.

from sys import argv

if is_interactive():
    params = [<list of default parameters>]
else:
    params = argv[1:]

Following the implementation of autonotebook, you can tell whether you are in a notebook using the following code.

def in_notebook():
    try:
        from IPython import get_ipython
        if 'IPKernelApp' not in get_ipython().config:  # pragma: no cover
            return False
    except ImportError:
        return False
    except AttributeError:
        return False
    return True

Solution 4 - Python

Recently I encountered a bug in Jupyter notebook which needs a workaround, and I wanted to do this without loosing functionality in other shells. I realized that keflavich's solution does not work in this case, because get_ipython() is available only directly from the notebook, and not from imported modules. So I found a way to detect from my module whether it is imported and used from a Jupyter notebook or not:

import sys

def in_notebook():
    """
    Returns ``True`` if the module is running in IPython kernel,
    ``False`` if in IPython shell or other Python shell.
    """
    return 'ipykernel' in sys.modules

# later I found out this:

def ipython_info():
    ip = False
    if 'ipykernel' in sys.modules:
        ip = 'notebook'
    elif 'IPython' in sys.modules:
        ip = 'terminal'
    return ip

Comments are appreciated if this is robust enough.

Similar way it is possible to get some info about the client, and IPython version as well:

import sys

if 'ipykernel' in sys.modules:
    ip = sys.modules['ipykernel']
    ip_version = ip.version_info
    ip_client = ip.write_connection_file.__module__.split('.')[0]

# and this might be useful too:

ip_version = IPython.utils.sysinfo.get_sys_info()['ipython_version']

Solution 5 - Python

Tested for python 3.7.3

CPython implementations have the name __builtins__ available as part of their globals which btw. can be retrieved by the function globals().
If a script is running in an Ipython environment then __IPYTHON__ should be an attribute of __builtins__.
The code below therefore returns True if run under Ipython or else it gives False

hasattr(__builtins__,'__IPYTHON__')

Solution 6 - Python

The question is what do you want execute differently.

We do our best in IPython prevent the kernel from knowing to which kind of frontend is connected, and actually you can even have a kernel connected to many differents frontends at the same time. Even if you can take a peek at the type of stderr/out to know wether you are in a ZMQ kernel or not, it does not guaranties you of what you have on the other side. You could even have no frontends at all.

You should probably write your code in a frontend independent manner, but if you want to display different things, you can use the rich display system (link pinned to version 4.x of IPython) to display different things depending on the frontend, but the frontend will choose, not the library.

Solution 7 - Python

All you have to do is to place these two cells at the beginning of your notebook:

Cell 1: (marked as "code"):

is_notebook = True

Cell 2: (marked as "Raw NBConvert"):

is_notebook = False

The first cell will always be executed, but the second cell will only be executed when you export the notebook as a Python script.

Later, you can check:

if is_notebook:
    notebook_code()
else:
    script_code()

Hope this helps.

Solution 8 - Python

As far as I know, Here has 3 kinds of ipython that used ipykernel

  1. ipython qtconsole ("qtipython" for short)
  2. IPython in spyder ("spyder" for short)
  3. IPython in jupyter notebook ("jn" for short)

use 'spyder' in sys.modules can distinguish spyder

but for qtipython and jn are hard to distinguish because

they have same sys.modules and same IPython config:get_ipython().config

I find a different between qtipython and jn:

first run os.getpid() in IPython shell to get the pid number

then run ps -ef|grep [pid number]

my qtipython pid is 8699

yanglei   8699  8693  4 20:31 ?        00:00:01 /home/yanglei/miniconda2/envs/py3/bin/python -m ipykernel_launcher -f /run/user/1000/jupyter/kernel-8693.json

my jn pid is 8832

yanglei   8832  9788 13 20:32 ?        00:00:01 /home/yanglei/miniconda2/bin/python -m ipykernel_launcher -f /run/user/1000/jupyter/kernel-ccb962ec-3cd3-4008-a4b7-805a79576b1b.json

the different of qtipython and jn is the ipython's json name, jn's json name are longer than qtipython's

so, we can auto-detect all Python Environment using the following code:

import sys,os
def jupyterNotebookOrQtConsole():
    env = 'Unknow'
    cmd = 'ps -ef'
    try:
        with os.popen(cmd) as stream:
            if not py2:
                stream = stream._stream
            s = stream.read()
        pid = os.getpid()
        ls = list(filter(lambda l:'jupyter' in l and str(pid) in l.split(' '), s.split('\n')))
        if len(ls) == 1:
            l = ls[0]
            import re
            pa = re.compile(r'kernel-([-a-z0-9]*)\.json')
            rs = pa.findall(l)
            if len(rs):
                r = rs[0]
                if len(r)<12:
                    env = 'qtipython'
                else :
                    env = 'jn'
        return env
    except:
        return env
    
pyv = sys.version_info.major
py3 = (pyv == 3)
py2 = (pyv == 2)
class pyi():
    '''
    python info
    
    plt : Bool
        mean plt avaliable
    env :
        belong [cmd, cmdipython, qtipython, spyder, jn]
    '''
    pid = os.getpid()
    gui = 'ipykernel' in sys.modules
    cmdipython = 'IPython' in sys.modules and not gui
    ipython = cmdipython or gui
    spyder = 'spyder' in sys.modules
    if gui:
        env = 'spyder' if spyder else jupyterNotebookOrQtConsole()
    else:
        env = 'cmdipython' if ipython else 'cmd'
    
    cmd = not ipython
    qtipython = env == 'qtipython'
    jn = env == 'jn'
    
    plt = gui or 'DISPLAY' in os.environ 

print('Python Envronment is %s'%pyi.env)

The source code is here: Detection Python Environment, Especially distinguish Spyder, Jupyter notebook, Qtconsole.py

Solution 9 - Python

The following captures the cases of https://stackoverflow.com/a/50234148/1491619 without needing to parse the output of ps

def pythonshell():
    """Determine python shell

    pythonshell() returns

    'shell' (started python on command line using "python")
    'ipython' (started ipython on command line using "ipython")
    'ipython-notebook' (e.g., running in Spyder or started with "ipython qtconsole")
    'jupyter-notebook' (running in a Jupyter notebook)

    See also https://stackoverflow.com/a/37661854
    """
    
    import os
    env = os.environ
    shell = 'shell'
    program = os.path.basename(env['_'])
    
    if 'jupyter-notebook' in program:
        shell = 'jupyter-notebook'
    elif 'JPY_PARENT_PID' in env or 'ipython' in program:
        shell = 'ipython'
        if 'JPY_PARENT_PID' in env:
            shell = 'ipython-notebook'
    
    return shell

Solution 10 - Python

I would recommend avoiding to detect specific frontend because there are too many of them. Instead you can just test if you are running from within iPython environment:

def is_running_from_ipython():
    from IPython import get_ipython
    return get_ipython() is not None

Above will return False if you are invoking running_from_ipython from usual python command line. When you invoke it from Jupyter Notebook, JupyterHub, iPython shell, Google Colab etc then it will return True.

Solution 11 - Python

A very simple and efficient solution is to check if the top of the call stack refers to IPython environment, as follows:

import traceback

def is_in_notebook():
    rstk = traceback.extract_stack(limit=1)[0]
    return rstk[0].startswith("<ipython")

This code works for both Python 2 and 3, on IPython or Jupyter, with no need to check, set or change the environment.

Solution 12 - Python

I am using Django Shell Plus to launch IPython, and I wanted to make 'running in notebook' available as a Django settings value. get_ipython() is not available when loading settings, so I use this (which is not bulletproof, but good enough for the local development environments it's used in):

import sys

if '--notebook' in sys.argv:
    ENVIRONMENT = "notebook"
else:
    ENVIRONMENT = "dev"

Solution 13 - Python

Assuming you have control of the Jupyter Notebook you could:

  1. set an environment value in a cell that uses this as a flag in your code. Place a unique comment in that cell (or all cells you want to exclude)

    exclude_from_export

    %set_env is_jupyter=1
    
  2. Export the notebook as a python script to be used in a different context. The export would exclude the commented cell(s) and subsequently the code that sets the environment value. Note: replace your_notebook.ipynb with the name of your actual notebook file.

    jupyter nbconvert --to script --RegexRemovePreprocessor.patterns="['^# exclude_from_export']" your_notebook.ipynb

This will generate a file that will not have the jupyter environment flag set allowing for code that uses it to deterministically execute.

Solution 14 - Python

How about something like this:

import sys

inJupyter = sys.argv[-1].endswith('json')

print(inJupyter);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionChristophView Question on Stackoverflow
Solution 1 - PythonGustavo BezerraView Answer on Stackoverflow
Solution 2 - PythonkeflavichView Answer on Stackoverflow
Solution 3 - PythonTill HoffmannView Answer on Stackoverflow
Solution 4 - PythondeeenesView Answer on Stackoverflow
Solution 5 - PythonRobert NowakView Answer on Stackoverflow
Solution 6 - PythonMattView Answer on Stackoverflow
Solution 7 - PythonJulio AlvesView Answer on Stackoverflow
Solution 8 - PythonYangView Answer on Stackoverflow
Solution 9 - PythonBob WeigelView Answer on Stackoverflow
Solution 10 - PythonShital ShahView Answer on Stackoverflow
Solution 11 - PythonOlivier OUDOTView Answer on Stackoverflow
Solution 12 - Pythonuser31415629View Answer on Stackoverflow
Solution 13 - PythonRon Sims IIView Answer on Stackoverflow
Solution 14 - Pythonuser431378View Answer on Stackoverflow