2020-03-13 13:04:55 +03:00
|
|
|
import os
|
2016-09-18 02:29:00 +03:00
|
|
|
import importlib
|
|
|
|
import json
|
2019-06-10 03:06:50 +03:00
|
|
|
import functools
|
2016-09-18 02:29:00 +03:00
|
|
|
|
|
|
|
from django.core.management.base import BaseCommand, CommandError
|
2019-06-10 03:06:50 +03:00
|
|
|
from django.utils import autoreload
|
2016-09-18 02:29:00 +03:00
|
|
|
|
2020-03-13 13:04:55 +03:00
|
|
|
from graphql import print_schema
|
2016-09-20 08:04:23 +03:00
|
|
|
from graphene_django.settings import graphene_settings
|
|
|
|
|
2017-12-18 20:02:04 +03:00
|
|
|
|
2017-12-10 08:53:13 +03:00
|
|
|
class CommandArguments(BaseCommand):
|
|
|
|
def add_arguments(self, parser):
|
|
|
|
parser.add_argument(
|
2018-07-20 02:51:33 +03:00
|
|
|
"--schema",
|
2017-12-10 08:53:13 +03:00
|
|
|
type=str,
|
2018-07-20 02:51:33 +03:00
|
|
|
dest="schema",
|
2017-12-10 08:53:13 +03:00
|
|
|
default=graphene_settings.SCHEMA,
|
2018-07-20 02:51:33 +03:00
|
|
|
help="Django app containing schema to dump, e.g. myproject.core.schema.schema",
|
|
|
|
)
|
2017-12-10 08:53:13 +03:00
|
|
|
|
|
|
|
parser.add_argument(
|
2018-07-20 02:51:33 +03:00
|
|
|
"--out",
|
2017-12-10 08:53:13 +03:00
|
|
|
type=str,
|
2018-07-20 02:51:33 +03:00
|
|
|
dest="out",
|
2017-12-10 08:53:13 +03:00
|
|
|
default=graphene_settings.SCHEMA_OUTPUT,
|
2018-09-08 15:33:30 +03:00
|
|
|
help="Output file, --out=- prints to stdout (default: schema.json)",
|
2018-07-20 02:51:33 +03:00
|
|
|
)
|
2017-12-10 08:53:13 +03:00
|
|
|
|
|
|
|
parser.add_argument(
|
2018-07-20 02:51:33 +03:00
|
|
|
"--indent",
|
2017-12-10 08:53:13 +03:00
|
|
|
type=int,
|
2018-07-20 02:51:33 +03:00
|
|
|
dest="indent",
|
2017-12-10 08:53:13 +03:00
|
|
|
default=graphene_settings.SCHEMA_INDENT,
|
2018-07-20 02:51:33 +03:00
|
|
|
help="Output file indent (default: None)",
|
|
|
|
)
|
2016-10-17 10:08:04 +03:00
|
|
|
|
2019-06-10 03:06:50 +03:00
|
|
|
parser.add_argument(
|
|
|
|
"--watch",
|
|
|
|
dest="watch",
|
|
|
|
default=False,
|
|
|
|
action="store_true",
|
|
|
|
help="Updates the schema on file changes (default: False)",
|
|
|
|
)
|
|
|
|
|
2016-09-18 02:29:00 +03:00
|
|
|
|
|
|
|
class Command(CommandArguments):
|
2020-03-13 13:04:55 +03:00
|
|
|
help = "Dump Graphene schema as a JSON or GraphQL file"
|
2016-09-18 02:29:00 +03:00
|
|
|
can_import_settings = True
|
2022-01-07 23:26:07 +03:00
|
|
|
requires_system_checks = []
|
2016-09-18 02:29:00 +03:00
|
|
|
|
2020-03-13 13:04:55 +03:00
|
|
|
def save_json_file(self, out, schema_dict, indent):
|
2018-07-20 02:51:33 +03:00
|
|
|
with open(out, "w") as outfile:
|
2019-03-31 13:30:29 +03:00
|
|
|
json.dump(schema_dict, outfile, indent=indent, sort_keys=True)
|
2016-09-18 02:29:00 +03:00
|
|
|
|
2020-03-13 13:04:55 +03:00
|
|
|
def save_graphql_file(self, out, schema):
|
Fix schema dump on windows (#1123)
Without explicitly setting the encoding to "utf-8" I get the following error on windows (python 3.9)
```
File "D:\env\lib\site-packages\graphene_django\management\commands\graphql_schema.py", line 115, in handle
self.get_schema(schema, out, indent)
File "D:\env\lib\site-packages\graphene_django\management\commands\graphql_schema.py", line 72, in get_schema
self.save_graphql_file(out, schema)
File "D:\env\lib\site-packages\graphene_django\management\commands\graphql_schema.py", line 59, in save_graphql_file
outfile.write(print_schema(schema.graphql_schema))
File "C:\Users\u\AppData\Local\Programs\Python\Python39\lib\encodings\cp1252.py", line 19, in encode
return codecs.charmap_encode(input,self.errors,encoding_table)[0]
```
2021-02-23 07:20:59 +03:00
|
|
|
with open(out, "w", encoding="utf-8") as outfile:
|
2020-05-09 14:13:47 +03:00
|
|
|
outfile.write(print_schema(schema.graphql_schema))
|
2020-03-13 13:04:55 +03:00
|
|
|
|
2019-06-10 03:06:50 +03:00
|
|
|
def get_schema(self, schema, out, indent):
|
|
|
|
schema_dict = {"data": schema.introspect()}
|
2020-12-31 02:37:57 +03:00
|
|
|
if out == "-" or out == "-.json":
|
2019-06-10 03:06:50 +03:00
|
|
|
self.stdout.write(json.dumps(schema_dict, indent=indent, sort_keys=True))
|
2020-12-31 02:37:57 +03:00
|
|
|
elif out == "-.graphql":
|
2022-11-30 15:34:09 +03:00
|
|
|
self.stdout.write(print_schema(schema.graphql_schema))
|
2019-06-10 03:06:50 +03:00
|
|
|
else:
|
2020-03-13 13:04:55 +03:00
|
|
|
# Determine format
|
|
|
|
_, file_extension = os.path.splitext(out)
|
|
|
|
|
|
|
|
if file_extension == ".graphql":
|
|
|
|
self.save_graphql_file(out, schema)
|
|
|
|
elif file_extension == ".json":
|
|
|
|
self.save_json_file(out, schema_dict, indent)
|
|
|
|
else:
|
2022-10-19 17:10:30 +03:00
|
|
|
raise CommandError(f'Unrecognised file format "{file_extension}"')
|
2019-06-10 03:06:50 +03:00
|
|
|
|
|
|
|
style = getattr(self, "style", None)
|
|
|
|
success = getattr(style, "SUCCESS", lambda x: x)
|
|
|
|
|
2022-10-19 17:10:30 +03:00
|
|
|
self.stdout.write(success(f"Successfully dumped GraphQL schema to {out}"))
|
2019-06-10 03:06:50 +03:00
|
|
|
|
2016-09-18 02:29:00 +03:00
|
|
|
def handle(self, *args, **options):
|
2018-07-20 02:51:33 +03:00
|
|
|
options_schema = options.get("schema")
|
2016-09-22 00:57:47 +03:00
|
|
|
|
|
|
|
if options_schema and type(options_schema) is str:
|
2018-07-20 02:51:33 +03:00
|
|
|
module_str, schema_name = options_schema.rsplit(".", 1)
|
2016-09-22 00:57:47 +03:00
|
|
|
mod = importlib.import_module(module_str)
|
|
|
|
schema = getattr(mod, schema_name)
|
|
|
|
|
|
|
|
elif options_schema:
|
|
|
|
schema = options_schema
|
|
|
|
|
2016-09-20 08:04:23 +03:00
|
|
|
else:
|
|
|
|
schema = graphene_settings.SCHEMA
|
|
|
|
|
2018-07-20 02:51:33 +03:00
|
|
|
out = options.get("out") or graphene_settings.SCHEMA_OUTPUT
|
2016-09-18 02:29:00 +03:00
|
|
|
|
2016-09-20 08:04:23 +03:00
|
|
|
if not schema:
|
2018-07-20 02:51:33 +03:00
|
|
|
raise CommandError(
|
|
|
|
"Specify schema on GRAPHENE.SCHEMA setting or by using --schema"
|
|
|
|
)
|
2016-09-18 02:29:00 +03:00
|
|
|
|
2018-07-20 02:51:33 +03:00
|
|
|
indent = options.get("indent")
|
2019-06-10 03:06:50 +03:00
|
|
|
watch = options.get("watch")
|
|
|
|
if watch:
|
|
|
|
autoreload.run_with_reloader(
|
|
|
|
functools.partial(self.get_schema, schema, out, indent)
|
|
|
|
)
|
2018-09-08 15:33:30 +03:00
|
|
|
else:
|
2019-06-10 03:06:50 +03:00
|
|
|
self.get_schema(schema, out, indent)
|