import importlib import json import sys import inspect import os from django.core.management.base import BaseCommand, CommandError from graphene_django.settings import graphene_settings from django.conf import settings INSTALLED_APPS = [app for app in settings.INSTALLED_APPS if 'django' not in app] PY_FILES = ['node.py', 'edge.py', '__init__.py', 'lib.py', 'resolvers.py'] pythonic_init = """ from .node import {model_name}Node """ pythonic_node = """ #encoding=utf-8 from lazy_import import lazy_module, lazy_callable from graphene_django import DjangoObjectType from graphene.relay import Node # lazy_modules imports from {application}.{model_module} import {model_name} class {model_name}Node(DjangoObjectType): class Meta: interfaces = ( Node, ) model = {model_name} neomodel_filter_fields = { # announce here dynamic filtering } only_fields = () exclude_fields = () """ def get_models(application, model_name, model_module_name="models"): # get models from application from neomodel import StructuredNode # noqa module_name = ".".join([application, model_module_name]) for name, obj in inspect.getmembers(sys.modules[module_name]): if inspect.isclass(obj) and (StructuredNode in obj.__bases__): if model_name == ".": yield obj elif model_name.strip() == name: yield obj class CommandArguments(BaseCommand): def add_arguments(self, parser): parser.add_argument( "-A", "--application", type=str, dest="application", required=True, help="Choose the django destination app", ) parser.add_argument( "-M", "--model", type=str, dest="model", required=True, help="Choose the model, or type . (ALL models)", ) parser.add_argument( "--app-module-models", type=str, dest="app_module_models", help="Choose the module of models", ) parser.add_argument( '-O', "--output-application", type=str, dest="output_app", help="Choose the output application of graphQL nodes", ) class Command(CommandArguments): help = "Django-GraphQL management module" can_import_settings = True def interpretate_model_to_graphqQL(self, model, out_application, application, app_module_models): # out_application(d) -> graphql(d) -> model(d) # -> node.py (f) # -> resolvers.py (f) # -> lib.py (f) # -> edge.py (f) package_dir = model.__name__.lower() output_path = os.path.join(settings.BASE_DIR, out_application, 'graphQL') if not os.path.exists(output_path): print("Does not exists", output_path, '. \nCreate...') os.mkdir(output_path) print("Directory graphQL in {} app created".format(out_application)) package_path = os.path.join(output_path, package_dir) if os.path.exists(package_dir): raise CommandError('Files for %s model already exists' % package_dir.capitalize()) print("Create path environment %s" % package_dir) os.mkdir(package_path) for file_name in PY_FILES: with open(os.path.join(package_path, file_name), 'w') as file: if file_name == "node.py": file.write(pythonic_node.format(application=application, model_module=app_module_models, model_name=model.__name__)) elif file_name == '__init__.py': file.write(pythonic_init.format(model.__name__)) def handle(self, *args, **options): application = options.get('application') out_application = options.get('output_app', application) app_module_models = options.get('app_module_models', 'models') if application not in INSTALLED_APPS: raise CommandError('Application %s does\'nt exists' % application) else: models = list(get_models(application, options.get('model', '.'), app_module_models)) if not models: raise CommandError('Application %s has not contains %s model' % (application, options.get('model'))) if out_application not in INSTALLED_APPS: raise CommandError('Application %s does\'nt exists' % out_application) for model in models: self.intepretate_model_to_graphQL(model, out_application, application, app_module_models) # 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)) # 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))