diff --git a/jupyverse_api/jupyverse_api/contents/__init__.py b/jupyverse_api/jupyverse_api/contents/__init__.py index 5f9b018f..d41fcc79 100644 --- a/jupyverse_api/jupyverse_api/contents/__init__.py +++ b/jupyverse_api/jupyverse_api/contents/__init__.py @@ -4,7 +4,7 @@ from typing import Dict, List, Optional, Union from fastapi import APIRouter, Depends, Request, Response -from jupyverse_api import Router +from jupyverse_api import Router, Config from .models import Checkpoint, Content, SaveContent from ..auth import Auth, User @@ -30,81 +30,87 @@ def unwatch(self, path: str, watcher): ... +class ContentsConfig(Config): + include_router: bool = True + prefix: str = "" + + class Contents(Router, ABC): - def __init__(self, app: App, auth: Auth): + def __init__(self, app: App, auth: Auth, contents_config: ContentsConfig): super().__init__(app=app) - router = APIRouter() - - @router.post( - "/api/contents/{path:path}/checkpoints", - status_code=201, - ) - async def create_checkpoint( - path, user: User = Depends(auth.current_user(permissions={"contents": ["write"]})) - ) -> Checkpoint: - return await self.create_checkpoint(path, user) - - @router.post( - "/api/contents{path:path}", - status_code=201, - ) - async def create_content( - path: Optional[str], - request: Request, - user: User = Depends(auth.current_user(permissions={"contents": ["write"]})), - ) -> Content: - return await self.create_content(path, request, user) - - @router.get("/api/contents") - async def get_root_content( - content: int, - user: User = Depends(auth.current_user(permissions={"contents": ["read"]})), - ) -> Content: - return await self.get_root_content(content, user) - - @router.get("/api/contents/{path:path}/checkpoints") - async def get_checkpoint( - path, user: User = Depends(auth.current_user(permissions={"contents": ["read"]})) - ) -> List[Checkpoint]: - return await self.get_checkpoint(path, user) - - @router.get("/api/contents/{path:path}") - async def get_content( - path: str, - content: int = 0, - user: User = Depends(auth.current_user(permissions={"contents": ["read"]})), - ) -> Content: - return await self.get_content(path, content, user) - - @router.put("/api/contents/{path:path}") - async def save_content( - path, - request: Request, - response: Response, - user: User = Depends(auth.current_user(permissions={"contents": ["write"]})), - ) -> Content: - return await self.save_content(path, request, response, user) - - @router.delete( - "/api/contents/{path:path}", - status_code=204, - ) - async def delete_content( - path, - user: User = Depends(auth.current_user(permissions={"contents": ["write"]})), - ): - return await self.delete_content(path, user) - - @router.patch("/api/contents/{path:path}") - async def rename_content( - path, - request: Request, - user: User = Depends(auth.current_user(permissions={"contents": ["write"]})), - ) -> Content: - return await self.rename_content(path, request, user) - - self.include_router(router) + if contents_config.include_router: + router = APIRouter() + + @router.post( + "/api/contents/{path:path}/checkpoints", + status_code=201, + ) + async def create_checkpoint( + path, user: User = Depends(auth.current_user(permissions={"contents": ["write"]})) + ) -> Checkpoint: + return await self.create_checkpoint(path, user) + + @router.post( + "/api/contents{path:path}", + status_code=201, + ) + async def create_content( + path: Optional[str], + request: Request, + user: User = Depends(auth.current_user(permissions={"contents": ["write"]})), + ) -> Content: + return await self.create_content(path, request, user) + + @router.get("/api/contents") + async def get_root_content( + content: int, + user: User = Depends(auth.current_user(permissions={"contents": ["read"]})), + ) -> Content: + return await self.get_root_content(content, user) + + @router.get("/api/contents/{path:path}/checkpoints") + async def get_checkpoint( + path, user: User = Depends(auth.current_user(permissions={"contents": ["read"]})) + ) -> List[Checkpoint]: + return await self.get_checkpoint(path, user) + + @router.get("/api/contents/{path:path}") + async def get_content( + path: str, + content: int = 0, + user: User = Depends(auth.current_user(permissions={"contents": ["read"]})), + ) -> Content: + return await self.get_content(path, content, user) + + @router.put("/api/contents/{path:path}") + async def save_content( + path, + request: Request, + response: Response, + user: User = Depends(auth.current_user(permissions={"contents": ["write"]})), + ) -> Content: + return await self.save_content(path, request, response, user) + + @router.delete( + "/api/contents/{path:path}", + status_code=204, + ) + async def delete_content( + path, + user: User = Depends(auth.current_user(permissions={"contents": ["write"]})), + ): + return await self.delete_content(path, user) + + @router.patch("/api/contents/{path:path}") + async def rename_content( + path, + request: Request, + user: User = Depends(auth.current_user(permissions={"contents": ["write"]})), + ) -> Content: + return await self.rename_content(path, request, user) + + self.include_router(router, prefix=contents_config.prefix) @property @abstractmethod diff --git a/jupyverse_api/jupyverse_api/kernels/__init__.py b/jupyverse_api/jupyverse_api/kernels/__init__.py index 0aa848c2..a868d472 100644 --- a/jupyverse_api/jupyverse_api/kernels/__init__.py +++ b/jupyverse_api/jupyverse_api/kernels/__init__.py @@ -10,116 +10,125 @@ from .models import Session +class KernelsConfig(Config): + default_kernel: str = "python3" + connection_path: Optional[str] = None + require_yjs: bool = False + include_router: bool = True + prefix: str = "" + + class Kernels(Router, ABC): - def __init__(self, app: App, auth: Auth): + def __init__(self, app: App, auth: Auth, kernels_config: KernelsConfig): super().__init__(app=app) - router = APIRouter() - - @router.get("/api/status") - async def get_status( - user: User = Depends(auth.current_user(permissions={"status": ["read"]})), - ): - return await self.get_status(user) - - @router.get("/api/kernelspecs") - async def get_kernelspecs( - user: User = Depends(auth.current_user(permissions={"kernelspecs": ["read"]})), - ): - return await self.get_kernelspecs(user) - - @router.get("/kernelspecs/{kernel_name}/{file_name}") - async def get_kernelspec( - kernel_name, - file_name, - user: User = Depends(auth.current_user()), - ): - return await self.get_kernelspec(kernel_name, file_name, user) - - @router.get("/api/kernels") - async def get_kernels( - user: User = Depends(auth.current_user(permissions={"kernels": ["read"]})), - ): - return await self.get_kernels(user) - - @router.delete("/api/sessions/{session_id}", status_code=204) - async def delete_session( - session_id: str, - user: User = Depends(auth.current_user(permissions={"sessions": ["write"]})), - ): - return await self.delete_session(session_id, user) - - @router.patch("/api/sessions/{session_id}") - async def rename_session( - request: Request, - user: User = Depends(auth.current_user(permissions={"sessions": ["write"]})), - ) -> Session: - return await self.rename_session(request, user) - - @router.get("/api/sessions") - async def get_sessions( - user: User = Depends(auth.current_user(permissions={"sessions": ["read"]})), - ) -> List[Session]: - return await self.get_sessions(user) - - @router.post( - "/api/sessions", - status_code=201, - response_model=Session, - ) - async def create_session( - request: Request, - user: User = Depends(auth.current_user(permissions={"sessions": ["write"]})), - ) -> Session: - return await self.create_session(request, user) - - @router.post("/api/kernels/{kernel_id}/interrupt") - async def interrupt_kernel( - kernel_id, - user: User = Depends(auth.current_user(permissions={"kernels": ["write"]})), - ): - return await self.interrupt_kernel(kernel_id, user) - - @router.post("/api/kernels/{kernel_id}/restart") - async def restart_kernel( - kernel_id, - user: User = Depends(auth.current_user(permissions={"kernels": ["write"]})), - ): - return await self.restart_kernel(kernel_id, user) - - @router.post("/api/kernels/{kernel_id}/execute") - async def execute_cell( - request: Request, - kernel_id, - user: User = Depends(auth.current_user(permissions={"kernels": ["write"]})), - ): - return await self.execute_cell(request, kernel_id, user) - - @router.get("/api/kernels/{kernel_id}") - async def get_kernel( - kernel_id, - user: User = Depends(auth.current_user(permissions={"kernels": ["read"]})), - ): - return await self.get_kernel(kernel_id, user) - - @router.delete("/api/kernels/{kernel_id}", status_code=204) - async def shutdown_kernel( - kernel_id, - user: User = Depends(auth.current_user(permissions={"kernels": ["write"]})), - ): - return await self.shutdown_kernel(kernel_id, user) - - @router.websocket("/api/kernels/{kernel_id}/channels") - async def kernel_channels( - kernel_id, - session_id, - websocket_permissions=Depends( - auth.websocket_auth(permissions={"kernels": ["execute"]}) - ), - ): - return await self.kernel_channels(kernel_id, session_id, websocket_permissions) - - self.include_router(router) + if kernels_config.include_router: + router = APIRouter() + + @router.get("/api/status") + async def get_status( + user: User = Depends(auth.current_user(permissions={"status": ["read"]})), + ): + return await self.get_status(user) + + @router.get("/api/kernelspecs") + async def get_kernelspecs( + user: User = Depends(auth.current_user(permissions={"kernelspecs": ["read"]})), + ): + return await self.get_kernelspecs(user) + + @router.get("/kernelspecs/{kernel_name}/{file_name}") + async def get_kernelspec( + kernel_name, + file_name, + user: User = Depends(auth.current_user()), + ): + return await self.get_kernelspec(kernel_name, file_name, user) + + @router.get("/api/kernels") + async def get_kernels( + user: User = Depends(auth.current_user(permissions={"kernels": ["read"]})), + ): + return await self.get_kernels(user) + + @router.delete("/api/sessions/{session_id}", status_code=204) + async def delete_session( + session_id: str, + user: User = Depends(auth.current_user(permissions={"sessions": ["write"]})), + ): + return await self.delete_session(session_id, user) + + @router.patch("/api/sessions/{session_id}") + async def rename_session( + request: Request, + user: User = Depends(auth.current_user(permissions={"sessions": ["write"]})), + ) -> Session: + return await self.rename_session(request, user) + + @router.get("/api/sessions") + async def get_sessions( + user: User = Depends(auth.current_user(permissions={"sessions": ["read"]})), + ) -> List[Session]: + return await self.get_sessions(user) + + @router.post( + "/api/sessions", + status_code=201, + response_model=Session, + ) + async def create_session( + request: Request, + user: User = Depends(auth.current_user(permissions={"sessions": ["write"]})), + ) -> Session: + return await self.create_session(request, user) + + @router.post("/api/kernels/{kernel_id}/interrupt") + async def interrupt_kernel( + kernel_id, + user: User = Depends(auth.current_user(permissions={"kernels": ["write"]})), + ): + return await self.interrupt_kernel(kernel_id, user) + + @router.post("/api/kernels/{kernel_id}/restart") + async def restart_kernel( + kernel_id, + user: User = Depends(auth.current_user(permissions={"kernels": ["write"]})), + ): + return await self.restart_kernel(kernel_id, user) + + @router.post("/api/kernels/{kernel_id}/execute") + async def execute_cell( + request: Request, + kernel_id, + user: User = Depends(auth.current_user(permissions={"kernels": ["write"]})), + ): + return await self.execute_cell(request, kernel_id, user) + + @router.get("/api/kernels/{kernel_id}") + async def get_kernel( + kernel_id, + user: User = Depends(auth.current_user(permissions={"kernels": ["read"]})), + ): + return await self.get_kernel(kernel_id, user) + + @router.delete("/api/kernels/{kernel_id}", status_code=204) + async def shutdown_kernel( + kernel_id, + user: User = Depends(auth.current_user(permissions={"kernels": ["write"]})), + ): + return await self.shutdown_kernel(kernel_id, user) + + @router.websocket("/api/kernels/{kernel_id}/channels") + async def kernel_channels( + kernel_id, + session_id, + websocket_permissions=Depends( + auth.websocket_auth(permissions={"kernels": ["execute"]}) + ), + ): + return await self.kernel_channels(kernel_id, session_id, websocket_permissions) + + self.include_router(router, prefix=kernels_config.prefix) @abstractmethod async def watch_connection_files(self, path: Path) -> None: @@ -235,9 +244,3 @@ async def kernel_channels( websocket_permissions, ): ... - - -class KernelsConfig(Config): - default_kernel: str = "python3" - connection_path: Optional[str] = None - require_yjs: bool = False diff --git a/plugins/contents/fps_contents/main.py b/plugins/contents/fps_contents/main.py index 36dc5cfe..35991ab0 100644 --- a/plugins/contents/fps_contents/main.py +++ b/plugins/contents/fps_contents/main.py @@ -1,12 +1,15 @@ from asphalt.core import Component, Context from jupyverse_api.app import App from jupyverse_api.auth import Auth -from jupyverse_api.contents import Contents +from jupyverse_api.contents import Contents, ContentsConfig from .routes import _Contents class ContentsComponent(Component): + def __init__(self, **kwargs) -> None: + self.contents_config = ContentsConfig(**kwargs) + async def start( self, ctx: Context, @@ -14,5 +17,5 @@ async def start( app = await ctx.request_resource(App) auth = await ctx.request_resource(Auth) # type: ignore - contents = _Contents(app, auth) + contents = _Contents(app, auth, self.contents_config) ctx.add_resource(contents, types=Contents) diff --git a/plugins/kernels/fps_kernels/main.py b/plugins/kernels/fps_kernels/main.py index cd856a40..24416c3a 100644 --- a/plugins/kernels/fps_kernels/main.py +++ b/plugins/kernels/fps_kernels/main.py @@ -16,7 +16,7 @@ class KernelsComponent(Component): - def __init__(self, **kwargs): + def __init__(self, **kwargs) -> None: self.kernels_config = KernelsConfig(**kwargs) @context_teardown diff --git a/plugins/kernels/fps_kernels/routes.py b/plugins/kernels/fps_kernels/routes.py index e87a7f9b..b17d4188 100644 --- a/plugins/kernels/fps_kernels/routes.py +++ b/plugins/kernels/fps_kernels/routes.py @@ -37,7 +37,7 @@ def __init__( frontend_config: FrontendConfig, yjs: Optional[Yjs], ) -> None: - super().__init__(app=app, auth=auth) + super().__init__(app=app, auth=auth, config=kernels_config) self.kernels_config = kernels_config self.frontend_config = frontend_config self.yjs = yjs