From 1c70f040d0d1043bef21a76d4e75c59896676f76 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 | 28 +++++++++++++++++++++++++++-
 requirements.txt            | 17 +++++++++--------
 2 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/examples/request_graphql.py b/examples/request_graphql.py
index 4322ac6e..c6a8b610 100644
--- a/examples/request_graphql.py
+++ b/examples/request_graphql.py
@@ -1,12 +1,15 @@
 import asyncio
+import sys
 
 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 +19,15 @@ 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)
+    print(response)
+    # convert response dict to schema
+    schema = build_client_schema(response["data"])
+
+    # create all films query
     query = """query {
        allFilms {
         title,
@@ -25,7 +37,21 @@ 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)
 
diff --git a/requirements.txt b/requirements.txt
index 91829112..f8f03e7f 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,8 +1,9 @@
-aiohttp >= 3.3.2
-pylibscrypt >= 1.7.1
-libnacl >= 1.6.1
-base58 >= 1.0.0
-jsonschema >= 2.6.0
-pypeg2 >= 2.15.2
-attr >= 0.3.1
-pyaes >= 1.6.1
\ No newline at end of file
+aiohttp>=3.3.2
+pylibscrypt>=1.7.1
+libnacl>=1.6.1
+base58>=1.0.0
+jsonschema>=2.6.0
+pypeg2>=2.15.2
+attr>=0.3.1
+pyaes>=1.6.1
+graphql-core>=3
\ No newline at end of file
-- 
GitLab