ExtensionApp’s config object is empty

In the Jupyter Server docs it states that the config property of the ExtensionApp instance should contain the ExtensionApp’s config object. However, when I print the config object it is empty (Server Extensions — Jupyter Server 1.11.0.dev0 documentation).

I expected to find the contents of jupyter_{name}_config.json in this object. Interestingly, I do find the contents of jupyter_{name}_config.json in the server_config property of the MyExtensionHandler(ExtensionHandlerMixin, JupyterHandler) instance. As such, at least I am sure that jupyter_{name}_config.json is getting found and loaded.

I chased it down to the HasTraits class, but the code gets pretty complicated there, so I was lost.

Can anyone provide any guidance on this?

1 Like

I think this bit of documentation refers to ExtensionApp's request handlers and not to ExtensionApp itself. In particular the ExtensionHandlerMixin is the provider of config for extension handler. Does it help?

Thank you (again). The documentation states, " *config : the ExtensionApp’s config object." Do you know what this actually means? I thought it meant that it would contain the contents of the extension config file.

It looks like this is where the config gets constructed: jupyter_server/application.py at a0f98a0f1a3bc6567ca0a4d64954d1ac5ab1f127 · jupyter-server/jupyter_server · GitHub

It’s not clear to me what the config property of the request handler instance is for and it’s also unclear to me why the contents of jupyter_{name}_config.json are in the server_config property of the settings dict.

I thought it meant that it would contain the contents of the extension config file.

I would think so too.

It’s not clear to me what the config property of the request handler instance is for and it’s also unclear to me why the contents of jupyter_{name}_config.json are in the server_config property of the settings dict.

Maybe the name of your extension in ExtensionApp is set to "server"? See Server Extensions — Jupyter Server 1.11.0.dev0 documentation.

That’s an interesting explanation, however I set the name to the name of the extension, (i.e., etc_jupyterlab_telemetry_extension). If you have time, please have a look at my ExtensionApp: etc_jupyterlab_telemetry_extension/etc_jupyterlab_telemetry_extension.py at 2f256ea2f9f5e0a3c1ea76071b5078a596a29476 · educational-technology-collective/etc_jupyterlab_telemetry_extension · GitHub

When I print('ConfigRouteHandler#config', self.config) in the ConfigRouteHandler, it displays an empty object.

1 Like

Your code looks good to me, but I have little knowledge of jupyter_server and traitlets so I may be missing something. I would try adding some print statements/logging.warns to a few places in jupyter_server/application.py at 05913dd7a35662f48907fddefa0edf6a5a674e07 · jupyter-server/jupyter_server · GitHub and jupyter_core/application.py at e21f003d4ea48a2119e526f7057edf79b2fad42e · jupyter/jupyter_core · GitHub which touch config_file.

1 Like

@adpatter, looking at your ExtensionApp, here; your application doesn’t have any configurable traits, so this config object should be empty.

A trait looks something like this:

from traitlets import Unicode

class ETCJupyterLabTelemetryExtension(ExtensionApp):
    ...
    my_trait = Unicode(default_value="hello").tag(config=True)


2 Likes

Also, if an ExtensionApp receives traits from its configuration file that it doesn’t recognize, it will pass those traits “upward” to its parent class (in this case, that’s the ServerApp). Because you haven’t tagged any traits as config=True, all values in this file will be passed to the ServerApp. I believe that’s what you’re seeing here.

Traitlets is a very difficult library to learn, so keep these questions coming!

1 Like

@Zsailer @krassowski Wow. These Traitlets are pretty cool. Yeah, I had misconceptualized how they work.

I was able to use the following trait in order to load the config file shown below into the self.config of the ETCJupyterLabTelemetryExtension instance.

etc_jupyterlab_telemetry_extension = Dict(value_trait=Dict(value_trait=Bool(), key_trait=Unicode()), key_trait=Unicode()).tag(config=True)

The config file named: jupyter_etc_jupyterlab_telemetry_extension_config.json:

{
    "ETCJupyterLabTelemetryExtension": {
        "etc_jupyterlab_telemetry_extension": {
            "mentoracademy.org/schemas/events/1.0.0/NotebookSaveEvent": {
                "enable": true
            },
            "mentoracademy.org/schemas/events/1.0.0/NotebookOpenEvent": {
                "enable": true
            },
            "mentoracademy.org/schemas/events/1.0.0/CellRemoveEvent": {
                "enable": true
            },
            "mentoracademy.org/schemas/events/1.0.0/CellAddEvent": {
                "enable": true
            },
            "mentoracademy.org/schemas/events/1.0.0/CellExecutionEvent": {
                "enable": true
            },
            "mentoracademy.org/schemas/events/1.0.0/NotebookScrollEvent": {
                "enable": true
            },
            "mentoracademy.org/schemas/events/1.0.0/ActiveCellChangeEvent": {
                "enable": true
            }
        }
    }
}

NB: In order to figure out where the config file should go, use: jupyter --path (Configuring Extensions — Jupyter Server 1.11.0.dev0 documentation)