Skip to content

Commit

Permalink
Creates document session (jupyterlab#108)
Browse files Browse the repository at this point in the history
* Creates document session

* Uses translator

* Update jupyter_collaboration/handlers.py

* Create a new endpoint for document sessions, changes tranlator property and deprecates old endpoints

---------

Co-authored-by: David Brochart <[email protected]>
  • Loading branch information
hbcarlos and davidbrochart committed Mar 1, 2023
1 parent c42c27e commit 29122c1
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 1 deletion.
11 changes: 10 additions & 1 deletion jupyter_server_ydoc/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@
from traitlets import Float, Int, Type
from ypy_websocket.ystore import BaseYStore # type: ignore

from .handlers import SQLiteYStore, YDocRoomIdHandler, YDocWebSocketHandler
from .handlers import (
DocSessionHandler,
SQLiteYStore,
YDocRoomIdHandler,
YDocWebSocketHandler,
)


class YDocExtension(ExtensionApp):
Expand Down Expand Up @@ -62,7 +67,11 @@ def initialize_settings(self):
def initialize_handlers(self):
self.handlers.extend(
[
# Deprecated - to remove for 1.0.0
(r"/api/yjs/roomid/(.*)", YDocRoomIdHandler),
# Deprecated - to remove for 1.0.0
(r"/api/yjs/(.*)", YDocWebSocketHandler),
(r"/api/collaboration/room/(.*)", YDocWebSocketHandler),
(r"/api/collaboration/session/(.*)", DocSessionHandler),
]
)
45 changes: 45 additions & 0 deletions jupyter_server_ydoc/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import asyncio
import json
import uuid
from logging import Logger
from pathlib import Path
from typing import Any, Dict, Optional, Tuple
Expand All @@ -24,6 +25,8 @@

YFILE = YDOCS["file"]

SERVER_SESSION = str(uuid.uuid4())


class TempFileYStore(_TempFileYStore):
prefix_dir = "jupyter_ystore_"
Expand Down Expand Up @@ -195,6 +198,11 @@ async def open(self, path):
self.saving_document = None
asyncio.create_task(self.websocket_server.serve(self))

# Close the connection if the document session expired
session_id = self.get_query_argument("sessionId", "")
if isinstance(self.room, DocumentRoom) and SERVER_SESSION != session_id:
self.close(1003, f"Document session {session_id} expired")

# cancel the deletion of the room if it was scheduled
if isinstance(self.room, DocumentRoom) and self.room.cleaner is not None:
self.room.cleaner.cancel()
Expand All @@ -221,6 +229,7 @@ async def open(self, path):
# if YStore updates and source file are out-of-sync, resync updates with source
if self.room.document.source != model["content"]:
read_from_source = True

if read_from_source:
self.room.document.source = model["content"]
if self.room.ystore:
Expand Down Expand Up @@ -405,3 +414,39 @@ async def put(self, path):
ws_url += str(idx)
self.log.info("Request for Y document '%s' with room ID: %s", path, ws_url)
return self.finish(ws_url)


class DocSessionHandler(APIHandler):
auth_resource = "contents"

@web.authenticated
@authorized
async def put(self, path):
body = json.loads(self.request.body)
format = body["format"]
content_type = body["type"]
file_id_manager = self.settings["file_id_manager"]

idx = file_id_manager.get_id(path)
if idx is not None:
# index already exists
self.log.info("Request for Y document '%s' with room ID: %s", path, idx)
data = json.dumps(
{"format": format, "type": content_type, "fileId": idx, "sessionId": SERVER_SESSION}
)
self.set_status(200)
return self.finish(data)

# try indexing
idx = file_id_manager.index(path)
if idx is None:
# file does not exists
raise web.HTTPError(404, f"File {path!r} does not exist")

# index successfully created
self.log.info("Request for Y document '%s' with room ID: %s", path, idx)
data = json.dumps(
{"format": format, "type": content_type, "fileId": idx, "sessionId": SERVER_SESSION}
)
self.set_status(201)
return self.finish(data)

0 comments on commit 29122c1

Please sign in to comment.