nixpkgs/pkgs/development/python-modules/jupyterhub/default.nix
2024-04-06 09:14:48 +00:00

213 lines
5.5 KiB
Nix

{ lib
, stdenv
, alembic
, async-generator
, beautifulsoup4
, buildPythonPackage
, certipy
, configurable-http-proxy
, cryptography
, entrypoints
, fetchPypi
, fetchzip
, importlib-metadata
, jinja2
, jsonschema
, jupyter-telemetry
, jupyterlab
, jupyter-core
, jupyter-server
, mock
, nbclassic
, nodePackages
, notebook
, oauthlib
, packaging
, pamela
, playwright
, prometheus-client
, pytest-asyncio
, pytestCheckHook
, python-dateutil
, pythonOlder
, requests
, requests-mock
, selenium
, sqlalchemy
, tornado
, traitlets
, virtualenv
}:
let
# js/css assets that setup.py tries to fetch via `npm install` when building
# from source. https://github.com/jupyterhub/jupyterhub/blob/master/package.json
bootstrap =
fetchzip {
url = "https://registry.npmjs.org/bootstrap/-/bootstrap-3.4.1.tgz";
sha256 = "1ywmxqdccg0mgx0xknrn1hlrfnhcwphc12y9l91zizx26fqfmzgc";
};
font-awesome =
fetchzip {
url = "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz";
sha256 = "1xnxbdlfdd60z5ix152m8r2kk9dkwlqwpypky1mm3dv64ajnzdbk";
};
jquery =
fetchzip {
url = "https://registry.npmjs.org/jquery/-/jquery-3.5.1.tgz";
sha256 = "0yi9ql493din1qa1s923nd5zvd0klk1sx00xj1wx2yambmq86vm9";
};
moment =
fetchzip {
url = "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz";
sha256 = "0ifzzla4zffw23g3xvhwx3fj3jny6cjzxfzl1x0317q8wa0c7w5i";
};
requirejs =
fetchzip {
url = "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz";
sha256 = "165hkli3qcd59cjqvli9r5f92i0h7czkmhcg1cgwamw2d0b7xibz";
};
in
buildPythonPackage rec {
pname = "jupyterhub";
version = "4.1.5";
format = "setuptools";
disabled = pythonOlder "3.7";
src = fetchPypi {
inherit pname version;
hash = "sha256-Y7ofxxhDbBUZRqWKO0A+xP6LP2JPsZW8HY5ww5sz4ZQ=";
};
# Most of this only applies when building from source (e.g. js/css assets are
# pre-built and bundled in the official release tarball on pypi).
#
# Stuff that's always needed:
# * At runtime, we need configurable-http-proxy, so we substitute the store
# path.
#
# Other stuff that's only needed when building from source:
# * js/css assets are fetched from npm.
# * substitute store path for `lessc` commmand.
# * set up NODE_PATH so `lessc` can find `less-plugin-clean-css`.
# * don't run `npm install`.
preBuild = ''
export NODE_PATH=${nodePackages.less-plugin-clean-css}/lib/node_modules
substituteInPlace jupyterhub/proxy.py --replace \
"'configurable-http-proxy'" \
"'${configurable-http-proxy}/bin/configurable-http-proxy'"
substituteInPlace jupyterhub/tests/test_proxy.py --replace \
"'configurable-http-proxy'" \
"'${configurable-http-proxy}/bin/configurable-http-proxy'"
substituteInPlace setup.py --replace \
"'npm'" "'true'"
declare -A deps
deps[bootstrap]=${bootstrap}
deps[font-awesome]=${font-awesome}
deps[jquery]=${jquery}
deps[moment]=${moment}
deps[requirejs]=${requirejs}
mkdir -p share/jupyter/hub/static/components
for dep in "''${!deps[@]}"; do
if [ ! -e share/jupyter/hub/static/components/$dep ]; then
cp -r ''${deps[$dep]} share/jupyter/hub/static/components/$dep
fi
done
'';
propagatedBuildInputs = [
alembic
async-generator
certipy
python-dateutil
entrypoints
jinja2
jupyter-telemetry
oauthlib
packaging
pamela
prometheus-client
requests
selenium
sqlalchemy
tornado
traitlets
jupyter-core
jupyter-server
] ++ lib.optionals (pythonOlder "3.10") [
importlib-metadata
];
nativeCheckInputs = [
beautifulsoup4
cryptography
notebook
jsonschema
nbclassic
mock
jupyterlab
playwright
pytest-asyncio
pytestCheckHook
requests-mock
virtualenv
];
preCheck = ''
substituteInPlace jupyterhub/tests/test_spawner.py --replace \
"'jupyterhub-singleuser'" "'$out/bin/jupyterhub-singleuser'"
export PATH="$PATH:$out/bin";
'';
disabledTests = [
# Tries to install older versions through pip
"test_upgrade"
# Testcase fails to find requests import
"test_external_service"
# Attempts to do TLS connection
"test_connection_notebook_wrong_certs"
# AttributeError: 'coroutine' object...
"test_valid_events"
"test_invalid_events"
"test_user_group_roles"
];
disabledTestPaths = [
# Not testing with a running instance
# AttributeError: 'coroutine' object has no attribute 'db'
"docs/test_docs.py"
"jupyterhub/tests/browser/test_browser.py"
"jupyterhub/tests/test_api.py"
"jupyterhub/tests/test_auth_expiry.py"
"jupyterhub/tests/test_auth.py"
"jupyterhub/tests/test_metrics.py"
"jupyterhub/tests/test_named_servers.py"
"jupyterhub/tests/test_orm.py"
"jupyterhub/tests/test_pages.py"
"jupyterhub/tests/test_proxy.py"
"jupyterhub/tests/test_scopes.py"
"jupyterhub/tests/test_services_auth.py"
"jupyterhub/tests/test_singleuser.py"
"jupyterhub/tests/test_spawner.py"
"jupyterhub/tests/test_user.py"
];
meta = with lib; {
description = "Serves multiple Jupyter notebook instances";
homepage = "https://jupyter.org/";
changelog = "https://github.com/jupyterhub/jupyterhub/blob/${version}/docs/source/reference/changelog.md";
license = licenses.bsd3;
maintainers = teams.jupyter.members;
# darwin: E OSError: dlopen(/nix/store/43zml0mlr17r5jsagxr00xxx91hz9lky-openpam-20170430/lib/libpam.so, 6): image not found
broken = stdenv.isDarwin;
};
}