Skip to content

Commit

Permalink
Add typing to resolver info
Browse files Browse the repository at this point in the history
  • Loading branch information
bellini666 committed Oct 17, 2021
1 parent 9ae2d4c commit 5842517
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 25 deletions.
40 changes: 20 additions & 20 deletions graphene_django_plus/mutations.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from .models import GuardedModel
from .perms import check_authenticated, check_perms
from .settings import graphene_django_plus_settings
from .types import MutationErrorType, UploadType, schema_for_field, schema_registry
from .types import MutationErrorType, ResolverInfo, UploadType, schema_for_field, schema_registry
from .utils import get_model_fields, get_node, get_nodes, update_dict_nested

_registry = get_global_registry()
Expand Down Expand Up @@ -225,7 +225,7 @@ def __init_subclass_with_meta__(
@classmethod
def get_node(
cls,
info,
info: ResolverInfo,
node_id: str,
field: str = "id",
only_type: Optional[ObjectType] = None,
Expand All @@ -247,9 +247,9 @@ def get_node(
@classmethod
def get_nodes(
cls,
info,
info: ResolverInfo,
ids: List[str],
field: str,
field: str = "ids",
only_type: Optional[ObjectType] = None,
) -> List[Any]:
"""Get a list of node objects given a list of relay global ids."""
Expand All @@ -261,7 +261,7 @@ def get_nodes(
return instances

@classmethod
def check_permissions(cls, info) -> bool:
def check_permissions(cls, info: ResolverInfo) -> bool:
"""Check permissions for the given user.
Subclasses can override this to avoid the permission checking or
Expand All @@ -278,7 +278,7 @@ def check_permissions(cls, info) -> bool:
return check_perms(user, cls._meta.permissions, any_perm=cls._meta.permissions_any)

@classmethod
def mutate_and_get_payload(cls: Type[_M], root, info, **data) -> _M:
def mutate_and_get_payload(cls: Type[_M], root, info: ResolverInfo, **data) -> _M:
"""Mutate checking permissions.
We override the default graphene's method to call
Expand All @@ -305,7 +305,7 @@ def mutate_and_get_payload(cls: Type[_M], root, info, **data) -> _M:
return cls(errors=[MutationErrorType(message=msg)])

@classmethod
def perform_mutation(cls: Type[_M], root, info, **data) -> _M:
def perform_mutation(cls: Type[_M], root, info: ResolverInfo, **data) -> _M:
"""Perform the mutation.
This should be implemented in subclasses to perform the mutation.
Expand Down Expand Up @@ -410,7 +410,7 @@ def __init_subclass_with_meta__(
@classmethod
def check_object_permissions(
cls,
info,
info: ResolverInfo,
instance: _T,
) -> bool:
"""Check object permissions for the given user.
Expand All @@ -435,7 +435,7 @@ def check_object_permissions(
)

@classmethod
def get_instance(cls, info, obj_id: str) -> _T:
def get_instance(cls, info: ResolverInfo, obj_id: str) -> _T:
"""Get an object given a relay global id."""
model_type = _registry.get_type_for_model(cls._meta.model)
instance = cls.get_node(info, obj_id, only_type=model_type)
Expand All @@ -444,7 +444,7 @@ def get_instance(cls, info, obj_id: str) -> _T:
return cast(_T, instance)

@classmethod
def before_save(cls, info, instance: _T, cleaned_input: Dict[str, Any]):
def before_save(cls, info: ResolverInfo, instance: _T, cleaned_input: Dict[str, Any]):
"""Perform "before save" operations.
Override this to perform any operation on the instance
Expand All @@ -453,7 +453,7 @@ def before_save(cls, info, instance: _T, cleaned_input: Dict[str, Any]):
pass

@classmethod
def after_save(cls, info, instance: _T, cleaned_input: Dict[str, Any]):
def after_save(cls, info: ResolverInfo, instance: _T, cleaned_input: Dict[str, Any]):
"""Perform "after save" operations.
Override this to perform any operation on the instance
Expand All @@ -462,7 +462,7 @@ def after_save(cls, info, instance: _T, cleaned_input: Dict[str, Any]):
pass

@classmethod
def save(cls, info, instance: _T, cleaned_input: Dict[str, Any]):
def save(cls, info: ResolverInfo, instance: _T, cleaned_input: Dict[str, Any]):
"""Save the instance to the database.
To do something with the instance "before" or "after" saving it,
Expand Down Expand Up @@ -491,7 +491,7 @@ def save(cls, info, instance: _T, cleaned_input: Dict[str, Any]):
cls.after_save(info, instance, cleaned_input=cleaned_input)

@classmethod
def before_delete(cls, info, instance: _T):
def before_delete(cls, info: ResolverInfo, instance: _T):
"""Perform "before delete" operations.
Override this to perform any operation on the instance
Expand All @@ -500,7 +500,7 @@ def before_delete(cls, info, instance: _T):
pass

@classmethod
def after_delete(cls, info, instance: _T):
def after_delete(cls, info: ResolverInfo, instance: _T):
"""Perform "after delete" operations.
Override this to perform any operation on the instance
Expand All @@ -509,7 +509,7 @@ def after_delete(cls, info, instance: _T):
pass

@classmethod
def delete(cls, info, instance: _T):
def delete(cls, info: ResolverInfo, instance: _T):
"""Delete the instance from the database.
To do something with the instance "before" or "after" deleting it,
Expand Down Expand Up @@ -550,7 +550,7 @@ class Meta:
abstract = True

@classmethod
def create_instance(cls, info, instance: _T, cleaned_data: Dict[str, Any]) -> _T:
def create_instance(cls, info: ResolverInfo, instance: _T, cleaned_data: Dict[str, Any]) -> _T:
"""Create a model instance given the already cleaned input data."""
opts = instance._meta

Expand All @@ -574,7 +574,7 @@ def create_instance(cls, info, instance: _T, cleaned_data: Dict[str, Any]) -> _T
return instance

@classmethod
def clean_instance(cls, info, instance: _T, clean_input: Dict[str, Any]) -> _T:
def clean_instance(cls, info: ResolverInfo, instance: _T, clean_input: Dict[str, Any]) -> _T:
"""Validate the instance by calling its `.full_clean()` method."""
try:
instance.full_clean(exclude=cls._meta.exclude_fields)
Expand All @@ -585,7 +585,7 @@ def clean_instance(cls, info, instance: _T, clean_input: Dict[str, Any]) -> _T:
return instance

@classmethod
def clean_input(cls, info, instance: _T, data: Dict[str, Any]):
def clean_input(cls, info: ResolverInfo, instance: _T, data: Dict[str, Any]):
"""Clear and normalize the input data."""
cleaned_input: Dict[str, Any] = {}

Expand Down Expand Up @@ -614,7 +614,7 @@ def clean_input(cls, info, instance: _T, data: Dict[str, Any]):

@classmethod
@transaction.atomic
def perform_mutation(cls: Type[_MM], root, info, **data) -> _MM:
def perform_mutation(cls: Type[_MM], root, info: ResolverInfo, **data) -> _MM:
"""Perform the mutation.
Create or update the instance, based on the existence of the
Expand Down Expand Up @@ -694,7 +694,7 @@ class Meta:

@classmethod
@transaction.atomic
def perform_mutation(cls: Type[_MM], root, info, **data) -> _MM:
def perform_mutation(cls: Type[_MM], root, info: ResolverInfo, **data) -> _MM:
"""Perform the mutation.
Delete the instance from the database given its `id` attribute
Expand Down
5 changes: 3 additions & 2 deletions graphene_django_plus/queries.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import graphene

from .types import ResolverInfo
from .types import SchemaType, schema_registry


Expand All @@ -23,9 +24,9 @@ class Query:
)

@staticmethod
def resolve_gql_object_schema(root, info, object_type, **kwargs):
def resolve_gql_object_schema(root, info: ResolverInfo, object_type: str):
return schema_registry.get(object_type, None)

@staticmethod
def resolve_gql_object_schema_all(root, info, **kwargs):
def resolve_gql_object_schema_all(root, info: ResolverInfo):
return sorted(schema_registry.values(), key=lambda obj: obj["object_type"])
16 changes: 13 additions & 3 deletions graphene_django_plus/types.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import datetime
import decimal
from typing import TYPE_CHECKING, Generic, List, Optional, TypeVar, Union
from typing import TYPE_CHECKING, Any, Generic, List, Optional, TypeVar, Union

from django.contrib.auth.models import AbstractUser, AnonymousUser
from django.core.exceptions import ImproperlyConfigured
from django.db import models
from django.db.models import Prefetch
from django.db.models.fields import NOT_PROVIDED
from django.db.models.fields.reverse_related import ManyToManyRel, ManyToOneRel
from django.http import HttpRequest as DJHttpRequest
import graphene
from graphene.utils.str_converters import to_camel_case
from graphene_django import DjangoObjectType
from graphene_django.converter import get_choices
from graphene_django.types import DjangoObjectTypeOptions
from graphql.execution.base import ResolveInfo

try:
import graphene_django_optimizer as gql_optimizer
Expand Down Expand Up @@ -92,6 +94,14 @@ def schema_for_field(field, name):
return s


class HttpRequest(DJHttpRequest):
user: Union[AbstractUser, AnonymousUser]


class ResolverInfo(ResolveInfo):
context: HttpRequest


class MutationErrorType(graphene.ObjectType):
"""An error that happened in a mutation."""

Expand Down Expand Up @@ -359,7 +369,7 @@ def __init_subclass_with_meta__(
def get_queryset(
cls,
qs: Union[models.QuerySet[_T], models.Manager[_T]],
info,
info: ResolverInfo,
) -> models.QuerySet[_T]:
"""Get the queryset checking for permissions and optimizing the query.
Expand Down Expand Up @@ -397,7 +407,7 @@ def get_queryset(
return ret

@classmethod
def get_node(cls, info, id_) -> Optional[_T]:
def get_node(cls, info: ResolverInfo, id_: Any) -> Optional[_T]:
"""Get the node instance given the relay global id."""
# NOTE: get_queryset will filter allowed models for the user so
# this will return None if he is not allowed to retrieve this
Expand Down

0 comments on commit 5842517

Please sign in to comment.