Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Environment inconsistent between IPython and Jupyter notebook launched in environment #2953

Closed
DavidMertz opened this issue Jul 1, 2016 · 30 comments
Labels
locked [bot] locked due to inactivity

Comments

@DavidMertz
Copy link

DavidMertz commented Jul 1, 2016

See https://github.com/ContinuumIO/anaconda-cluster/issues/1022 for the details (I'll copy them over below too). We initially thought the error was elsewhere than where it actually applies.

@DavidMertz
Copy link
Author

Let me detail the issue more carefully. Thank you @brendancol for making the initial note of it. From a shell:

504-Dask % activate py2-env
discarding /Users/dmertz/anaconda/bin from PATH
prepending /Users/dmertz/anaconda/envs/py2-env/bin to PATH
(py2-env)505-Dask % ipython
Python 2.7.12 |Continuum Analytics, Inc.| (default, Jun 29 2016, 11:09:23) 
Type "copyright", "credits" or "license" for more information.

IPython 4.2.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: from dask.distributed import Executor, progress

In [2]: 
Do you really want to exit ([y]/n)? y
(py2-env)506-Dask % jupyter notebook
[I 22:02:28.843 NotebookApp] Serving notebooks from local directory: /Users/dmertz/Projects/training-products/Dask
[I 22:02:28.844 NotebookApp] 0 active kernels 
[I 22:02:28.844 NotebookApp] The Jupyter Notebook is running at: http://localhost:8888/
[I 22:02:28.844 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).

Within the launched notebook environment I see this:

importerror

For completeness, here are the kernel messages:

[W 22:03:14.947 NotebookApp] 404 GET /nbextensions/IPython-notebook-extensions-3.x/usability/runtools/main.js?v=20160630220228 (::1) 12.78ms referer=http://localhost:8888/notebooks/07_Distributed_Custom.ipynb
[I 22:03:15.481 NotebookApp] Kernel started: 16078bbd-6c08-4cdd-9999-80bbbe652114
/Users/dmertz/anaconda/envs/py27/lib/python2.7/site-packages/IPython/kernel/__init__.py:13: ShimWarning: The `IPython.kernel` package has been deprecated. You should import from ipykernel or jupyter_client instead.
  "You should import from ipykernel or jupyter_client instead.", ShimWarning)
[I 22:03:48.729 NotebookApp] Kernel restarted: 16078bbd-6c08-4cdd-9999-80bbbe652114
/Users/dmertz/anaconda/envs/py27/lib/python2.7/site-packages/IPython/kernel/__init__.py:13: ShimWarning: The `IPython.kernel` package has been deprecated. You should import from ipykernel or jupyter_client instead.
  "You should import from ipykernel or jupyter_client instead.", ShimWarning)
[I 22:05:15.465 NotebookApp] Saving file at /07_Distributed_Custom.ipynb
^C[I 22:08:55.988 NotebookApp] interrupted
Serving notebooks from local directory: /Users/dmertz/Projects/training-products/Dask
1 active kernels 
The Jupyter Notebook is running at: http://localhost:8888/
Shutdown this notebook server (y/[n])? y
[C 22:08:57.306 NotebookApp] Shutdown confirmed
[I 22:08:57.307 NotebookApp] Shutting down kernels
[I 22:08:57.726 NotebookApp] Kernel shutdown: 16078bbd-6c08-4cdd-9999-80bbbe652114

My environment looks like this:

(py2-env)507-Dask % conda env export 
name: py2-env
dependencies:
- appnope=0.1.0=py27_0
- backports=1.0=py27_0
- backports.shutil_get_terminal_size=1.0.0=py27_0
- backports_abc=0.4=py27_0
- bokeh=0.12.0=py27_0
- boto3=1.3.1=py27_0
- botocore=1.4.28=py27_0
- click=6.6=py27_0
- cloudpickle=0.2.1=py27_2
- configparser=3.5.0b2=py27_1
- dask=0.10.0=py27_1
- decorator=4.0.10=py27_0
- distributed=1.11.0=py27_0
- docutils=0.12=py27_2
- entrypoints=0.2.2=py27_0
- freetype=2.5.5=1
- functools32=3.2.3.2=py27_0
- futures=3.0.5=py27_0
- get_terminal_size=1.0.0=py27_0
- ipykernel=4.3.1=py27_0
- ipython=4.2.0=py27_1
- ipython_genutils=0.1.0=py27_0
- ipywidgets=4.1.1=py27_0
- jinja2=2.8=py27_1
- jmespath=0.9.0=py27_0
- jsonschema=2.5.1=py27_0
- jupyter=1.0.0=py27_3
- jupyter_client=4.3.0=py27_0
- jupyter_console=4.1.1=py27_0
- jupyter_core=4.1.0=py27_0
- libpng=1.6.22=0
- locket=0.2.0=py27_1
- markupsafe=0.23=py27_2
- mistune=0.7.2=py27_1
- mkl=11.3.3=0
- msgpack-python=0.4.6=py27_0
- nbconvert=4.2.0=py27_0
- nbformat=4.0.1=py27_0
- notebook=4.2.1=py27_0
- numpy=1.11.0=py27_1
- openssl=1.0.2h=1
- pandas=0.18.1=np111py27_0
- partd=0.3.4=py27_0
- path.py=8.2.1=py27_0
- pathlib2=2.1.0=py27_0
- pexpect=4.0.1=py27_0
- pickleshare=0.7.2=py27_0
- pip=8.1.2=py27_0
- psutil=4.3.0=py27_0
- ptyprocess=0.5.1=py27_0
- pygments=2.1.3=py27_0
- pyqt=4.11.4=py27_3
- python=2.7.12=0
- python-dateutil=2.5.3=py27_0
- python.app=1.2=py27_4
- pytz=2016.4=py27_0
- pyyaml=3.11=py27_4
- pyzmq=15.2.0=py27_1
- qt=4.8.7=3
- qtconsole=4.2.1=py27_0
- readline=6.2=2
- requests=2.10.0=py27_0
- s3fs=0.0.6=py27_0
- setuptools=23.0.0=py27_0
- simplegeneric=0.8.1=py27_1
- singledispatch=3.4.0.3=py27_0
- sip=4.16.9=py27_0
- six=1.10.0=py27_0
- sqlite=3.13.0=0
- ssl_match_hostname=3.5.0.1=py27_0
- tblib=1.3.0=py27_0
- terminado=0.6=py27_0
- tk=8.5.18=0
- toolz=0.8.0=py27_0
- tornado=4.3=py27_1
- traitlets=4.2.1=py27_0
- wheel=0.29.0=py27_0
- yaml=0.1.6=0
- zlib=1.2.8=3
- pip:
  - backports-abc==0.4
  - backports.shutil-get-terminal-size==1.0.0
  - backports.ssl-match-hostname==3.5.0.1
  - ipython-genutils==0.1.0
  - jupyter-client==4.3.0
  - jupyter-console==4.1.1
  - jupyter-core==4.1.0

@DavidMertz
Copy link
Author

DavidMertz commented Jul 1, 2016

@quasiben notes this:

As you said, I think this issue is not related to cluster but happy to help. Looking at your debug output i noticed something odd:

/Users/dmertz/anaconda/envs/py27/lib/python2.7/site-packages/IPython/kernel/__init__.py:13: ShimWarning: The `IPython.kernel` package has been deprecated. You should import from ipykernel or jupyter_client instead.

Look at the path: /Users/dmertz/anaconda/envs/py27. This is not, the env you activate: /Users/dmertz/anaconda/envs/py2-env/. What I think is happening is that jupyter notebook is not in env: py2-env and it is py27. I would guess there is a PATH issue?

However:

Smart observation, @quasiben. I think that path problem is probably related. However, it remains strange that running conda env list within the launched notebook identifies the correct environment still. This definitely seems like a conda issue, not an anaconda-cluster one though. Brendon just noted it when we were in the middle of class, and we didn't have time to think through and identify all the details of exactly what was going wrong in front of a group of students to report it most accurately I'll file a conda issue with these details.

condaenv

@quasiben
Copy link
Contributor

quasiben commented Jul 1, 2016

@DavidMertz within py2-env can you show the output for which jupyter and also echo $PATH?

@DavidMertz
Copy link
Author

DavidMertz commented Jul 1, 2016

510-Dask % source activate py2-env
discarding /Users/dmertz/anaconda/bin from PATH
prepending /Users/dmertz/anaconda/envs/py2-env/bin to PATH
(py2-env)511-Dask % which jupyter
/Users/dmertz/anaconda/envs/py2-env/bin/jupyter
(py2-env)512-Dask % echo $PATH | tr ':' '\n'
/Users/dmertz/anaconda/envs/py2-env/bin
/Library/Frameworks/Python.framework/Versions/3.6/bin
/Library/Frameworks/Python.framework/Versions/3.5/bin
/Library/Frameworks/Python.framework/Versions/3.4/bin
/usr/local/bin
/sw/bin
/usr/local/sbin
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin
/opt/X11/bin
/usr/local/git/bin
/Library/TeX/texbin

@mcg1969
Copy link
Contributor

mcg1969 commented Jul 1, 2016

Doesn't Jupyter have some configuration file somewhere that tells it where to launch a kernel? Perhaps that has been configured somehow to go to py27 instead of py2-env?

@mcg1969
Copy link
Contributor

mcg1969 commented Jul 1, 2016

I think this is related to these: #2548, jupyter/notebook#1508

Jupyter relies on files outside of the conda environment system for configuration. If that is what is causing the mismatched kernel here, there is nothing conda itself can do about it. It suggests instead that somehow we need to patch Jupyter itself to play nicely with virtual environments (not just conda's).

@mcg1969
Copy link
Contributor

mcg1969 commented Jul 1, 2016

In particular: what does your directory ~/.jupyter look like? And what happens here if you remove it?

@DavidMertz
Copy link
Author

DavidMertz commented Jul 1, 2016

Nothing indicating suspicious paths:

(py2-env)519-Dask % tree ~/.jupyter/
/Users/dmertz/.jupyter/
├── migrated
└── nbconfig
    ├── edit.json
    └── notebook.json

1 directory, 3 files
(py2-env)520-Dask % find ~/.jupyter -type f -print0 | xargs -0 -I '{}' sh -c "echo; echo {}; cat {}" 

/Users/dmertz/.jupyter/migrated
2016-01-09T18:52:56.588665
/Users/dmertz/.jupyter/nbconfig/edit.json
{
  "Editor": {
    "codemirror_options": {
      "vimMode": false,
      "keyMap": "default"
    }
  }
}
/Users/dmertz/.jupyter/nbconfig/notebook.json
{
  "calico-spell-check": true,
  "load_extensions": {
    "calico-spell-check": true,
    "IPython-notebook-extensions-3.x/usability/runtools/main": true,
    "calico-cell-tools": true,
    "calico-document-tools": true
  },
  "calico-cell-tools": true,
  "calico-document-tools": true

@DavidMertz
Copy link
Author

Also trying to rule out one more thing: grep py2 07_Distributed_Custom.ipynb. On the odd possibility the environment and/or path is somehow encoded in the notebook I opened... but the string doesn't occur (which would be in either path/environment for py2-env or py27)

@quasiben
Copy link
Contributor

quasiben commented Jul 1, 2016

Can you post the full output of jupyter notebook. I'm curious if you are getting the following error (or some other weird oddity:

[W 13:23:08.598 NotebookApp] Native kernel (python2) is not available

@DavidMertz
Copy link
Author

DavidMertz commented Jul 1, 2016

The entire output from my run of jupyter notebook is posted in the above description. That shows everything from launching it, to getting the error within a notebook, to canceling the kernel with ^C (i.e. I didn't omit any output).

In particular, the "Native kernel not available" message you show does not occur for me.

@mcg1969
Copy link
Contributor

mcg1969 commented Jul 1, 2016

@bollwyvl, would you by any chance have an idea what's going on? I must be frank I'm still not convinced this is a conda issue. But what can we do to determine that with some certainty?

@quasiben
Copy link
Contributor

quasiben commented Jul 1, 2016

@DavidMertz (i think will fill in the details) but we some latent kernel files lying around in /usr/local/share/jupyter/kernels thanks to @ahmadia for additional debugging. This isn't a conda problem, but maybe conda could help ?

@mcg1969
Copy link
Contributor

mcg1969 commented Jul 1, 2016

I think the right place to put any such "help" is in one of the Jupyter-related conda packages. I'm thinking of perhaps a post-link script that searches for these "external" influences on Jupyter and warns the user about them.

@DavidMertz
Copy link
Author

DavidMertz commented Jul 2, 2016

Skipping some intermediate dead ends we tried, here's the actual issue. I might be in a conda environment like py2-env with its own version of Python installed (e.g. at Users/dmertz/anaconda/envs/py2-env2/bin/python). However, when I launch jupyter notebook from the environment, it looks for extra installed kernels of the same basic Python family.

E.g. within the notebook:

In [1] import sys; sys.path[:3]
Out [1]
['',
 '/Users/dmertz/anaconda/envs/py27/lib/python27.zip',
 '/Users/dmertz/anaconda/envs/py27/lib/python2.7']

It's finding this information from here:

% cat /usr/local/share/jupyter/kernels/python2/kernel.json 
{
 "display_name": "Python 2", 
 "language": "python", 
 "argv": [
  "/Users/dmertz/anaconda/envs/py27/bin/python", 
  "-m", 
  "IPython.kernel", 
  "-f", 
  "{connection_file}"
 ]
}
% ls -o /usr/local/share/jupyter/kernels/python2/kernel.json 
-rw-r--r--  1 dmertz  182 Aug 19  2015 /usr/local/share/jupyter/kernels/python2/kernel.json

If I move kernel.json to kernel.old the notebook will use the correct Python version (as verified by sys.path).

@mcg1969
Copy link
Contributor

mcg1969 commented Jul 2, 2016

Thanks for the update, David. I find it interesting that jupyter is giving priority to /usr/local/share/jupyter/kernels over a kernel found in sys.prefix. I personally would consider this a Jupyter bug, or at least, a sign that Jupyter as designed does not play well in virtual environments (whether created by conda or not).

@DavidMertz
Copy link
Author

DavidMertz commented Jul 2, 2016

A wrinkle here is that I want to be able to launch other kernels from within a Notebook (and my students want that capability). So when I open (usually) a Python 3 notebook in an environment with Py3.5, it's nice to have the menu to launch other notebooks that use R, Julia, Python2, or other kernels, as I can do currently.

But at the very least, the notebook I open from a command shell should preferentially use the current environment, even if I have the option of opening other kernels within the Jupyter navigation page.

This sort of makes me think that conda should adjust the configuration of kernels to use the active environment (as long as it uses the same major version of Python anyway). I.e. typing conda activate py2-env could, in principle, check whether /usr/local/share/jupyter/kernels/python2 exists, and if it does, it could modify the kernel.json file contained therein to point to the active path.

I think this behavior makes sense because there is no canonical "right" Python2 kernel to use for the "New/Notebook/Python 2" menu... and the one I launched Jupyter from seems like a better answer than "the one that got configured somehow a year ago."

@mcg1969
Copy link
Contributor

mcg1969 commented Jul 2, 2016

Yeah, I just can't see this; and while I'm not the decisionmaker here, I would have to voice my opposition to it to those who are. It requires giving conda a special understanding of a specific project, counter to its long-term goal of being platform/language agnostic. It would require conda maintainers to track development of Jupyter and test their changes against it. And it requires giving conda expanded abilities to modify files outside of its root or child environments.

The flaw here is quite clearly Jupyter's. It needs to learn to play nicer with virtual environments. (And not just conda virtual environments.) At the very least, it needs to intelligently merge the local configuration information in sys.prefix with the global configuration information in /usr/local/share/jupyter, giving preference to the former.

On the other hand, I could see a way to resolve most of my objections and still provide the specific conda activate functionality you seek. It would involve the creation of a "post activate script" capability. Any conda package could include such a script. The Jupyter conda package could then include a script that performs the necessary modifications in /usr/local/share that you are proposing. It shifts the responsibility for maintaining this capability with the Jupyter team (or at least, the Jupyter package maintainer) where it belongs.

This still gives conda (or more accurately, conda packages) the ability to modify files outside of its installed environment, something I am definitely not wild about. But we already provide that with post-link scripts.

@mcg1969
Copy link
Contributor

mcg1969 commented Jul 2, 2016

@kalefranz now that the cause of this issue is clear, what do you think?

@kalefranz
Copy link
Contributor

I think I'm driving and shouldn't be reading this right now 😬😱

Will catch up soon.

@DavidMertz
Copy link
Author

This issue might have been fixed for us. Flying now and typing on tablet, so can't verify.

But I installed the latest Anaconda 4.1.0, with a newer Jupyter in the bundle. I noticed in the New/Notebook menu it now shows all my environments, instead of simply (some unspecified) Python 2.

This hints that they have learned a better strategy for identifying the best Python path to use. I'll check more carefully tomorrow or tonight.

@damianavila
Copy link

But I installed the latest Anaconda 4.1.0, with a newer Jupyter in the bundle. I noticed in the New/Notebook menu it now shows all my environments, instead of simply (some unspecified) Python 2.
This hints that they have learned a better strategy for identifying the best Python path to use. I'll check more carefully tomorrow or tonight.

Just to give you more context, this is something we (CIO) do... not Jupyter itselft (even when I am Jupyter dev, I originally wrote this on CIO time)... and it is called nb_conda_kernels... it is a nbextension that creates kernelspecs on the fly pointing to the correct "executables" in your environments. I wrote that functionality more that a year ago and then I rewrote it again several months ago (other people was working in something similar and I took the best parts from them 😉) when we started to work in some notebook extension for a better integration with conda/anaconda. Then NickB joined the team and added a lot of good stuff on these and other extensions (and wrote other new and really exciting ones). Finally, some of them are now shipped by default with Anaconda.

@DavidMertz
Copy link
Author

DavidMertz commented Jul 3, 2016

Cool feature @damianavila! Unfortunately, I'm not sure what makes it appear. I thought it should be an update to some Jupyter package, but that doesn't seem to be the case exactly. Or maybe only the py35_3 packages but not the py27_* versions.

Under root, I get the cool new New/Notebook behavior that shows all the environments. However, under py2-env I only get the old kernels listed, and also get the wrong kernel chosen for opening an existing notebook, per sys.path in the notebook (I restored /usr/local/share/jupyter/python2/kernel.json to see if the broken behavior still exists).

I hadn't yet tried to upgrade Jupyter in py2-env, but before I did that I ran conda list | grep jupyter in each place. That shows this:

% diff py2-env-jupyter-versions root-env-jupyter-versions
1c1
< jupyter                   1.0.0                    py27_3    defaults
---
> jupyter                   1.0.0                    py35_3    defaults
5,7c5,7
< jupyter_client            4.3.0                    py27_0    defaults
< jupyter_console           4.1.1                    py27_0    defaults
< jupyter_core              4.1.0                    py27_0    defaults
---
> jupyter_client            4.3.0                    py35_0    defaults
> jupyter_console           4.1.1                    py35_0    defaults
> jupyter_core              4.1.0                    py35_0    defaults

The identical versions of everything obviously Jupyter related is installed both places, except that one is the py35 packages, the other the py27 ones.

Maybe the extension has a non-obvious name, and it's possible to install or update that to get the right behavior?

@DavidMertz
Copy link
Author

Oh... Doh! @damianavila already mentioned it was called nb_conda_kernels. So that's the good news (sort of). I did an install, and now:

(py2-env)538-tmp % conda list | grep nb_conda_kernels
nb_conda_kernels          1.0.3                    py27_0    defaults

The bad news is that after doing this install, I neither get the selection of all the environment kernels, nor open existing notebooks using the current environment. So while a cool feature, Damien's extension does not cure this particular problem (nor do ANYTHING under the old environment!?)

@damianavila
Copy link

The bad news is that after doing this install, I neither get the selection of all the environment kernels, nor open existing notebooks using the current environment. So while a cool feature, Damien's extension does not cure this particular problem (nor do ANYTHING under the old environment!?)

This is probably because the nb_conda_kernels from repo.cio do not have the post-script step to enable the extension... and this is one asymmetry we need to cover @bollwyvl... see the Notebook flow for more details, I have written some of my thoughts there (I was not following the latest developments on this front because I was assigned to other tasks). Essentially, you need to enable the extension on that specific environments if you want to see the extension working from a notebook server living on that environment... something like this should help, in the py2-env run:

python -m nb_conda_kernels.install --enable --prefix $PREFIX

where PREFIX is the prefix of your env...

This step is done in post-script in our original recipes and by a metapackage in the latest Anaconda Distribution... so you are getting the worst experience installing it because you are installing from repo.cio and this is why I say there is an asymmetry we need to fix somehow...

I can help you a little more during the week.

@DavidMertz
Copy link
Author

Excellent progress... albeit not perfect. If I do this:

% python -m nb_conda_kernels.install --enable --prefix /Users/dmertz/anaconda/envs/py2-env

Then I get the extension enabled. While an extra step, this at least seems like something we can document (and that I can teach and know). Launching jupyter notebook [notebook-name.ipynb] gets the extension to choose environments for new notebooks.

An arguable flaw is that when a notebook is actually opened (either via navigating within the notebook file manager or by launching one from the command line directly), I get the below dialog. I can select the environment I used to open Jupyter from here, but I feel like it ought to actually default to that instead.

kernel-not-found

@damianavila
Copy link

An arguable flaw is that when a notebook is actually opened (either via navigating within the notebook file manager or by launching one from the command line directly), I get the below dialog. I can select the environment I used to open Jupyter from here, but I feel like it ought to actually default to that instead.

That's because you have that notebook saved with the kernel name pointing to the previous python2 name... you should not see that with new notebook nor after saving the old ones with the new kernel you select... probably we should try to deal with this in a better way and let the people use one of the python envs available.... see the discussion here for more thoughts: anaconda/nb_conda_kernels#11 (comment)

@ijstokes
Copy link

ijstokes commented Jul 7, 2016

I think this has some relationship to this community-created issue around non-portable Kernel names that encode the environment into the kernel meta-data entry: ContinuumIO/anaconda-issues#877

But for @mcg1969 's sake, I would definitely say that this is not a Conda issue, but rather a combination of Jupyter configuration complexity (e.g. jupyter/notebook#1508) and how we implement the extension. I'm going to move it to the nb_conda_kernel repo.

@ijstokes
Copy link

ijstokes commented Jul 7, 2016

This issue was moved to anaconda/nb_conda_kernels#33

@github-actions
Copy link

Hi there, thank you for your contribution to Conda!

This issue has been automatically locked since it has not had recent activity after it was closed.

Please open a new issue if needed.

@github-actions github-actions bot added the locked [bot] locked due to inactivity label Nov 19, 2021
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 19, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
locked [bot] locked due to inactivity
Projects
None yet
Development

No branches or pull requests

6 participants