mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-16 12:38:17 -06:00
feat: plugins can extend the GraphQL schema
This commit is contained in:
parent
c15cfc26f1
commit
ceb0d9d78f
@ -1,7 +1,10 @@
|
||||
import collections
|
||||
import inspect
|
||||
import graphene
|
||||
from packaging import version
|
||||
|
||||
from graphql.type.definition import GraphQLType
|
||||
|
||||
from django.apps import AppConfig
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.template.loader import get_template
|
||||
@ -15,6 +18,10 @@ from extras.plugins.utils import import_object
|
||||
# Initialize plugin registry stores
|
||||
registry['plugin_template_extensions'] = collections.defaultdict(list)
|
||||
registry['plugin_menu_items'] = {}
|
||||
registry['graphql_queries'] = []
|
||||
registry['graphql_mutations'] = []
|
||||
registry['graphql_subscriptions'] = []
|
||||
registry['graphql_types'] = []
|
||||
|
||||
|
||||
#
|
||||
@ -50,6 +57,12 @@ class PluginConfig(AppConfig):
|
||||
# Django-rq queues dedicated to the plugin
|
||||
queues = []
|
||||
|
||||
# Graphene GraphQL schema extension points
|
||||
graphql_queries = []
|
||||
graphql_mutations = []
|
||||
graphql_subscriptions = []
|
||||
graphql_types = []
|
||||
|
||||
# Default integration paths. Plugin authors can override these to customize the paths to
|
||||
# integrated components.
|
||||
template_extensions = 'template_content.template_extensions'
|
||||
@ -67,6 +80,10 @@ class PluginConfig(AppConfig):
|
||||
if menu_items is not None:
|
||||
register_menu_items(self.verbose_name, menu_items)
|
||||
|
||||
# Register GraphQL schema extensions
|
||||
register_graphql_schema(self.graphql_queries, self.graphql_mutations, self.graphql_subscriptions,
|
||||
self.graphql_types)
|
||||
|
||||
@classmethod
|
||||
def validate(cls, user_config, netbox_version):
|
||||
|
||||
@ -242,3 +259,20 @@ def register_menu_items(section_name, class_list):
|
||||
raise TypeError(f"{button} must be an instance of extras.plugins.PluginMenuButton")
|
||||
|
||||
registry['plugin_menu_items'][section_name] = class_list
|
||||
|
||||
|
||||
def register_graphql_schema(queries, mutations, subscriptions, types):
|
||||
"""
|
||||
Register extensions to the GraphQL schema
|
||||
"""
|
||||
for object_type in [*queries, *mutations, *subscriptions]:
|
||||
if not issubclass(object_type, graphene.ObjectType):
|
||||
raise TypeError(f"{object_type} must be a subclass of graphene.types.objecttype.ObjectType")
|
||||
|
||||
for graphql_type in types:
|
||||
if not issubclass(graphql_type, GraphQLType):
|
||||
raise TypeError(f"f{graphql_type} must be a subclass of graphql.type.definition.GraphQLType")
|
||||
|
||||
registry['graphql_queries'].extend(queries)
|
||||
registry['graphql_subscriptions'].extend(subscriptions)
|
||||
registry['graphql_types'].extend(types)
|
||||
|
@ -3,14 +3,14 @@ import graphene
|
||||
from circuits.graphql.schema import CircuitsQuery
|
||||
from dcim.graphql.schema import DCIMQuery
|
||||
from extras.graphql.schema import ExtrasQuery
|
||||
from extras.plugins import registry
|
||||
from ipam.graphql.schema import IPAMQuery
|
||||
from tenancy.graphql.schema import TenancyQuery
|
||||
from users.graphql.schema import UsersQuery
|
||||
from virtualization.graphql.schema import VirtualizationQuery
|
||||
from wireless.graphql.schema import WirelessQuery
|
||||
|
||||
|
||||
class Query(
|
||||
query_types = [
|
||||
CircuitsQuery,
|
||||
DCIMQuery,
|
||||
ExtrasQuery,
|
||||
@ -19,9 +19,45 @@ class Query(
|
||||
UsersQuery,
|
||||
VirtualizationQuery,
|
||||
WirelessQuery,
|
||||
*registry['graphql_queries'],
|
||||
]
|
||||
|
||||
mutation_types = [
|
||||
*registry['graphql_mutations'],
|
||||
]
|
||||
|
||||
subscription_types = [
|
||||
*registry['graphql_subscriptions'],
|
||||
]
|
||||
|
||||
extra_types = [
|
||||
*registry['graphql_types'],
|
||||
]
|
||||
|
||||
|
||||
class Query(
|
||||
*query_types,
|
||||
graphene.ObjectType
|
||||
):
|
||||
pass
|
||||
|
||||
|
||||
schema = graphene.Schema(query=Query, auto_camelcase=False)
|
||||
class Mutation(
|
||||
*mutation_types,
|
||||
graphene.ObjectType
|
||||
):
|
||||
pass
|
||||
|
||||
|
||||
class Subscription(
|
||||
*subscription_types,
|
||||
graphene.ObjectType
|
||||
):
|
||||
pass
|
||||
|
||||
|
||||
schema = graphene.Schema(query=Query,
|
||||
mutation=Mutation if len(mutation_types) > 0 else None,
|
||||
subscription=Subscription if len(subscription_types) > 0 else None,
|
||||
types=extra_types if len(extra_types) > 0 else None,
|
||||
auto_camelcase=False)
|
||||
|
Loading…
Reference in New Issue
Block a user