strawberry
strawberry copied to clipboard
Enum types from Pydantic models are not registered in GraphQL schema
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_)
Facing the same issue. In the meantime, I will register the types manually. Thanks for the insight!
+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_)
...
+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 ofreplace_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?
+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 ofreplace_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
@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.
when will this be resolved?
@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