class_docstr: Handles a WebSocket connection from the browser
docstr: Return the first subprotocol in the given list.
  
  This method is used by Tornado to select a protocol when the
  Sec-WebSocket-Protocol header is set in an HTTP Upgrade request.
  
  NOTE: We repurpose the Sec-WebSocket-Protocol header here in a slightly
  unfortunate (but necessary) way. The browser WebSocket API doesn't allow us to
  set arbitrary HTTP headers, and this header is the only one where we have the
  ability to set it to arbitrary values, so we use it to pass tokens (in this
  case, the previous session ID to allow us to reconnect to it) from client to
  server as the *third* value in the list.
  
  The reason why the auth token is set as the third value is that:
    * when Sec-WebSocket-Protocol is set, many clients expect the server to
      respond with a selected subprotocol to use. We don't want that reply to be
      the session token, so we by convention have the client always set the first
      protocol to "streamlit" and select that.
    * the second protocol in the list is reserved in some deployment environments
      for an auth token that we currently don't use
docstr_tok: ["Return","the","first","subprotocol","in","the","given","list",".","This","method","is","used","by","Tornado","to","select","a","protocol","when","the","Sec-WebSocket-Protocol","header","is","set","in","an","HTTP","Upgrade","request",".","NOTE",":","We","repurpose","the","Sec-WebSocket-Protocol","header","here","in","a","slightly","unfortunate","(","but","necessary",")","way",".","The","browser","WebSocket","API","does","n't","allow","us","to","set","arbitrary","HTTP","headers",",","and","this","header","is","the","only","one","where","we","have","the","ability","to","set","it","to","arbitrary","values",",","so","we","use","it","to","pass","tokens","(","in","this","case",",","the","previous","session","ID","to","allow","us","to","reconnect","to","it",")","from","client","to","server","as","the","*","third","*","value","in","the","list",".","The","reason","why","the","auth","token","is","set","as","the","third","value","is","that",":","*","when","Sec-WebSocket-Protocol","is","set",",","many","clients","expect","the","server","to","respond","with","a","selected","subprotocol","to","use",".","We","do","n't","want","that","reply","to","be","the","session","token",",","so","we","by","convention","have","the","client","always","set","the","first","protocol","to","``","streamlit","''","and","select","that",".","*","the","second","protocol","in","the","list","is","reserved","in","some","deployment","environments","for","an","auth","token","that","we","currently","do","n't","use"]
code: def select_subprotocol(
      self, subprotocols: List[str]
  ) -> Optional[str]:
      """Return the first subprotocol in the given list.
  
      This method is used by Tornado to select a protocol when the
      Sec-WebSocket-Protocol header is set in an HTTP Upgrade request.
  
      NOTE: We repurpose the Sec-WebSocket-Protocol header here in a slightly
      unfortunate (but necessary) way. The browser WebSocket API doesn't allow us to
      set arbitrary HTTP headers, and this header is the only one where we have the
      ability to set it to arbitrary values, so we use it to pass tokens (in this
      case, the previous session ID to allow us to reconnect to it) from client to
      server as the *third* value in the list.
  
      The reason why the auth token is set as the third value is that:
        * when Sec-WebSocket-Protocol is set, many clients expect the server to
          respond with a selected subprotocol to use. We don't want that reply to be
          the session token, so we by convention have the client always set the first
          protocol to "streamlit" and select that.
        * the second protocol in the list is reserved in some deployment environments
          for an auth token that we currently don't use
      """
      if subprotocols:
          return subprotocols[0]
  
      return None
  
imports: import base64
  import binascii
  import json
  from typing import Any, Awaitable, Dict, List, Optional, Union
  import tornado.concurrent
  import tornado.locks
  import tornado.netutil
  import tornado.web
  import tornado.websocket
  from tornado.websocket import WebSocketHandler
  from typing_extensions import Final
  from streamlit import config
  from streamlit.logger import get_logger
  from streamlit.proto.BackMsg_pb2 import BackMsg
  from streamlit.proto.ForwardMsg_pb2 import ForwardMsg
  from streamlit.runtime import Runtime, SessionClient, SessionClientDisconnectedError
  from streamlit.runtime.runtime_util import serialize_forward_msg
  from streamlit.web.server.server_util import is_url_from_allowed_origins
label_desc: Use image node_id 4 for calling the BrowserWebSocketHandler obj's underlying member method code with example usage: obj.select_subprotocol(subprotocols) and returns: None, subprotocols