burr icon indicating copy to clipboard operation
burr copied to clipboard

pydantic: uninformative error

Open zilto opened this issue 1 year ago • 6 comments

I'm building an application with burr.integrations.pydantic and building the graph + application fails. The following error message isn't helpful because it exposes internal implementation (i.e., the key "state" is nowhere in my code.

Traceback (most recent call last):
  File "/home/tjean/projects/form_helper/app.py", line 45, in <module>
    @pydantic_action(reads=["form"], writes=["current_field"])
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/tjean/projects/form_helper/.venv/lib/python3.11/site-packages/burr/integrations/pydantic.py", line 180, in decorator
    itype, otype = _validate_and_extract_signature_types(fn)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/tjean/projects/form_helper/.venv/lib/python3.11/site-packages/burr/integrations/pydantic.py", line 116, in _validate_and_extract_signature_types
    if (state_model := type_hints["state"]) is inspect.Parameter.empty or not issubclass(
                       ~~~~~~~~~~^^^^^^^^^
KeyError: 'state'

The only hint is to look at "line 45", but I can't tell what's the issue. I ended up finding that the issue is the function signature on line 46.

Original:

@pydantic_action(reads=["form"], writes=["current_field"])
def prompt_user(state):

Fix:

@pydantic_action(reads=["form"], writes=["current_field"])
def prompt_user(state: BurrState):

zilto avatar Oct 03 '24 14:10 zilto

This should be as simple as throwing the appropriate error message here

elijahbenizzy avatar Oct 03 '24 15:10 elijahbenizzy

Hi @elijahbenizzy can't I just simply add:

state_model = type_hints.get("state", None)

in line 115 of pydantic.py and then change the if condition to raise ValueError

rajatkriplani avatar Oct 16 '24 18:10 rajatkriplani

here

Yep, I think that will work. In fact, you don't have to have the None there, you can just do .get(...) which returns None if it's not there!

elijahbenizzy avatar Oct 16 '24 18:10 elijahbenizzy

Yep, I think that will work. In fact, you don't have to have the None there, you can just do .get(...) which returns None if it's not there!

Oh yes, thanks for reminding me that. Please let me know if if statement is checking all the conditions correctly:

state_model = type_hints.get("state")

    if state_model is None or state_model is inspect.Parameter.empty or not issubclass(state_model, pydantic.BaseModel):
        raise ValueError(
            f"Function fn: {fn.__qualname__} is not a valid pydantic action. "
            "The 'state' parameter must be annotated with a type extending pydantic.BaseModel."
        )

rajatkriplani avatar Oct 16 '24 18:10 rajatkriplani

Hey @elijahbenizzy @zilto can anyone of you give me feedback on the if condition?

rajatkriplani avatar Oct 18 '24 00:10 rajatkriplani

Hey @elijahbenizzy @zilto can anyone of you give me feedback on the if condition?

Hey! Looks good at first glance. Open a PR and add some tests, then I can give you more feedback there!

elijahbenizzy avatar Oct 18 '24 01:10 elijahbenizzy