Coverage for zombie_nomnom_api/graphql_app/schema.py: 100%

50 statements  

« prev     ^ index     » next       coverage.py v7.6.9, created at 2024-12-07 04:25 +0000

1from enum import Enum 

2from logging import getLogger 

3import os 

4 

5from ariadne import ( 

6 EnumType, 

7 ObjectType, 

8 SchemaBindable, 

9 make_executable_schema, 

10 load_schema_from_path, 

11) 

12from typing import TypeVar 

13from zombie_nomnom import DieColor, Face 

14 

15 

16_logger = getLogger(__name__) 

17_registry: dict[str, SchemaBindable] = {} 

18 

19TRegistry = TypeVar("TRegistry", bound=SchemaBindable) 

20 

21 

22def register(graphql_type: TRegistry) -> TRegistry: 

23 """Adds bindable type to schema registry for the instantiation of the graphql executable schema. 

24 

25 **Parameters** 

26 - graphql_type (SchemaBindable): The type we are registering. 

27 

28 **Returns** 

29 - SchemaBindable: The type that was registered 

30 """ 

31 if not isinstance(graphql_type, SchemaBindable): 

32 _logger.warning( 

33 f"Failed to register a non bindable type, Type must implement SchemaBindable from ariadne." 

34 ) 

35 return 

36 

37 try: 

38 key = ( 

39 graphql_type.name 

40 ) # not defined in base type but all used types will have it. 

41 except AttributeError: 

42 _logger.warning(f"Unable to resolve name for schema {graphql_type}") 

43 return 

44 if key in _registry: 

45 _logger.warning( 

46 f"{key} is already defined as a type skipping duplicate registration." 

47 ) 

48 return 

49 _logger.debug(f"Registered type: {key}") 

50 _registry[key] = graphql_type 

51 return graphql_type 

52 

53 

54def register_enum(enum_type: type[Enum], *, name: str = None): 

55 """Shortcut function to register the enum type to the graphql type registry. 

56 

57 **Parameters** 

58 - enum_type (EnumType): The enum type we want to add to graphql schema. 

59 - name (str, optional): An alias name used by grapqhl to refer to the enum if the enum name is different then what is in the schema. 

60 """ 

61 return register(EnumType(name or enum_type.__name__, enum_type)) 

62 

63 

64def build_schema(): 

65 path_to_schema = os.path.normpath( 

66 os.path.join( 

67 os.path.dirname(__file__), 

68 "schema.gql", 

69 ), 

70 ) 

71 _logger.debug(f"Loading schema from path: {path_to_schema}") 

72 _logger.debug(f"Registered schemas: {list(_registry.keys())}") 

73 raw_schema = load_schema_from_path(path_to_schema) 

74 return make_executable_schema(raw_schema, *_registry.values()) 

75 

76 

77Query = register(ObjectType("Query")) 

78""" 

79Query type that is used as the entrypoint for reads in grapqhl 

80""" 

81Mutation = register(ObjectType("Mutation")) 

82""" 

83Mutation type that is used as the entrypoint for writes in grapqhl 

84""" 

85GameResource = register(ObjectType("Game")) 

86""" 

87Game type that we expose in graphql 

88""" 

89Round = register(ObjectType("Round")) 

90""" 

91Round type that we expose in graphql 

92""" 

93PlayerResource = register(ObjectType("Player")) 

94""" 

95Player type that we expose in graphql 

96""" 

97DieBagResource = register(ObjectType("DieBag")) 

98""" 

99DieBag type that we expose in graphql 

100""" 

101DieResource = register(ObjectType("Die")) 

102""" 

103Die type that we expose in graphql 

104""" 

105Move = register(ObjectType("Move")) 

106""" 

107Move type that we expose in graphql 

108""" 

109 

110# Register enums for GQL 

111register_enum(DieColor) 

112register_enum(Face, name="DieFace")