Skip to content

Public API to get a view of the shared document model #270

@krassowski

Description

@krassowski

Problem

Other server extensions would like to use the shared document model to access the content of the notebook without the overhead of sending it over from the frontend, and without the risk of using an outdated (or even inaccessible) copy stored on the disk.

Currently, while this is possible as demonstrated in jupyterlab/jupyter-ai#708, it requires:

  • accessing a private _document attribute of the DocumentRoom
  • re-creating the room ID using encode_file_path and other some black magic (which has no guarantee of working if the id format changes in a future release of jupyter-collaboration)

Proposed Solution

Expose a new get_document() method on the YDocExtension. It could look like:

def get_document(
    self: YDocExtension,
    path: str,
    content_type: 'notebook' | 'file',
    file_format: 'json' | 'text'
) -> YBaseDoc | None:
    file_id_manager = self.settings["file_id_manager"]
    file_id = file_id_manager.index(request.path)

    # these two lines would be moved to an utility function to avoid drift from the code used in the handler.
    encoded_path = encode_file_path(file_format, content_type, file_id)
    room_id: str = encoded_path.split("/")[-1]

    try:
        room = await collaboration.ywebsocket_server.get_room(room_id)
    except RoomNotFound:
        return None

    if isinstance(room, DocumentRoom):
        document = room._document
        return document

One question raised by @3coins on the server call was whether such API should return a read-only view of the document:

  • In case of YNotebook subclass this could mean an encapsulation hiding methods such as append_cell and set_cell. This would require defining read-only variants/wrapper for each of the data structures defined in jupyter-ydoc.
  • Alternatively, we could use a copy of the model as implemented by @davidbrochart for forking in Support suggestions #239. Creating a copy might have performance implications; while we still do not send the notebook over wire, we are making an in-memory copy - which should be orders of magnitude faster, but still slower than not doing it.

Task list:

  • benchmark the performance penalty of cloning the document as done in forking (relatively to sending it over the wire)
  • establish consensus on the way forward with making the result read-only
  • implement the new method
  • add tests
  • add documentation

Additional context

This would follow the same pattern as used by jupyter-server-fileid which exposes a small (two methods) public API as documented here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions