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