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