class_docstr: Represents a websocket connection to a server-side session.
  
  Each server session stores a Document, which is kept in sync with the
  corresponding Document for this ``ClientSession`` instance. Updates on
  either side of the connection will automatically propagate to the other
  side, as long as the connection is open.
  
  ClientSession objects can (and usually should) be used as a context manager
  so that the session is properly closed:
  
  .. code-block:: python
  
      with pull_session(url=app_url) as mysession:
          # customize session here
          script = server_session(session_id=mysession.id, url=app_url)
          return render_template("embed.html", script=script, template="Flask")
  
  If you do not use ``ClientSession`` in this way, it is up to you to ensure
  that ``mysession.close()`` is called.
code: def _attach_document(self, document: Document) -> None:
      self._document = document
      self._document.callbacks.on_change_dispatch_to(self)
  
      self._callbacks.add_session_callbacks(
          self._document.session_callbacks
      )
  
imports: from __future__ import annotations
  import logging
  from typing import TYPE_CHECKING, Any, Literal
  from urllib.parse import quote_plus
  from ..core.types import ID
  from ..document import Document
  from ..resources import DEFAULT_SERVER_HTTP_URL, SessionCoordinates
  from ..util.browser import NEW_PARAM, BrowserLike, BrowserTarget
  from ..util.token import generate_jwt_token, generate_session_id
  from .states import ErrorReason
  from .util import server_url_for_websocket_url, websocket_url_for_server_url
label_desc: Use image node_id 20 for calling the ClientSession obj's underlying member method code with example usage: obj._attach_document(document) without return types