'Internal implementation for adding session callbacks.
Args:
callback_obj (SessionCallback) :
A session callback object that wraps a callable and is
passed to ``trigger_on_change``.
callback (callable) :
A callable to execute when session events happen.
one_shot (bool) :
Whether the callback should immediately auto-remove itself
after one execution.
Returns:
SessionCallback : passed in as ``callback_obj``.
Raises:
ValueError, if the callback has been previously added'

def _add_session_callback(self, callback_obj, callback, one_shot):

    from .server.events import SessionCallbackAdded
    if (callback in self._session_callbacks):
        raise ValueError('callback    has    already    been    added')
    if one_shot:
        @wraps(callback)
        def remove_then_invoke(*args, **kwargs):
            if (callback in self._session_callbacks):
                obj = self._session_callbacks[callback]
                if (obj is callback_obj):
                    self._remove_session_callback(callback)
            return callback(*args, **kwargs)
        actual_callback = remove_then_invoke
    else:
        actual_callback = callback
    callback_obj._callback = self._wrap_with_self_as_curdoc(actual_callback)
    self._session_callbacks[callback] = callback_obj
    self._trigger_on_change(SessionCallbackAdded(self, callback_obj))
    return callback_obj
