#-----------------------------------------------------------------------------# Copyright (c) 2012 - 2024, Anaconda, Inc., and Bokeh Contributors.# All rights reserved.## The full license is in the file LICENSE.txt, distributed with this software.#-----------------------------------------------------------------------------''' Encapsulate handling of all Bokeh Protocol messages a Bokeh server mayreceive.'''#-----------------------------------------------------------------------------# Boilerplate#-----------------------------------------------------------------------------from__future__importannotationsimportlogging# isort:skiplog=logging.getLogger(__name__)#-----------------------------------------------------------------------------# Imports#-----------------------------------------------------------------------------# Standard library importsfromtypingimportAny,Callable# Bokeh importsfrom..protocol.exceptionsimportProtocolErrorfrom.sessionimportServerSession#-----------------------------------------------------------------------------# Globals and constants#-----------------------------------------------------------------------------__all__=('ProtocolHandler',)#-----------------------------------------------------------------------------# General API#-----------------------------------------------------------------------------
[docs]classProtocolHandler:''' A Bokeh server may be expected to receive any of the following protocol messages: * ``PATCH-DOC`` * ``PULL-DOC-REQ`` * ``PUSH-DOC`` * ``SERVER-INFO-REQ`` The job of ``ProtocolHandler`` is to direct incoming messages to the right specialized handler for each message type. When the server receives a new message on a connection it will call ``handler`` with the message and the connection that the message arrived on. Most messages are ultimately handled by the ``ServerSession`` class, but some simpler messages types such as ``SERVER-INFO-REQ`` may be handled directly by ``ProtocolHandler``. Any unexpected messages will result in a ``ProtocolError``. '''_handlers:dict[str,Callable[...,Any]]def__init__(self)->None:self._handlers={}self._handlers['PULL-DOC-REQ']=ServerSession.pullself._handlers['PUSH-DOC']=ServerSession.pushself._handlers['PATCH-DOC']=ServerSession.patchself._handlers['SERVER-INFO-REQ']=self._server_info_req
[docs]asyncdefhandle(self,message,connection):''' Delegate a received message to the appropriate handler. Args: message (Message) : The message that was receive that needs to be handled connection (ServerConnection) : The connection that received this message Raises: ProtocolError '''handler=self._handlers.get(message.msgtype)ifhandlerisNone:handler=self._handlers.get(message.msgtype)ifhandlerisNone:raiseProtocolError(f"{message} not expected on server")try:work=awaithandler(message,connection)exceptExceptionase:log.error("error handling message\n message: %r\n error: %r",message,e,exc_info=True)work=connection.error(message,repr(e))returnwork