fractal-analytics-platform / fractal-web

Web client for Fractal
https://fractal-analytics-platform.github.io/fractal-web/
BSD 3-Clause "New" or "Revised" License
6 stars 0 forks source link

Sandbox vs webclient behavior for nested arguments #538

Closed tcompa closed 2 months ago

tcompa commented 2 months ago

With @zonia3000 we reviewed and now better understand the difference between the sandbox and the webclient (ref #537). The brief explanation is that the backend most often provides some initial arguments data, while the sandbox typically uses empty data. This does not seem related to any recent change in fractal-web, but it became evident due to recent fractal-tasks-core updates (notably as of fractal-tasks-core 1.1.0, 1.1.1 and 1.2.0 versions, where the cellpose-task call signature was changed).

Side note: this unexpected difference probably already entered previous discussions, e.g. in this comment.


Current status:


Improvements

  1. Short term, we should at least make the sandbox mimic what the backend does - by prepopulating the top-level defaults in data.

  2. On the backend side, I think we could deprecate this pre-populating feature. It's TBD, but my first guess is that this is a legacy feature that made sense when we were mostly using CLI clients and didn't want to write down a lot of arguments.

    • Even if this is a reasonable change, it will not affect the current discussion. The only result will be to postpone the switch from case A to case B, which will likely still take place after a few user interactions.
  3. More complex, but clearly relevant, we can review the way fractal-web displays defaults of nested arguments.


[continues with an example]

tcompa commented 2 months ago

The following example fully reproduces the issue in https://github.com/fractal-analytics-platform/fractal-web/issues/537 within the sandbox, with no need to use actual server/client instances.


We use this python script

import json
from typing import Optional

from pydantic import validate_call, BaseModel, Field
from fractal_tasks_core.dev.lib_args_schemas import create_schema_for_single_task

class ComplexArg(BaseModel):
    sub_attr_1: int = 99

@validate_call
def task_function(
        arg_A: ComplexArg = Field(default_factory=ComplexArg),
        arg_B: int = 1,
        ):
    """
    Short task description

    Args:
        arg_A: Description of arg_A.
        arg_B: Description of arg_B.
    """
    pass

schema = create_schema_for_single_task(
    task_function=task_function,
    executable=__file__,
    package=None,
)
print(json.dumps(schema, indent=2))

and generate this schema

{
  "$defs": {
    "ComplexArg": {
      "properties": {
        "sub_attr_1": {
          "default": 99,
          "title": "Sub Attr 1",
          "type": "integer"
        }
      },
      "title": "ComplexArg",
      "type": "object",
      "description": "Missing description for ComplexArg."
    }
  },
  "additionalProperties": false,
  "properties": {
    "arg_A": {
      "$ref": "#/$defs/ComplexArg",
      "title": "Arg A",
      "description": "Description of arg_A."
    },
    "arg_B": {
      "default": 1,
      "title": "Arg B",
      "type": "integer",
      "description": "Description of arg_B."
    }
  },
  "type": "object",
  "title": "TaskFunction"
}

If we use this schema in the sandbox without setting any JSON data (case A), we do see the 99 default: image

However, if we include the same schema and also set the data to

{
  "arg_B": 1
}

then we are back to case B, and we don't see 99 any more image

tcompa commented 2 months ago

This was fixed in fractal-server 1.3.6, where we stopped pre-populating the defaults from the backend. Refs

Right now, the behavior in the webclient when a task is added for the first time is the same as in the sandbox.