graphene-django/graphene_django/management/commands/graphql_schema.py
Gary Donovan fcc3de2a90 Allow graphql schema export to use a canonical representation (#439)
When we use the `graphql_schema` management command, the output can vary from run to run depending on arbitrary factors (because there is no guarantee made about the order used to output JSON dictionary keys). This makes it difficult to compare two schema's at different points in time.

We address this by including a new `canonical` flag to the command, which uses standard `json.dump` funcitonality to sort dictionary keys and force pretty-printed output.
2019-03-31 11:30:29 +01:00

76 lines
2.3 KiB
Python

import importlib
import json
from django.core.management.base import BaseCommand, CommandError
from graphene_django.settings import graphene_settings
class CommandArguments(BaseCommand):
def add_arguments(self, parser):
parser.add_argument(
"--schema",
type=str,
dest="schema",
default=graphene_settings.SCHEMA,
help="Django app containing schema to dump, e.g. myproject.core.schema.schema",
)
parser.add_argument(
"--out",
type=str,
dest="out",
default=graphene_settings.SCHEMA_OUTPUT,
help="Output file, --out=- prints to stdout (default: schema.json)",
)
parser.add_argument(
"--indent",
type=int,
dest="indent",
default=graphene_settings.SCHEMA_INDENT,
help="Output file indent (default: None)",
)
class Command(CommandArguments):
help = "Dump Graphene schema JSON to file"
can_import_settings = True
def save_file(self, out, schema_dict, indent):
with open(out, "w") as outfile:
json.dump(schema_dict, outfile, indent=indent, sort_keys=True)
def handle(self, *args, **options):
options_schema = options.get("schema")
if options_schema and type(options_schema) is str:
module_str, schema_name = options_schema.rsplit(".", 1)
mod = importlib.import_module(module_str)
schema = getattr(mod, schema_name)
elif options_schema:
schema = options_schema
else:
schema = graphene_settings.SCHEMA
out = options.get("out") or graphene_settings.SCHEMA_OUTPUT
if not schema:
raise CommandError(
"Specify schema on GRAPHENE.SCHEMA setting or by using --schema"
)
indent = options.get("indent")
schema_dict = {"data": schema.introspect()}
if out == '-':
self.stdout.write(json.dumps(schema_dict, indent=indent, sort_keys=True))
else:
self.save_file(out, schema_dict, indent)
style = getattr(self, "style", None)
success = getattr(style, "SUCCESS", lambda x: x)
self.stdout.write(success("Successfully dumped GraphQL schema to %s" % out))