From cc1fd272345e74a889d7778438b41f4d1b9e25e9 Mon Sep 17 00:00:00 2001 From: Wh1isper <9573586@qq.com> Date: Fri, 11 Nov 2022 17:27:53 +0800 Subject: [PATCH 01/11] add default kernel config and ~/.local search path --- plugins/kernels/fps_kernels/config.py | 13 +++++++++++ plugins/kernels/fps_kernels/routes.py | 31 +++++++++++++++++---------- plugins/kernels/pyproject.toml | 3 +++ 3 files changed, 36 insertions(+), 11 deletions(-) create mode 100644 plugins/kernels/fps_kernels/config.py diff --git a/plugins/kernels/fps_kernels/config.py b/plugins/kernels/fps_kernels/config.py new file mode 100644 index 00000000..bad8b1a0 --- /dev/null +++ b/plugins/kernels/fps_kernels/config.py @@ -0,0 +1,13 @@ +from fps.config import PluginModel, get_config # type: ignore +from fps.hooks import register_config # type: ignore + + +class KernelConfig(PluginModel): + default_kernel: str = "python3" + + +def get_kernel_config(): + return get_config(KernelConfig) + + +c = register_config(KernelConfig) diff --git a/plugins/kernels/fps_kernels/routes.py b/plugins/kernels/fps_kernels/routes.py index cf0a697c..0cf5b87b 100644 --- a/plugins/kernels/fps_kernels/routes.py +++ b/plugins/kernels/fps_kernels/routes.py @@ -19,12 +19,14 @@ kernels, ) from .models import CreateSession, Execution, Session +from .config import get_kernel_config router = APIRouter() kernelspecs: dict = {} sessions: dict = {} prefix_dir: Path = Path(sys.prefix) +user_local_dir: Path = Path.home() / '.local' @router.on_event("shutdown") @@ -36,19 +38,26 @@ async def stop_kernels(): @router.get("/api/kernelspecs") async def get_kernelspecs( frontend_config=Depends(get_frontend_config), + kernel_config=Depends(get_kernel_config), user: User = Depends(current_user(permissions={"kernelspecs": ["read"]})), ): - for path in (prefix_dir / "share" / "jupyter" / "kernels").glob("*/kernel.json"): - with open(path) as f: - spec = json.load(f) - name = path.parent.name - resources = { - f.stem: f"{frontend_config.base_url}kernelspecs/{name}/{f.name}" - for f in path.parent.iterdir() - if f.is_file() and f.name != "kernel.json" - } - kernelspecs[name] = {"name": name, "spec": spec, "resources": resources} - return {"default": "python3", "kernelspecs": kernelspecs} + kernelspec_search_path = [ + prefix_dir / "share" / "jupyter" / "kernels", + user_local_dir / "share" / "jupyter" / "kernels" + ] + + for search_path in kernelspec_search_path: + for path in search_path.glob("*/kernel.json"): + with open(path) as f: + spec = json.load(f) + name = path.parent.name + resources = { + f.stem: f"{frontend_config.base_url}kernelspecs/{name}/{f.name}" + for f in path.parent.iterdir() + if f.is_file() and f.name != "kernel.json" + } + kernelspecs[name] = {"name": name, "spec": spec, "resources": resources} + return {"default": f"{kernel_config.default_kernel}", "kernelspecs": kernelspecs} @router.get("/kernelspecs/{kernel_name}/{file_name}") diff --git a/plugins/kernels/pyproject.toml b/plugins/kernels/pyproject.toml index ae76f551..c27eb03e 100644 --- a/plugins/kernels/pyproject.toml +++ b/plugins/kernels/pyproject.toml @@ -32,5 +32,8 @@ skip = [ "check-links",] [project.entry-points.fps_router] fps-kernels = "fps_kernels.routes" +[project.entry-points.fps_config] +fps-kernels = "fps_kernels.config" + [tool.hatch.version] path = "fps_kernels/__init__.py" From ba3c2ea89eb8cc770e12c6a059fed52c320e2e1c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 11 Nov 2022 09:30:19 +0000 Subject: [PATCH 02/11] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- plugins/kernels/fps_kernels/routes.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/kernels/fps_kernels/routes.py b/plugins/kernels/fps_kernels/routes.py index 0cf5b87b..baa91187 100644 --- a/plugins/kernels/fps_kernels/routes.py +++ b/plugins/kernels/fps_kernels/routes.py @@ -12,6 +12,7 @@ from fps_yjs.routes import YDocWebSocketHandler # type: ignore from starlette.requests import Request # type: ignore +from .config import get_kernel_config from .kernel_driver.driver import KernelDriver # type: ignore from .kernel_server.server import ( # type: ignore AcceptedWebSocket, @@ -19,14 +20,13 @@ kernels, ) from .models import CreateSession, Execution, Session -from .config import get_kernel_config router = APIRouter() kernelspecs: dict = {} sessions: dict = {} prefix_dir: Path = Path(sys.prefix) -user_local_dir: Path = Path.home() / '.local' +user_local_dir: Path = Path.home() / ".local" @router.on_event("shutdown") @@ -43,7 +43,7 @@ async def get_kernelspecs( ): kernelspec_search_path = [ prefix_dir / "share" / "jupyter" / "kernels", - user_local_dir / "share" / "jupyter" / "kernels" + user_local_dir / "share" / "jupyter" / "kernels", ] for search_path in kernelspec_search_path: From fe141447045c36b6a4861545a386998f1856a3d5 Mon Sep 17 00:00:00 2001 From: Wh1isper <9573586@qq.com> Date: Mon, 14 Nov 2022 12:52:17 +0800 Subject: [PATCH 03/11] using kernelspec_dirs to find kernelsepce resource --- plugins/kernels/fps_kernels/routes.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/plugins/kernels/fps_kernels/routes.py b/plugins/kernels/fps_kernels/routes.py index baa91187..641c29ef 100644 --- a/plugins/kernels/fps_kernels/routes.py +++ b/plugins/kernels/fps_kernels/routes.py @@ -4,7 +4,7 @@ from http import HTTPStatus from pathlib import Path -from fastapi import APIRouter, Depends, Response +from fastapi import APIRouter, Depends, Response, HTTPException from fastapi.responses import FileResponse from fps.hooks import register_router # type: ignore from fps_auth_base import User, current_user, websocket_auth # type: ignore @@ -14,6 +14,7 @@ from .config import get_kernel_config from .kernel_driver.driver import KernelDriver # type: ignore +from .kernel_driver.kernelspec import kernelspec_dirs, find_kernelspec from .kernel_server.server import ( # type: ignore AcceptedWebSocket, KernelServer, @@ -41,13 +42,8 @@ async def get_kernelspecs( kernel_config=Depends(get_kernel_config), user: User = Depends(current_user(permissions={"kernelspecs": ["read"]})), ): - kernelspec_search_path = [ - prefix_dir / "share" / "jupyter" / "kernels", - user_local_dir / "share" / "jupyter" / "kernels", - ] - - for search_path in kernelspec_search_path: - for path in search_path.glob("*/kernel.json"): + for search_path in kernelspec_dirs(): + for path in Path(search_path).glob("*/kernel.json"): with open(path) as f: spec = json.load(f) name = path.parent.name @@ -66,7 +62,11 @@ async def get_kernelspec( file_name, user: User = Depends(current_user()), ): - return FileResponse(prefix_dir / "share" / "jupyter" / "kernels" / kernel_name / file_name) + for search_path in kernelspec_dirs(): + file_path = Path(search_path) / kernel_name / file_name + if file_path.exists(): + return FileResponse(file_path) + raise HTTPException(404) @router.get("/api/kernels") @@ -136,9 +136,7 @@ async def create_session( create_session = CreateSession(**(await request.json())) kernel_name = create_session.kernel.name kernel_server = KernelServer( - kernelspec_path=( - prefix_dir / "share" / "jupyter" / "kernels" / kernel_name / "kernel.json" - ).as_posix(), + kernelspec_path=find_kernelspec(kernel_name), kernel_cwd=str(Path(create_session.path).parent), ) kernel_id = str(uuid.uuid4()) From 7c789bf0bc8b8595e0ff373d4663a8e9e0696f4a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 14 Nov 2022 04:52:34 +0000 Subject: [PATCH 04/11] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- plugins/kernels/fps_kernels/routes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/kernels/fps_kernels/routes.py b/plugins/kernels/fps_kernels/routes.py index 641c29ef..ad8f25b4 100644 --- a/plugins/kernels/fps_kernels/routes.py +++ b/plugins/kernels/fps_kernels/routes.py @@ -4,7 +4,7 @@ from http import HTTPStatus from pathlib import Path -from fastapi import APIRouter, Depends, Response, HTTPException +from fastapi import APIRouter, Depends, HTTPException, Response from fastapi.responses import FileResponse from fps.hooks import register_router # type: ignore from fps_auth_base import User, current_user, websocket_auth # type: ignore @@ -14,7 +14,7 @@ from .config import get_kernel_config from .kernel_driver.driver import KernelDriver # type: ignore -from .kernel_driver.kernelspec import kernelspec_dirs, find_kernelspec +from .kernel_driver.kernelspec import find_kernelspec, kernelspec_dirs from .kernel_server.server import ( # type: ignore AcceptedWebSocket, KernelServer, From fcf7b4312f24eaa8273a66e5d1e335fd2d803391 Mon Sep 17 00:00:00 2001 From: Wh1isper <9573586@qq.com> Date: Mon, 14 Nov 2022 13:00:04 +0800 Subject: [PATCH 05/11] remove useless code --- plugins/kernels/fps_kernels/routes.py | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/kernels/fps_kernels/routes.py b/plugins/kernels/fps_kernels/routes.py index ad8f25b4..fb6b1614 100644 --- a/plugins/kernels/fps_kernels/routes.py +++ b/plugins/kernels/fps_kernels/routes.py @@ -27,7 +27,6 @@ kernelspecs: dict = {} sessions: dict = {} prefix_dir: Path = Path(sys.prefix) -user_local_dir: Path = Path.home() / ".local" @router.on_event("shutdown") From e9573cc2dc6b487b6c72d23f80b600929c6ee8a5 Mon Sep 17 00:00:00 2001 From: Wh1isper <9573586@qq.com> Date: Mon, 14 Nov 2022 13:06:37 +0800 Subject: [PATCH 06/11] correct kernelspec path in post exec cell --- plugins/kernels/fps_kernels/routes.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/plugins/kernels/fps_kernels/routes.py b/plugins/kernels/fps_kernels/routes.py index fb6b1614..c17afadf 100644 --- a/plugins/kernels/fps_kernels/routes.py +++ b/plugins/kernels/fps_kernels/routes.py @@ -192,12 +192,9 @@ async def execute_cell( cell["outputs"] = [] kernel = kernels[kernel_id] - kernelspec_path = ( - prefix_dir / "share" / "jupyter" / "kernels" / kernel["name"] / "kernel.json" - ).as_posix() if not kernel["driver"]: kernel["driver"] = driver = KernelDriver( - kernelspec_path=kernelspec_path, + kernelspec_path=find_kernelspec(kernel["name"]), write_connection_file=False, connection_file=kernel["server"].connection_file_path, ) From 7bf3f60624109314709e0303d793fb3bf54c7515 Mon Sep 17 00:00:00 2001 From: Wh1isper <9573586@qq.com> Date: Tue, 15 Nov 2022 16:17:14 +0800 Subject: [PATCH 07/11] fix ci --- plugins/auth/fps_auth/fixtures.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/auth/fps_auth/fixtures.py b/plugins/auth/fps_auth/fixtures.py index 184baa31..93098fd3 100644 --- a/plugins/auth/fps_auth/fixtures.py +++ b/plugins/auth/fps_auth/fixtures.py @@ -75,7 +75,7 @@ def authenticated_client(client, permissions): # we should now have a cookie assert "fastapiusersauth" in client.cookies # check our identity, since we're logged in - response = client.get("/api/me", json={"permissions": permissions}) + response = client.request('GET', "/api/me", json={"permissions": permissions}) assert response.status_code == 200 me = response.json() assert me["identity"]["username"] == username From 698f5dcb1f1ee1c364a44ccde394a859f25a9059 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 15 Nov 2022 08:17:33 +0000 Subject: [PATCH 08/11] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- plugins/auth/fps_auth/fixtures.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/auth/fps_auth/fixtures.py b/plugins/auth/fps_auth/fixtures.py index 93098fd3..1d4e06ff 100644 --- a/plugins/auth/fps_auth/fixtures.py +++ b/plugins/auth/fps_auth/fixtures.py @@ -75,7 +75,7 @@ def authenticated_client(client, permissions): # we should now have a cookie assert "fastapiusersauth" in client.cookies # check our identity, since we're logged in - response = client.request('GET', "/api/me", json={"permissions": permissions}) + response = client.request("GET", "/api/me", json={"permissions": permissions}) assert response.status_code == 200 me = response.json() assert me["identity"]["username"] == username From 74364e2a8acec551c54e86923ae63caff276322e Mon Sep 17 00:00:00 2001 From: Wh1isper <9573586@qq.com> Date: Wed, 16 Nov 2022 07:30:19 +0800 Subject: [PATCH 09/11] Apply suggestions from code review Co-authored-by: David Brochart --- plugins/kernels/fps_kernels/routes.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/kernels/fps_kernels/routes.py b/plugins/kernels/fps_kernels/routes.py index c17afadf..340d42de 100644 --- a/plugins/kernels/fps_kernels/routes.py +++ b/plugins/kernels/fps_kernels/routes.py @@ -52,7 +52,7 @@ async def get_kernelspecs( if f.is_file() and f.name != "kernel.json" } kernelspecs[name] = {"name": name, "spec": spec, "resources": resources} - return {"default": f"{kernel_config.default_kernel}", "kernelspecs": kernelspecs} + return {"default": kernel_config.default_kernel, "kernelspecs": kernelspecs} @router.get("/kernelspecs/{kernel_name}/{file_name}") @@ -65,7 +65,7 @@ async def get_kernelspec( file_path = Path(search_path) / kernel_name / file_name if file_path.exists(): return FileResponse(file_path) - raise HTTPException(404) + raise HTTPException(status_code=404, detail=f"Kernelspec {kernel_name}/{file_name} not found") @router.get("/api/kernels") @@ -135,7 +135,7 @@ async def create_session( create_session = CreateSession(**(await request.json())) kernel_name = create_session.kernel.name kernel_server = KernelServer( - kernelspec_path=find_kernelspec(kernel_name), + kernelspec_path=Path(find_kernelspec(kernel_name)).as_posix(), kernel_cwd=str(Path(create_session.path).parent), ) kernel_id = str(uuid.uuid4()) @@ -194,7 +194,7 @@ async def execute_cell( kernel = kernels[kernel_id] if not kernel["driver"]: kernel["driver"] = driver = KernelDriver( - kernelspec_path=find_kernelspec(kernel["name"]), + kernelspec_path=Path(find_kernelspec(kernel["name"])).as_posix(), write_connection_file=False, connection_file=kernel["server"].connection_file_path, ) From 4d415d5b05c5d47137098ec11ce32af191fb923a Mon Sep 17 00:00:00 2001 From: Wh1isper <9573586@qq.com> Date: Wed, 16 Nov 2022 07:53:43 +0800 Subject: [PATCH 10/11] trigger GitHub actions From f85d6bbb5926c8963ad6b1911cdf1017854c91da Mon Sep 17 00:00:00 2001 From: Wh1isper <9573586@qq.com> Date: Thu, 17 Nov 2022 22:51:55 +0800 Subject: [PATCH 11/11] bump fastapi>=0.87.0 --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c80fe874..36dee87d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,7 @@ keywords = ["jupyter", "server", "fastapi", "pluggy", "plugins"] dynamic = ["version"] requires-python = ">=3.7" dependencies = [ - "fastapi>=0.82.0", + "fastapi>=0.87.0", "fps>=0.0.19", "fps-uvicorn>=0.0.19", "fps-auth-base>=0.0.42", @@ -57,7 +57,7 @@ pre-install-commands = [ "pip install -e ./plugins/terminals", "pip install -e ./plugins/yjs", ] -dependencies = ["fastapi>=0.82.0"] +dependencies = ["fastapi>=0.87.0"] features = ["test"] [tool.hatch.envs.dev.overrides]