Only call spawner.auth_state_hook once
Bug description
I've been familiarizing myself with the code base for JupyterHub, and I noticed that spawner.auth_state_hook is called twice (once in jupyterhub.handlers.pages.SpawnHandler.get at this line and once at jupyterhub.user.User.spawn at this other line). This seems to open up a problem for any use cases where the spawner.auth_state_hook makes some changes that it only expects to make once. For example, I am using the spawner.auth_state_hook to update the spawner config with user specific settings, and one of the things I'm doing is appending to the profile_list to give some users additional options when spawning a server. However, with the current implementation, the items are appended to the profile list twice.
I think this was done to accommodate two use cases based on the discussion around https://github.com/jupyterhub/jupyterhub/pull/2881. First, it seems like there is a need to run the spawner.auth_state_hook before the options form is displayed (which I think is the right decision) leading to the use of jupyterhub.handlers.pages.SpawnHandler.get at this line, and then I think that there is a need to accommodate the case where someone sidesteps the traditional spawner page for some reason, leading to running it at jupyterhub.user.User.spawn at this other line. However, I think it is unnecessary to do this to accommodate both use cases.
I think that this can be fixed by adding the spawner.auth_state_hook during the creation of the spawner at jupyterhub.user.User._new_spawner. This should be called, to the best of my understanding, anytime a new spawner is created for a user. I think the hook could probably be called right after https://github.com/jupyterhub/jupyterhub/blob/fd28e224f2de5e7b525483330150988ec3e295c6/jupyterhub/user.py#L287
and hopefully everything should just work.
However, I am really quite new to the JupyterHub code base, and I don't want to assume I understand the reasons for the code being written the way it is. If this seems like a reasonable fix to what is a bug (and not intentional behavior for some reason), then I'll be happy to create a pull request with this minimal change.
Expected behaviour
I expect spawner.auth_state_hook to run exactly once.
Actual behaviour
spawner.auth_state_hook runs twice.
How to reproduce
Create a jupyterhub_config.py file with the following contents:
def test_function(spawner, auth_state):
print("Auth_state_hook")
c.Spawner.auth_state_hook = test_functionand then start jupyterhub using the config file. Spawn a server, you will see that "Auth_state_hook" appears twice in the logs.
Your personal set up
- OS: Mac OS
- Version: 1.1.0
- Configuration: See "steps to reproduce"
Source: jupyterhub/jupyterhub