[conda] install python 2 in separate kernel env
MODIFY
repo2docker/buildpacks/conda/__init__.py
repo2docker/buildpacks/conda/__init__.py
@@ -6,7 +6,7 @@ import os
import re
from ruamel.yaml import YAML
-from traitlets import default
+from traitlets import default, Unicode
from ..base import BuildPack
@@ -46,7 +46,7 @@ class CondaBuildPack(BuildPack):
files = {
'conda/install-miniconda.bash': '/tmp/install-miniconda.bash',
}
- py_version = self.detect_python_version()
+ py_version = self.python_version
self.log.info("Building conda environment for python=%s" % py_version)
# Select the frozen base environment based on Python version.
# avoids expensive and possibly conflicting upgrades when changing
@@ -55,6 +55,10 @@ class CondaBuildPack(BuildPack):
# the default base environment is used.
frozen_name = 'environment.frozen.yml'
if py_version:
+ if self.py2:
+ # python 2 goes in a different env
+ files['conda/environment.py-2.7.frozen.yml'] = '/tmp/kernel-environment.yml'
+ else:
py_frozen_name = \
'environment.py-{py}.frozen.yml'.format(py=py_version)
if os.path.exists(os.path.join(HERE, py_frozen_name)):
@@ -64,27 +68,17 @@ class CondaBuildPack(BuildPack):
files['conda/' + frozen_name] = '/tmp/environment.yml'
return files
- @default('assemble_scripts')
- def setup_assembly(self):
- assembly_scripts = []
- environment_yml = self.binder_path('environment.yml')
- if os.path.exists(environment_yml):
- assembly_scripts.append((
- '${NB_USER}',
- r"""
- conda env update -v -n root -f "{}" && \
- conda clean -tipsy
- """.format(environment_yml)
- ))
- return assembly_scripts
-
+ python_version = Unicode()
+ @default('python_version')
def detect_python_version(self):
"""Detect the Python version for a given environment.yml
- Will return 'x.y' if found, or None.
+ Will return 'x.y' if found, or Falsy '' if not.
"""
py_version = None
environment_yml = self.binder_path('environment.yml')
+ if not os.path.exists(environment_yml):
+ return ''
with open(environment_yml) as f:
env = YAML().load(f)
for dep in env.get('dependencies', []):
@@ -104,5 +98,28 @@ class CondaBuildPack(BuildPack):
# return major.minor
return '.'.join(py_version[:2])
+ return ''
+
+ @property
+ def py2(self):
+ """Am I building a Python 2 kernel environment?"""
+ return self.python_version and self.python_version.split('.')[0] == '2'
+
+ @default('assemble_scripts')
+ def setup_assembly(self):
+ assembly_scripts = []
+ environment_yml = self.binder_path('environment.yml')
+ env_name = 'kernel' if self.py2 else 'root'
+ if os.path.exists(environment_yml):
+ assembly_scripts.append((
+ '${NB_USER}',
+ r"""
+ conda env update -v -n {} -f "{}" && \
+ conda clean -tipsy
+ """.format(env_name, environment_yml)
+ ))
+ return assembly_scripts
+
+
def detect(self):
return os.path.exists(self.binder_path('environment.yml')) and super().detect()

MODIFY
repo2docker/buildpacks/conda/environment.py-2.7.frozen.yml
repo2docker/buildpacks/conda/environment.py-2.7.frozen.yml
# AUTO GENERATED FROM environment.py-2.7.yml, DO NOT MANUALLY MODIFY
-# Frozen on 2018-01-03 15:29:14 UTC
+# Frozen on 2018-01-03 16:56:23 UTC
name: r2d
channels:
- conda-forge
@@ -8,37 +8,18 @@ dependencies:
- backports=1.0=py27_1
- backports.shutil_get_terminal_size=1.0.0=py_3
- backports_abc=0.5=py27_0
-- bleach=2.0.0=py27_0
- ca-certificates=2017.11.5=0
- certifi=2017.11.5=py27_0
-- configparser=3.5.0=py27_0
- decorator=4.1.2=py27_0
-- entrypoints=0.2.3=py27_1
- enum34=1.1.6=py27_1
-- functools32=3.2.3.2=py27_1
-- futures=3.2.0=py27_0
-- gmp=6.1.2=0
-- html5lib=1.0.1=py_0
- ipykernel=4.7.0=py27_0
- ipython=5.5.0=py27_0
- ipython_genutils=0.2.0=py27_0
-- ipywidgets=6.0.1=py27_0
-- jinja2=2.10=py27_0
-- jsonschema=2.6.0=py27_0
- jupyter_client=5.2.0=py27_0
- jupyter_core=4.4.0=py_0
-- jupyterlab=0.30.6=py27_0
-- jupyterlab_launcher=0.6.0=py27_0
- libsodium=1.0.15=1
-- markupsafe=1.0=py27_0
-- mistune=0.8.3=py_0
-- nbconvert=5.3.1=py_1
-- nbformat=4.4.0=py27_0
- ncurses=5.9=10
-- notebook=5.2.2=py27_1
- openssl=1.0.2n=0
-- pandoc=2.0.5=0
-- pandocfilters=1.4.1=py27_0
- pathlib2=2.3.0=py27_0
- pexpect=4.3.1=py27_0
- pickleshare=0.7.4=py27_0
@@ -57,16 +38,11 @@ dependencies:
- six=1.11.0=py27_1
- sqlite=3.20.1=2
- ssl_match_hostname=3.5.0.1=py27_1
-- subprocess32=3.2.7=py27_0
-- terminado=0.8.1=py27_0
-- testpath=0.3.1=py27_0
- tk=8.6.7=0
- tornado=4.5.2=py27_0
- traitlets=4.3.2=py27_0
- wcwidth=0.1.7=py27_0
-- webencodings=0.5=py27_0
- wheel=0.30.0=py_1
-- widgetsnbextension=2.0.1=py27_0
- zeromq=4.2.1=1
- zlib=1.2.11=0
prefix: /opt/conda/envs/r2d

ADD
repo2docker/buildpacks/conda/environment.py-2.7.yml
+dependencies:
+- python=2.7.*
+- ipykernel==4.7.0

MODIFY
repo2docker/buildpacks/conda/install-miniconda.bash
repo2docker/buildpacks/conda/install-miniconda.bash
@@ -32,6 +32,12 @@ ${CONDA_DIR}/bin/conda config --system --set show_channel_urls true
${CONDA_DIR}/bin/conda env update -n root -f /tmp/environment.yml
+if [[ -f /tmp/kernel-environment.yml ]]; then
+ # install kernel env and register kernelspec
+ ${CONDA_DIR}/bin/conda env create -n kernel -f /tmp/kernel-environment.yml
+ ${CONDA_DIR}/envs/kernel/bin/ipython kernel install --prefix "${CONDA_DIR}"
+fi
+
# Clean things out!
${CONDA_DIR}/bin/conda clean -tipsy

MODIFY
tests/conda/simple-py2/verify
tests/conda/simple-py2/verify
#!/usr/bin/env python
import sys
-assert sys.version_info[:2] == (2, 7), sys.version
+assert sys.version_info[:2] == (3, 6), sys.version
-import numpy
+# verify that we have Python 2 and Python 3 kernelspecs
+from jupyter_client.kernelspec import KernelSpecManager
+ksm = KernelSpecManager()
+specs = ksm.get_all_specs()
+assert sorted(specs) == ['python2', 'python3'], specs.keys()
+
+# verify that we created the kernel env
+import json
+from subprocess import check_output
+envs = json.loads(check_output(['conda', 'env', 'list', '--json']).decode('utf8'))
+assert envs == {'envs': ['/srv/conda/envs/kernel']}, envs
+
+pkgs = json.loads(check_output(['conda', 'list', '-n', 'kernel', '--json']).decode('utf8'))
+pkg_names = [pkg['name'] for pkg in pkgs]
+assert 'ipykernel' in pkg_names, pkg_names
+assert 'numpy' in pkg_names
+for pkg in pkgs:
+ if pkg['name'] == 'python':
+ assert pkg['version'].startswith('2.7.')
+ break
+else:
+ assert False, "python not found in %s" % pkg_names

[conda] install python 2 in separate kernel env