4cat
4cat copied to clipboard
Allow dynamic form options in processors
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 ifmodelis not empty, or (in the case of a boolean/checkbox) notFalse. Equivalent to"requires": "model!="."requires": "model=openai": Enable ifmodelisopenai."requires": "model!=openai": Enable ifmodelis notopenai."requires": "model~=openai": Enable ifmodelcontainsopenai."requires": "model^=openai": Enable ifmodelstarts withopenai."requires": "model$=openai": Enable ifmodelends withopenai.
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).
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.
Yes, nested conditionals are not supported (currently they may or may not work).
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.