Skip to content

Instantly share code, notes, and snippets.

@Yankzy
Created June 28, 2024 23:30
Show Gist options
  • Select an option

  • Save Yankzy/dc2b3d0343586a52959ad0d8526bb726 to your computer and use it in GitHub Desktop.

Select an option

Save Yankzy/dc2b3d0343586a52959ad0d8526bb726 to your computer and use it in GitHub Desktop.
graphene custom scalar
import re
from typing import Any, Dict, List, Pattern, Type, Union
import graphene
from graphene.types import Scalar
from graphql.language import ast
class CustomScalar(Scalar):
@classmethod
def __init_subclass_with_meta__(cls, validate_pattern: str = None, **options):
super().__init_subclass_with_meta__(**options)
if validate_pattern:
cls.validate_pattern = re.compile(validate_pattern)
@classmethod
def serialize(cls, value: Any) -> Any:
cls.validate(value)
return value
@classmethod
def parse_value(cls, value: Any) -> Any:
cls.validate(value)
return value
@classmethod
def parse_literal(cls, node: ast.Node) -> Any:
if isinstance(node, (ast.StringValue, ast.IntValue, ast.FloatValue, ast.BooleanValue)):
value = node.value
cls.validate(value)
return value
return None
@classmethod
def validate(cls, value: Any) -> None:
if hasattr(cls, 'validate_pattern') and not cls.validate_pattern.match(str(value)):
raise ValueError(f"'{value}' is invalid for {cls.__name__}")
class Stringy(CustomScalar):
"""Custom string scalar"""
validate_pattern = re.compile(r'^[a-zA-Z\s]+$')
class Inty(CustomScalar):
"""Custom int scalar"""
validate_pattern = re.compile(r'^\d+$')
@classmethod
def serialize(cls, value: int) -> int:
cls.validate(value)
return int(value)
@classmethod
def parse_value(cls, value: Union[str, int]) -> int:
cls.validate(value)
return int(value)
class Floaty(CustomScalar):
"""Custom float scalar"""
validate_pattern = re.compile(r'^[+-]?([0-9]+([.][0-9]*)?)$')
@classmethod
def serialize(cls, value: float) -> float:
cls.validate(value)
return float(value)
@classmethod
def parse_value(cls, value: Union[str, float]) -> float:
cls.validate(value)
return float(value)
class Booly(CustomScalar):
"""Custom boolean scalar"""
validate_pattern = re.compile(r'^true|false$', re.IGNORECASE)
@classmethod
def serialize(cls, value: bool) -> bool:
return bool(value)
@classmethod
def parse_value(cls, value: Union[str, bool]) -> bool:
if isinstance(value, str):
cls.validate(value)
return value.lower() == 'true'
return bool(value)
class Idy(CustomScalar):
"""Custom ID scalar"""
validate_pattern = re.compile(r'^[a-zA-Z\d]+$')
class Usage(graphene.Mutation):
to_return = graphene.List('UsageType')
class Arguments:
name = Stringy(required=True)
email = Stringy(required=True, validate_pattern=r'^[a-z0-9]+[\._]?[a-z0-9]+[@]\w+[.]\w{2,3}$')
id = Idy(required=True)
floaty = Floaty(required=True)
booly = Booly(required=True)
inty = Inty(required=True)
def mutate(self, info, **kwargs):
return Usage(to_return=Model.objects.get(email=kwargs['email']))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment