From 652b366f18f0387399906f055b3ff8553a34350b Mon Sep 17 00:00:00 2001 From: Anton Shutik Date: Thu, 31 Oct 2024 08:41:12 +0100 Subject: [PATCH] Added queries dir support --- shopify_client/__init__.py | 4 ++-- shopify_client/graphql.py | 20 ++++++++++++++++---- tests/test_graphql.py | 14 +++++++++++++- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/shopify_client/__init__.py b/shopify_client/__init__.py index f84db18..31b5fd5 100644 --- a/shopify_client/__init__.py +++ b/shopify_client/__init__.py @@ -16,7 +16,7 @@ class ShopifyClient(requests.Session): - def __init__(self, api_url, api_token, api_version=SHOPIFY_API_VERSION): + def __init__(self, api_url, api_token, api_version=SHOPIFY_API_VERSION, grapgql_queries_dir=None): super().__init__() self.api_url = api_url self.api_version = api_version @@ -109,7 +109,7 @@ def __init__(self, api_url, api_token, api_version=SHOPIFY_API_VERSION): self.webhooks = Endpoint(client=self, endpoint="webhooks") # GraphQL - self.query = GraphQL(client=self) + self.query = GraphQL(client=self, grapgql_queries_dir=grapgql_queries_dir) self.hooks["response"].append(rate_limit) diff --git a/shopify_client/graphql.py b/shopify_client/graphql.py index cb8482e..30ba788 100644 --- a/shopify_client/graphql.py +++ b/shopify_client/graphql.py @@ -8,19 +8,31 @@ class GraphQL: - def __init__(self, client): + def __init__(self, client, grapgql_queries_dir=None): self.client = client self.endpoint = "graphql.json" + self.grapgql_queries_dir = grapgql_queries_dir def __build_url(self, **params): return self.endpoint def __call__(self, *args, **kwargs): return self.__query(*args, **kwargs) + + def __query_from_name(self, name): + assert self.grapgql_queries_dir, "GraphQL queries directory is not set" + + with open(f"{self.grapgql_queries_dir}/{name}.graphql") as f: + return f.read() + + def __query(self, query=None, query_name=None, variables=None, operation_name=None, paginate=False, page_size=100): + assert query or query_name, "Either 'query' or 'query_name' must be provided" - def __query(self, query, variables=None, operation_name=None, paginate=False, page_size=100): + if query is None and query_name: + query = self.__query_from_name(query_name) + if paginate: - return self.__paginate(query, variables, operation_name, page_size) + return self.__paginate(query=query, variables=variables, operation_name=operation_name, page_size=page_size) try: response = self.client.post( self.__build_url(), @@ -45,7 +57,7 @@ def __paginate(self, query, variables=None, operation_name=None, page_size=100): while has_next_page: variables["cursor"] = cursor - response = self.__query(query, variables, operation_name) + response = self.__query(query=query, variables=variables, operation_name=operation_name) page_info = self.__find_page_info(response) has_next_page = page_info.get("hasNextPage", False) cursor = page_info.get("endCursor", None) diff --git a/tests/test_graphql.py b/tests/test_graphql.py index 6647054..d6f816b 100644 --- a/tests/test_graphql.py +++ b/tests/test_graphql.py @@ -1,6 +1,6 @@ from copy import deepcopy import json -from unittest.mock import call +from unittest.mock import MagicMock, call, mock_open, patch import requests import pytest from shopify_client.graphql import GraphQL @@ -16,6 +16,18 @@ def test_graphql_query(graphql, mock_client): mock_client.post.assert_called_once_with("graphql.json", json={"query": "query { key }", "variables": None, "operationName": None}) assert response == {"data": {"key": "value"}} +def test_graphql_query_with_query_name(graphql, mock_client): + mock_query_content = "query { items { id } }" + graphql.grapgql_queries_dir = "queries" + with patch("builtins.open", mock_open(read_data=mock_query_content)): + mock_client.post.return_value = {"data": {"items": []}} + response = graphql(query_name="test_query") + mock_client.post.assert_called_once_with( + "graphql.json", + json={"query": mock_query_content, "variables": None, "operationName": None}, + ) + assert response == {"data": {"items": []}} + def test_graphql_query_with_variables(graphql, mock_client): mock_client.post.return_value = {"data": {"key": "value"}} variables = {"var1": "value1"}