Skip to content

Commit fcb155b

Browse files
committed
Fix types
1 parent 62ef0c6 commit fcb155b

File tree

2 files changed

+25
-20
lines changed

2 files changed

+25
-20
lines changed

jupyter_server_ydoc/app.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
raise ModuleNotFoundError("Jupyter Server must be installed to use this extension.")
88

99
from traitlets import Float, Int, Type, Unicode, observe
10-
from ypy_websocket.ystore import BaseYStore, SQLiteYStore
10+
from ypy_websocket.ystore import BaseYStore, SQLiteYStore # type: ignore
1111

1212
from .handlers import YDocRoomIdHandler, YDocWebSocketHandler, sqlite_ystore_factory
1313

jupyter_server_ydoc/handlers.py

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,17 @@
55
import json
66
from logging import Logger
77
from pathlib import Path
8-
from typing import Any, Dict, Optional, Tuple
8+
from typing import Any, Dict, Optional, Tuple, Type
99

1010
from jupyter_server.auth import authorized
1111
from jupyter_server.base.handlers import APIHandler, JupyterHandler
1212
from jupyter_server.utils import ensure_async
1313
from jupyter_ydoc import ydocs as YDOCS # type: ignore
1414
from tornado import web
1515
from tornado.websocket import WebSocketHandler
16-
from ypy_websocket import WebsocketServer, YMessageType, YRoom
17-
from ypy_websocket.ystore import BaseYStore, SQLiteYStore, TempFileYStore, YDocNotFound
16+
from ypy_websocket.websocket_server import WebsocketServer, YRoom # type: ignore
17+
from ypy_websocket.ystore import BaseYStore, SQLiteYStore, TempFileYStore, YDocNotFound # type: ignore
18+
from ypy_websocket.yutils import YMessageType # type: ignore
1819

1920
YFILE = YDOCS["file"]
2021

@@ -25,7 +26,7 @@ class JupyterTempFileYStore(TempFileYStore):
2526

2627
def sqlite_ystore_factory(
2728
db_path: str = ".jupyter_ystore.db", document_ttl: Optional[int] = None
28-
) -> SQLiteYStore:
29+
) -> Type[SQLiteYStore]:
2930
_db_path = db_path
3031
_document_ttl = document_ttl
3132

@@ -39,8 +40,6 @@ class JupyterSQLiteYStore(SQLiteYStore):
3940
class DocumentRoom(YRoom):
4041
"""A Y room for a possibly stored document (e.g. a notebook)."""
4142

42-
is_transient = False
43-
4443
def __init__(self, type: str, ystore: BaseYStore, log: Optional[Logger]):
4544
super().__init__(ready=False, ystore=ystore, log=log)
4645
self.type = type
@@ -52,8 +51,6 @@ def __init__(self, type: str, ystore: BaseYStore, log: Optional[Logger]):
5251
class TransientRoom(YRoom):
5352
"""A Y room for sharing state (e.g. awareness)."""
5453

55-
is_transient = True
56-
5754
def __init__(self, log: Optional[Logger]):
5855
super().__init__(log=log)
5956

@@ -135,6 +132,7 @@ async def __anext__(self):
135132

136133
def get_file_info(self) -> Tuple[str, str, str]:
137134
assert self.websocket_server is not None
135+
assert isinstance(self.room, DocumentRoom)
138136
room_name = self.websocket_server.get_room_name(self.room)
139137
file_format: str
140138
file_type: str
@@ -178,10 +176,10 @@ async def open(self, path):
178176
asyncio.create_task(self.websocket_server.serve(self))
179177

180178
# cancel the deletion of the room if it was scheduled
181-
if not self.room.is_transient and self.room.cleaner is not None:
179+
if isinstance(self.room, DocumentRoom) and self.room.cleaner is not None:
182180
self.room.cleaner.cancel()
183181

184-
if not self.room.is_transient and not self.room.ready:
182+
if isinstance(self.room, DocumentRoom) and not self.room.ready:
185183
file_format, file_type, file_path = self.get_file_info()
186184
self.log.debug("Opening Y document from disk: %s", file_path)
187185
model = await ensure_async(
@@ -191,26 +189,30 @@ async def open(self, path):
191189
# check again if ready, because loading the file can be async
192190
if not self.room.ready:
193191
# try to apply Y updates from the YStore for this document
194-
try:
195-
await self.room.ystore.apply_updates(self.room.ydoc)
196-
read_from_source = False
197-
except YDocNotFound:
198-
# YDoc not found in the YStore, create the document from the source file (no change history)
199-
read_from_source = True
192+
read_from_source = True
193+
if self.room.ystore is not None:
194+
try:
195+
await self.room.ystore.apply_updates(self.room.ydoc)
196+
read_from_source = False
197+
except YDocNotFound:
198+
# YDoc not found in the YStore, create the document from the source file (no change history)
199+
pass
200200
if not read_from_source:
201201
# if YStore updates and source file are out-of-sync, resync updates with source
202202
if self.room.document.source != model["content"]:
203203
read_from_source = True
204204
if read_from_source:
205205
self.room.document.source = model["content"]
206-
await self.room.ystore.encode_state_as_update(self.room.ydoc)
206+
if self.room.ystore:
207+
await self.room.ystore.encode_state_as_update(self.room.ydoc)
207208
self.room.document.dirty = False
208209
self.room.ready = True
209210
self.room.watcher = asyncio.create_task(self.watch_file())
210211
# save the document when changed
211212
self.room.document.observe(self.on_document_change)
212213

213214
async def watch_file(self):
215+
assert isinstance(self.room, DocumentRoom)
214216
poll_interval = self.settings["collaborative_file_poll_interval"]
215217
if not poll_interval:
216218
self.room.watcher = None
@@ -220,6 +222,7 @@ async def watch_file(self):
220222
await self.maybe_load_document()
221223

222224
async def maybe_load_document(self):
225+
assert isinstance(self.room, DocumentRoom)
223226
file_format, file_type, file_path = self.get_file_info()
224227
async with self.lock:
225228
model = await ensure_async(
@@ -270,7 +273,7 @@ def on_message(self, message):
270273
# filter out message depending on changes
271274
if skip:
272275
self.log.debug(
273-
"Filtered out Y message of type: %s", YMessageType(message_type).raw_str()
276+
"Filtered out Y message of type: %s", YMessageType(message_type).name
274277
)
275278
return skip
276279
self._message_queue.put_nowait(message)
@@ -279,12 +282,13 @@ def on_message(self, message):
279282
def on_close(self) -> None:
280283
# stop serving this client
281284
self._message_queue.put_nowait(b"")
282-
if not self.room.is_transient and self.room.clients == [self]:
285+
if isinstance(self.room, DocumentRoom) and self.room.clients == [self]:
283286
# no client in this room after we disconnect
284287
# keep the document for a while in case someone reconnects
285288
self.room.cleaner = asyncio.create_task(self.clean_room())
286289

287290
async def clean_room(self) -> None:
291+
assert isinstance(self.room, DocumentRoom)
288292
seconds = self.settings["collaborative_document_cleanup_delay"]
289293
if seconds is None:
290294
return
@@ -312,6 +316,7 @@ def on_document_change(self, event):
312316
self.saving_document = asyncio.create_task(self.maybe_save_document())
313317

314318
async def maybe_save_document(self):
319+
assert isinstance(self.room, DocumentRoom)
315320
seconds = self.settings["collaborative_document_save_delay"]
316321
if seconds is None:
317322
return

0 commit comments

Comments
 (0)