jayhack / prefect

The easiest way to coordinate your dataflow

Home Page:https://prefect.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Block editor UI breaks when a block field is `Union` of Pydantic model and string

jayhack opened this issue · comments

First check

  • I added a descriptive title to this issue.
  • I used the GitHub search to find a similar issue and didn't find it.
  • I searched the Prefect documentation for this issue.
  • I checked that this issue is related to Prefect and not one of its dependencies.

Bug summary

When a block class defined in Python contains a Field whose type is a Union of a Pydantic BaseModel (or anything that subclasses it, like a block) and str, a UI error occurs when you toggle from to the model to the string and back again.

More broadly, it looks like this happens when one of the members of the union maps to a JavaScript object, and another member of the union maps to a JavaScript string (which includes some built-in Pydantic types like AnyUrl). The error does not happen if the type maps a non-string JS primitive type like boolean or number.

Here's an example showing SqlAlchemyConnector in the Prefect Cloud UI:

UI Error Video

Here's what I see in the DevTools console:
Screenshot 2023-03-17 at 11 19 02 AM

See below for block code to reproduce the error. You can register the block to view it in the UI by saving the code in a Python file and then running prefect block register -f <filename>:

It will exhibit the same behavior shown in the video, and the same happens if you change Union[BrokenModel, str] to Union[BrokenModel, AnyUrl].

Reproduction

from typing import Union

from prefect.blocks.core import Block
from pydantic import AnyUrl, BaseModel, Field, SecretStr


class BrokenModel(BaseModel):
    name: str = Field(..., description="The name of the user")
    password: SecretStr = Field(..., description="The password of the user")
    happiness_rating: int = Field(..., description="The happiness rating of the user, where 0 is existential dread and 10 is bliss")


class BrokenBlock(Block):
    _block_type_name = "Broken UI"
    name: str = Field(..., description="The name of the block")
    broken: Union[BrokenModel, str] = Field(..., description="The broken field")

Error

No response

Versions

Prefect Cloud API, Prefect 2.8.5 client

Additional context

No response