1
+ """A Websocket Handler for emitting Jupyter server events.
2
+
3
+ .. versionadded:: 2.0
4
+ """
1
5
import logging
2
6
3
- import tornado .web
4
- import tornado .websocket
5
7
from jupyter_telemetry .eventlog import _skip_message
6
8
from pythonjsonlogger import jsonlogger
9
+ from tornado import web , websocket
7
10
8
11
from jupyter_server .base .handlers import JupyterHandler
9
12
13
+ AUTH_RESOURCE = "events"
14
+
10
15
11
16
class TornadoWebSocketLoggingHandler (logging .Handler ):
12
- """Logging handler that routes records to a Tornado websocket."""
17
+ """Python logging handler that routes records to a Tornado websocket."""
13
18
14
19
def __init__ (self , websocket ):
15
20
super ().__init__ ()
@@ -22,13 +27,41 @@ def emit(self, record):
22
27
23
28
class SubscribeWebsocket (
24
29
JupyterHandler ,
25
- tornado . websocket .WebSocketHandler ,
30
+ websocket .WebSocketHandler ,
26
31
):
32
+ """Websocket Handler for listening to eve"""
33
+
34
+ auth_resource = AUTH_RESOURCE
35
+
36
+ def pre_get (self ):
37
+ """Handles authentication/authorization when
38
+ attempting to subscribe to events emitted by
39
+ Jupyter Server's eventbus.
40
+ """
41
+ # authenticate the request before opening the websocket
42
+ user = self .current_user
43
+ if user is None :
44
+ self .log .warning ("Couldn't authenticate WebSocket connection" )
45
+ raise web .HTTPError (403 )
46
+
47
+ # authorize the user.
48
+ if not self .authorizer .is_authorized (self , user , "execute" , "events" ):
49
+ raise web .HTTPError (403 )
50
+
51
+ async def get (self , * args , ** kwargs ):
52
+ self .pre_get ()
53
+ res = super ().get (* args , ** kwargs )
54
+ await res
55
+
27
56
@property
28
57
def event_bus (self ):
58
+ """Jupyter Server's event bus that emits structured event data."""
29
59
return self .settings ["event_bus" ]
30
60
31
61
def open (self ):
62
+ """Routes events that are emitted by Jupyter Server's
63
+ EventBus to a WebSocket client in the browser.
64
+ """
32
65
self .logging_handler = TornadoWebSocketLoggingHandler (self )
33
66
# Add a JSON formatter to the handler.
34
67
formatter = jsonlogger .JsonFormatter (json_serializer = _skip_message )
0 commit comments