strawberry icon indicating copy to clipboard operation
strawberry copied to clipboard

Enum types from Pydantic models are not registered in GraphQL schema

Open merlinus1 opened this issue 2 years ago • 5 comments

If pydantic model contains Enum field this enum definition is not registered in GraphQL Schema

Running following code raises error:

import typing
from enum import Enum

import strawberry
from pydantic import BaseModel


class ModelTypeEnum(str, Enum):
    type_1 = "type_1"
    type_2 = "type_2"


class PydanticModel(BaseModel):
    name: str
    model_type: typing.Optional[ModelTypeEnum]


@strawberry.experimental.pydantic.type(model=PydanticModel, all_fields=True)
class StrawberryModel:
    pass


@strawberry.type
class Query:
    models: typing.List[StrawberryModel]


def get_models():
    return []


@strawberry.type
class Query:
    models: typing.List[StrawberryModel] = strawberry.field(resolver=get_models)


if __name__ == '__main__':
    schema = strawberry.Schema(query=Query)
Traceback (most recent call last):
  File "C:\Users\merlinus1\PycharmProjects\test_strawbery\main.py", line 38, in <module>
    schema = strawberry.Schema(query=Query)
  File "C:\Users\merlinus1\AppData\Local\pypoetry\Cache\virtualenvs\test-strawbery-ZCOgkqdC-py3.9\lib\site-packages\strawberry\schema\schema.py", line 84, in __init__
    self._schema = GraphQLSchema(
  File "C:\Users\merlinus1\AppData\Local\pypoetry\Cache\virtualenvs\test-strawbery-ZCOgkqdC-py3.9\lib\site-packages\graphql\type\schema.py", line 208, in __init__
    collect_referenced_types(query)
  File "C:\Users\merlinus1\AppData\Local\pypoetry\Cache\virtualenvs\test-strawbery-ZCOgkqdC-py3.9\lib\site-packages\graphql\type\schema.py", line 423, in collect_referenced_types
    collect_referenced_types(field.type)
  File "C:\Users\merlinus1\AppData\Local\pypoetry\Cache\virtualenvs\test-strawbery-ZCOgkqdC-py3.9\lib\site-packages\graphql\type\schema.py", line 422, in collect_referenced_types
    for field in named_type.fields.values():
  File "C:\Program Files\Python39\lib\functools.py", line 993, in __get__
    val = self.func(instance)
  File "C:\Users\merlinus1\AppData\Local\pypoetry\Cache\virtualenvs\test-strawbery-ZCOgkqdC-py3.9\lib\site-packages\graphql\type\definition.py", line 737, in fields
    raise TypeError(f"{self.name} fields cannot be resolved. {error}")
TypeError: StrawberryModel fields cannot be resolved. _enum_definition

Manually registering enum fixes error:

strawberry.enum(ModelTypeEnum)

But maybe enum has to be auto registered? Probably in replace_pydantic_types method https://github.com/strawberry-graphql/strawberry/blob/7738ceacf10c928f3bae7e00184286cc245ed2bc/strawberry/experimental/pydantic/object_type.py#L47

if issubclass(type_, Enum):
    strawberry.enum(type_)

merlinus1 avatar Jan 27 '22 09:01 merlinus1

Facing the same issue. In the meantime, I will register the types manually. Thanks for the insight!

checor avatar Feb 02 '22 05:02 checor

+1 Facing the same issue.

In my case I had a a list of enum types: List[EnumType] as a field type so the above solution did not work out of the box. I ended up adding the following at the top of replace_pydantic_types to get this to work:

import inspect

def replace_pydantic_types(type_: Any, is_input: bool):
    if inspect.isclass(type_) and issubclass(type_, Enum):
        return strawberry.enum(type_)

    ...

motherofcoconuts avatar Apr 24 '22 10:04 motherofcoconuts

+1 Facing the same issue.

In my case I had a a list of enum types: List[EnumType] as a field type so the above solution did not work out of the box. I ended up adding the following at the top of replace_pydantic_types to get this to work:

import inspect

def replace_pydantic_types(type_: Any, is_input: bool):
    if inspect.isclass(type_) and issubclass(type_, Enum):
        return strawberry.enum(type_)

    ...

@motherofcoconuts let me investigate this, manually registering should have worked. Whats your strawberry version? Could you have a small example to replicate?

thejaminator avatar Apr 25 '22 11:04 thejaminator

+1 Facing the same issue. In my case I had a a list of enum types: List[EnumType] as a field type so the above solution did not work out of the box. I ended up adding the following at the top of replace_pydantic_types to get this to work:

import inspect

def replace_pydantic_types(type_: Any, is_input: bool):
    if inspect.isclass(type_) and issubclass(type_, Enum):
        return strawberry.enum(type_)

    ...

@motherofcoconuts let me investigate this, manually registering should have worked. Whats your strawberry version? Could you have a small example to replicate?

same issue here strawberry-graphql = "0.112.0"

*update: fixed by adding @strawberry.enum to Enum class image

SuHotdog avatar Jun 01 '22 16:06 SuHotdog

@motherofcoconuts let me investigate this, manually registering should have worked. Whats your strawberry version? Could you have a small example to replicate?

Sorry for the delayed response, must of missed this.

Version = 0.114.1 Fix: I put the following lines in my __init__.py

super_rpt = strawberry.experimental.pydantic.fields.replace_pydantic_types

def replace_pydantic_types(type_: Any, is_input: bool) -> Any:
    if inspect.isclass(type_) and issubclass(type_, Enum):
        return strawberry.enum(type_)
    return super_rpt(type_, is_input)

strawberry.experimental.pydantic.fields.replace_pydantic_types = replace_pydantic_types

The example @merlinus1 gives is a perfect example of the error. Copy and paste my fix to the top of that solution and the error disappears without having to register each type to the schema. Registering each type to the schema manually is something i want to avoid as i use ALOT of enums in my application.

motherofcoconuts avatar Jun 11 '22 08:06 motherofcoconuts

when will this be resolved?

cat-turner avatar Jan 24 '23 08:01 cat-turner

@cat-turner Hi, we can fix this by manually registering the enum / decorating the enum class with @strawberry.enum.

Do you mean you are looking for an automatic enum registering feature?

There is a documentation here by Patrick, the creator of strawberry, on how to register an enum. This will fix it for now.

  • https://github.com/strawberry-graphql/strawberry/blob/main/docs/errors/object-is-not-an-enum.md

shipitparrotclemz avatar Feb 18 '23 12:02 shipitparrotclemz