magicgui icon indicating copy to clipboard operation
magicgui copied to clipboard

user input validation

Open lufre1 opened this issue 1 year ago • 5 comments

A feature that checks the inputs given with a customizable logic. This would help e.g. to prevent code being executed that depends on several inputs but some inputs are missing. code example:

def validate(params):
    logic_for_desired_behavior
    ...

@magic_factory(
    pbar={"visible": False, "max": 0, "value": 0, "label": "working..."},
    call_button="Do something",
    save_path={"mode": "d"},  # choose a directory
    tile_shape_x={"min": 256, "max": 2048},
    tile_shape_y={"min": 256, "max": 2048},
    halo_x={"min": 0, "max": 2048},
    halo_y={"min": 0, "max": 2048},
    validate=validate, # <-- something like this
def function_that_uses_logic(
    save_path: Optional[Path] = None,  # where embeddings for this image are cached (optional)
    tile_shape_x: int = None,
    tile_shape_y: int = None,
    halo_x: int = None,
    halo_y: int = None,
):
    code_that_needs_all_inputs_to_be_executed
    ...

Is there something similar that I haven't found yet? The current solution would be to use exception handling.

lufre1 avatar Mar 08 '24 15:03 lufre1

Hi @lufre1, can you clarify the moment at which you would have the data validated?

The values coming from the widget should always be of the valid type, so, if you declared an int with a min/max for example, you should never receive anything from a widget that is invalid. However, that doesn't prevent you or a user from manually calling your function with invalid stuff. So, I'm interested to know a bit more about the use case that brought you to thinking about this feature request (i.e. under what circumstances did you hit invalid data)

Another comment is that validation is a huge ball of wax that appears at first to be simple (certainly for simple types), but ends up being complex. If you need validated data, I would suggest using pydantic or other similar libraries that perform validation and coercion. magicgui has experimental support for pydantic models (i.e. it can create a widget from a pydantic model), but at the moment, the functionality is not public and is a bit hard to find. See https://forum.image.sc/t/using-magicgui-to-create-pydantic-class-instances/92520 and https://forum.image.sc/t/building-a-napari-widget-from-a-pydantic-model/90257 for a bit more info on that

tlambert03 avatar Mar 08 '24 16:03 tlambert03

Hi @tlambert03, The feature I had in mind was not related to advanced data validation (pydantic models) or the restrictions to data types (e.g. int with min/max values).
I was thinking about a feature to "check" the inputs made by users before further processing (e.g. required fields or a brief check to see if the inputs are sufficient). Here is a example from web content management systems, in this case Drupal:

public function validateForm(array &$form, FormStateInterface $form_state) {
  if (strlen($form_state->getValue('phone_number')) < 3) {
    $form_state->setErrorByName('phone_number', $this->t('The phone number is too short. Please enter a full phone number.'));
  }
}

The intent is to inform the user via tiny messages of missing/incorrect inputs without the need for exception handling.

lufre1 avatar Mar 11 '24 10:03 lufre1

inputs made by users before further processing

If you mean inputs made by the user in the widgets, then yeah, I can see that as a good feature, but probably only for the string fields (line edits). All the other widgets should already be validated.

Does that fit with your expectations?

Qt, for example, does allow custom validators to be attached to line edits, and we could look into making that easier to hook into

tlambert03 avatar Mar 11 '24 11:03 tlambert03

Yes exactly, To make things clearer, here is another example of a use case with self-dependent inputs:

  • Shipping Address Form:
    • User chooses to have the parcel delivered instead of collecting it from the store
    • User enters their country in a dropdown menu.
    • Based on the chosen country, the form dynamically displays relevant state/province options (or removes them if not applicable).

For use cases like the one shown above, where the required fields are changed dynamically, it would be nice to have a hook like the one you mentioned. Additionally, it would also be nice that this feature is not limited to line edits (strings) but for all user inputs.

lufre1 avatar Mar 11 '24 12:03 lufre1

ok thanks. I think we've got a mutual vision now :)

Additionally, it would also be nice that this feature is not limited to line edits (strings) but for all user inputs.

i do think this might be a widget-specific consideration. for example, number widgets should already have all the info necessary such that it's impossible to get an invalid number. But, just for the sake of generality, i agree it could make sense to let all widgets take a user-provided validation function.

This is a relatively significant feature, so it will take some time to think about, but I agree on the need. thanks for the issue!

tlambert03 avatar Mar 11 '24 12:03 tlambert03