Table of Content

I used small script to make one python version portable before, it seems not necessary to intro extra switch script at all,why not just place python2 and python3 together at same time in portable usb driver.

Few pain points:

  • python installation hardcoded python path to all tools and scripts, such as pip, easy_install, ipython, jupyter
    it is not working after move location
  • when add python2/3 env in PATH, cannot call right tool since they are same name, for example python.exe
  • jupyter notebook kernel mess up

Portable path of python

you can change hardcoded path to general one in binary editor,

#!C:\\python.exe
to
#!python.exe

or you can directly run it without any change, no matter what is path hardcoded inside,

//python //ipython.exe

so best way is just to have alias to it, I used those python alias in portabledevops.


# portable python
PY2PATH=$PORTABLEPATH/python/Python27
PY3PATH=$PORTABLEPATH/python/Python34

export PATH=$PY2PATH:$PY2PATH/Scripts:$PY3PATH:$PY3PATH/Scripts:$PATH
alias py2="$PY2PATH/python.exe"
alias py3="$PY3PATH/python.exe"
alias pip2="$PY2PATH/python.exe $PY2PATH/Scripts/pip.exe"
alias pip3="$PY3PATH/python.exe $PY3PATH/Scripts/pip.exe"
alias ipy2="$PY2PATH/python.exe $PY2PATH/Scripts/ipython.exe"
alias ipy3="$PY3PATH/python.exe $PY3PATH/Scripts/ipython.exe"
alias jupy2="$PY2PATH/python.exe $PY2PATH/Scripts/jupyter.exe"
alias jupy3="$PY3PATH/python.exe $PY3PATH/Scripts/jupyter.exe"
alias easy2="$PY2PATH/python.exe $PY2PATH/Scripts/easy_install.exe"
alias easy3="$PY3PATH/python.exe $PY3PATH/Scripts/easy_install.exe"

Jupyter notebook kernel

The default jupyter kenel location on windows is C:\ProgramData\jupyter\kernels.

jupyter kernel install

#!/usr/bin/bash 
# name: jupykernel.sh
# install ipython kernel for both python2/3 to user location ~/.ipython/kernels
# usage: $source jupykernel.sh
# Nov 27, 2016
# Robert Wang

# install ipython kernel to default C:\ProgramData\jupyter\kernels
# alias ipy2='/L/portabledevops/python/Python27/python /L/portabledevops/python/Python27/Scripts/ipython.exe'
# alias ipy3='/L/portabledevops/python/Python34/python /L/portabledevops/python/Python34/Scripts/ipython.exe'

ipy2 kernel install > /dev/null
ipy3 kernel install > /dev/null

if [ ! -d /home/$USERNAME/.ipython/kernels ]; then
	mkdir -p /home/$USERNAME/.ipython/kernels
fi

if [ -d /home/$USERNAME/.ipython/kernels/python2 ];then
    rm -r /home/$USERNAME/.ipython/kernels/python2
fi 

if [ -d /home/$USERNAME/.ipython/kernels/python3 ];then
    rm -r /home/$USERNAME/.ipython/kernels/python3
fi 

mv /c/ProgramData/jupyter/kernels/python2 /home/$USERNAME/.ipython/kernels
mv /c/ProgramData/jupyter/kernels/python3 /home/$USERNAME/.ipython/kernels

echo "installed ipython kernels to location: /home/$USERNAME/.ipython/kernels"
ls -ltr /home/$USERNAME/.ipython/kernels/python*

Here is sample to create jupyter notebook kernels.

$ source jupykernel.sh
installed ipython kernels to location: /home//.ipython/kernels
/home//.ipython/kernels/python2:
total 9
-rw-r--r-- 1 1049089 1084 Jun 12 07:41 logo-32x32.png
-rw-r--r-- 1 1049089 2180 Jun 12 07:41 logo-64x64.png
-rw-r--r-- 1 1049089  192 Nov 27 14:35 kernel.json

/home//.ipython/kernels/python3:
total 9
-rw-r--r-- 1 1049089 1084 Jun 12 16:48 logo-32x32.png
-rw-r--r-- 1 1049089 2180 Jun 12 16:48 logo-64x64.png
-rw-r--r-- 1 1049089  186 Nov 27 14:35 kernel.json

You can verify jupyter notebook kernel from web interface notebooks drop down menu.

$ jupy2 notebook
[I 11:24:31.634 NotebookApp] Serving notebooks from local directory: L:\portabledevops\git\home\
[I 11:24:31.634 NotebookApp] 0 active kernels
[I 11:24:31.635 NotebookApp] The Jupyter Notebook is running at: http://localhost:8888/
[I 11:24:31.635 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[W 11:24:36.068 NotebookApp] 404 GET /undefined (::1) 10.00ms referer=None
[I 11:24:36.092 NotebookApp] Creating new notebook in
[W 11:24:37.174 NotebookApp] 404 GET /nbextensions/widgets/notebook/js/extension.js?v=20161127112431 (::1) 5.00ms referer=http://localhost:8888/notebooks/Untitled3.ipynb?kernel_name=python2
[I 11:24:37.450 NotebookApp] Kernel started: 5e607246-a891-4635-bfc9-404f81c93d1e
[I 11:26:37.579 NotebookApp] Saving file at /Untitled3.ipynb

open another terminal, 
$ jupy3 notebook
[I 11:24:10.552 NotebookApp] The port 8888 is already in use, trying another port.
[I 11:24:10.780 NotebookApp] Serving notebooks from local directory: L:\portabledevops\git\home\
[I 11:24:10.780 NotebookApp] 0 active kernels
[I 11:24:10.780 NotebookApp] The Jupyter Notebook is running at: http://localhost:8889/
[I 11:24:10.782 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[W 11:24:18.203 NotebookApp] 404 GET /api/kernels/e5bd5f52-c59e-412d-920a-98188a716d09/channels?session_id=6187E46166514BA586D0AB5F214C6910 (::1): Kernel does not exist: e5bd5f52-c59e-412d-920a-98188a716d09
[W 11:24:18.213 NotebookApp] 404 GET /api/kernels/e5bd5f52-c59e-412d-920a-98188a716d09/channels?session_id=6187E46166514BA586D0AB5F214C6910 (::1) 26.00ms referer=None
[W 11:24:34.226 NotebookApp] Replacing stale connection: e5bd5f52-c59e-412d-920a-98188a716d09:6187E46166514BA586D0AB5F214C6910
[W 11:24:53.489 NotebookApp] 404 GET /undefined (::1) 4.00ms referer=None
[I 11:24:53.533 NotebookApp] Creating new notebook in
[W 11:24:54.526 NotebookApp] 404 GET /nbextensions/widgets/notebook/js/extension.js?v=20161127112410 (::1) 5.00ms referer=http://localhost:8889/notebooks/Untitled5.ipynb?kernel_name=python3
[I 11:24:54.782 NotebookApp] Kernel started: 5b71774e-5f59-4f66-acf3-2dab96739728
[I 11:26:54.930 NotebookApp] Saving file at /Untitled5.ipynb