Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix incomplete kernel search path #246

Merged
merged 11 commits into from
Nov 17, 2022
2 changes: 1 addition & 1 deletion plugins/auth/fps_auth/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 13 additions & 0 deletions plugins/kernels/fps_kernels/config.py
Original file line number Diff line number Diff line change
@@ -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)
43 changes: 23 additions & 20 deletions plugins/kernels/fps_kernels/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@
from http import HTTPStatus
from pathlib import Path

from fastapi import APIRouter, Depends, Response
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
from fps_frontend.config import get_frontend_config # type: ignore
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_driver.kernelspec import find_kernelspec, kernelspec_dirs
from .kernel_server.server import ( # type: ignore
AcceptedWebSocket,
KernelServer,
Expand All @@ -36,19 +38,21 @@ 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}
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
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": kernel_config.default_kernel, "kernelspecs": kernelspecs}


@router.get("/kernelspecs/{kernel_name}/{file_name}")
Expand All @@ -57,7 +61,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(status_code=404, detail=f"Kernelspec {kernel_name}/{file_name} not found")


@router.get("/api/kernels")
Expand Down Expand Up @@ -127,9 +135,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=Path(find_kernelspec(kernel_name)).as_posix(),
kernel_cwd=str(Path(create_session.path).parent),
)
kernel_id = str(uuid.uuid4())
Expand Down Expand Up @@ -186,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=Path(find_kernelspec(kernel["name"])).as_posix(),
write_connection_file=False,
connection_file=kernel["server"].connection_file_path,
)
Expand Down
3 changes: 3 additions & 0 deletions plugins/kernels/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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]
Expand Down