Closed ammarA94 closed 1 year ago
That tutorial is not up-to-date with this library. Please see the !! Breaking change notice for version 5.0.0 !! notice in the README and follow instructions there for setting an api_version.
this thing is already added in session.py file. [session.py]
import time import hmac import json from hashlib import sha256 try: import simplejson as json except ImportError: import json import re from contextlib import contextmanager from six.moves import urllib from shopify.api_version import ApiVersion, Release, Unstable import six
class ValidationException(Exception): pass
class Session(object): api_key = None secret = None protocol = 'https' myshopify_domain = 'myshopify.com' port = None
@classmethod
def setup(cls, **kwargs):
for k, v in six.iteritems(kwargs):
setattr(cls, k, v)
@classmethod
@contextmanager
def temp(cls, domain, version, token):
import shopify
original_domain = shopify.ShopifyResource.url
original_token = shopify.ShopifyResource.get_headers().get('X-Shopify-Access-Token')
original_version = shopify.ShopifyResource.get_version() or version
original_session = shopify.Session(original_domain, original_version, original_token)
**session = Session(domain, version, token)**
shopify.ShopifyResource.activate_session(session)
yield
shopify.ShopifyResource.activate_session(original_session)
def __init__(self, shop_url, version=None, token=None):
self.url = self.__prepare_url(shop_url)
self.token = token
self.version = ApiVersion.coerce_to_version(version)
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
return "https://%s/admin/oauth/authorize?%s" % (self.url, urllib.parse.urlencode(query_params))
def request_token(self, params):
if self.token:
return self.token
if not self.validate_params(params):
raise ValidationException('Invalid HMAC: Possibly malicious login')
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)
request = urllib.request.Request(url, urllib.parse.urlencode(query_params).encode('utf-8'))
response = urllib.request.urlopen(request)
if response.code == 200:
self.token = json.loads(response.read().decode('utf-8'))['access_token']
return self.token
else:
raise Exception(response.msg)
@property
def api_version(self):
return self.version
@property
def site(self):
return self.version.api_path("%s://%s" % (self.protocol, self.url))
@property
def valid(self):
return self.url is not None and self.token is not None
@classmethod
def __prepare_url(cls, url):
if not url or (url.strip() == ""):
return None
url = re.sub("^https?://", "", url)
shop = urllib.parse.urlparse("https://" + url).hostname
if shop is None:
return None
idx = shop.find(".")
if idx != -1:
shop = shop[0:idx]
if len(shop) == 0:
return None
shop += "." + cls.myshopify_domain
if cls.port:
shop += ":" + str(cls.port)
return shop
@classmethod
def validate_params(cls, params):
# Avoid replay attacks by making sure the request
# isn't more than a day old.
one_day = 24 * 60 * 60
if int(params.get('timestamp', 0)) < time.time() - one_day:
return False
return cls.validate_hmac(params)
@classmethod
def validate_hmac(cls, params):
if 'hmac' not in params:
return False
hmac_calculated = cls.calculate_hmac(params).encode('utf-8')
hmac_to_verify = params['hmac'].encode('utf-8')
# Try to use compare_digest() to reduce vulnerability to timing attacks.
# If it's not available, just fall back to regular string comparison.
try:
return hmac.compare_digest(hmac_calculated, hmac_to_verify)
except AttributeError:
return hmac_calculated == hmac_to_verify
@classmethod
def calculate_hmac(cls, params):
"""
Calculate the HMAC of the given parameters in line with Shopify's rules for OAuth authentication.
See http://docs.shopify.com/api/authentication/oauth#verification.
"""
encoded_params = cls.__encoded_params_for_signature(params)
# Generate the hex digest for the sorted parameters using the secret.
return hmac.new(cls.secret.encode(), encoded_params.encode(), sha256).hexdigest()
@classmethod
def __encoded_params_for_signature(cls, params):
"""
Sort and combine query parameters into a single string, excluding those that should be removed and joining with '&'
"""
def encoded_pairs(params):
for k, v in six.iteritems(params):
if k == 'hmac':
continue
if k.endswith('[]'):
#foo[]=1&foo[]=2 has to be transformed as foo=["1", "2"] note the whitespace after comma
k = k.rstrip('[]')
v = json.dumps(list(map(str, v)))
# escape delimiters to avoid tampering
k = str(k).replace("%", "%25").replace("=", "%3D")
v = str(v).replace("%", "%25")
yield '{0}={1}'.format(k, v).replace("&", "%26")
return "&".join(sorted(encoded_pairs(params)))
you need to add api_version while creating the session
session = shopify.Session(shop_url,"2022-04")
This issue is stale because it has been open for 60 days with no activity. It will be closed if no further action occurs in 14 days.
We are closing this issue because it has been inactive for a few months. 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 file for guidelines
Thank you!
i am following 'https://medium.com/@dernis/shopify-embedded-sdk-with-python-flask-6af197e88c63' this tutorial, after everything when i go to link https://localhost:5000/shopify?shop=.myshopify.com by putting my shop_name it gives me that error
shopify.api_version.VersionNotFoundError shopify.api_version.VersionNotFoundError
Traceback (most recent call last) File "C:\Users\92344\Anaconda3\lib\site-packages\flask\app.py", line 2309, in call return self.wsgi_app(environ, start_response) File "C:\Users\92344\Anaconda3\lib\site-packages\flask\app.py", line 2295, in wsgi_app response = self.handle_exception(e) File "C:\Users\92344\Anaconda3\lib\site-packages\flask\app.py", line 1741, in handle_exception reraise(exc_type, exc_value, tb) File "C:\Users\92344\Anaconda3\lib\site-packages\flask_compat.py", line 35, in reraise raise value File "C:\Users\92344\Anaconda3\lib\site-packages\flask\app.py", line 2292, in wsgi_app response = self.full_dispatch_request() File "C:\Users\92344\Anaconda3\lib\site-packages\flask\app.py", line 1815, in full_dispatch_request rv = self.handle_user_exception(e) File "C:\Users\92344\Anaconda3\lib\site-packages\flask\app.py", line 1718, in handle_user_exception reraise(exc_type, exc_value, tb) File "C:\Users\92344\Anaconda3\lib\site-packages\flask_compat.py", line 35, in reraise raise value File "C:\Users\92344\Anaconda3\lib\site-packages\flask\app.py", line 1813, in full_dispatch_request rv = self.dispatch_request() File "C:\Users\92344\Anaconda3\lib\site-packages\flask\app.py", line 1799, in dispatch_request return self.view_functionsrule.endpoint File "C:\Users\92344\Downloads\HelloShopify-master\helloshopify\shopify_bp\views.py", line 36, in install session = shopify.Session(shop_url) File "C:\Users\92344\Anaconda3\lib\site-packages\shopify\session.py", line 47, in init self.version = ApiVersion.coerce_to_version(version) File "C:\Users\92344\Anaconda3\lib\site-packages\shopify\api_version.py", line 18, in coerce_to_version raise VersionNotFoundError shopify.api_version.VersionNotFoundError