1{ lib 2, buildPythonPackage 3, fetchPypi 4, fetchzip 5, alembic 6, ipython 7, jinja2 8, python-oauth2 9, pamela 10, sqlalchemy 11, tornado 12, traitlets 13, requests 14, pythonOlder 15, nodePackages 16}: 17 18let 19 # js/css assets that setup.py tries to fetch via `npm install` when building 20 # from source. 21 bootstrap = 22 fetchzip { 23 url = "https://registry.npmjs.org/bootstrap/-/bootstrap-3.3.7.tgz"; 24 sha256 = "0r7s54bbf68ri1na9bbabyf12mcpb6zk5ja2q6z82aw1fa4xi3yd"; 25 }; 26 font-awesome = 27 fetchzip { 28 url = "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz"; 29 sha256 = "1xnxbdlfdd60z5ix152m8r2kk9dkwlqwpypky1mm3dv64ajnzdbk"; 30 }; 31 jquery = 32 fetchzip { 33 url = "https://registry.npmjs.org/jquery/-/jquery-3.2.1.tgz"; 34 sha256 = "1j6y18miwzafdj8kfpwbmbn9qvgnbnpc7l4arqrhqj33m04xrlgi"; 35 }; 36 moment = 37 fetchzip { 38 url = "https://registry.npmjs.org/moment/-/moment-2.18.1.tgz"; 39 sha256 = "1b4vyvs24v6y92pf2iqjm5aa7jg7khcpspn00girc7lpi917f9vw"; 40 }; 41 requirejs = 42 fetchzip { 43 url = "https://registry.npmjs.org/requirejs/-/requirejs-2.3.4.tgz"; 44 sha256 = "0q6mkj0iv341kks06dya6lfs2kdw0n6vc7n4a7aa3ia530fk9vja"; 45 }; 46 47in 48 49buildPythonPackage rec { 50 pname = "jupyterhub"; 51 version = "0.8.1"; 52 53 src = fetchPypi { 54 inherit pname version; 55 sha256 = "100cf18d539802807a45450d38fefbb376cf1c810f3b1b31be31638829a5c69c"; 56 }; 57 58 # Most of this only applies when building from source (e.g. js/css assets are 59 # pre-built and bundled in the official release tarball on pypi). 60 # 61 # Stuff that's always needed: 62 # * At runtime, we need configurable-http-proxy, so we substitute the store 63 # path. 64 # 65 # Other stuff that's only needed when building from source: 66 # * js/css assets are fetched from npm. 67 # * substitute store path for `lessc` commmand. 68 # * set up NODE_PATH so `lessc` can find `less-plugin-clean-css`. 69 # * don't run `npm install`. 70 preBuild = '' 71 export NODE_PATH=${nodePackages.less-plugin-clean-css}/lib/node_modules 72 73 substituteInPlace jupyterhub/proxy.py --replace \ 74 "'configurable-http-proxy'" \ 75 "'${nodePackages.configurable-http-proxy}/bin/configurable-http-proxy'" 76 77 substituteInPlace jupyterhub/tests/test_proxy.py --replace \ 78 "'configurable-http-proxy'" \ 79 "'${nodePackages.configurable-http-proxy}/bin/configurable-http-proxy'" 80 81 substituteInPlace setup.py --replace \ 82 "'npm', 'run', 'lessc', '--'" \ 83 "'${nodePackages.less}/bin/lessc'" 84 85 substituteInPlace setup.py --replace \ 86 "'npm', 'install', '--progress=false'" \ 87 "'true'" 88 89 declare -A deps 90 deps[bootstrap]=${bootstrap} 91 deps[font-awesome]=${font-awesome} 92 deps[jquery]=${jquery} 93 deps[moment]=${moment} 94 deps[requirejs]=${requirejs} 95 96 mkdir -p share/jupyter/hub/static/components 97 for dep in "''${!deps[@]}"; do 98 if [ ! -e share/jupyter/hub/static/components/$dep ]; then 99 cp -r ''${deps[$dep]} share/jupyter/hub/static/components/$dep 100 fi 101 done 102 ''; 103 104 propagatedBuildInputs = [ 105 alembic ipython jinja2 pamela python-oauth2 requests sqlalchemy tornado 106 traitlets 107 ]; 108 109 # Disable tests because they take an excessive amount of time to complete. 110 doCheck = false; 111 112 disabled = pythonOlder "3.4"; 113 114 meta = with lib; { 115 description = "Serves multiple Jupyter notebook instances"; 116 homepage = http://jupyter.org/; 117 license = licenses.bsd3; 118 maintainers = with maintainers; [ ixxie cstrahan ]; 119 }; 120}