Skip to content

Commit

Permalink
Draft of the proposed path resolver API
Browse files Browse the repository at this point in the history
  • Loading branch information
krassowski committed Sep 28, 2023
1 parent 2563bae commit bf388fd
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 0 deletions.
33 changes: 33 additions & 0 deletions jupyter_server/services/api/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,41 @@ def get(self):
self.write(json.dumps(model))


class PathResolverHandler(APIHandler):
"""Path resolver handler."""

auth_resource = AUTH_RESOURCE
_track_activity = False

@web.authenticated
@authorized
async def get(self):
"""Resolve the path."""
path = self.get_query_argument("path")
kernel_uuid = self.get_query_argument("kernel", default=None)

scopes = [
self.contents_manager,
# TODO vs multi_kernel_manager?
# TODO: kernel lives in client so we may need to implement it there.
self.kernel_manager.get_kernel(kernel_uuid),
# *self.get_additional_scopes(kernel_uuid)
]
# TODO: maybe client should be able to define their own scope? this way
# ipykernel can return {"scope": "source"} or {scope: 'kernel'}
# TODO: how to plug in the additional scopes? a traitlet? maybe...
resolved = [
{"scope": scope, "path": await scope.resolve_path(path)}
for scope in scopes
if hasattr(scope, "resolve_path")
]
response = {"resolved": [entry for entry in resolved if entry["path"] is not None]}
self.finish(json.dumps(response))


default_handlers = [
(r"/api/spec.yaml", APISpecHandler),
(r"/api/status", APIStatusHandler),
(r"/api/me", IdentityHandler),
(r"/api/resolvePath", PathResolverHandler),
]
13 changes: 13 additions & 0 deletions jupyter_server/services/contents/filemanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,19 @@ def exists(self, path):
os_path = self._get_os_path(path=path)
return exists(os_path)

def resolve_path(self, path: str):
"""Resolve path relative to root resource."""
# transform OS path to API path
relative_path = to_api_path(path, self.root_dir)
# check if the API path is within contents directory
try:
os_path = self._get_os_path(path=relative_path)
except web.HTTPError:
return None
if exists(os_path):
return relative_path
return None

def _base_model(self, path):
"""Build the common base of a contents model"""
os_path = self._get_os_path(path)
Expand Down
4 changes: 4 additions & 0 deletions jupyter_server/services/contents/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,10 @@ async def rename_file(self, old_path, new_path):
# ContentsManager API part 2: methods that have useable default
# implementations, but can be overridden in subclasses.

async def resolve_path(self, path: str):
"""Resolve path relative to root resource."""
return None

async def delete(self, path):
"""Delete a file/directory and any associated checkpoints."""
path = path.strip("/")
Expand Down

0 comments on commit bf388fd

Please sign in to comment.