diff --git a/pkgs/development/python-modules/jupyterlab-server/default.nix b/pkgs/development/python-modules/jupyterlab-server/default.nix index a87b821b54aa..b091c9a92abf 100644 --- a/pkgs/development/python-modules/jupyterlab-server/default.nix +++ b/pkgs/development/python-modules/jupyterlab-server/default.nix @@ -1,8 +1,12 @@ { lib, buildPythonPackage, - fetchPypi, + fetchFromGitHub, + + # build-system hatchling, + + # dependencies babel, jinja2, json5, @@ -10,30 +14,40 @@ jupyter-server, packaging, requests, + + # optional-dependencies openapi-core, + ruamel-yaml, + + # tests pytest-jupyter, + pytest-timeout, pytestCheckHook, requests-mock, - ruamel-yaml, strict-rfc3339, + writableTmpDirAsHomeHook, }: -buildPythonPackage rec { +buildPythonPackage (finalAttrs: { pname = "jupyterlab-server"; version = "2.28.0"; pyproject = true; - src = fetchPypi { - pname = "jupyterlab_server"; - inherit version; - hash = "sha256-NbqoGJixX5NXPi3spQ0RrArkB+u2iCmdOlITJlAzcSw="; + src = fetchFromGitHub { + owner = "jupyterlab"; + repo = "jupyterlab_server"; + tag = "v${finalAttrs.version}"; + hash = "sha256-/h25HBKt6maaxuZRK+VMVA0AqTZhQkDnGVDgBisQcCw="; }; - postPatch = '' - sed -i "/timeout/d" pyproject.toml - ''; + patches = [ + # oopenapi-core changed their API, which breaks jupyterlab-server + ./fix-openapi-core-compat.patch + ]; - build-system = [ hatchling ]; + build-system = [ + hatchling + ]; dependencies = [ babel @@ -52,38 +66,30 @@ buildPythonPackage rec { ]; }; + pythonImportsCheck = [ "jupyterlab_server" ]; + nativeCheckInputs = [ pytest-jupyter + pytest-timeout pytestCheckHook requests-mock strict-rfc3339 + writableTmpDirAsHomeHook ] - ++ optional-dependencies.openapi; - - preCheck = '' - export HOME=$(mktemp -d) - ''; - - pytestFlags = [ - "-Wignore::DeprecationWarning" - ]; + ++ finalAttrs.passthru.optional-dependencies.openapi; disabledTestPaths = [ # require optional language pack packages for tests "tests/test_translation_api.py" ]; - pythonImportsCheck = [ - "jupyterlab_server" - ]; - __darwinAllowLocalNetworking = true; meta = { description = "Set of server components for JupyterLab and JupyterLab like applications"; homepage = "https://github.com/jupyterlab/jupyterlab_server"; - changelog = "https://github.com/jupyterlab/jupyterlab_server/blob/v${version}/CHANGELOG.md"; + changelog = "https://github.com/jupyterlab/jupyterlab_server/blob/${finalAttrs.src.tag}/CHANGELOG.md"; license = lib.licenses.bsd3; teams = [ lib.teams.jupyter ]; }; -} +}) diff --git a/pkgs/development/python-modules/jupyterlab-server/fix-openapi-core-compat.patch b/pkgs/development/python-modules/jupyterlab-server/fix-openapi-core-compat.patch new file mode 100644 index 000000000000..0b736618e12f --- /dev/null +++ b/pkgs/development/python-modules/jupyterlab-server/fix-openapi-core-compat.patch @@ -0,0 +1,58 @@ +diff --git a/jupyterlab_server/spec.py b/jupyterlab_server/spec.py +index 94347b9..6e0d7d4 100644 +--- a/jupyterlab_server/spec.py ++++ b/jupyterlab_server/spec.py +@@ -9,17 +9,17 @@ import typing + from pathlib import Path + + if typing.TYPE_CHECKING: +- from openapi_core.spec.paths import Spec ++ from jsonschema_path import SchemaPath + + HERE = Path(os.path.dirname(__file__)).resolve() + + +-def get_openapi_spec() -> Spec: ++def get_openapi_spec() -> SchemaPath: + """Get the OpenAPI spec object.""" +- from openapi_core.spec.paths import Spec ++ from jsonschema_path import SchemaPath + + openapi_spec_dict = get_openapi_spec_dict() +- return Spec.from_dict(openapi_spec_dict) # type:ignore[arg-type] ++ return SchemaPath.from_dict(openapi_spec_dict) + + + def get_openapi_spec_dict() -> dict[str, typing.Any]: +diff --git a/jupyterlab_server/test_utils.py b/jupyterlab_server/test_utils.py +index c1d8956..337bb53 100644 +--- a/jupyterlab_server/test_utils.py ++++ b/jupyterlab_server/test_utils.py +@@ -13,8 +13,8 @@ from urllib.parse import parse_qs, urlparse + + import tornado.httpclient + import tornado.web ++from jsonschema_path import SchemaPath + from openapi_core import V30RequestValidator, V30ResponseValidator +-from openapi_core.spec.paths import Spec + from openapi_core.validation.request.datatypes import RequestParameters + from tornado.httpclient import HTTPRequest, HTTPResponse + from werkzeug.datastructures import Headers, ImmutableMultiDict +@@ -32,7 +32,7 @@ class TornadoOpenAPIRequest: + Converts a torando request to an OpenAPI one + """ + +- def __init__(self, request: HTTPRequest, spec: Spec): ++ def __init__(self, request: HTTPRequest, spec: SchemaPath): + """Initialize the request.""" + self.request = request + self.spec = spec +@@ -76,7 +76,7 @@ class TornadoOpenAPIRequest: + # https://github.com/OAI/OpenAPI-Specification/issues/892 + url = None + o = urlparse(self.request.url) +- for path_ in self.spec["paths"]: ++ for path_ in self.spec["paths"].keys(): + if url: + continue # type:ignore[unreachable] + has_arg = "{" in path_