How to parse mem_lim and cpu_lim using options_form in DockerSpawner?

Hello everyone,

I am a newbie in using Jupyterhub, and I am trying to understand how to parse parameters to the Spawner. More specifically, I would like to read cpu_lim and mem_lim through parameters parsed from options_form.

I came out with a test configuration file, where I am trying to parse only mem_lim:

import shlex
from dockerspawner import DockerSpawner

c = get_config()

class DemoFormSpawner(DockerSpawner):
    default_memo_lim = "1G"

    def _options_form_default(self):
        return """
        <div class="form-group">
            <label for="args">Extra notebook CLI arguments</label>
            <input name="args" class="form-control"
                placeholder="e.g. --debug"></input>
        <div class="form-group">
         <label for="memo_lim">Memory Limit:</label>
         <input type="text" id="memo_lim" name="memo_lim"></input>

    def options_from_form(self, formdata):
        self.log.debug("Executing options_from_form")
        options = {}
        memo_lim = formdata.get('memo_lim', [''])[0].strip()
        options["memo_lim"] = shlex.split(memo_lim) if memo_lim else []
        print("MEM Limit:", options["memo_lim"])
        arg_s = formdata.get('args', [''])[0].strip()
        if arg_s:
            options['argv'] = shlex.split(arg_s)
            print("Extra CLI Arguments:", options['argv'])
        return options

    def get_args(self):
        """Return arguments to pass to the notebook server"""
        argv = super().get_args()
        if self.user_options.get('argv'):
        return argv

    def get_memo(self):
        memo_lim = self.default_memo_lim  
        if self.user_options.get('memo_lim'):
        return memo_lim

c.JupyterHub.spawner_class = DemoFormSpawner
spawner_instance = c.JupyterHub.spawner_class()
memo_limit = spawner_instance.get_mem_limit()

When running the script, I am noticing that spawner_instance.get_mem_limit() is called before options_from_form.

Few questions:

  1. Is it actually possible to perform these tasks using the DockerSpawner?
  2. If it is possible, how can I parse memo_lim from CustoDockerSpawner to the variable called memory_limit?
  3. Are there alternative way that I am not aware of?

Thanks in advance for any feedback! :slight_smile:

Can you try with this snippet? I m not sure if it works, but config should be something like this.

In your config, you are instantiating an object out of spawner class and calling get_memo() directly on it. You should provide just the class and it is JupyterHub’s responsibility to instantiate spawner object and call the methods properly to parse the options from form before spawning a single user server.

Thank you for your answer!

The snippet works with the only difference that I need to remove async from start:

  def start(self):
        self.log.debug("Current memory limit: %s", self.get_memo())
        return super().start()

I have modified the function including mem_lim inside start, I will now check if the parameters are correctly parsed:

  def start(self):
        self.log.debug("Current memory limit: %s", self.get_memo())
        return super().start()

It seems to work! :grin:

1 Like