4cat icon indicating copy to clipboard operation
4cat copied to clipboard

Allow dynamic form options in processors

Open stijn-uva opened this issue 2 years ago • 3 comments

This PR adds a setting to processor options, requires, which controls the visibility of the option. For example, this could be used to only make a field asking for an API key appear if a processor option that necessitates the use of that API is chosen:

options = {
  "model": {
    "type": UserInput.OPTION_CHOICE,
    "help": "LLM to use for analysis",
    "options": {
        "openai": "Use OpenAI LLM",
        "local": "Use LLM running on local GPU"
    }
  },
  "apikey": {
    "type": UserInput.OPTION_TEXT,
    "help": "OpenAI API key",
    "requires": "model=openai"
  }
}

In this example, the 'apikey' control would only be available if 'Use OpenAI LLM' is chosen in the first option.

There is a limited set of other syntaxes to use for the requires setting:

  • "requires": "model": Enable if model is not empty, or (in the case of a boolean/checkbox) not False. Equivalent to "requires": "model!=".
  • "requires": "model=openai": Enable if model is openai.
  • "requires": "model!=openai": Enable if model is not openai.
  • "requires": "model~=openai": Enable if model contains openai.
  • "requires": "model^=openai": Enable if model starts with openai.
  • "requires": "model$=openai": Enable if model ends with openai.

If the requires condition is not met, the processor behaves as if the option does not exist at all, i.e. no value is stored for it.

Behaviour for options whose requires condition involves the value of other options with a requires setting is undefined (i.e. you shouldn't do that).

stijn-uva avatar Nov 17 '23 12:11 stijn-uva

Could you clarify "Behaviour for options whose requires condition involves the value of other options with a requires setting is undefined (i.e. you shouldn't do that)."? Does that mean you cannot have a setting which requires another setting with a requires statement or something else? E.g., you could not chain options.

dale-wahl avatar Nov 20 '23 11:11 dale-wahl

Yes, nested conditionals are not supported (currently they may or may not work).

stijn-uva avatar Nov 20 '23 11:11 stijn-uva

Uhhhhhhh.

So, datasources fail with Invalid datasource if they use the requires in an option. Only for non admin users so I did not notice for awhile! They fail here: https://github.com/digitalmethodsinitiative/4cat/blob/c5fbe02f59111050bc6c2be3d35cb6493e0eb93a/webtool/templates/components/create-dataset-option.html#L22 due to current_user.get_attribute(settings.requires) with jinja2.exceptions.UndefinedError: 'common.lib.user.User object' has no attribute 'get_attribute'.

Ok, the get_attribute function was presumably removed at some point. But what is that line supposed to be doing? I think, it actually had to do with this: https://github.com/digitalmethodsinitiative/4cat/blob/c5fbe02f59111050bc6c2be3d35cb6493e0eb93a/datasources/reddit/search_reddit.py#L48 That line appears to have nothing to do with this new requires field. I think this line in create-dataset-option.html was using it.

I think the line in create-dataset-option can be removed and we remove/rename that Reddit option. I'm guess that current_user.get_attribute() was changed and works differently in adding tags and this error just happens to be triggered in this PR since we happened to use option['requires'] for this!

Let me know if that makes any sense to you and if you think we can safely remove line 22 in create-dataset-option.html.

dale-wahl avatar Jan 18 '24 11:01 dale-wahl