How to pass the class path to ipython's notebo

2019-08-30 07:09发布

问题:

I've been using iypthon as set from ipzope (buildout) for a while and it works without problems.

Now I'm trying to use ipython's notebook and I cannot set it up properly.

When I create a new notebook it stops IPython's Kernel with an ImportError (see below). I guess that the created Thread in IPython.html.notebook.start() opens the webbrowser without passing the sys.path from the calling process.

My workaround is to add the paths in ipzope to PYTHONPATH.

When I add all the paths then ipython's notebook works perfectly and I can debug and manipulate Plone.

If I only add ipython, pyzmq, Jinja, and tornado to PYTHONPATH ipython's notebook works but it has no access to the ipzope vars (app, utils etc.)

Question: Any hint how to pass the paths to ipython's notebook without using PYTHONPATH?

I start ipython's notebook from ipzope with

sys.argv[1:1] = "notebook --ip=192.168.45.135 --profile=zope".split()

The ImportError is:

IPython Notebook 14-03-22 14:57:17.141 [NotebookApp] Connecting to: tcp://127.0.0.1:50948
2014-03-22 14:57:17.143 [NotebookApp] Kernel started: b573fbc0-5dee-410b-91cb-01afd2e9acce
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: No module named IPython.kernel.zmq.kernelapp

回答1:

I quote Min RK IPython developer:

"When you start plain terminal IPython, the shell is created in the same process. That means that IPython executes in the same context as the changes you have made to sys.path, so the changes have the desired effect. In the notebook, only the notebook server exists in that context. Kernels are started as subprocesses, and thus recreate sys.path at startup, following the standard procedure for a Python process, and do not inherit any runtime changes to sys.path that may have happened in parent processes." (https://github.com/ipython/ipython/issues/5420)

My Solution

Thus the only way to pass the path to notebook is via PYTHONPATH.

My workaround by now is to set os.environ['PYTHONPATH'] = ':'.join(sys.path) in the script. With this you don't need to mess the PYTHONPATH (if any) of your system and you make sure that all the necessary paths will be passed to the kernel.

The os.environ is passed as env argument of Popen to the subprocess in launch_kernel (.../ipython-1.2.1-py2.7.egg/IPython/kernel/launcher.py).

If you need to use ipython's notebook and want buildout to generate the script, add the following to your buildout (e.g. in .../Plone-4.3.2/zeocluster/develop.cfg)

parts +=
...
    ipzopenb
...
[ipzopenb]
recipe = zc.recipe.egg
eggs =
    ipython
    pyzmq
    tornado
    Jinja2
#following for nbconvert
    Pygments
    Sphinx
    ${client2:eggs}
initialization =
    import sys, os
    os.environ["INSTANCE_HOME"] = "${client2:location}"
    os.environ['PYTHONPATH'] = ':'.join(sys.path)
    sys.argv[1:1] = "notebook --ip=192.168.45.135 --profile=zope".split()
scripts = ipython=ipzopenb
...
[versions]
Jinja2 = 2.7.2
Pygments = 1.6
Sphinx = 1.2.2