From 1c9e42e6119bbe1a06aef417c98f5ef2510be9b9 Mon Sep 17 00:00:00 2001 From: GhostApps Date: Wed, 22 Jan 2020 15:44:58 +0000 Subject: [PATCH 01/22] Add support for fulfillment_order --- shopify/resources/__init__.py | 2 ++ shopify/resources/fulfillment_order.py | 23 +++++++++++++++++++++++ shopify/resources/order.py | 7 ++++++- 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 shopify/resources/fulfillment_order.py diff --git a/shopify/resources/__init__.py b/shopify/resources/__init__.py index 8233cb1f..3d4e23c5 100644 --- a/shopify/resources/__init__.py +++ b/shopify/resources/__init__.py @@ -72,5 +72,7 @@ from .collection_publication import CollectionPublication from .product_publication import ProductPublication from .graphql import GraphQL +from .application_credit import ApplicationCredit +from .fulfillment_order import FulfillmentOrder from ..base import ShopifyResource diff --git a/shopify/resources/fulfillment_order.py b/shopify/resources/fulfillment_order.py new file mode 100644 index 00000000..2a70e54b --- /dev/null +++ b/shopify/resources/fulfillment_order.py @@ -0,0 +1,23 @@ +from ..base import ShopifyResource +import json + +class FulfillmentOrder(ShopifyResource): + + @classmethod + def find(cls, key=None, **kwargs): + order_id = kwargs.get("order_id") + if order_id: + return super(FulfillmentOrder, cls).find(from_="%s/orders/%s/fulfillment_orders.json" % ( cls.site, order_id), **kwargs) + else: + return super(FulfillmentOrder, cls).find(key) + + + def cancel(self): + self._load_attributes_from_response(self.post("cancel")) + + def close(self): + self._load_attributes_from_response(self.post("close")) + + def move(self, new_location_id): + body = { 'fulfillment_order' : { 'new_location_id' : new_location_id } } + self.post("move", body=json.dumps(body).encode()) diff --git a/shopify/resources/order.py b/shopify/resources/order.py index 4e780b0a..6b4e0c41 100644 --- a/shopify/resources/order.py +++ b/shopify/resources/order.py @@ -1,7 +1,7 @@ from ..base import ShopifyResource from shopify import mixins from .transaction import Transaction - +from .fulfillment_order import FulfillmentOrder class Order(ShopifyResource, mixins.Metafields, mixins.Events): @@ -19,3 +19,8 @@ def transactions(self): def capture(self, amount=""): return Transaction.create({"amount": amount, "kind": "capture", "order_id": self.id}) + + def fulfillment_orders(self, **kwargs): + return FulfillmentOrder.find(from_="%s/orders/%s/fulfillment_orders.json" % ( + ShopifyResource.site, self.id), **kwargs) + From 92ba9aa2d400201b1e8f4eba81bbfae476debad6 Mon Sep 17 00:00:00 2001 From: GhostApps Date: Wed, 22 Jan 2020 17:16:08 +0000 Subject: [PATCH 02/22] Add application credit --- shopify/resources/application_credit.py | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 shopify/resources/application_credit.py diff --git a/shopify/resources/application_credit.py b/shopify/resources/application_credit.py new file mode 100644 index 00000000..fe48ca47 --- /dev/null +++ b/shopify/resources/application_credit.py @@ -0,0 +1,5 @@ +from ..base import ShopifyResource + + +class ApplicationCredit(ShopifyResource): + pass From ae733834b62444e3ca0ba29518fa1c0dfb45cd48 Mon Sep 17 00:00:00 2001 From: GhostApps Date: Wed, 22 Jan 2020 15:44:58 +0000 Subject: [PATCH 03/22] Add support for fulfillment_order --- shopify/resources/__init__.py | 2 ++ shopify/resources/fulfillment_order.py | 23 +++++++++++++++++++++++ shopify/resources/order.py | 7 ++++++- 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 shopify/resources/fulfillment_order.py diff --git a/shopify/resources/__init__.py b/shopify/resources/__init__.py index ce91cf3c..99213ee5 100644 --- a/shopify/resources/__init__.py +++ b/shopify/resources/__init__.py @@ -72,5 +72,7 @@ from .collection_publication import CollectionPublication from .product_publication import ProductPublication from .graphql import GraphQL +from .application_credit import ApplicationCredit +from .fulfillment_order import FulfillmentOrder from ..base import ShopifyResource diff --git a/shopify/resources/fulfillment_order.py b/shopify/resources/fulfillment_order.py new file mode 100644 index 00000000..2a70e54b --- /dev/null +++ b/shopify/resources/fulfillment_order.py @@ -0,0 +1,23 @@ +from ..base import ShopifyResource +import json + +class FulfillmentOrder(ShopifyResource): + + @classmethod + def find(cls, key=None, **kwargs): + order_id = kwargs.get("order_id") + if order_id: + return super(FulfillmentOrder, cls).find(from_="%s/orders/%s/fulfillment_orders.json" % ( cls.site, order_id), **kwargs) + else: + return super(FulfillmentOrder, cls).find(key) + + + def cancel(self): + self._load_attributes_from_response(self.post("cancel")) + + def close(self): + self._load_attributes_from_response(self.post("close")) + + def move(self, new_location_id): + body = { 'fulfillment_order' : { 'new_location_id' : new_location_id } } + self.post("move", body=json.dumps(body).encode()) diff --git a/shopify/resources/order.py b/shopify/resources/order.py index 4e780b0a..6b4e0c41 100644 --- a/shopify/resources/order.py +++ b/shopify/resources/order.py @@ -1,7 +1,7 @@ from ..base import ShopifyResource from shopify import mixins from .transaction import Transaction - +from .fulfillment_order import FulfillmentOrder class Order(ShopifyResource, mixins.Metafields, mixins.Events): @@ -19,3 +19,8 @@ def transactions(self): def capture(self, amount=""): return Transaction.create({"amount": amount, "kind": "capture", "order_id": self.id}) + + def fulfillment_orders(self, **kwargs): + return FulfillmentOrder.find(from_="%s/orders/%s/fulfillment_orders.json" % ( + ShopifyResource.site, self.id), **kwargs) + From f7a5f531baa48fa8464ec4c4a31931a32e2d1b6e Mon Sep 17 00:00:00 2001 From: GhostApps Date: Wed, 22 Jan 2020 17:16:08 +0000 Subject: [PATCH 04/22] Add application credit --- shopify/resources/application_credit.py | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 shopify/resources/application_credit.py diff --git a/shopify/resources/application_credit.py b/shopify/resources/application_credit.py new file mode 100644 index 00000000..fe48ca47 --- /dev/null +++ b/shopify/resources/application_credit.py @@ -0,0 +1,5 @@ +from ..base import ShopifyResource + + +class ApplicationCredit(ShopifyResource): + pass From a0a55bbba3696eb3711b842c99b5e0af20144e25 Mon Sep 17 00:00:00 2001 From: GhostApps Date: Mon, 27 Jul 2020 15:12:27 +0100 Subject: [PATCH 05/22] Add support for locations for move --- .vscode/settings.json | 3 +++ shopify/resources/fulfillment_order.py | 5 +++++ 2 files changed, 8 insertions(+) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..615aafb0 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python.pythonPath": "/usr/bin/python3" +} \ No newline at end of file diff --git a/shopify/resources/fulfillment_order.py b/shopify/resources/fulfillment_order.py index 2a70e54b..9715f0e4 100644 --- a/shopify/resources/fulfillment_order.py +++ b/shopify/resources/fulfillment_order.py @@ -1,4 +1,5 @@ from ..base import ShopifyResource +from .location import Location import json class FulfillmentOrder(ShopifyResource): @@ -11,6 +12,10 @@ def find(cls, key=None, **kwargs): else: return super(FulfillmentOrder, cls).find(key) + def locations_for_move(self, **kwargs): + return Location.find(from_="%s/fulfillment_orders/%s/locations_for_move.json" % ( + ShopifyResource.site, self.id), **kwargs) + def cancel(self): self._load_attributes_from_response(self.post("cancel")) From c73fa51450ea16ceab2f47ae2354b49908220c05 Mon Sep 17 00:00:00 2001 From: GhostApps Date: Wed, 22 Jan 2020 15:44:58 +0000 Subject: [PATCH 06/22] Add support for fulfillment_order --- shopify/resources/__init__.py | 2 ++ shopify/resources/fulfillment_order.py | 23 +++++++++++++++++++++++ shopify/resources/order.py | 7 ++++++- 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 shopify/resources/fulfillment_order.py diff --git a/shopify/resources/__init__.py b/shopify/resources/__init__.py index 16220739..73d60fdb 100644 --- a/shopify/resources/__init__.py +++ b/shopify/resources/__init__.py @@ -78,5 +78,7 @@ from .collection_publication import CollectionPublication from .product_publication import ProductPublication from .graphql import GraphQL +from .application_credit import ApplicationCredit +from .fulfillment_order import FulfillmentOrder from ..base import ShopifyResource diff --git a/shopify/resources/fulfillment_order.py b/shopify/resources/fulfillment_order.py new file mode 100644 index 00000000..2a70e54b --- /dev/null +++ b/shopify/resources/fulfillment_order.py @@ -0,0 +1,23 @@ +from ..base import ShopifyResource +import json + +class FulfillmentOrder(ShopifyResource): + + @classmethod + def find(cls, key=None, **kwargs): + order_id = kwargs.get("order_id") + if order_id: + return super(FulfillmentOrder, cls).find(from_="%s/orders/%s/fulfillment_orders.json" % ( cls.site, order_id), **kwargs) + else: + return super(FulfillmentOrder, cls).find(key) + + + def cancel(self): + self._load_attributes_from_response(self.post("cancel")) + + def close(self): + self._load_attributes_from_response(self.post("close")) + + def move(self, new_location_id): + body = { 'fulfillment_order' : { 'new_location_id' : new_location_id } } + self.post("move", body=json.dumps(body).encode()) diff --git a/shopify/resources/order.py b/shopify/resources/order.py index 2e31a8c3..6609b4f9 100644 --- a/shopify/resources/order.py +++ b/shopify/resources/order.py @@ -1,7 +1,7 @@ from ..base import ShopifyResource from shopify import mixins from .transaction import Transaction - +from .fulfillment_order import FulfillmentOrder class Order(ShopifyResource, mixins.Metafields, mixins.Events): _prefix_source = "/customers/$customer_id/" @@ -28,3 +28,8 @@ def transactions(self): def capture(self, amount=""): return Transaction.create({"amount": amount, "kind": "capture", "order_id": self.id}) + + def fulfillment_orders(self, **kwargs): + return FulfillmentOrder.find(from_="%s/orders/%s/fulfillment_orders.json" % ( + ShopifyResource.site, self.id), **kwargs) + From c709376555b01aae6fd3d62047f81628b93adefb Mon Sep 17 00:00:00 2001 From: GhostApps Date: Wed, 22 Jan 2020 17:16:08 +0000 Subject: [PATCH 07/22] Add application credit --- shopify/resources/application_credit.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/shopify/resources/application_credit.py b/shopify/resources/application_credit.py index ecc12fa0..251e302f 100644 --- a/shopify/resources/application_credit.py +++ b/shopify/resources/application_credit.py @@ -2,4 +2,8 @@ class ApplicationCredit(ShopifyResource): +<<<<<<< HEAD pass +======= + pass +>>>>>>> f7a5f53... Add application credit From f462330fd1b87de29dd0220b087bc248078d9921 Mon Sep 17 00:00:00 2001 From: GhostApps Date: Wed, 22 Jan 2020 15:44:58 +0000 Subject: [PATCH 08/22] Add support for fulfillment_order --- shopify/resources/application_credit.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/shopify/resources/application_credit.py b/shopify/resources/application_credit.py index 251e302f..fe48ca47 100644 --- a/shopify/resources/application_credit.py +++ b/shopify/resources/application_credit.py @@ -2,8 +2,4 @@ class ApplicationCredit(ShopifyResource): -<<<<<<< HEAD - pass -======= pass ->>>>>>> f7a5f53... Add application credit From f901ff56ac1e98ee50bc26b72dcb9ab8d0285d68 Mon Sep 17 00:00:00 2001 From: GhostApps Date: Mon, 27 Jul 2020 15:12:27 +0100 Subject: [PATCH 09/22] Add support for locations for move --- .vscode/settings.json | 3 +++ shopify/resources/fulfillment_order.py | 5 +++++ 2 files changed, 8 insertions(+) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..615aafb0 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python.pythonPath": "/usr/bin/python3" +} \ No newline at end of file diff --git a/shopify/resources/fulfillment_order.py b/shopify/resources/fulfillment_order.py index 2a70e54b..9715f0e4 100644 --- a/shopify/resources/fulfillment_order.py +++ b/shopify/resources/fulfillment_order.py @@ -1,4 +1,5 @@ from ..base import ShopifyResource +from .location import Location import json class FulfillmentOrder(ShopifyResource): @@ -11,6 +12,10 @@ def find(cls, key=None, **kwargs): else: return super(FulfillmentOrder, cls).find(key) + def locations_for_move(self, **kwargs): + return Location.find(from_="%s/fulfillment_orders/%s/locations_for_move.json" % ( + ShopifyResource.site, self.id), **kwargs) + def cancel(self): self._load_attributes_from_response(self.post("cancel")) From 79efd41469cdccd9efb9e995cb7878dbc04bf0ad Mon Sep 17 00:00:00 2001 From: GhostApps Date: Tue, 9 Nov 2021 20:31:28 +0000 Subject: [PATCH 10/22] Update fulfillment_order.py --- shopify/resources/fulfillment_order.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/shopify/resources/fulfillment_order.py b/shopify/resources/fulfillment_order.py index 9715f0e4..e902f7a1 100644 --- a/shopify/resources/fulfillment_order.py +++ b/shopify/resources/fulfillment_order.py @@ -12,6 +12,11 @@ def find(cls, key=None, **kwargs): else: return super(FulfillmentOrder, cls).find(key) + @classmethod + def locations_for_move(cls, key=None, **kwargs): + return Location.find(from_="%s/fulfillment_orders/%s/locations_for_move.json" % ( + ShopifyResource.site, key), **kwargs) + def locations_for_move(self, **kwargs): return Location.find(from_="%s/fulfillment_orders/%s/locations_for_move.json" % ( ShopifyResource.site, self.id), **kwargs) From 70645a9d0c77a092437f8076036c5fa01108a406 Mon Sep 17 00:00:00 2001 From: GhostApps Date: Tue, 9 Nov 2021 20:35:07 +0000 Subject: [PATCH 11/22] Update fulfillment_order.py --- shopify/resources/fulfillment_order.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/shopify/resources/fulfillment_order.py b/shopify/resources/fulfillment_order.py index e902f7a1..b73c68f8 100644 --- a/shopify/resources/fulfillment_order.py +++ b/shopify/resources/fulfillment_order.py @@ -16,11 +16,6 @@ def find(cls, key=None, **kwargs): def locations_for_move(cls, key=None, **kwargs): return Location.find(from_="%s/fulfillment_orders/%s/locations_for_move.json" % ( ShopifyResource.site, key), **kwargs) - - def locations_for_move(self, **kwargs): - return Location.find(from_="%s/fulfillment_orders/%s/locations_for_move.json" % ( - ShopifyResource.site, self.id), **kwargs) - def cancel(self): self._load_attributes_from_response(self.post("cancel")) From b6d23d404dfe9e5eb224d05ed99161a02232d108 Mon Sep 17 00:00:00 2001 From: Alex Dicketts Date: Sun, 6 Nov 2022 11:27:22 +0000 Subject: [PATCH 12/22] Export FulfillmentV2, Remove FulfillmentOrders just in case --- shopify/resources/__init__.py | 2 +- shopify/resources/fulfillment.py | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/shopify/resources/__init__.py b/shopify/resources/__init__.py index 73d60fdb..db6d38c5 100644 --- a/shopify/resources/__init__.py +++ b/shopify/resources/__init__.py @@ -38,7 +38,7 @@ from .page import Page from .country import Country from .refund import Refund -from .fulfillment import Fulfillment, FulfillmentOrders +from .fulfillment import Fulfillment, FulfillmentV2 from .fulfillment_event import FulfillmentEvent from .fulfillment_service import FulfillmentService from .carrier_service import CarrierService diff --git a/shopify/resources/fulfillment.py b/shopify/resources/fulfillment.py index fcf74863..d40db885 100644 --- a/shopify/resources/fulfillment.py +++ b/shopify/resources/fulfillment.py @@ -20,10 +20,6 @@ def update_tracking(self, tracking_info, notify_customer): self._load_attributes_from_response(fulfill.update_tracking(tracking_info, notify_customer)) -class FulfillmentOrders(ShopifyResource): - _prefix_source = "/orders/$order_id/" - - class FulfillmentV2(ShopifyResource): _singular = "fulfillment" _plural = "fulfillments" From 2fb3353427ca21a331ace38b06c0fd72b4bd5e05 Mon Sep 17 00:00:00 2001 From: Alex Dicketts Date: Sun, 6 Nov 2022 18:55:04 +0000 Subject: [PATCH 13/22] Update FulfillmentV2 --- shopify/resources/__init__.py | 2 +- shopify/resources/fulfillment.py | 33 +++++++++++++++----------------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/shopify/resources/__init__.py b/shopify/resources/__init__.py index db6d38c5..32cc9be3 100644 --- a/shopify/resources/__init__.py +++ b/shopify/resources/__init__.py @@ -38,7 +38,7 @@ from .page import Page from .country import Country from .refund import Refund -from .fulfillment import Fulfillment, FulfillmentV2 +from .fulfillment import FulfillmentV2 from .fulfillment_event import FulfillmentEvent from .fulfillment_service import FulfillmentService from .carrier_service import CarrierService diff --git a/shopify/resources/fulfillment.py b/shopify/resources/fulfillment.py index d40db885..72c43488 100644 --- a/shopify/resources/fulfillment.py +++ b/shopify/resources/fulfillment.py @@ -2,28 +2,25 @@ import json -class Fulfillment(ShopifyResource): - _prefix_source = "/orders/$order_id/" - - def cancel(self): - self._load_attributes_from_response(self.post("cancel")) - - def complete(self): - self._load_attributes_from_response(self.post("complete")) - - def open(self): - self._load_attributes_from_response(self.post("open")) - - def update_tracking(self, tracking_info, notify_customer): - fulfill = FulfillmentV2() - fulfill.id = self.id - self._load_attributes_from_response(fulfill.update_tracking(tracking_info, notify_customer)) - - class FulfillmentV2(ShopifyResource): _singular = "fulfillment" _plural = "fulfillments" + @classmethod + def find(cls, key=None, **kwargs): + order_id = kwargs.get("order_id") + fulfillment_order = kwargs.get("fulfillment_order_id") + if order_id: + if key: + return super(FulfillmentV2, cls).find_one(from_="%s/orders/%s/fulfillments/%s.json" % ( cls.site, order_id, key), **kwargs) + else: + return super(FulfillmentV2, cls).find(from_="%s/orders/%s/fulfillments.json" % ( cls.site, order_id), **kwargs) + elif fulfillment_order: + return super(FulfillmentV2, cls).find(from_="%s/fulfillment_orders/%s/fulfillments.json" % ( cls.site, fulfillment_order), **kwargs) + + def cancel(self): + self._load_attributes_from_response(self.post("cancel")) + def update_tracking(self, tracking_info, notify_customer): body = {"fulfillment": {"tracking_info": tracking_info, "notify_customer": notify_customer}} return self.post("update_tracking", json.dumps(body).encode()) From b07ede244a56702e14f4c15ba4292ef2e3ea25e7 Mon Sep 17 00:00:00 2001 From: Alex Dicketts Date: Tue, 15 Nov 2022 18:53:13 +0000 Subject: [PATCH 14/22] Handle errors and rate limiting --- shopify/base.py | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/shopify/base.py b/shopify/base.py index 47f40cb3..44e598bd 100644 --- a/shopify/base.py +++ b/shopify/base.py @@ -1,9 +1,11 @@ +import logging import pyactiveresource.connection from pyactiveresource.activeresource import ActiveResource, ResourceMeta, formats import shopify.yamlobjects import shopify.mixins as mixins import shopify import threading +import time import sys from six.moves import urllib import six @@ -22,12 +24,33 @@ def __init__(self, site, user=None, password=None, timeout=None, format=formats. def _open(self, *args, **kwargs): self.response = None - try: - self.response = super(ShopifyConnection, self)._open(*args, **kwargs) - except pyactiveresource.connection.ConnectionError as err: - self.response = err.response - raise - return self.response + count_server_error = 0 + while True: + try: + self.response = super(ShopifyConnection, self)._open(*args, **kwargs) + return self.response + except pyactiveresource.connection.ClientError as e: + if e.response.code == 429: + retry_after = float(e.response.headers.get("Retry-After", 4)) + logging.warning("Service exceeds Shopify API call limit, will retry to send request in %d seconds", retry_after) + time.sleep(retry_after) + else: + raise e + except pyactiveresource.connection.ServerError as se: + # For handling Server Errors like 500, 502, 503 etc + if 500 <= se.code <= 599: + retry_after = 2 + logging.warning("Server responded with error code %d will retry to send request in %d seconds", se.code, retry_after) + time.sleep(retry_after) + if count_server_error >= 3: + logging.error("Error connecting to Shopify API, please try again") + self.response = se.response + raise + else: + logging.warning("Server Error Patch Retrying. Current Count - %d", count_server_error) + count_server_error += 1 + else: + raise se # Inherit from pyactiveresource's metaclass in order to use ShopifyConnection From 2fdc504db19bb626c0da44551ac3d6e4452a472d Mon Sep 17 00:00:00 2001 From: Alex Dicketts Date: Fri, 18 Nov 2022 17:51:56 +0000 Subject: [PATCH 15/22] Return graphql result as json --- shopify/resources/graphql.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/shopify/resources/graphql.py b/shopify/resources/graphql.py index 33525ef1..41b9103c 100644 --- a/shopify/resources/graphql.py +++ b/shopify/resources/graphql.py @@ -1,5 +1,4 @@ import shopify -from ..base import ShopifyResource from six.moves import urllib import json @@ -16,7 +15,6 @@ def merge_headers(self, *headers): return merged_headers def execute(self, query, variables=None, operation_name=None): - endpoint = self.endpoint default_headers = {"Accept": "application/json", "Content-Type": "application/json"} headers = self.merge_headers(default_headers, self.headers) data = {"query": query, "variables": variables, "operationName": operation_name} @@ -25,7 +23,7 @@ def execute(self, query, variables=None, operation_name=None): try: response = urllib.request.urlopen(req) - return response.read().decode("utf-8") + return json.loads(response.read().decode("utf-8")) except urllib.error.HTTPError as e: print((e.read())) print("") From 806c85cbe21498d55678903cd2b92559c891fd2f Mon Sep 17 00:00:00 2001 From: Alex Dicketts Date: Sat, 18 Mar 2023 10:19:51 +0000 Subject: [PATCH 16/22] Improve logging --- shopify/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shopify/base.py b/shopify/base.py index 3bb8c1d0..2cf430b8 100644 --- a/shopify/base.py +++ b/shopify/base.py @@ -29,7 +29,7 @@ def _open(self, *args, **kwargs): except pyactiveresource.connection.ClientError as e: if e.response.code == 429: retry_after = float(e.response.headers.get("Retry-After", 4)) - logging.warning("Service exceeds Shopify API call limit, will retry to send request in %d seconds", retry_after) + logging.warning("%s limited, will retry in %d seconds", e.url, retry_after) time.sleep(retry_after) else: raise e From ae1f1da1083b6d057242789a9f092bae8c14e9f6 Mon Sep 17 00:00:00 2001 From: Alex Dicketts Date: Sun, 16 Apr 2023 16:10:09 +0100 Subject: [PATCH 17/22] Add support for split order move --- shopify/resources/fulfillment_order.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shopify/resources/fulfillment_order.py b/shopify/resources/fulfillment_order.py index b73c68f8..34be5fd6 100644 --- a/shopify/resources/fulfillment_order.py +++ b/shopify/resources/fulfillment_order.py @@ -23,6 +23,6 @@ def cancel(self): def close(self): self._load_attributes_from_response(self.post("close")) - def move(self, new_location_id): - body = { 'fulfillment_order' : { 'new_location_id' : new_location_id } } + def move(self, new_location_id, fulfillment_order_line_items = []): + body = { 'fulfillment_order' : { 'new_location_id' : new_location_id, 'fulfillment_order_line_items': fulfillment_order_line_items } } self.post("move", body=json.dumps(body).encode()) From 9604ea187128302bf970853a04c567503a6f3b32 Mon Sep 17 00:00:00 2001 From: Alex Dicketts Date: Thu, 27 Apr 2023 18:18:38 +0100 Subject: [PATCH 18/22] Fixes --- shopify/base.py | 2 +- shopify/resources/fulfillment_order.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/shopify/base.py b/shopify/base.py index 2cf430b8..e58baf23 100644 --- a/shopify/base.py +++ b/shopify/base.py @@ -28,7 +28,7 @@ def _open(self, *args, **kwargs): return self.response except pyactiveresource.connection.ClientError as e: if e.response.code == 429: - retry_after = float(e.response.headers.get("Retry-After", 4)) + retry_after = 2 logging.warning("%s limited, will retry in %d seconds", e.url, retry_after) time.sleep(retry_after) else: diff --git a/shopify/resources/fulfillment_order.py b/shopify/resources/fulfillment_order.py index 34be5fd6..caf40a51 100644 --- a/shopify/resources/fulfillment_order.py +++ b/shopify/resources/fulfillment_order.py @@ -24,5 +24,7 @@ def close(self): self._load_attributes_from_response(self.post("close")) def move(self, new_location_id, fulfillment_order_line_items = []): - body = { 'fulfillment_order' : { 'new_location_id' : new_location_id, 'fulfillment_order_line_items': fulfillment_order_line_items } } + body = { 'fulfillment_order' : { 'new_location_id' : new_location_id } } + if fulfillment_order_line_items: + body['fulfillment_order']['fulfillment_order_line_items'] = fulfillment_order_line_items self.post("move", body=json.dumps(body).encode()) From 90a982e14ab221d6f4b04b210dbb7ea52ab3f665 Mon Sep 17 00:00:00 2001 From: Alex Dicketts Date: Sun, 5 Nov 2023 17:00:02 +0000 Subject: [PATCH 19/22] Update versions --- shopify/api_version.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/shopify/api_version.py b/shopify/api_version.py index 049ee45c..75c63af1 100644 --- a/shopify/api_version.py +++ b/shopify/api_version.py @@ -27,13 +27,12 @@ def define_version(cls, version): @classmethod def define_known_versions(cls): cls.define_version(Unstable()) - cls.define_version(Release("2021-10")) - cls.define_version(Release("2022-01")) - cls.define_version(Release("2022-04")) - cls.define_version(Release("2022-07")) - cls.define_version(Release("2022-10")) cls.define_version(Release("2023-01")) cls.define_version(Release("2023-04")) + cls.define_version(Release("2023-07")) + cls.define_version(Release("2023-10")) + cls.define_version(Release("2024-01")) + cls.define_version(Release("2024-04")) @classmethod def clear_defined_versions(cls): From f2f7d5c4d620a5c5f79e90d290f64111e23415bb Mon Sep 17 00:00:00 2001 From: Alex Dicketts Date: Sun, 30 Jun 2024 21:04:33 +0100 Subject: [PATCH 20/22] Bump version --- shopify/api_version.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/shopify/api_version.py b/shopify/api_version.py index 75c63af1..c92afff4 100644 --- a/shopify/api_version.py +++ b/shopify/api_version.py @@ -27,12 +27,11 @@ def define_version(cls, version): @classmethod def define_known_versions(cls): cls.define_version(Unstable()) - cls.define_version(Release("2023-01")) - cls.define_version(Release("2023-04")) cls.define_version(Release("2023-07")) cls.define_version(Release("2023-10")) cls.define_version(Release("2024-01")) cls.define_version(Release("2024-04")) + cls.define_version(Release("2024-07")) @classmethod def clear_defined_versions(cls): From 2eeee9507f57ac1639120f7a5cee6feb9623d50e Mon Sep 17 00:00:00 2001 From: Alex Dicketts Date: Wed, 9 Oct 2024 18:30:59 +0100 Subject: [PATCH 21/22] Add versions --- shopify/api_version.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/shopify/api_version.py b/shopify/api_version.py index c92afff4..c65437dd 100644 --- a/shopify/api_version.py +++ b/shopify/api_version.py @@ -27,11 +27,14 @@ def define_version(cls, version): @classmethod def define_known_versions(cls): cls.define_version(Unstable()) - cls.define_version(Release("2023-07")) - cls.define_version(Release("2023-10")) cls.define_version(Release("2024-01")) cls.define_version(Release("2024-04")) cls.define_version(Release("2024-07")) + cls.define_version(Release("2024-10")) + cls.define_version(Release("2025-01")) + cls.define_version(Release("2025-04")) + cls.define_version(Release("2025-07")) + cls.define_version(Release("2025-10")) @classmethod def clear_defined_versions(cls): From 06b7b4907bd8377dde875eaac24a8255d001ca6e Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 4 Jan 2026 11:52:27 +0000 Subject: [PATCH 22/22] Update version --- shopify/api_version.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/shopify/api_version.py b/shopify/api_version.py index c65437dd..90fa3d6d 100644 --- a/shopify/api_version.py +++ b/shopify/api_version.py @@ -27,14 +27,14 @@ def define_version(cls, version): @classmethod def define_known_versions(cls): cls.define_version(Unstable()) - cls.define_version(Release("2024-01")) - cls.define_version(Release("2024-04")) - cls.define_version(Release("2024-07")) - cls.define_version(Release("2024-10")) cls.define_version(Release("2025-01")) cls.define_version(Release("2025-04")) cls.define_version(Release("2025-07")) cls.define_version(Release("2025-10")) + cls.define_version(Release("2026-01")) + cls.define_version(Release("2026-04")) + cls.define_version(Release("2026-07")) + cls.define_version(Release("2026-10")) @classmethod def clear_defined_versions(cls):