Skip to content

Commit 8b6b2b6

Browse files
authored
Add compatibility with Jupyter Collaboration v4 (#106)
* standardize labextension plugin IDs * disable jupyter_collaboration extensions thru metadata * fix missing plugin error, now works w/ JCollab4 * add new JCollab 4 + JSD dev env, remove old ones * add jupyter_events integration * fix wrong room_id doc comment * add JCollab Python API * use same event schema IDs as jupyter_collaboration * fix JAI compatibility issue * remove custom type only supported in Py >3.12
1 parent 2b65f40 commit 8b6b2b6

File tree

19 files changed

+364
-46
lines changed

19 files changed

+364
-46
lines changed

devenv-jcollab-backend.yml

Lines changed: 0 additions & 12 deletions
This file was deleted.

devenv-jcollab-frontend.yml

Lines changed: 0 additions & 11 deletions
This file was deleted.

devenv-jcollab.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
name: serverdocs-jcollab
2+
channels:
3+
- conda-forge
4+
dependencies:
5+
- python
6+
- nodejs=22
7+
- uv
8+
- jupyterlab
9+
- pip:
10+
- jupyterlab>=4.4.0,<5.0.0
11+
- jupyter_collaboration~=4.0
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
{
22
"ServerApp": {
33
"jpserver_extensions": {
4-
"jupyter_server_documents": true
4+
"jupyter_server_documents": true,
5+
"jupyter_server_ydoc": false
56
}
67
}
78
}

jupyter_server_documents/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111

1212
from .app import ServerDocsApp
13+
from .events import JSD_AWARENESS_EVENT_URI, JSD_ROOM_EVENT_URI
1314

1415

1516
def _jupyter_labextension_paths():

jupyter_server_documents/app.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
from .websockets import YRoomWebsocket
88
from .rooms.yroom_manager import YRoomManager
99
from .outputs import OutputsManager, outputs_handlers
10+
from .events import JSD_AWARENESS_EVENT_SCHEMA, JSD_ROOM_EVENT_SCHEMA
11+
from .jcollab_api import JCollabAPI
1012

1113
class ServerDocsApp(ExtensionApp):
1214
name = "jupyter_server_documents"
@@ -51,6 +53,10 @@ def initialize(self):
5153
super().initialize()
5254

5355
def initialize_settings(self):
56+
# Register event schemas
57+
self.serverapp.event_logger.register_event_schema(JSD_ROOM_EVENT_SCHEMA)
58+
self.serverapp.event_logger.register_event_schema(JSD_AWARENESS_EVENT_SCHEMA)
59+
5460
# Get YRoomManager arguments from server extension context.
5561
# We cannot access the 'file_id_manager' key immediately because server
5662
# extensions initialize in alphabetical order. 'jupyter_server_documents' <
@@ -65,13 +71,22 @@ def get_fileid_manager():
6571
self.settings["yroom_manager"] = YRoomManager(
6672
get_fileid_manager=get_fileid_manager,
6773
contents_manager=contents_manager,
74+
event_logger=self.serverapp.event_logger,
6875
loop=loop,
6976
log=log
7077
)
71-
78+
7279
# Initialize OutputsManager
7380
self.outputs_manager = self.outputs_manager_class(config=self.config)
7481
self.settings["outputs_manager"] = self.outputs_manager
82+
83+
# Serve Jupyter Collaboration API on
84+
# `self.settings["jupyter_server_ydoc"]` for compatibility with
85+
# extensions depending on Jupyter Collaboration
86+
self.settings["jupyter_server_ydoc"] = JCollabAPI(
87+
get_fileid_manager=get_fileid_manager,
88+
yroom_manager=self.settings["yroom_manager"]
89+
)
7590

7691
def _link_jupyter_server_extension(self, server_app):
7792
"""Setup custom config needed by this extension."""
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from pathlib import Path
2+
3+
EVENTS_DIR = Path(__file__).parent
4+
5+
# Use the same schema ID as `jupyter_collaboration` for compatibility
6+
JSD_ROOM_EVENT_URI = "https://schema.jupyter.org/jupyter_collaboration/session/v1"
7+
JSD_AWARENESS_EVENT_URI = "https://schema.jupyter.org/jupyter_collaboration/awareness/v1"
8+
9+
JSD_ROOM_EVENT_SCHEMA = EVENTS_DIR / "room.yaml"
10+
JSD_AWARENESS_EVENT_SCHEMA = EVENTS_DIR / "awareness.yaml"
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
"$id": https://schema.jupyter.org/jupyter_collaboration/awareness/v1
2+
"$schema": "http://json-schema.org/draft-07/schema"
3+
version: "1"
4+
title: Collaborative awareness events
5+
personal-data: true
6+
description: |
7+
Awareness events emitted from server-side during a collaborative session.
8+
type: object
9+
required:
10+
- roomid
11+
- username
12+
- action
13+
properties:
14+
roomid:
15+
type: string
16+
description: |
17+
Room ID. Usually composed by the file type, format and ID.
18+
username:
19+
type: string
20+
description: |
21+
The name of the user who joined or left room.
22+
action:
23+
enum:
24+
- join
25+
- leave
26+
description: |
27+
Possible values:
28+
1. join
29+
2. leave
30+
msg:
31+
type: string
32+
description: |
33+
Optional event message.
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
"$id": https://schema.jupyter.org/jupyter_collaboration/session/v1
2+
"$schema": "http://json-schema.org/draft-07/schema"
3+
version: "1"
4+
title: Room events
5+
personal-data: true
6+
description: |
7+
An event emitted by a collaboration room.
8+
type: object
9+
required:
10+
- level
11+
- room
12+
- path
13+
properties:
14+
level:
15+
enum:
16+
- INFO
17+
- DEBUG
18+
- WARNING
19+
- ERROR
20+
- CRITICAL
21+
description: |
22+
Message type.
23+
room:
24+
type: string
25+
description: |
26+
Room ID. This is a composite ID that takes the format `{file_format}:{file_type}:{file_id}`.
27+
path:
28+
type: string
29+
description: |
30+
Path of the file.
31+
store:
32+
type: string
33+
description: |
34+
The store used to track the document history.
35+
action:
36+
enum:
37+
- initialize
38+
- load
39+
- save
40+
- overwrite
41+
- clean
42+
description: |
43+
Action performed in a room during a collaborative session.
44+
Possible values:
45+
1. initialize
46+
Initialize a room by loading the content from the contents manager or a store.
47+
2. load
48+
Load the content from the contents manager.
49+
3. save
50+
Save the content with the contents manager.
51+
4. overwrite
52+
Overwrite the content in a room with content from the contents manager.
53+
This can happen when multiple rooms access the same file or when a user
54+
modifies the file outside Jupyter Server (e.g. using a different app).
55+
5. clean
56+
Clean the room once is empty (aka there is no more users connected to it).
57+
msg:
58+
type: string
59+
description: |
60+
Event message.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .jcollab_api import JCollabAPI

0 commit comments

Comments
 (0)