From 0d193fdc6d52acc641bb1958bbca841fea643f09 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

---
 examples/request_graphql.py | 30 ++++++++++++++++++++++++++++--
 pyproject.toml              |  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/pyproject.toml b/pyproject.toml
index 70dfedbe..6986539d 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -32,6 +32,7 @@ attrs = "^20.2.0"
 base58 = "^2.0.0"
 libnacl = "^1.7.2"
 pyaes = "^1.6.1"
+graphql-core = "^3.1.2"
 
 [tool.poetry.dev-dependencies]
 black = "^20.8b1"
-- 
GitLab