A new way to write ObjectType with python3's annotation
See original GitHub issueThis issue is a feature discussion.
For now, the way to write a ObjectType is as below:
class Hero(ObjectType):
name = Field(List(String), only_first_name=Boolean())
age = Int()
def resolve_name(self, info, only_first_name=False):
if only_first_name:
return [self._first_name]
return [self._first_name, self._last_name]
def resolve_age(self, info):
return self._age
I define name twice (Hero.name
and Hero.resolve_name
) because I have to define types of arguments and return value. This will cause some reading and writing problems.
Since python3, annotation feature bring a native way to describe types. By using annotation, we can rewrite this class with a clearer way:
class Heroine(AnnotationObjectType):
def name(self, info, only_first_name: Boolean() = False) -> List(String):
if only_first_name:
return [self._first_name]
return [self._first_name, self._last_name]
def age(self, info) -> Int():
return self._age
print(Heroine.name.__annotations__)
# {'only_first_name': <graphene.types.scalars.Boolean object at 0x104cb8550>, 'return': <graphene.types.structures.List object at 0x105742f28>}
AnnotationObjectType
shouldn’t be difficult to write if we somehow transform it into ObjectType
. But I think a looooot of cases should be tested before being released.
Of cause even if we write an AnnotationObjectType
class, ObjectType
class will not be dropped since python2.7 doesn’t support annotation.
I would like to hear you guys’ comments and suggestions before doing this.
Issue Analytics
- State:
- Created 5 years ago
- Reactions:29
- Comments:28 (7 by maintainers)
Top GitHub Comments
@ocavue thanks for opening the discussion.
The new resolution syntax on Graphene 2
root, info, **options
was took specially with typing in mind, so it could be very easy to annotate the resolver arguments in the future.Personally, I do really like the way
NamedTuple
works in thetyping
package for defining the attributes for the named tuple: https://docs.python.org/3/library/typing.html#typing.NamedTuple In Python 3.7 onwards, the@dataclass
attribute will let the user create a data class very easily: https://www.python.org/dev/peps/pep-0557/Inspired in all this I think the next version of Graphene (Graphene 3.0) could also allow developers to type their schemas like the following: (while maintaining 100% compatibility with the previous syntax)
There are some reasons on why I think this is a very powerful syntax:
self
in resolvers (currently, on Graphene 2,self
is referring to the root object, automatically marking the resolver as a@staticmethod
… and sometimes this might be confusing)However, there are some cons of this approach:
Optional[T] = Union[T, None]
*, Optional types will need to be explicitly defined and being required will be the default.ObjectType
have other attributes annotated (that we don’t want to expose to GraphQL) they will be exposed automatically. We can solve this in various ways:_
(private) to GraphQLWhat are your thoughts?
Looks like someone already thought of combining Pydantic and Graphene… https://github.com/upsidetravel/graphene-pydantic