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}