From 946b9716ad0c72dbb76c8e9863df0d84622ee481 Mon Sep 17 00:00:00 2001 From: Jeremy Tuloup Date: Mon, 27 Nov 2023 10:38:19 +0100 Subject: [PATCH 1/9] Use `pytest-jupyterhub` --- dev-requirements.txt | 7 ++-- pytest.ini | 1 + setup.py | 2 +- tljh_repo2docker/tests/conftest.py | 53 ++++++------------------------ 4 files changed, 16 insertions(+), 47 deletions(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index 4a0a7e6..618eb9d 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,8 +1,9 @@ -git+https://github.com/jupyterhub/the-littlest-jupyterhub -jupyterhub~=1.5 -notebook<7 +git+https://github.com/jupyterhub/the-littlest-jupyterhub@1.0.0 +jupyterhub>=4,<5 +notebook pytest pytest-aiohttp pytest-asyncio pytest-cov +pytest-jupyterhub requests-mock diff --git a/pytest.ini b/pytest.ini index 0ee949b..faf59a4 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,2 +1,3 @@ [pytest] python_files = test_*.py +asyncio_mode = auto \ No newline at end of file diff --git a/setup.py b/setup.py index 54ce4b7..aefdf20 100644 --- a/setup.py +++ b/setup.py @@ -1 +1 @@ -__import__("setuptools").setup() \ No newline at end of file +__import__("setuptools").setup() diff --git a/tljh_repo2docker/tests/conftest.py b/tljh_repo2docker/tests/conftest.py index 1155930..0c26ee0 100644 --- a/tljh_repo2docker/tests/conftest.py +++ b/tljh_repo2docker/tests/conftest.py @@ -5,21 +5,8 @@ import pytest from aiodocker import Docker, DockerError -from jupyterhub.tests.conftest import ( - io_loop, - event_loop, - db, - pytest_collection_modifyitems, -) -from jupyterhub.tests.mocking import MockHub from tljh_repo2docker import tljh_custom_jupyterhub_config -from traitlets import Bunch - -class DummyConfig: - def __getattr__(self, k): - if k not in self.__dict__: - self.__dict__[k] = Bunch() - return self.__dict__[k] +from traitlets.config import Config async def remove_docker_image(image_name): @@ -50,38 +37,18 @@ def image_name(): return "tljh-repo2docker-test:HEAD" -@pytest.fixture(scope='module') -def app(request, io_loop): - """ - Adapted from: - https://github.com/jupyterhub/jupyterhub/blob/8a3790b01ff944c453ffcc0486149e2a58ffabea/jupyterhub/tests/conftest.py#L74 - """ - - mocked_app = MockHub.instance() - c = DummyConfig() - c.JupyterHub = mocked_app - tljh_custom_jupyterhub_config(c) - - async def make_app(): - await mocked_app.initialize([]) - await mocked_app.start() - - def fin(): - # disconnect logging during cleanup because pytest closes captured FDs prematurely - mocked_app.log.handlers = [] - MockHub.clear_instance() - try: - mocked_app.stop() - except Exception as e: - print("Error stopping Hub: %s" % e, file=sys.stderr) +@pytest.fixture +async def app(hub_app): + config = Config() + tljh_custom_jupyterhub_config(config) - request.addfinalizer(fin) - io_loop.run_sync(make_app) - return mocked_app + app = await hub_app(config=config) + print(app) + return app @pytest.fixture(autouse=True) -def remove_all_test_images(image_name, generated_image_name, io_loop): +async def remove_all_test_images(image_name, generated_image_name, app): try: yield finally: @@ -89,4 +56,4 @@ async def _clean(): await remove_docker_image(image_name) await remove_docker_image(generated_image_name) - io_loop.run_sync(_clean) + app.io_loop.run_sync(_clean) From ee1d3c56ee0ccd74dc6c3c9e210e3e37b6876786 Mon Sep 17 00:00:00 2001 From: Jeremy Tuloup Date: Mon, 27 Nov 2023 13:25:41 +0100 Subject: [PATCH 2/9] Fix fixture cleanup --- tljh_repo2docker/tests/conftest.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/tljh_repo2docker/tests/conftest.py b/tljh_repo2docker/tests/conftest.py index 0c26ee0..708ab3d 100644 --- a/tljh_repo2docker/tests/conftest.py +++ b/tljh_repo2docker/tests/conftest.py @@ -43,17 +43,11 @@ async def app(hub_app): tljh_custom_jupyterhub_config(config) app = await hub_app(config=config) - print(app) return app @pytest.fixture(autouse=True) async def remove_all_test_images(image_name, generated_image_name, app): - try: - yield - finally: - async def _clean(): - await remove_docker_image(image_name) - await remove_docker_image(generated_image_name) - - app.io_loop.run_sync(_clean) + yield + await remove_docker_image(image_name) + await remove_docker_image(generated_image_name) From 82958d3af50a9656cc6d88cd7781519beebcf863 Mon Sep 17 00:00:00 2001 From: Jeremy Tuloup Date: Mon, 27 Nov 2023 13:35:31 +0100 Subject: [PATCH 3/9] Fix JupyterHub 4 warning --- tljh_repo2docker/builder.py | 6 +++--- tljh_repo2docker/images.py | 4 ++-- tljh_repo2docker/logs.py | 5 ++--- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/tljh_repo2docker/builder.py b/tljh_repo2docker/builder.py index fbef6d3..083b799 100644 --- a/tljh_repo2docker/builder.py +++ b/tljh_repo2docker/builder.py @@ -3,7 +3,7 @@ from aiodocker import Docker, DockerError from jupyterhub.apihandlers import APIHandler -from jupyterhub.utils import admin_only +from jupyterhub.scopes import needs_scope from tornado import web from .docker import build_image @@ -17,7 +17,7 @@ class BuildHandler(APIHandler): """ @web.authenticated - @admin_only + @needs_scope('admin-ui') async def delete(self): data = self.get_json_body() name = data["name"] @@ -31,7 +31,7 @@ async def delete(self): self.finish(json.dumps({"status": "ok"})) @web.authenticated - @admin_only + @needs_scope('admin-ui') async def post(self): data = self.get_json_body() repo = data["repo"] diff --git a/tljh_repo2docker/images.py b/tljh_repo2docker/images.py index df1be13..ddceeb3 100644 --- a/tljh_repo2docker/images.py +++ b/tljh_repo2docker/images.py @@ -1,6 +1,6 @@ from inspect import isawaitable from jupyterhub.handlers.base import BaseHandler -from jupyterhub.utils import admin_only +from jupyterhub.scopes import needs_scope from tornado import web from .docker import list_containers, list_images @@ -12,7 +12,7 @@ class ImagesHandler(BaseHandler): """ @web.authenticated - @admin_only + @needs_scope('admin-ui') async def get(self): images = await list_images() containers = await list_containers() diff --git a/tljh_repo2docker/logs.py b/tljh_repo2docker/logs.py index e431412..7c87e16 100644 --- a/tljh_repo2docker/logs.py +++ b/tljh_repo2docker/logs.py @@ -2,9 +2,8 @@ from aiodocker import Docker from jupyterhub.apihandlers import APIHandler -from jupyterhub.utils import admin_only +from jupyterhub.scopes import needs_scope from tornado import web -from tornado.ioloop import IOLoop from tornado.iostream import StreamClosedError @@ -13,7 +12,7 @@ class LogsHandler(APIHandler): Expose a handler to follow the build logs. """ @web.authenticated - @admin_only + @needs_scope('admin-ui') async def get(self, name): self.set_header("Content-Type", "text/event-stream") self.set_header("Cache-Control", "no-cache") From a57eaa6c68bd8e6f478403e73d992f4dabd6e9f3 Mon Sep 17 00:00:00 2001 From: Jeremy Tuloup Date: Mon, 27 Nov 2023 13:46:12 +0100 Subject: [PATCH 4/9] Update docs for TLJH 1.0 --- README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d61fb3c..b290cd0 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,10 @@ TLJH plugin to build and use Docker images as user environments. The Docker images are built using [`repo2docker`](https://repo2docker.readthedocs.io/en/latest/). +## Requirements + +This plugin requires [The Littlest JupyterHub](https://tljh.jupyter.org) 1.0 or later. + ## Installation During the [TLJH installation process](http://tljh.jupyter.org/en/latest/install/index.html), use the following post-installation script: @@ -20,9 +24,10 @@ sudo apt update && sudo apt install -y docker-ce # pull the repo2docker image sudo docker pull quay.io/jupyterhub/repo2docker:main -# install TLJH -curl https://raw.githubusercontent.com/jupyterhub/the-littlest-jupyterhub/master/bootstrap/bootstrap.py \ +# install TLJH 1.0 +curl https://tljh.jupyter.org/bootstrap.py | sudo python3 - \ + --version 1.0.0 \ --admin test:test \ --plugin git+https://github.com/plasmabio/tljh-repo2docker@master ``` @@ -30,7 +35,6 @@ curl https://raw.githubusercontent.com/jupyterhub/the-littlest-jupyterhub/master Refer to [The Littlest JupyterHub documentation](http://tljh.jupyter.org/en/latest/topic/customizing-installer.html?highlight=plugins#installing-tljh-plugins) for more info on installing TLJH plugins. - ## Usage ### List the environments From ac39f72d2db12bbcf71d9fe341011590eed28280 Mon Sep 17 00:00:00 2001 From: Jeremy Tuloup Date: Mon, 27 Nov 2023 14:02:22 +0100 Subject: [PATCH 5/9] Test JupyterHub 4 only --- .github/workflows/test.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index cf118d2..6a44687 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,7 +13,6 @@ jobs: fail-fast: false matrix: python-version: ["3.8", "3.9", "3.10"] - jupyterhub-version: [latest, 1.2.2] steps: - uses: actions/checkout@v2 @@ -32,10 +31,6 @@ jobs: python -m pip install --upgrade pip setuptools python -m pip install -r dev-requirements.txt python -m pip install -e . - - name: Downgrade jupyterhub - if: ${{ matrix.jupyterhub-version != 'latest' }} - run: | - python -m pip install -U 'jupyterhub==${{ matrix.jupyterhub-version }}' - name: Run Tests run: | python -m pytest --cov From 8b27bffaeb1b56be548f8d8d2300dd5881b966d1 Mon Sep 17 00:00:00 2001 From: Jeremy Tuloup Date: Mon, 27 Nov 2023 14:03:04 +0100 Subject: [PATCH 6/9] Remove notebook from dev dependencies --- dev-requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index 618eb9d..5a9414a 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,6 +1,5 @@ git+https://github.com/jupyterhub/the-littlest-jupyterhub@1.0.0 jupyterhub>=4,<5 -notebook pytest pytest-aiohttp pytest-asyncio From 49f1c00f63aec6fbf6ab9ba3d37dd683e83bd91c Mon Sep 17 00:00:00 2001 From: Jeremy Tuloup Date: Mon, 27 Nov 2023 14:04:40 +0100 Subject: [PATCH 7/9] Update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b290cd0..1c4cc94 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ TLJH plugin to build and use Docker images as user environments. The Docker imag ## Requirements -This plugin requires [The Littlest JupyterHub](https://tljh.jupyter.org) 1.0 or later. +This plugin requires [The Littlest JupyterHub](https://tljh.jupyter.org) 1.0 or later (running on JupyterHub 4+). ## Installation From 0b3db2563ab5319cf63786fc718c60a07645d17f Mon Sep 17 00:00:00 2001 From: Jeremy Tuloup Date: Tue, 28 Nov 2023 08:26:29 +0100 Subject: [PATCH 8/9] Remove unused imports --- tljh_repo2docker/tests/conftest.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tljh_repo2docker/tests/conftest.py b/tljh_repo2docker/tests/conftest.py index 708ab3d..5b7ee87 100644 --- a/tljh_repo2docker/tests/conftest.py +++ b/tljh_repo2docker/tests/conftest.py @@ -1,7 +1,3 @@ -import asyncio -import os -import sys - import pytest from aiodocker import Docker, DockerError From f96d67106c7275f21af7fad6f7bab2b926cc1f46 Mon Sep 17 00:00:00 2001 From: Duc Trung Le Date: Mon, 11 Mar 2024 22:40:36 +0100 Subject: [PATCH 9/9] Update `pyproject.toml` --- pyproject.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index cfcdd81..4436659 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,8 +10,7 @@ license = { file = "LICENSE" } dependencies = [ "aiodocker~=0.19", "dockerspawner~=12.1", - "jupyter_client~=6.1", - "sqlalchemy<2", + "jupyter_client>=6.1,<8" ] [project.entry-points.tljh]