def push_session(document, session_id=None, url='default', io_loop=None):
    ''' Create a session by pushing the given document to the server,
    overwriting any existing server-side document.

    ``session.document`` in the returned session will be your supplied
    document. While the connection to the server is open, changes made on the
    server side will be applied to this document, and changes made on the
    client side will be synced to the server.

    In a production scenario, the ``session_id`` should be unique for each
    browser tab, which keeps users from stomping on each other. It's neither
    scalable nor secure to use predictable session IDs or to share session
    IDs across users.

    For a notebook running on a single machine, ``session_id`` could be
    something human-readable such as ``"default"`` for convenience.

    If you allow ``push_session()`` to generate a unique ``session_id``, you
    can obtain the generated ID with the ``id`` property on the returned
    ``ClientSession``.

    Args:
        document : (bokeh.document.Document)
            The document to be pushed and set as session.document

        session_id : (string, optional)
            The name of the session, None to autogenerate a random one (default: None)

        url : (str, optional): The URL to a Bokeh application on a Bokeh server
            can also be `"default"` which will connect to the default app URL

        io_loop : (tornado.ioloop.IOLoop, optional)
            The IOLoop to use for the websocket

    Returns:
        ClientSession
            A new ClientSession connected to the server

    '''
    coords = _SessionCoordinates(session_id=session_id, url=url)
    session = ClientSession(session_id=coords.session_id, websocket_url=websocket_url_for_server_url(coords.url), io_loop=io_loop)
    session.push(document)
    return session
Create a session by pushing the given document to the server,
    overwriting any existing server-side document.

    ``session.document`` in the returned session will be your supplied
    document. While the connection to the server is open, changes made on the
    server side will be applied to this document, and changes made on the
    client side will be synced to the server.

    In a production scenario, the ``session_id`` should be unique for each
    browser tab, which keeps users from stomping on each other. It's neither
    scalable nor secure to use predictable session IDs or to share session
    IDs across users.

    For a notebook running on a single machine, ``session_id`` could be
    something human-readable such as ``"default"`` for convenience.

    If you allow ``push_session()`` to generate a unique ``session_id``, you
    can obtain the generated ID with the ``id`` property on the returned
    ``ClientSession``.

    Args:
        document : (bokeh.document.Document)
            The document to be pushed and set as session.document

        session_id : (string, optional)
            The name of the session, None to autogenerate a random one (default: None)

        url : (str, optional): The URL to a Bokeh application on a Bokeh server
            can also be `"default"` which will connect to the default app URL

        io_loop : (tornado.ioloop.IOLoop, optional)
            The IOLoop to use for the websocket

    Returns:
        ClientSession
            A new ClientSession connected to the server