From 954f49afc480c574942d890f271bbffdadf1def9 Mon Sep 17 00:00:00 2001
From: vtexier <vit@free.fr>
Date: Sun, 15 Dec 2019 13:00:25 +0100
Subject: [PATCH] [enh] #59 use graphql-core library to validate GraphQL
 queries against server schema

Add graphql-core >= 3 and python >= 3.6 dependencies
---
 examples/request_graphql.py | 30 ++++++++++++++++++++++++++++--
 requirements.txt            |  1 +
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/examples/request_graphql.py b/examples/request_graphql.py
index 4322ac6e..d50e956e 100644
--- a/examples/request_graphql.py
+++ b/examples/request_graphql.py
@@ -1,12 +1,16 @@
 import asyncio
+import sys
+import json
 
 from duniterpy.api.client import Client
+from graphql import get_introspection_query, build_client_schema, language, validate
+from graphql.error import GraphQLSyntaxError
 
 # CONFIG #######################################
 
 # You can either use a complete defined endpoint : [NAME_OF_THE_API] [DOMAIN] [IPv4] [IPv6] [PORT]
 # or the simple definition : [NAME_OF_THE_API] [DOMAIN] [PORT]
-# Here we use the secure BASIC_MERKLED_API (BMAS)
+# Here we use the secure BASIC_MERKLED_API (BMAS) for standard http over ssl requests
 SWAPI_ENDPOINT = "BMAS swapi.graph.cool 443"
 
 
@@ -16,6 +20,14 @@ SWAPI_ENDPOINT = "BMAS swapi.graph.cool 443"
 async def main():
     client = Client(SWAPI_ENDPOINT)
 
+    # get query to get schema from api
+    query = get_introspection_query(False)
+    # get schema from api
+    response = await client.query(query)
+    # convert response dict to schema
+    schema = build_client_schema(response["data"])
+
+    # create all films query
     query = """query {
        allFilms {
         title,
@@ -25,9 +37,23 @@ async def main():
       }
      }
     """
+    # check query syntax
+    try:
+        ast_document = language.parse(query)
+    except GraphQLSyntaxError as exception:
+        print("Query syntax error: {0}".format(exception.message))
+        sys.exit(1)
+
+    # validate query against schema
+    errors = validate(schema, ast_document)
+    if errors:
+        print("Schema errors:")
+        print(errors)
+        sys.exit(1)
 
+    # send valid query to api
     response = await client.query(query)
-    print(response)
+    print(json.dumps(response, indent=2))
 
     # Close client aiohttp session
     await client.close()
diff --git a/requirements.txt b/requirements.txt
index 81583a9b..639b46bd 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -6,3 +6,4 @@ jsonschema>=2.6.0
 pypeg2>=2.15.2
 attrs==19.3.0
 pyaes>=1.6.1
+graphql-core>=3
\ No newline at end of file
-- 
GitLab