From 36c136e4cbf3e175730638f9db30e0cc50437699 Mon Sep 17 00:00:00 2001 From: Nathan Booker Date: Sun, 22 Jan 2023 14:14:26 -0600 Subject: [PATCH 1/2] Add basic GQL API support --- README.rst | 25 +++++++- bigcommerce/connection.py | 117 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index ce1ce9b..d04c757 100644 --- a/README.rst +++ b/README.rst @@ -116,7 +116,30 @@ it can be used to access V3 APIs using the OAuthConnection object: api_path='/stores/{}/v3/{}') v3client.get('/catalog/products', include_fields='name,sku', limit=5, page=1) -Managing OAuth Rate Limits +Accessing GraphQL Admin API +~~~~~~~~~~~~~~~~~~~~~~~~~~~ +There is a basic GraphQL client which allows you to submit GraphQL queries to the GraphQL Admin API. + +:: + + gql = bigcommerce.connection.GraphQLConnection( + client_id=client_id, + store_hash=store_hash, + access_token=access_token + ) + # Make a basic query + time_query_result = gql.query(""" + query { + system { + time + } + } + """) + # Fetch the schema + schema = gql.introspection_query() + + +Managing Rate Limits ~~~~~~~~~~~~~~~~~~~~~~~~~~ You can optionally pass a ``rate_limiting_management`` object into ``bigcommerce.api.BigcommerceApi`` or ``bigcommerce.connection.OAuthConnection`` for automatic rate limiting management, ex: diff --git a/bigcommerce/connection.py b/bigcommerce/connection.py index 7de7916..6b9df11 100644 --- a/bigcommerce/connection.py +++ b/bigcommerce/connection.py @@ -287,3 +287,120 @@ def _handle_response(self, url, res, suppress_empty=True): callback() return result + + +class GraphQLConnection(OAuthConnection): + def __init__(self, client_id, store_hash, access_token=None, host='api.bigcommerce.com', + api_path='/stores/{}/graphql', rate_limiting_management=None): + self.client_id = client_id + self.store_hash = store_hash + self.host = host + self.api_path = api_path + self.graphql_path = "https://" + self.host + self.api_path.format(self.store_hash) + self.timeout = 7.0 # can attach to session? + self.rate_limiting_management = rate_limiting_management + + self._session = requests.Session() + self._session.headers = {"Accept": "application/json", + "Accept-Encoding": "gzip"} + if access_token and store_hash: + self._session.headers.update(self._oauth_headers(client_id, access_token)) + + self._last_response = None # for debugging + + self.rate_limit = {} + + def query(self, query, variables=None): + return self.post(self.graphql_path, dict(query=query, variables=variables)) + + def introspection_query(self): + return self.query(""" + fragment FullType on __Type { + kind + name + fields(includeDeprecated: true) { + name + args { + ...InputValue + } + type { + ...TypeRef + } + isDeprecated + deprecationReason + } + inputFields { + ...InputValue + } + interfaces { + ...TypeRef + } + enumValues(includeDeprecated: true) { + name + isDeprecated + deprecationReason + } + possibleTypes { + ...TypeRef + } + } + fragment InputValue on __InputValue { + name + type { + ...TypeRef + } + defaultValue + } + fragment TypeRef on __Type { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + } + } + } + } + } + } + } + } + query IntrospectionQuery { + __schema { + queryType { + name + } + mutationType { + name + } + types { + ...FullType + } + directives { + name + locations + args { + ...InputValue + } + } + } + } + """) From 7043eb3bb7ce9fc669c0830f3228e57ecaa5e905 Mon Sep 17 00:00:00 2001 From: Nathan Booker Date: Thu, 30 Mar 2023 17:08:11 -0500 Subject: [PATCH 2/2] Release 0.23.0 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 4566daf..1da3e57 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ def read(fname): return open(os.path.join(os.path.dirname(__file__), fname)).read() -VERSION = '0.22.3' +VERSION = '0.23.0' setup( name='bigcommerce',