From f7f7e92758cf495213ea663273f304c6e26ebe27 Mon Sep 17 00:00:00 2001 From: Bill Klenotiz Date: Wed, 7 Dec 2022 09:16:44 -0500 Subject: [PATCH 01/46] add reason --- .github/workflows/stale.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index c194ded1..6b670540 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -29,3 +29,4 @@ jobs: days-before-pr-close: -1 repo-token: ${{ secrets.GITHUB_TOKEN }} exempt-issue-labels: "feature request" + close-issue-reason: "not_planned" \ No newline at end of file From 20bca2195530206719557461126ed7452a2e758a Mon Sep 17 00:00:00 2001 From: Dylan Thacker-Smith Date: Mon, 12 Dec 2022 09:58:05 -0500 Subject: [PATCH 02/46] Trigger CI on PR events --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4c9bc93e..8127de2c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,5 +1,5 @@ name: CI -on: [push] +on: [push, pull_request] jobs: build: runs-on: ubuntu-latest From 2a2b0cd77023433d52e1763e5a3c58cdf40ba3b1 Mon Sep 17 00:00:00 2001 From: Kevin O'Sullivan Date: Mon, 12 Dec 2022 14:25:26 -0500 Subject: [PATCH 03/46] Update 3.10.0 to 3.10 to trigger CI --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8127de2c..75aad488 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,7 +6,7 @@ jobs: name: Python ${{ matrix.version }} strategy: matrix: - version: [3.7, 3.10.0] + version: ["3.7", "3.10"] steps: - name: Checkout From 13ae8ed7bdf7908c9f21896a396325f59411ed90 Mon Sep 17 00:00:00 2001 From: Bill Klenotiz Date: Mon, 12 Dec 2022 16:09:27 -0500 Subject: [PATCH 04/46] add new line --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 6b670540..cd1f94c0 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -29,4 +29,4 @@ jobs: days-before-pr-close: -1 repo-token: ${{ secrets.GITHUB_TOKEN }} exempt-issue-labels: "feature request" - close-issue-reason: "not_planned" \ No newline at end of file + close-issue-reason: "not_planned" From a4670ebae6fb36af4bdfa684c250c91cff315a53 Mon Sep 17 00:00:00 2001 From: Bill Klenotiz Date: Mon, 12 Dec 2022 16:44:41 -0500 Subject: [PATCH 05/46] upgrade pylint --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f8b66bfe..5adbcb8a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,6 +11,6 @@ repos: hooks: - id: black - repo: https://github.com/PyCQA/pylint - rev: pylint-2.7.2 + rev: pylint-2.15.8 hooks: - id: pylint From ebb55d6cb53742b622d0da8dc5b6d6538bc9ff95 Mon Sep 17 00:00:00 2001 From: Paulo Margarido <64600052+paulomarg@users.noreply.github.com> Date: Tue, 13 Dec 2022 09:17:58 -0500 Subject: [PATCH 06/46] Update pylint version in CI --- .pre-commit-config.yaml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f8b66bfe..43267923 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,16 +1,16 @@ # See https://pre-commit.com for more information # See https://pre-commit.com/hooks.html for more hooks repos: -- repo: https://github.com/pre-commit/pre-commit-hooks + - repo: https://github.com/pre-commit/pre-commit-hooks rev: v3.4.0 hooks: - - id: end-of-file-fixer - - id: trailing-whitespace -- repo: https://github.com/psf/black + - id: end-of-file-fixer + - id: trailing-whitespace + - repo: https://github.com/psf/black rev: 22.3.0 hooks: - - id: black -- repo: https://github.com/PyCQA/pylint - rev: pylint-2.7.2 + - id: black + - repo: https://github.com/PyCQA/pylint + rev: v2.15.8 hooks: - - id: pylint + - id: pylint From 8d248d653052ef07f88211c42ef179ea4bfa242b Mon Sep 17 00:00:00 2001 From: Paulo Margarido <64600052+paulomarg@users.noreply.github.com> Date: Tue, 13 Dec 2022 09:28:39 -0500 Subject: [PATCH 07/46] Fix linting errors --- shopify/base.py | 3 --- test/base_test.py | 3 --- test/marketing_event_test.py | 3 --- 3 files changed, 9 deletions(-) diff --git a/shopify/base.py b/shopify/base.py index 47f40cb3..449e288b 100644 --- a/shopify/base.py +++ b/shopify/base.py @@ -17,9 +17,6 @@ class ShopifyConnection(pyactiveresource.connection.Connection): response = None - def __init__(self, site, user=None, password=None, timeout=None, format=formats.JSONFormat): - super(ShopifyConnection, self).__init__(site, user, password, timeout, format) - def _open(self, *args, **kwargs): self.response = None try: diff --git a/test/base_test.py b/test/base_test.py index 5817872e..5cc19a60 100644 --- a/test/base_test.py +++ b/test/base_test.py @@ -17,9 +17,6 @@ def setUpClass(self): def tearDownClass(self): shopify.ApiVersion.clear_defined_versions() - def setUp(self): - super(BaseTest, self).setUp() - def tearDown(self): shopify.ShopifyResource.clear_session() diff --git a/test/marketing_event_test.py b/test/marketing_event_test.py index a3753d63..2f73029d 100644 --- a/test/marketing_event_test.py +++ b/test/marketing_event_test.py @@ -4,9 +4,6 @@ class MarketingEventTest(TestCase): - def setUp(self): - super(MarketingEventTest, self).setUp() - def test_get_marketing_event(self): self.fake("marketing_events/1", method="GET", body=self.load_fixture("marketing_event")) marketing_event = shopify.MarketingEvent.find(1) From 805892e3929bd11c7be27b08f00d1f62f49792e6 Mon Sep 17 00:00:00 2001 From: Rohan Bansal Date: Fri, 28 Oct 2022 16:36:14 +0530 Subject: [PATCH 08/46] feat: update API version to 2022-10 --- CHANGELOG | 1 + shopify/api_version.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index e4f2619f..088dd17f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,5 @@ == Unreleased +- Update API version with 2022-10 release, remove API version 2021-10 == Version 12.0.1 - Allow up to 10 seconds clock skew to avoid `ImmatureSignatureError` diff --git a/shopify/api_version.py b/shopify/api_version.py index 72740b73..5c506c31 100644 --- a/shopify/api_version.py +++ b/shopify/api_version.py @@ -27,10 +27,10 @@ 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")) @classmethod def clear_defined_versions(cls): From 37a639c8735d9b213c4b38249a7e5ad04f57ff0b Mon Sep 17 00:00:00 2001 From: Kevin O'Sullivan Date: Tue, 13 Dec 2022 13:54:34 -0500 Subject: [PATCH 09/46] Add 2022-10 back into api_version.py --- CHANGELOG | 2 +- shopify/api_version.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 088dd17f..c7abf352 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,5 @@ == Unreleased -- Update API version with 2022-10 release, remove API version 2021-10 +- Add API version with 2022-10 release == Version 12.0.1 - Allow up to 10 seconds clock skew to avoid `ImmatureSignatureError` diff --git a/shopify/api_version.py b/shopify/api_version.py index 5c506c31..8beee194 100644 --- a/shopify/api_version.py +++ b/shopify/api_version.py @@ -27,6 +27,7 @@ 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")) From 72c9ecc4d3b62db709a267d57cece7376e5b8918 Mon Sep 17 00:00:00 2001 From: Kevin O'Sullivan Date: Tue, 13 Dec 2022 14:01:02 -0500 Subject: [PATCH 10/46] Release v12.1.0 --- CHANGELOG | 2 ++ shopify/version.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index c7abf352..76b2277f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,6 @@ == Unreleased + +== Version 12.1.0 - Add API version with 2022-10 release == Version 12.0.1 diff --git a/shopify/version.py b/shopify/version.py index 08d8f853..910a54d5 100644 --- a/shopify/version.py +++ b/shopify/version.py @@ -1 +1 @@ -VERSION = "12.0.1" +VERSION = "12.1.0" From c8906a380afd0480ac72dc1c62b70eca78121143 Mon Sep 17 00:00:00 2001 From: Paulo Margarido <64600052+paulomarg@users.noreply.github.com> Date: Thu, 5 Jan 2023 09:42:06 -0500 Subject: [PATCH 11/46] Add support for version 2023-01 --- CHANGELOG | 282 +++++++++++++++++++++++------------------ shopify/api_version.py | 1 + 2 files changed, 162 insertions(+), 121 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 76b2277f..ab2b1e6b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,20 +1,27 @@ == Unreleased +- Update API version with 2023-01 release ([#](https://github.com/Shopify/shopify_python_api/pull/)) + == Version 12.1.0 + - Add API version with 2022-10 release == Version 12.0.1 + - Allow up to 10 seconds clock skew to avoid `ImmatureSignatureError` -([#609](https://github.com/Shopify/shopify_python_api/pull/609)) + ([#609](https://github.com/Shopify/shopify_python_api/pull/609)) == Version 12.0.0 + - Update API version with 2022-04 release, remove API version 2021-07 ([#591](https://github.com/Shopify/shopify_python_api/pull/591)) == Version 11.0.0 + - Update API version with 2022-04 release - remove API version 2020-10, 2021-01, 2021-04 as they are all unsupported as of 2022-04 == Version 10.0.0 + - Update API version with 2022-01 release, remove API version 2020-07 == Version 9.0.0 @@ -23,18 +30,23 @@ - Update API version with 2021-10 release, remove API version 2020-04 ([#548](https://github.com/Shopify/shopify_python_api/pull/548)) == Version 8.4.2 + - Update API version with 2021-07 release, remove API version 2020-01 ([#521](https://github.com/Shopify/shopify_python_api/pull/521)) == Version 8.4.1 + - Bug fix: `sanitize_shop_domain` now returns `None` rather than `'none.myshopify.com'` if no `shop_domain` arg is passed in ([#499](https://github.com/Shopify/shopify_python_api/pull/499)) == Version 8.4.0 + - Revert Feature #441 Dynamic API Versioning ([#495](https://github.com/Shopify/shopify_python_api/pull/495)) == Version 8.3.1 + - Fix bug: Add the `shopify/utils` sub-package when building the source distribution ([#493](https://github.com/Shopify/shopify_python_api/pull/493)) == Version 8.3.0 + - Add support for [session tokens](https://shopify.dev/concepts/apps/building-embedded-apps-using-session-tokens) ([#479](https://github.com/Shopify/shopify_python_api/pull/479)) - Use `session_token.decode_from_header` to obtain a decoded session token from an HTTP Authorization header - Create a `utils` sub-package with a `shop_url` utility file ([#483](https://github.com/Shopify/shopify_python_api/pull/483)) @@ -48,297 +60,325 @@ - Add support for retrieving all orders using customer_id ([#466](https://github.com/Shopify/shopify_python_api/pull/466)) == Version 8.2.0 + - [Feature] Add support for Dynamic API Versioning. When the library is initialized, it will now make a request to -Shopify to fetch a list of the available API versions. ([#441](https://github.com/Shopify/shopify_python_api/pull/441)) + Shopify to fetch a list of the available API versions. ([#441](https://github.com/Shopify/shopify_python_api/pull/441)) == Version 8.1.0 + - [Feature] Add support for Shopify Payments resources (#428) == Version 8.0.4 + - Release API version 2020-10 - Deprecate API version 2019-10 == Version 8.0.3 -- Patch for replacing call to _build_list() with _build_collection() in gift_card.py + +- Patch for replacing call to \_build_list() with \_build_collection() in gift_card.py == Version 8.0.2 + - Patch for product updating with variants == Version 8.0.1 + - release api version 2020-07 - deprecate api version 2019-07 - Add support for FulfillmentOrder resource (#390) == Version 8.0.0 + - release api version 2020-04 - deprecate api version 2019-04 == Version 7.0.3 + - bug fix for temporary sessions - deprecation fix for regexs == Version 7.0.2 + - bug fix for variant updates after the 2019-10 api version == Version 7.0.1 + - bug fix for string interpolation == Version 7.0.0 -* Made no_iter_next default to True on collection so that by default it only -fetches a single page -* Passes kwargs to paginated collections so that attributes can be set with -find() -* Allow case insensitive check for the link header for cursor pagination. + +- Made no_iter_next default to True on collection so that by default it only + fetches a single page +- Passes kwargs to paginated collections so that attributes can be set with + find() +- Allow case insensitive check for the link header for cursor pagination. == Version 6.0.1 -* Made the collection access more consistent so that there is no confusion -between a collection and a paginated collection + +- Made the collection access more consistent so that there is no confusion + between a collection and a paginated collection == Version 6.0.0 -* Add Cursor pagination support + +- Add Cursor pagination support == Version 5.1.2 -* Add version 2020-01 to known ApiVersions. This version will not be usable until October 2019. + +- Add version 2020-01 to known ApiVersions. This version will not be usable until October 2019. == Version 5.1.1 -* Fix initializing API with basic auth URL. + +- Fix initializing API with basic auth URL. == Version 5.1.0 -* Added support for GraphQL queries with a GraphQL resource + +- Added support for GraphQL queries with a GraphQL resource == Version 5.0.1 -* Fixing missing class variable causing exception when creating a session without a token + +- Fixing missing class variable causing exception when creating a session without a token == Version 5.0.0 -* Added support for Shopify API Versioning + +- Added support for Shopify API Versioning == Version 4.0.0 -* Added AccessScope resource -* Added ApiPermission resource -* Added User resource -* Added Publication, CollectionPublication and ProductPublication resources -* Added Currency resource -* Added TenderTransaction resource -* Added shopify.Limits class, for retrieving the current status of Shopify rate limiting. -* Added support for Refund.calculate -* Added support for Location.inventory_levels -* Added support for PriceRule batch operations -* Removed `cancel()` method for RecurringApplicationCharge resource (use `destroy()` going forward) -* Fix for handling array query parameters (e.g. `foo[]=1&foo[]=2`) during HMAC calculation -* Fixed Python 3 compatibility with the API console + +- Added AccessScope resource +- Added ApiPermission resource +- Added User resource +- Added Publication, CollectionPublication and ProductPublication resources +- Added Currency resource +- Added TenderTransaction resource +- Added shopify.Limits class, for retrieving the current status of Shopify rate limiting. +- Added support for Refund.calculate +- Added support for Location.inventory_levels +- Added support for PriceRule batch operations +- Removed `cancel()` method for RecurringApplicationCharge resource (use `destroy()` going forward) +- Fix for handling array query parameters (e.g. `foo[]=1&foo[]=2`) during HMAC calculation +- Fixed Python 3 compatibility with the API console == Version 3.1.0 -* Adds InventoryItem resource -* Adds InventoryLevel resource -* Adds GiftCardAdjustment resource -* Fix to properly handle byte data for Asset.attach() + +- Adds InventoryItem resource +- Adds InventoryLevel resource +- Adds GiftCardAdjustment resource +- Fix to properly handle byte data for Asset.attach() == Version 3.0.0 -* Added CollectListing resource -* Added ResourceFeedback resource -* Added StorefrontAccessToken resource -* Added ProductListing resource -* Removed deprecated ProductSearchEngine resource -* Removed deprecated Discount resource -* Fixed Python3 compatibility issue with `Image.attach_image()` + +- Added CollectListing resource +- Added ResourceFeedback resource +- Added StorefrontAccessToken resource +- Added ProductListing resource +- Removed deprecated ProductSearchEngine resource +- Removed deprecated Discount resource +- Fixed Python3 compatibility issue with `Image.attach_image()` == Version 2.6.0 -* Added support for Marketing Event API through Marketing Event resource + +- Added support for Marketing Event API through Marketing Event resource == Version 2.5.1 -* Fixed an issue preventing creation of Order Risk resources + +- Fixed an issue preventing creation of Order Risk resources == Version 2.5.0 -* Added Price Rule and Discount Code resources + +- Added Price Rule and Discount Code resources == Version 2.4.0 -* Add support for report publishing + +- Add support for report publishing == Version 2.3.0 -* Add support for customer#send_invite + +- Add support for customer#send_invite == Version 2.2.0 -* Add support for draft orders + +- Add support for draft orders == Version 2.1.8 -* Added support for `open` method on fulfillments + +- Added support for `open` method on fulfillments == Version 2.1.7 -* Removed all references to the deprecated MD5 `signature` parameter which is no longer provided by Shopify. +- Removed all references to the deprecated MD5 `signature` parameter which is no longer provided by Shopify. == Version 2.1.6 -* Added Refund resource +- Added Refund resource == Version 2.1.5 -* bump pyactiveresource for camelcase bugfix +- bump pyactiveresource for camelcase bugfix == Version 2.1.4 == Version 2.1.3 -* Fixed hmac signature validation for params with delimiters (`&`, `=` or `%`) +- Fixed hmac signature validation for params with delimiters (`&`, `=` or `%`) == Version 2.1.2 -* Fixed an issue with unicode strings in params passed to validate_hmac -* Added shop domain verification when creating a session +- Fixed an issue with unicode strings in params passed to validate_hmac +- Added shop domain verification when creating a session == Version 2.1.1 -* Added Checkout resource -* Updated to pyactiveresource v2.1.1 which includes a test-related bugfix -* Changed OAuth validation from MD5 to HMAC-SHA256 +- Added Checkout resource +- Updated to pyactiveresource v2.1.1 which includes a test-related bugfix +- Changed OAuth validation from MD5 to HMAC-SHA256 == Version 2.1.0 -* Added python 3 compatibility -* Fixed setting the format attribute on carrier and fulfillment services -* Add a specific exception for signature validation failures +- Added python 3 compatibility +- Fixed setting the format attribute on carrier and fulfillment services +- Add a specific exception for signature validation failures == Version 2.0.4 -* Bug fixes -* Added CarrierService resource -* Added Property resource to LineItem +- Bug fixes +- Added CarrierService resource +- Added Property resource to LineItem == Version 2.0.3 -* Add Order Risk resource +- Add Order Risk resource == Version 2.0.2 -* Add access to FulfillmentService endpoint -* Fix some import bugs +- Add access to FulfillmentService endpoint +- Fix some import bugs == Version 2.0.1 -* Package bug fix +- Package bug fix == Version 2.0.0 -* Removed support for legacy auth -* Updated to pyactiveresource v2.0.0 which changes the default form to JSON -* in Session::request_token params is no longer optional, you must pass all the params +- Removed support for legacy auth +- Updated to pyactiveresource v2.0.0 which changes the default form to JSON +- in Session::request_token params is no longer optional, you must pass all the params and the method will now extract the code -* made create_permission_url an instance method, you'll need an instance +- made create_permission_url an instance method, you'll need an instance of session to call this method from now on -* Updated session.request_token -* Updated Session to better match the ShopifyAPI Ruby gem -* Updated the readme to better describe how to use the library -* Added support for CustomerSavedSearch (CustomerGroup is deprecated) +- Updated session.request_token +- Updated Session to better match the ShopifyAPI Ruby gem +- Updated the readme to better describe how to use the library +- Added support for CustomerSavedSearch (CustomerGroup is deprecated) == Version 1.0.7 -* Fix thread local headers to store a copy of the default hash which -prevents activate_session in one thread from affecting other threads. +- Fix thread local headers to store a copy of the default hash which + prevents activate_session in one thread from affecting other threads. == Version 1.0.6 -* Fix deserializing and serializing fulfillments which can now contain -arrays of strings in the tracking_urls attribute. +- Fix deserializing and serializing fulfillments which can now contain + arrays of strings in the tracking_urls attribute. == Version 1.0.5 -* Fix parameter passing for order cancellation. -* Fix Product.price_range method for variants with different prices. +- Fix parameter passing for order cancellation. +- Fix Product.price_range method for variants with different prices. == Version 1.0.4 -* Fixed another bug in Image size methods regex. +- Fixed another bug in Image size methods regex. == Version 1.0.3 -* Fix bug in setting format attribute on Webhook instances. -* Fixed missing slash in return value of Image size methods -* Upgrade pyactiveresource to fix unicode encoding issues +- Fix bug in setting format attribute on Webhook instances. +- Fixed missing slash in return value of Image size methods +- Upgrade pyactiveresource to fix unicode encoding issues == Version 1.0.2 -* Made ShopifyResource.clear_session idempotent. +- Made ShopifyResource.clear_session idempotent. == Version 1.0.1 -* Use the correct redirect parameter in Session.create_permission_url. -Was redirect_url but corrected to redirect_uri. +- Use the correct redirect parameter in Session.create_permission_url. + Was redirect_url but corrected to redirect_uri. == Version 1.0.0 -* Added support for OAuth2. -* ShopifyResource.activate_session must now be used with OAuth2 instead -of setting ShopifyResource.site directly. -* Session.__init__ no longer allows params to be passed in as **params -* Session.__init__ now makes an HTTP request when using OAuth2 if -params are specified -* Session now exposes the access token through the token instance -variable to simplify session saving and resuming +- Added support for OAuth2. +- ShopifyResource.activate_session must now be used with OAuth2 instead + of setting ShopifyResource.site directly. +- Session.**init** no longer allows params to be passed in as \*\*params +- Session.**init** now makes an HTTP request when using OAuth2 if + params are specified +- Session now exposes the access token through the token instance + variable to simplify session saving and resuming == Version 0.4.0 -* Using setup.py no longer requires all dependencies -* More compatibility fixes for using the latest pyactiveresource -* ShopifyResource.activate_session is not recommended over setting site -directly for forward compatibility with coming OAuth2 changes. +- Using setup.py no longer requires all dependencies +- More compatibility fixes for using the latest pyactiveresource +- ShopifyResource.activate_session is not recommended over setting site + directly for forward compatibility with coming OAuth2 changes. == Version 0.3.1 -* Compatibility fixes for using latest (unreleased) pyactiveresource +- Compatibility fixes for using latest (unreleased) pyactiveresource == Version 0.3.0 -* Added support for customer search and customer group search. -* Resource errors are cleared on save from previous save attempt. -* Made the library thread-safe using thread-local connections. +- Added support for customer search and customer group search. +- Resource errors are cleared on save from previous save attempt. +- Made the library thread-safe using thread-local connections. == Version 0.2.1 -* Fixed a regression that caused a different connection -object to be created on each resource. +- Fixed a regression that caused a different connection + object to be created on each resource. == Version 0.2.0 -* Made responses available through the connection object. +- Made responses available through the connection object. == Version 0.1.8 -* Added ability to add metafields on customers. +- Added ability to add metafields on customers. == Version 0.1.7 -* Fixed missing theme_id in return value of Asset.find. +- Fixed missing theme_id in return value of Asset.find. == Version 0.1.6 -* Fixed attribute setting on Asset objects -* Strip path from shop_url to get just the shop's domain. +- Fixed attribute setting on Asset objects +- Strip path from shop_url to get just the shop's domain. == Version 0.1.5 -* Fixed Asset.find() -* Fixed Variant.find(id) -* Allow running from source directory with PYTHONPATH=./lib +- Fixed Asset.find() +- Fixed Variant.find(id) +- Allow running from source directory with PYTHONPATH=./lib == Version 0.1.4 -* Fixed a bug in metafields method caused by missing import. -* Prefix options can be specified in the attributes dict on creation -* Allow count method to be used the same way as find +- Fixed a bug in metafields method caused by missing import. +- Prefix options can be specified in the attributes dict on creation +- Allow count method to be used the same way as find == Version 0.1.3 -* Fixed the automatic download of dependencies. -* Updated the README instructions. +- Fixed the automatic download of dependencies. +- Updated the README instructions. == Version 0.1.2 -* Add python 2.5 compatibility +- Add python 2.5 compatibility == Version 0.1.1 -* Make creating a session simpler with django +- Make creating a session simpler with django == Version 0.1.0 -* ported ShopifyAPI from ruby to python +- ported ShopifyAPI from ruby to python diff --git a/shopify/api_version.py b/shopify/api_version.py index 8beee194..df2bc5bb 100644 --- a/shopify/api_version.py +++ b/shopify/api_version.py @@ -32,6 +32,7 @@ def define_known_versions(cls): cls.define_version(Release("2022-04")) cls.define_version(Release("2022-07")) cls.define_version(Release("2022-10")) + cls.define_version(Release("2023-01")) @classmethod def clear_defined_versions(cls): From b00e5061da834e74d49bd311b80760e755e99782 Mon Sep 17 00:00:00 2001 From: Paulo Margarido <64600052+paulomarg@users.noreply.github.com> Date: Thu, 5 Jan 2023 11:39:00 -0500 Subject: [PATCH 12/46] Release v12.2.0 --- CHANGELOG | 4 +++- shopify/version.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index ab2b1e6b..0fede9d6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,8 @@ == Unreleased -- Update API version with 2023-01 release ([#](https://github.com/Shopify/shopify_python_api/pull/)) +== Version 12.2.0 + +- Update API version with 2023-01 release ([#631](https://github.com/Shopify/shopify_python_api/pull/631)) == Version 12.1.0 diff --git a/shopify/version.py b/shopify/version.py index 910a54d5..e77ed636 100644 --- a/shopify/version.py +++ b/shopify/version.py @@ -1 +1 @@ -VERSION = "12.1.0" +VERSION = "12.2.0" From 4f21cbc843df44e41f1a3adc8b66fdbf65c3f762 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Wed, 12 Apr 2023 07:51:42 +0100 Subject: [PATCH 13/46] Remove unused cgi import --- CHANGELOG | 2 ++ shopify/collection.py | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 0fede9d6..cacf47b7 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,7 @@ == Unreleased +- Remove `cgi` import to avoid triggering a `DeprecationWarning` on Python 3.11. + == Version 12.2.0 - Update API version with 2023-01 release ([#631](https://github.com/Shopify/shopify_python_api/pull/631)) diff --git a/shopify/collection.py b/shopify/collection.py index 42bc8ebb..62728eb9 100644 --- a/shopify/collection.py +++ b/shopify/collection.py @@ -1,6 +1,4 @@ from pyactiveresource.collection import Collection -from six.moves.urllib.parse import urlparse, parse_qs -import cgi class PaginatedCollection(Collection): From 5f72f840f02db4e2bec9c094f4c9544bfc2a2ba7 Mon Sep 17 00:00:00 2001 From: Kevin O'Sullivan Date: Wed, 12 Apr 2023 11:41:51 -0400 Subject: [PATCH 14/46] Add API release 2023-04 --- shopify/api_version.py | 1 + 1 file changed, 1 insertion(+) diff --git a/shopify/api_version.py b/shopify/api_version.py index df2bc5bb..049ee45c 100644 --- a/shopify/api_version.py +++ b/shopify/api_version.py @@ -33,6 +33,7 @@ def define_known_versions(cls): cls.define_version(Release("2022-07")) cls.define_version(Release("2022-10")) cls.define_version(Release("2023-01")) + cls.define_version(Release("2023-04")) @classmethod def clear_defined_versions(cls): From 91945a47639b85013f81223349fe61655dc5f8de Mon Sep 17 00:00:00 2001 From: Kevin O'Sullivan Date: Wed, 12 Apr 2023 11:43:53 -0400 Subject: [PATCH 15/46] Update CHANGELOG --- CHANGELOG | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 0fede9d6..796971ff 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,7 @@ == Unreleased +- Update API version with 2023-04 release ([#649](https://github.com/Shopify/shopify_python_api/pull/649)) + == Version 12.2.0 - Update API version with 2023-01 release ([#631](https://github.com/Shopify/shopify_python_api/pull/631)) From cfc417fbd5e9c268da92cd00a25a74b6b3ffec95 Mon Sep 17 00:00:00 2001 From: Kevin O'Sullivan Date: Wed, 12 Apr 2023 11:46:16 -0400 Subject: [PATCH 16/46] Add 3.8, 3.9 and 3.11 to test matrix --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 75aad488..2a44a442 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,13 +6,13 @@ jobs: name: Python ${{ matrix.version }} strategy: matrix: - version: ["3.7", "3.10"] + version: ["3.7", "3.8", "3.9", "3.10", "3.11"] steps: - name: Checkout uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.version }} - name: Install Dependencies From 8d8e01e0330c1d9e256f4eee73d4b8b5d2116cd3 Mon Sep 17 00:00:00 2001 From: Kevin O'Sullivan Date: Wed, 12 Apr 2023 11:52:12 -0400 Subject: [PATCH 17/46] Update setup.py with additional versions --- setup.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index a798cb78..dae5a810 100755 --- a/setup.py +++ b/setup.py @@ -39,11 +39,11 @@ "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.4", - "Programming Language :: Python :: 3.5", - "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", "Topic :: Software Development", "Topic :: Software Development :: Libraries", "Topic :: Software Development :: Libraries :: Python Modules", From 5f295932bebbdde1835d35c4865093ff83564cdc Mon Sep 17 00:00:00 2001 From: Kevin O'Sullivan Date: Wed, 12 Apr 2023 12:10:00 -0400 Subject: [PATCH 18/46] Release v12.3.0 --- CHANGELOG | 2 ++ shopify/version.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 796971ff..868d99c1 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,7 @@ == Unreleased +== Version 12.3.0 + - Update API version with 2023-04 release ([#649](https://github.com/Shopify/shopify_python_api/pull/649)) == Version 12.2.0 diff --git a/shopify/version.py b/shopify/version.py index e77ed636..a48d177f 100644 --- a/shopify/version.py +++ b/shopify/version.py @@ -1 +1 @@ -VERSION = "12.2.0" +VERSION = "12.3.0" From df252c81c47e993d3a07cb0bb62c643f483dec02 Mon Sep 17 00:00:00 2001 From: Lewis Morris <36413348+lewis-morris@users.noreply.github.com> Date: Thu, 14 Sep 2023 21:51:35 +0100 Subject: [PATCH 19/46] Update README.md no imports listed in guide --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d473a015..cc61c076 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ pip install --upgrade ShopifyAPI 1. We then need to supply these keys to the Shopify Session Class so that it knows how to authenticate. ```python + import shopify shopify.Session.setup(api_key=API_KEY, secret=API_SECRET) ``` 1. In order to access a shop's data, apps need an access token from that specific shop. We need to authenticate with that shop using OAuth, which we can start in the following way: From 454481d70cfb8acc23ef67ddddaa097ecca9c88f Mon Sep 17 00:00:00 2001 From: Alessandro <72794815+alemrcc@users.noreply.github.com> Date: Wed, 29 Nov 2023 21:05:17 +0100 Subject: [PATCH 20/46] I added a bit more information about the usage of the method find() and the usage of parameters since it took me a while to figure out how to do it. --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index d473a015..3f9aa737 100644 --- a/README.md +++ b/README.md @@ -160,6 +160,12 @@ product.destroy() # Delete the resource from the remote server (i.e. Shopify) ``` +Here is another example to retrieve a list of open orders using certain parameters: + +```python +new_orders = shopify.Order.find(status="open", limit="50") +``` + ### Prefix options Some resources such as `Fulfillment` are prefixed by a parent resource in the Shopify API (e.g. `orders/450789469/fulfillments/255858046`). In order to interact with these resources, you must specify the identifier of the parent resource in your request. From 5165407f50d7784c21c32d12e3b47c875647792d Mon Sep 17 00:00:00 2001 From: Paulo Margarido <64600052+paulomarg@users.noreply.github.com> Date: Wed, 10 Jan 2024 17:22:02 -0300 Subject: [PATCH 21/46] Add support for missing API versions --- .github/workflows/pre-commit.yml | 2 +- CHANGELOG | 2 ++ shopify/api_version.py | 3 +++ test/session_token_test.py | 2 +- 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 54fc61d5..048bc5a2 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -12,6 +12,6 @@ jobs: - name: Checkout uses: actions/checkout@v2 - name: Setup - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 - name: Pre-commit uses: pre-commit/action@v2.0.0 diff --git a/CHANGELOG b/CHANGELOG index 868d99c1..3fb31f2c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,7 @@ == Unreleased +- Update API version with 2023-07, 2023-10, 2024-01 releases ([#694](https://github.com/Shopify/shopify_python_api/pull/694)) + == Version 12.3.0 - Update API version with 2023-04 release ([#649](https://github.com/Shopify/shopify_python_api/pull/649)) diff --git a/shopify/api_version.py b/shopify/api_version.py index 049ee45c..ba137d57 100644 --- a/shopify/api_version.py +++ b/shopify/api_version.py @@ -34,6 +34,9 @@ def define_known_versions(cls): 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")) @classmethod def clear_defined_versions(cls): diff --git a/test/session_token_test.py b/test/session_token_test.py index f94fe0b2..0df7147f 100644 --- a/test/session_token_test.py +++ b/test/session_token_test.py @@ -79,7 +79,7 @@ def test_raises_if_aud_doesnt_match_api_key(self): with self.assertRaises(session_token.SessionTokenError) as cm: session_token.decode_from_header(self.build_auth_header(), api_key=self.api_key, secret=self.secret) - self.assertEqual("Invalid audience", str(cm.exception)) + self.assertEqual("Audience doesn't match", str(cm.exception)) def test_raises_if_issuer_hostname_is_invalid(self): self.payload["iss"] = "bad_shop_hostname" From 2b1561b9f4a08676410dee6299c6365bd0649b06 Mon Sep 17 00:00:00 2001 From: Melanie Wang Date: Wed, 10 Jan 2024 16:04:36 -0500 Subject: [PATCH 22/46] Release v12.4.0 --- CHANGELOG | 2 ++ shopify/version.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 3fb31f2c..fb65b5a9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,7 @@ == Unreleased +== 12.4.0 + - Update API version with 2023-07, 2023-10, 2024-01 releases ([#694](https://github.com/Shopify/shopify_python_api/pull/694)) == Version 12.3.0 diff --git a/shopify/version.py b/shopify/version.py index a48d177f..7c16e69e 100644 --- a/shopify/version.py +++ b/shopify/version.py @@ -1 +1 @@ -VERSION = "12.3.0" +VERSION = "12.4.0" From c1df76338fb779784b31a0c79c79d2faa0605446 Mon Sep 17 00:00:00 2001 From: Fai Date: Fri, 19 Jan 2024 23:31:32 +0800 Subject: [PATCH 23/46] Add ipython support for console interaction --- scripts/shopify_api.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/scripts/shopify_api.py b/scripts/shopify_api.py index 141f4bee..5dfab93a 100755 --- a/scripts/shopify_api.py +++ b/scripts/shopify_api.py @@ -16,10 +16,18 @@ def start_interpreter(**variables): # add the current working directory to the sys paths sys.path.append(os.getcwd()) - console = type("shopify " + shopify.version.VERSION, (code.InteractiveConsole, object), {}) - import readline + try: + from IPython import start_ipython + from traitlets.config.loader import Config - console(variables).interact() + config = Config(TerminalInteractiveShell={"banner2": "(shopify %s)" % shopify.version.VERSION}) + start_ipython(argv=[], user_ns=variables, config=config) + + except ImportError: + console = type("shopify " + shopify.version.VERSION, (code.InteractiveConsole, object), {}) + import readline + + console(variables).interact() class ConfigFileError(Exception): From 65b2408d97e03e646de66094e61f2766b4bcdd52 Mon Sep 17 00:00:00 2001 From: Luke Singham Date: Wed, 24 Jan 2024 13:31:22 +0000 Subject: [PATCH 24/46] Add code highlighting code block --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d473a015..eb051f4c 100644 --- a/README.md +++ b/README.md @@ -242,7 +242,7 @@ python setup.py test ## Relative Cursor Pagination Cursor based pagination support has been added in 6.0.0. -``` +```python import shopify page1 = shopify.Product.find() From 832a53d1f964004a677f29e3bc1727180883c21a Mon Sep 17 00:00:00 2001 From: Ju Liu Date: Tue, 13 Feb 2024 11:33:08 +0000 Subject: [PATCH 25/46] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1d67ba2b..2329b18c 100644 --- a/README.md +++ b/README.md @@ -47,13 +47,14 @@ pip install --upgrade ShopifyAPI ```python import shopify + shopify.Session.setup(api_key=API_KEY, secret=API_SECRET) ``` 1. In order to access a shop's data, apps need an access token from that specific shop. We need to authenticate with that shop using OAuth, which we can start in the following way: ```python shop_url = "SHOP_NAME.myshopify.com" - api_version = '2020-10' + api_version = '2024-01' state = binascii.b2a_hex(os.urandom(15)).decode("utf-8") redirect_uri = "http://myapp.com/auth/shopify/callback" scopes = ['read_products', 'read_orders'] From 8c2931fe535b183fe5616bb4b668a97b92f5dfff Mon Sep 17 00:00:00 2001 From: Ju Liu Date: Tue, 13 Feb 2024 11:34:28 +0000 Subject: [PATCH 26/46] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2329b18c..7dc84ed5 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ pip install --upgrade ShopifyAPI ```python import shopify - + shopify.Session.setup(api_key=API_KEY, secret=API_SECRET) ``` 1. In order to access a shop's data, apps need an access token from that specific shop. We need to authenticate with that shop using OAuth, which we can start in the following way: From 81252346c63cb51d25ebdd1e0d44c85b68aa7479 Mon Sep 17 00:00:00 2001 From: Elizabeth Kenyon Date: Mon, 8 Apr 2024 13:43:41 -0500 Subject: [PATCH 27/46] Add support for April24 API version --- CHANGELOG | 1 + shopify/api_version.py | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index c7309ca8..0a0c47e4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ == Unreleased - Remove `cgi` import to avoid triggering a `DeprecationWarning` on Python 3.11. +- Update API version with 2024-04 release. == Version 12.4.0 diff --git a/shopify/api_version.py b/shopify/api_version.py index ba137d57..a0a1531e 100644 --- a/shopify/api_version.py +++ b/shopify/api_version.py @@ -37,6 +37,7 @@ def define_known_versions(cls): 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 74373bfc93ddc2539b2bd442f5ea2876ec5345ec Mon Sep 17 00:00:00 2001 From: Elizabeth Kenyon Date: Mon, 8 Apr 2024 14:58:51 -0500 Subject: [PATCH 28/46] Update codecov action Testing to see if this resolves the pipeline failures --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2a44a442..58a2a8cb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,7 +24,7 @@ jobs: - name: Run Tests run: python -m pytest -v - name: upload coverage to Codecov - uses: codecov/codecov-action@v1 + uses: codecov/codecov-action@v3 with: name: codecov-umbrella fail_ci_if_error: true From 8029a749cafeac18a95fe5546867a369a4c719c8 Mon Sep 17 00:00:00 2001 From: Elizabeth Kenyon Date: Tue, 9 Apr 2024 09:53:00 -0500 Subject: [PATCH 29/46] turn off CI failure for codecov We are getting increasing failures because of this task --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 58a2a8cb..e7ec6d36 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,7 +24,7 @@ jobs: - name: Run Tests run: python -m pytest -v - name: upload coverage to Codecov - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v1 with: name: codecov-umbrella - fail_ci_if_error: true + fail_ci_if_error: false From 65f5ce2a6f30d49995c8af6ff52796f5a0ffe9cc Mon Sep 17 00:00:00 2001 From: Elizabeth Kenyon Date: Tue, 9 Apr 2024 10:28:01 -0500 Subject: [PATCH 30/46] Preparing for release --- CHANGELOG | 3 ++- shopify/version.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 0a0c47e4..c4462f6e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,7 +1,8 @@ == Unreleased +== Version 12.5.0 - Remove `cgi` import to avoid triggering a `DeprecationWarning` on Python 3.11. -- Update API version with 2024-04 release. +- Update API version with 2024-04 release.([710](https://github.com/Shopify/shopify_python_api/pull/710)) == Version 12.4.0 diff --git a/shopify/version.py b/shopify/version.py index 7c16e69e..3958d1de 100644 --- a/shopify/version.py +++ b/shopify/version.py @@ -1 +1 @@ -VERSION = "12.4.0" +VERSION = "12.5.0" From 2ef7f2219fe06260e7af4d7ca531f9a8f9f3db3d Mon Sep 17 00:00:00 2001 From: bvoelsch Date: Thu, 11 Jan 2024 15:08:14 -0700 Subject: [PATCH 31/46] Update __init__.py Add FulfillmentV2 method to init --- shopify/resources/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shopify/resources/__init__.py b/shopify/resources/__init__.py index 16220739..0d420b38 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, FulfillmentOrders, FulfillmentV2 from .fulfillment_event import FulfillmentEvent from .fulfillment_service import FulfillmentService from .carrier_service import CarrierService From a9277784740ef03c2789c868dfb957b3e670725a Mon Sep 17 00:00:00 2001 From: Matteo Depalo Date: Wed, 22 May 2024 15:43:20 +0100 Subject: [PATCH 32/46] Rename master to main --- .github/workflows/pre-commit.yml | 2 +- .github/workflows/stale.yml | 2 +- README.md | 34 ++++++++++++++++++++------------ RELEASING | 2 +- SECURITY.md | 2 +- 5 files changed, 25 insertions(+), 17 deletions(-) diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 048bc5a2..f92848d7 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -3,7 +3,7 @@ name: pre-commit on: pull_request: push: - branches: [master] + branches: [main] jobs: pre-commit: diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index cd1f94c0..2d0a3ec7 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -22,7 +22,7 @@ jobs: This probably means that it is not reproducible or it has been fixed in a newer version. If it’s an enhancement and hasn’t been taken on since it was submitted, then it seems other issues have taken priority. - If you still encounter this issue with the latest stable version, please reopen using the issue template. You can also contribute directly by submitting a pull request– see the [CONTRIBUTING.md](https://github.com/Shopify/shopify_python_api/blob/master/CONTRIBUTING.md) file for guidelines + If you still encounter this issue with the latest stable version, please reopen using the issue template. You can also contribute directly by submitting a pull request– see the [CONTRIBUTING.md](https://github.com/Shopify/shopify_python_api/blob/main/CONTRIBUTING.md) file for guidelines Thank you! days-before-pr-stale: -1 diff --git a/README.md b/README.md index 7dc84ed5..d8519b1b 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ [![Build Status](https://github.com/Shopify/shopify_python_api/workflows/CI/badge.svg)](https://github.com/Shopify/shopify_python_api/actions) [![PyPI version](https://badge.fury.io/py/ShopifyAPI.svg)](https://badge.fury.io/py/ShopifyAPI) -[![codecov](https://codecov.io/gh/Shopify/shopify_python_api/branch/master/graph/badge.svg?token=pNTx0TARUx)](https://codecov.io/gh/Shopify/shopify_python_api) -[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/Shopify/shopify_python_api/blob/master/LICENSE) +[![codecov](https://codecov.io/gh/Shopify/shopify_python_api/branch/main/graph/badge.svg?token=pNTx0TARUx)](https://codecov.io/gh/Shopify/shopify_python_api) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/Shopify/shopify_python_api/blob/main/LICENSE) [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit) The [Shopify Admin API](https://shopify.dev/docs/admin-api) Python Library @@ -23,20 +23,28 @@ pip install --upgrade ShopifyAPI ### Table of Contents -- [Getting Started](#getting-started) - - [Public and Custom Apps](#public-and-custom-apps) - - [Private Apps](#private-apps) -- [Billing](#billing) -- [Session Tokens](docs/session-tokens.md) -- [Handling Access Scope Operations](docs/api-access.md) -- [Advanced Usage](#advanced-usage) -- [Prefix Options](#prefix-options) -- [Console](#console) -- [GraphQL](#graphql) +- [Usage](#usage) + - [Requirements](#requirements) + - [Installation](#installation) + - [Table of Contents](#table-of-contents) + - [Getting Started](#getting-started) + - [Public and Custom Apps](#public-and-custom-apps) + - [Private Apps](#private-apps) + - [With full session](#with-full-session) + - [With temporary session](#with-temporary-session) + - [Billing](#billing) + - [Advanced Usage](#advanced-usage) + - [Prefix options](#prefix-options) + - [Console](#console) + - [GraphQL](#graphql) - [Using Development Version](#using-development-version) + - [Building and installing dev version](#building-and-installing-dev-version) + - [Running Tests](#running-tests) - [Relative Cursor Pagination](#relative-cursor-pagination) +- [Set up pre-commit locally \[OPTIONAL\]](#set-up-pre-commit-locally-optional) - [Limitations](#limitations) - [Additional Resources](#additional-resources) + - [Sample apps built using this library](#sample-apps-built-using-this-library) ### Getting Started @@ -263,7 +271,7 @@ page2 = shopify.Product.find(from_=next_url) ``` ## Set up pre-commit locally [OPTIONAL] -[Pre-commit](https://pre-commit.com/) is set up as a GitHub action that runs on pull requests and pushes to the `master` branch. If you want to run pre-commit locally, install it and set up the git hook scripts +[Pre-commit](https://pre-commit.com/) is set up as a GitHub action that runs on pull requests and pushes to the `main` branch. If you want to run pre-commit locally, install it and set up the git hook scripts ```shell pip install -r requirements.txt pre-commit install diff --git a/RELEASING b/RELEASING index f84fa314..a15667a0 100644 --- a/RELEASING +++ b/RELEASING @@ -15,6 +15,6 @@ Releasing shopify_python_api git tag -m "Release X.Y.Z" vX.Y.Z 7. Push the changes to github - git push --tags origin master + git push --tags origin main 8. Shipit! diff --git a/SECURITY.md b/SECURITY.md index 2d13b5e1..2a0e9c48 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -4,7 +4,7 @@ ### New features -New features will only be added to the master branch and will not be made available in point releases. +New features will only be added to the main branch and will not be made available in point releases. ### Bug fixes From 741555f072d41309d1233fe07e08977715498aa6 Mon Sep 17 00:00:00 2001 From: Paulo Margarido <64600052+paulomarg@users.noreply.github.com> Date: Tue, 2 Jul 2024 14:19:41 -0400 Subject: [PATCH 33/46] Add support for 2024-07 API version --- .github/workflows/build.yml | 4 ++-- CHANGELOG | 3 +++ README.md | 2 +- shopify/api_version.py | 1 + 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e7ec6d36..c0cd5ab9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,7 +6,7 @@ jobs: name: Python ${{ matrix.version }} strategy: matrix: - version: ["3.7", "3.8", "3.9", "3.10", "3.11"] + version: ["3.8", "3.9", "3.10", "3.11", "3.12"] steps: - name: Checkout @@ -18,7 +18,7 @@ jobs: - name: Install Dependencies run: | python -m pip install --upgrade pip - pip install pytest mock pytest-cov + pip install pytest mock pytest-cov setuptools python setup.py install pytest --cov=./ --cov-report=xml - name: Run Tests diff --git a/CHANGELOG b/CHANGELOG index c4462f6e..24fb1752 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,9 @@ == Unreleased +- Update API version with 2024-07 release ([#](https://github.com/Shopify/shopify_python_api/pull/)) + == Version 12.5.0 + - Remove `cgi` import to avoid triggering a `DeprecationWarning` on Python 3.11. - Update API version with 2024-04 release.([710](https://github.com/Shopify/shopify_python_api/pull/710)) diff --git a/README.md b/README.md index d8519b1b..066bd343 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ pip install --upgrade ShopifyAPI ```python shop_url = "SHOP_NAME.myshopify.com" - api_version = '2024-01' + api_version = '2024-07' state = binascii.b2a_hex(os.urandom(15)).decode("utf-8") redirect_uri = "http://myapp.com/auth/shopify/callback" scopes = ['read_products', 'read_orders'] diff --git a/shopify/api_version.py b/shopify/api_version.py index a0a1531e..22df6052 100644 --- a/shopify/api_version.py +++ b/shopify/api_version.py @@ -38,6 +38,7 @@ def define_known_versions(cls): 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 05d59c88c82994dfebf683c35acdebea9a8fab7b Mon Sep 17 00:00:00 2001 From: Paulo Margarido <64600052+paulomarg@users.noreply.github.com> Date: Tue, 2 Jul 2024 14:38:26 -0400 Subject: [PATCH 34/46] Release v12.6.0 --- CHANGELOG | 4 +++- shopify/version.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 24fb1752..cd636df3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,8 @@ == Unreleased -- Update API version with 2024-07 release ([#](https://github.com/Shopify/shopify_python_api/pull/)) +== Version 12.6.0 + +- Update API version with 2024-07 release ([#723](https://github.com/Shopify/shopify_python_api/pull/723)) == Version 12.5.0 diff --git a/shopify/version.py b/shopify/version.py index 3958d1de..7293b298 100644 --- a/shopify/version.py +++ b/shopify/version.py @@ -1 +1 @@ -VERSION = "12.5.0" +VERSION = "12.6.0" From f7fe4c663c4d341fbbbed0b9691354ba288fa7ba Mon Sep 17 00:00:00 2001 From: James Gilmore Date: Tue, 9 Jul 2024 10:53:52 +0100 Subject: [PATCH 35/46] Add support for building the package in Python 3.12 As discussed in the [issue](https://github.com/Shopify/shopify_python_api/issues/725) there is an issue when trying to install this package when using Python 3.12. The issue is caused by [PEP-632](https://peps.python.org/pep-0632/) removing `distutils` from the built-in libraries this version of python is shipped with. In versions 6.0.0 and lower of PyYaml, this causes the build the fail. As mentioned in their [issue](https://github.com/yaml/pyyaml/issues/756) using v6.0.1 or later will resolve this issue. So updating our `setup.py` install_requires dependency specifications to reflect this. While I'm here, also update the classifiers to include support for PY3.12 and show this more clearly on the README of the repo. --- README.md | 1 + setup.py | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 066bd343..a8fa6d74 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![Build Status](https://github.com/Shopify/shopify_python_api/workflows/CI/badge.svg)](https://github.com/Shopify/shopify_python_api/actions) [![PyPI version](https://badge.fury.io/py/ShopifyAPI.svg)](https://badge.fury.io/py/ShopifyAPI) +![Supported Python Versions](https://img.shields.io/badge/python-3.7%20|%203.8%20|%203.9%20|%203.10%20|%203.11%20|%203.12-brightgreen) [![codecov](https://codecov.io/gh/Shopify/shopify_python_api/branch/main/graph/badge.svg?token=pNTx0TARUx)](https://codecov.io/gh/Shopify/shopify_python_api) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/Shopify/shopify_python_api/blob/main/LICENSE) [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit) diff --git a/setup.py b/setup.py index dae5a810..eb23ab08 100755 --- a/setup.py +++ b/setup.py @@ -24,7 +24,8 @@ install_requires=[ "pyactiveresource>=2.2.2", "PyJWT >= 2.0.0", - "PyYAML", + "PyYAML>=6.0.1; python_version>='3.12'", + "PyYAML; python_version<'3.12'", "six", ], test_suite="test", @@ -44,6 +45,7 @@ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Topic :: Software Development", "Topic :: Software Development :: Libraries", "Topic :: Software Development :: Libraries :: Python Modules", From fdc155e64bcc86504834b1a01d0871232b7c5e08 Mon Sep 17 00:00:00 2001 From: Elizabeth Kenyon Date: Tue, 24 Sep 2024 13:36:25 -0500 Subject: [PATCH 36/46] Make API version more flexible Allow the use of API versions that are not previsouly defined --- CHANGELOG | 1 + shopify/api_version.py | 4 ++++ test/api_version_test.py | 14 ++++++++++++++ test/session_test.py | 13 +++++++++++++ 4 files changed, 32 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index cd636df3..5a5ed5db 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,5 @@ == Unreleased +- Remove requirement to use a predefined API version. Now you can use any valid API version string. ([#737](https://github.com/Shopify/shopify_python_api/pull/737)) == Version 12.6.0 diff --git a/shopify/api_version.py b/shopify/api_version.py index 22df6052..32276668 100644 --- a/shopify/api_version.py +++ b/shopify/api_version.py @@ -17,6 +17,9 @@ def coerce_to_version(cls, version): try: return cls.versions[version] except KeyError: + # Dynamically create a new Release object if version string is not found + if Release.FORMAT.match(version): + return Release(version) raise VersionNotFoundError @classmethod @@ -39,6 +42,7 @@ def define_known_versions(cls): cls.define_version(Release("2024-01")) cls.define_version(Release("2024-04")) cls.define_version(Release("2024-07")) + cls.define_version(Release("2024-10")) @classmethod def clear_defined_versions(cls): diff --git a/test/api_version_test.py b/test/api_version_test.py index 3089daee..9dce8cb2 100644 --- a/test/api_version_test.py +++ b/test/api_version_test.py @@ -29,6 +29,20 @@ def test_coerce_to_version_raises_with_string_that_does_not_match_known_version( with self.assertRaises(shopify.VersionNotFoundError): shopify.ApiVersion.coerce_to_version("crazy-name") + def test_coerce_to_version_creates_new_release_on_the_fly(self): + new_version = "2025-01" + coerced_version = shopify.ApiVersion.coerce_to_version(new_version) + + self.assertIsInstance(coerced_version, shopify.Release) + self.assertEqual(coerced_version.name, new_version) + self.assertEqual( + coerced_version.api_path("https://test.myshopify.com"), + f"https://test.myshopify.com/admin/api/{new_version}", + ) + + # Verify that the new version is not added to the known versions + self.assertNotIn(new_version, shopify.ApiVersion.versions) + class ReleaseTest(TestCase): def test_raises_if_format_invalid(self): diff --git a/test/session_test.py b/test/session_test.py index 806d551b..d7cd5c3d 100644 --- a/test/session_test.py +++ b/test/session_test.py @@ -288,3 +288,16 @@ def normalize_url(self, url): scheme, netloc, path, query, fragment = urllib.parse.urlsplit(url) query = "&".join(sorted(query.split("&"))) return urllib.parse.urlunsplit((scheme, netloc, path, query, fragment)) + + def test_session_with_coerced_version(self): + future_version = "2030-01" + session = shopify.Session("test.myshopify.com", future_version, "token") + self.assertEqual(session.api_version.name, future_version) + self.assertEqual( + session.api_version.api_path("https://test.myshopify.com"), + f"https://test.myshopify.com/admin/api/{future_version}", + ) + + def test_session_with_invalid_version(self): + with self.assertRaises(shopify.VersionNotFoundError): + shopify.Session("test.myshopify.com", "invalid-version", "token") From 7229004441645b1bc0a4c848cc1a6593fc9d6281 Mon Sep 17 00:00:00 2001 From: Matteo Depalo Date: Wed, 30 Oct 2024 10:46:27 +0000 Subject: [PATCH 37/46] Release v12.7.0 --- CHANGELOG | 3 +++ shopify/version.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 5a5ed5db..50cae06e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,7 @@ == Unreleased + +== Version 12.7.0 + - Remove requirement to use a predefined API version. Now you can use any valid API version string. ([#737](https://github.com/Shopify/shopify_python_api/pull/737)) == Version 12.6.0 diff --git a/shopify/version.py b/shopify/version.py index 7293b298..126c3ab4 100644 --- a/shopify/version.py +++ b/shopify/version.py @@ -1 +1 @@ -VERSION = "12.6.0" +VERSION = "12.7.0" From 9451fe5f45c6d809787384e9ceaa294fec1b66c6 Mon Sep 17 00:00:00 2001 From: "yuichi.nasukawa" Date: Wed, 8 Jan 2025 22:01:30 +0900 Subject: [PATCH 38/46] Add REST API deprecation notice to README --- README.md | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a8fa6d74..6226bcb1 100644 --- a/README.md +++ b/README.md @@ -87,10 +87,11 @@ pip install --upgrade ShopifyAPI session = shopify.Session(shop_url, api_version, access_token) shopify.ShopifyResource.activate_session(session) - shop = shopify.Shop.current() # Get the current shop - product = shopify.Product.find(179761209) # Get a specific product + # Note: REST API examples will be deprecated in 2025 + shop = shopify.Shop.current() # Get the current shop + product = shopify.Product.find(179761209) # Get a specific product - # execute a graphQL call + # GraphQL API example shopify.GraphQL().execute("{ shop { name id } }") ``` @@ -150,6 +151,13 @@ _Note: Your application must be public to test the billing process. To test on a ``` ### Advanced Usage + +> **⚠️ Note**: As of October 1, 2024, the REST Admin API is legacy: +> - Public apps must migrate to GraphQL by February 2025 +> - Custom apps must migrate to GraphQL by April 2025 +> +> For migration guidance, see [Shopify's migration guide](https://shopify.dev/docs/apps/build/graphql/migrate/new-product-model) + It is recommended to have at least a basic grasp on the principles of the [pyactiveresource](https://github.com/Shopify/pyactiveresource) library, which is a port of rails/ActiveResource to Python and upon which this package relies heavily. Instances of `pyactiveresource` resources map to RESTful resources in the Shopify API. @@ -157,6 +165,7 @@ Instances of `pyactiveresource` resources map to RESTful resources in the Shopif `pyactiveresource` exposes life cycle methods for creating, finding, updating, and deleting resources which are equivalent to the `POST`, `GET`, `PUT`, and `DELETE` HTTP verbs. ```python +# Note: REST API examples will be deprecated in 2025 product = shopify.Product() product.title = "Shopify Logo T-Shirt" product.id # => 292082188312 @@ -182,6 +191,7 @@ new_orders = shopify.Order.find(status="open", limit="50") Some resources such as `Fulfillment` are prefixed by a parent resource in the Shopify API (e.g. `orders/450789469/fulfillments/255858046`). In order to interact with these resources, you must specify the identifier of the parent resource in your request. ```python +# Note: This REST API example will be deprecated in the future shopify.Fulfillment.find(255858046, order_id=450789469) ``` @@ -196,6 +206,9 @@ This package also includes the `shopify_api.py` script to make it easy to open a This library also supports Shopify's new [GraphQL API](https://help.shopify.com/en/api/graphql-admin-api). The authentication process is identical. Once your session is activated, simply construct a new graphql client and use `execute` to execute the query. +> **Note**: Shopify recommends using GraphQL API for new development as REST API will be deprecated. +> See [Migration Guide](https://shopify.dev/docs/apps/build/graphql/migrate/new-product-model) for more details. + ```python result = shopify.GraphQL().execute('{ shop { name id } }') ``` From 024d94691ed889d047704d2f1615f40a03cc02ac Mon Sep 17 00:00:00 2001 From: Tyler J Date: Sat, 11 Jan 2025 13:31:05 -0500 Subject: [PATCH 39/46] Refactor `create_permission_url` to handle optional `scope`. Modified `create_permission_url` to make `scope` optional, allowing it to be omitted when specified in the app's configuration (TOML). Updated the README to reflect this change and clarify usage. This improves flexibility and simplifies configuration management. --- README.md | 4 +++- shopify/session.py | 9 +++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a8fa6d74..0b680d07 100644 --- a/README.md +++ b/README.md @@ -66,10 +66,12 @@ pip install --upgrade ShopifyAPI api_version = '2024-07' state = binascii.b2a_hex(os.urandom(15)).decode("utf-8") redirect_uri = "http://myapp.com/auth/shopify/callback" + # `scope` should be omitted if provided by app's TOML scopes = ['read_products', 'read_orders'] newSession = shopify.Session(shop_url, api_version) - auth_url = newSession.create_permission_url(scopes, redirect_uri, state) + # `scope` should be omitted if provided by app's TOML + auth_url = newSession.create_permission_url(redirect_uri, scopes, state) # redirect to auth_url ``` diff --git a/shopify/session.py b/shopify/session.py index 39ce5f7b..52dc83f4 100644 --- a/shopify/session.py +++ b/shopify/session.py @@ -53,10 +53,11 @@ def __init__(self, shop_url, version=None, token=None, access_scopes=None): self.access_scopes = access_scopes return - def create_permission_url(self, scope, redirect_uri, state=None): - query_params = dict(client_id=self.api_key, scope=",".join(scope), redirect_uri=redirect_uri) - if state: - query_params["state"] = state + def create_permission_url(self, redirect_uri, scope=None, state=None): + query_params = dict(client_id=self.api_key, redirect_uri=redirect_uri) + # `scope` should be omitted if provided by app's TOML + if scope: query_params["scope"] = ",".join(scope) + if state: query_params["state"] = state return "https://%s/admin/oauth/authorize?%s" % (self.url, urllib.parse.urlencode(query_params)) def request_token(self, params): From cdaa10d2d6a82d44652468d0d78aba537df08baa Mon Sep 17 00:00:00 2001 From: "yuichi.nasukawa" Date: Sun, 12 Jan 2025 08:40:56 +0900 Subject: [PATCH 40/46] chore: upgrade pre-commit dependencies --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 43267923..f3500257 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,15 +2,15 @@ # See https://pre-commit.com/hooks.html for more hooks repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.4.0 + rev: v5.0.0 hooks: - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/psf/black - rev: 22.3.0 + rev: 24.10.0 hooks: - id: black - repo: https://github.com/PyCQA/pylint - rev: v2.15.8 + rev: v3.3.3 hooks: - id: pylint From 7b044441d59fe9087abc02554cbf267fb9a6d923 Mon Sep 17 00:00:00 2001 From: "yuichi.nasukawa" Date: Sun, 12 Jan 2025 08:44:30 +0900 Subject: [PATCH 41/46] fix: resolve new pylint warnings - Fix warnings introduced by pylint v3.3.3 upgrade --- scripts/shopify_api.py | 2 +- shopify/api_access.py | 1 - shopify/mixins.py | 2 +- shopify/session.py | 4 ++-- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/scripts/shopify_api.py b/scripts/shopify_api.py index 5dfab93a..bab35f15 100755 --- a/scripts/shopify_api.py +++ b/scripts/shopify_api.py @@ -128,7 +128,7 @@ def add(cls, connection): if os.path.exists(filename): raise ConfigFileError("There is already a config file at " + filename) else: - config = dict(protocol="https") + config = {"protocol": "https"} domain = input("Domain? (leave blank for %s.myshopify.com) " % (connection)) if not domain.strip(): domain = "%s.myshopify.com" % (connection) diff --git a/shopify/api_access.py b/shopify/api_access.py index d5ffbe35..19b80671 100644 --- a/shopify/api_access.py +++ b/shopify/api_access.py @@ -14,7 +14,6 @@ class ApiAccessError(Exception): class ApiAccess: - SCOPE_DELIMITER = "," SCOPE_RE = re.compile(r"\A(?Punauthenticated_)?(write|read)_(?P.*)\Z") IMPLIED_SCOPE_RE = re.compile(r"\A(?Punauthenticated_)?write_(?P.*)\Z") diff --git a/shopify/mixins.py b/shopify/mixins.py index 54496dbf..5a13ca3a 100644 --- a/shopify/mixins.py +++ b/shopify/mixins.py @@ -24,7 +24,7 @@ def add_metafield(self, metafield): if self.is_new(): raise ValueError("You can only add metafields to a resource that has been saved") - metafield._prefix_options = dict(resource=self.__class__.plural, resource_id=self.id) + metafield._prefix_options = {"resource": self.__class__.plural, "resource_id": self.id} metafield.save() return metafield diff --git a/shopify/session.py b/shopify/session.py index 39ce5f7b..c3ec6d4b 100644 --- a/shopify/session.py +++ b/shopify/session.py @@ -54,7 +54,7 @@ def __init__(self, shop_url, version=None, token=None, access_scopes=None): return def create_permission_url(self, scope, redirect_uri, state=None): - query_params = dict(client_id=self.api_key, scope=",".join(scope), redirect_uri=redirect_uri) + query_params = {"client_id": self.api_key, "scope": ",".join(scope), "redirect_uri": redirect_uri} if state: query_params["state"] = state return "https://%s/admin/oauth/authorize?%s" % (self.url, urllib.parse.urlencode(query_params)) @@ -69,7 +69,7 @@ def request_token(self, params): code = params["code"] url = "https://%s/admin/oauth/access_token?" % self.url - query_params = dict(client_id=self.api_key, client_secret=self.secret, code=code) + query_params = {"client_id": self.api_key, "client_secret": self.secret, "code": code} request = urllib.request.Request(url, urllib.parse.urlencode(query_params).encode("utf-8")) response = urllib.request.urlopen(request) From ceada2433b004365b7d9f74669b9c1067e299ccb Mon Sep 17 00:00:00 2001 From: Tyler J Date: Sun, 12 Jan 2025 11:33:31 -0500 Subject: [PATCH 42/46] Update to version 12.7.1 and update the CHANGELOG. --- CHANGELOG | 2 ++ shopify/version.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 50cae06e..e9910c2e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,7 @@ == Unreleased +- Remove requirement to provide scopes to Permission URL, as it should be omitted if defined with the TOML file. + == Version 12.7.0 - Remove requirement to use a predefined API version. Now you can use any valid API version string. ([#737](https://github.com/Shopify/shopify_python_api/pull/737)) diff --git a/shopify/version.py b/shopify/version.py index 126c3ab4..dfb0b4e4 100644 --- a/shopify/version.py +++ b/shopify/version.py @@ -1 +1 @@ -VERSION = "12.7.0" +VERSION = "12.7.1" From 07d6c47146e00c35bb39a83d86033f9b250623af Mon Sep 17 00:00:00 2001 From: Tyler J Date: Sun, 12 Jan 2025 11:48:02 -0500 Subject: [PATCH 43/46] Fix typo in method signature of create_permission_url Removed an unnecessary extra space in the method signature of `create_permission_url`. --- shopify/session.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shopify/session.py b/shopify/session.py index 52dc83f4..eec40517 100644 --- a/shopify/session.py +++ b/shopify/session.py @@ -53,7 +53,7 @@ def __init__(self, shop_url, version=None, token=None, access_scopes=None): self.access_scopes = access_scopes return - def create_permission_url(self, redirect_uri, scope=None, state=None): + def create_permission_url(self, redirect_uri, scope=None, state=None): query_params = dict(client_id=self.api_key, redirect_uri=redirect_uri) # `scope` should be omitted if provided by app's TOML if scope: query_params["scope"] = ",".join(scope) From adaf770a0b5a99ae791048967f39d89e13ea500f Mon Sep 17 00:00:00 2001 From: Tyler J Date: Fri, 17 Jan 2025 14:28:20 -0500 Subject: [PATCH 44/46] Update tests for `create_permission_url` method. Updated tests to improve clarity and consistency in naming and arguments. Modified `create_permission_url` calls to match new positional order for `redirect_uri` and `scope`. Enhanced assertion coverage for edge cases like empty scopes and added tests for state parameter handling. --- test/session_test.py | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/test/session_test.py b/test/session_test.py index d7cd5c3d..04d30748 100644 --- a/test/session_test.py +++ b/test/session_test.py @@ -86,51 +86,69 @@ def test_temp_works_without_currently_active_session(self): self.assertEqual("https://testshop.myshopify.com/admin/api/unstable", assigned_site) self.assertEqual("https://none/admin/api/unstable", shopify.ShopifyResource.site) - def test_create_permission_url_returns_correct_url_with_single_scope_and_redirect_uri(self): + def test_create_permission_url_returns_correct_url_with_redirect_uri(self): + shopify.Session.setup(api_key="My_test_key", secret="My test secret") + session = shopify.Session("http://localhost.myshopify.com", "unstable") + permission_url = session.create_permission_url("my_redirect_uri.com") + self.assertEqual( + "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&redirect_uri=my_redirect_uri.com", + self.normalize_url(permission_url), + ) + + def test_create_permission_url_returns_correct_url_with_redirect_uri_and_single_scope(self): shopify.Session.setup(api_key="My_test_key", secret="My test secret") session = shopify.Session("http://localhost.myshopify.com", "unstable") scope = ["write_products"] - permission_url = session.create_permission_url(scope, "my_redirect_uri.com") + permission_url = session.create_permission_url("my_redirect_uri.com", scope=scope) self.assertEqual( "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&redirect_uri=my_redirect_uri.com&scope=write_products", self.normalize_url(permission_url), ) - def test_create_permission_url_returns_correct_url_with_dual_scope_and_redirect_uri(self): + def test_create_permission_url_returns_correct_url_with_redirect_uri_and_dual_scope(self): shopify.Session.setup(api_key="My_test_key", secret="My test secret") session = shopify.Session("http://localhost.myshopify.com", "unstable") scope = ["write_products", "write_customers"] - permission_url = session.create_permission_url(scope, "my_redirect_uri.com") + permission_url = session.create_permission_url("my_redirect_uri.com", scope=scope) self.assertEqual( "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&redirect_uri=my_redirect_uri.com&scope=write_products%2Cwrite_customers", self.normalize_url(permission_url), ) - def test_create_permission_url_returns_correct_url_with_no_scope_and_redirect_uri(self): + def test_create_permission_url_returns_correct_url_with_redirect_uri_and_empty_scope(self): shopify.Session.setup(api_key="My_test_key", secret="My test secret") session = shopify.Session("http://localhost.myshopify.com", "unstable") scope = [] - permission_url = session.create_permission_url(scope, "my_redirect_uri.com") + permission_url = session.create_permission_url("my_redirect_uri.com", scope=scope) + self.assertEqual( + "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&redirect_uri=my_redirect_uri.com", + self.normalize_url(permission_url), + ) + + def test_create_permission_url_returns_correct_url_with_redirect_uri_and_state(self): + shopify.Session.setup(api_key="My_test_key", secret="My test secret") + session = shopify.Session("http://localhost.myshopify.com", "unstable") + permission_url = session.create_permission_url("my_redirect_uri.com", state="mystate") self.assertEqual( - "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&redirect_uri=my_redirect_uri.com&scope=", + "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&redirect_uri=my_redirect_uri.com&state=mystate", self.normalize_url(permission_url), ) - def test_create_permission_url_returns_correct_url_with_no_scope_and_redirect_uri_and_state(self): + def test_create_permission_url_returns_correct_url_with_redirect_uri_empty_scope_and_state(self): shopify.Session.setup(api_key="My_test_key", secret="My test secret") session = shopify.Session("http://localhost.myshopify.com", "unstable") scope = [] - permission_url = session.create_permission_url(scope, "my_redirect_uri.com", state="mystate") + permission_url = session.create_permission_url("my_redirect_uri.com", scope=scope, state="mystate") self.assertEqual( - "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&redirect_uri=my_redirect_uri.com&scope=&state=mystate", + "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&redirect_uri=my_redirect_uri.com&state=mystate", self.normalize_url(permission_url), ) - def test_create_permission_url_returns_correct_url_with_single_scope_and_redirect_uri_and_state(self): + def test_create_permission_url_returns_correct_url_with_redirect_uri_and_single_scope_and_state(self): shopify.Session.setup(api_key="My_test_key", secret="My test secret") session = shopify.Session("http://localhost.myshopify.com", "unstable") scope = ["write_customers"] - permission_url = session.create_permission_url(scope, "my_redirect_uri.com", state="mystate") + permission_url = session.create_permission_url( "my_redirect_uri.com", scope=scope, state="mystate") self.assertEqual( "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&redirect_uri=my_redirect_uri.com&scope=write_customers&state=mystate", self.normalize_url(permission_url), From 12e933ba9cadd2ba5b834fe5143cb70438e9e34b Mon Sep 17 00:00:00 2001 From: Tyler J Date: Mon, 20 Jan 2025 08:32:20 -0500 Subject: [PATCH 45/46] Fix linting errors Removes extra white space in parameters in session_test.py and changes conditional formatting in shopify/session.py. --- shopify/session.py | 8 +++++--- test/session_test.py | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/shopify/session.py b/shopify/session.py index eec40517..dcb41d41 100644 --- a/shopify/session.py +++ b/shopify/session.py @@ -54,10 +54,12 @@ def __init__(self, shop_url, version=None, token=None, access_scopes=None): return def create_permission_url(self, redirect_uri, scope=None, state=None): - query_params = dict(client_id=self.api_key, redirect_uri=redirect_uri) + query_params = {"client_id": self.api_key, "redirect_uri": redirect_uri} # `scope` should be omitted if provided by app's TOML - if scope: query_params["scope"] = ",".join(scope) - if state: query_params["state"] = state + if scope: + query_params["scope"] = ",".join(scope) + if state: + query_params["state"] = state return "https://%s/admin/oauth/authorize?%s" % (self.url, urllib.parse.urlencode(query_params)) def request_token(self, params): diff --git a/test/session_test.py b/test/session_test.py index 04d30748..8d73e293 100644 --- a/test/session_test.py +++ b/test/session_test.py @@ -148,7 +148,7 @@ def test_create_permission_url_returns_correct_url_with_redirect_uri_and_single_ shopify.Session.setup(api_key="My_test_key", secret="My test secret") session = shopify.Session("http://localhost.myshopify.com", "unstable") scope = ["write_customers"] - permission_url = session.create_permission_url( "my_redirect_uri.com", scope=scope, state="mystate") + permission_url = session.create_permission_url("my_redirect_uri.com", scope=scope, state="mystate") self.assertEqual( "https://localhost.myshopify.com/admin/oauth/authorize?client_id=My_test_key&redirect_uri=my_redirect_uri.com&scope=write_customers&state=mystate", self.normalize_url(permission_url), From 2f998c691bd15608603ef25e31238f6c22abc544 Mon Sep 17 00:00:00 2001 From: Tyler J Date: Mon, 20 Jan 2025 08:40:04 -0500 Subject: [PATCH 46/46] Fix linting errors Removes extra white space in parameters in session_test.py and changes conditional formatting in shopify/session.py. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d8378880..cadda24e 100644 --- a/README.md +++ b/README.md @@ -157,7 +157,7 @@ _Note: Your application must be public to test the billing process. To test on a > **⚠️ Note**: As of October 1, 2024, the REST Admin API is legacy: > - Public apps must migrate to GraphQL by February 2025 > - Custom apps must migrate to GraphQL by April 2025 -> +> > For migration guidance, see [Shopify's migration guide](https://shopify.dev/docs/apps/build/graphql/migrate/new-product-model) It is recommended to have at least a basic grasp on the principles of the [pyactiveresource](https://github.com/Shopify/pyactiveresource) library, which is a port of rails/ActiveResource to Python and upon which this package relies heavily.