diff --git a/README.md b/README.md index 54549db..a9a6c54 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,8 @@ export NS_TOKEN_SECRET=xxxx The following snippet shows how to use TBA to initialize the SDK. +Note: By default the SDK implementation is using the wsdl version '2019_1', if you wish to use other than the default wsdl version, you can pass an optional wsdl_version. The wsdl_version should be in following format: 'year_version' eg. '2023_1' or '2022_2' etc. + ```python import os import itertools @@ -45,7 +47,9 @@ def connect_tba(): consumer_key=NS_CONSUMER_KEY, consumer_secret=NS_CONSUMER_SECRET, token_key=NS_TOKEN_KEY, - token_secret=NS_TOKEN_SECRET + token_secret=NS_TOKEN_SECRET, + #optional wsdl_version to use version other than '2019_1' + wsdl_version='2023_2' ) return nc diff --git a/netsuitesdk/connection.py b/netsuitesdk/connection.py index 6ba3d97..93e3651 100644 --- a/netsuitesdk/connection.py +++ b/netsuitesdk/connection.py @@ -36,10 +36,11 @@ class NetSuiteConnection: def __init__(self, account, consumer_key, consumer_secret, token_key, token_secret, caching=True, caching_timeout=2592000, caching_path=None, - search_body_fields_only=True, page_size: int = 100): + search_body_fields_only=True, page_size: int = 100, wsdl_version: str = None): + ns_client = NetSuiteClient(account=account, caching=caching, caching_timeout=caching_timeout, caching_path=caching_path, search_body_fields_only=search_body_fields_only, - page_size=page_size) + page_size=page_size, wsdl_version=wsdl_version) ns_client.connect_tba( consumer_key=consumer_key, consumer_secret=consumer_secret, diff --git a/netsuitesdk/internal/client.py b/netsuitesdk/internal/client.py index 92a1d87..56e921c 100644 --- a/netsuitesdk/internal/client.py +++ b/netsuitesdk/internal/client.py @@ -3,6 +3,7 @@ Zeep to connect to a NetSuite account and make requests. """ +import re import base64 import hashlib import hmac @@ -30,8 +31,8 @@ class NetSuiteClient: """The Netsuite client class providing access to the Netsuite SOAP/WSDL web service""" - WSDL_URL_TEMPLATE = 'https://{account}.suitetalk.api.netsuite.com/wsdl/v2019_1_0/netsuite.wsdl' - DATACENTER_URL_TEMPLATE = 'https://{account}.suitetalk.api.netsuite.com/services/NetSuitePort_2019_1' + WSDL_URL_TEMPLATE = 'https://{account}.suitetalk.api.netsuite.com/wsdl/{wsdl_version}/netsuite.wsdl' + DATACENTER_URL_TEMPLATE = 'https://{account}.suitetalk.api.netsuite.com/services/{netsuite_port_version}' _search_preferences = None _passport = None @@ -45,7 +46,7 @@ class NetSuiteClient: _app_id = None def __init__(self, account=None, caching=True, caching_timeout=2592000, caching_path=None, search_body_fields_only=True, - page_size: int = 100): + page_size: int = 100, wsdl_version: str = None): """ Initialize the Zeep SOAP client, parse the xsd specifications of Netsuite and store the complex types as attributes of this @@ -57,13 +58,26 @@ def __init__(self, account=None, caching=True, caching_timeout=2592000, caching_ If None, defaults to 30 days :param str caching_path: Sqlite base file path. Default to python library path. """ + if wsdl_version: + if not re.match(r'^\d{4}_(\d{1,2})?$', wsdl_version): + raise ValueError("Invalid wsdl_version format. It should be in the following format: year_version eg: '2023_1'") + self.logger = logging.getLogger(self.__class__.__name__) assert account, 'Invalid account' assert '-' not in account, 'Account cannot have hyphens, it is likely an underscore' self._account = account - self._wsdl_url = self.WSDL_URL_TEMPLATE.format(account=account.replace('_', '-')) - self._datacenter_url = self.DATACENTER_URL_TEMPLATE.format(account=account.replace('_', '-')) + self.wsdl_version = 'v2019_1_0' + self.netsuite_port_version = 'NetSuitePort_2019_1' + self.netsuite_binding_version = '2019_1' + + if wsdl_version: + self.wsdl_version = 'v{wsdl_version}_0'.format(wsdl_version=wsdl_version) + self.netsuite_port_version = 'NetSuitePort_{wsdl_version}'.format(wsdl_version=wsdl_version) + self.netsuite_binding_version = wsdl_version + + self._wsdl_url = self.WSDL_URL_TEMPLATE.format(account=account.replace('_', '-'), wsdl_version=self.wsdl_version) + self._datacenter_url = self.DATACENTER_URL_TEMPLATE.format(account=account.replace('_', '-'), netsuite_port_version=self.netsuite_port_version) if caching: base_path = os.path.dirname(os.path.abspath(__file__)) if not caching_path else caching_path @@ -78,8 +92,10 @@ def __init__(self, account=None, caching=True, caching_timeout=2592000, caching_ self._client = Client(self._wsdl_url, transport=transport) # default service points to wrong data center. need to create a new service proxy and replace the default one + netsuite_binding_str = '{{urn:platform_{0}.webservices.netsuite.com}}NetSuiteBinding'.format(self.netsuite_binding_version) self._service_proxy = self._client.create_service( - '{urn:platform_2019_1.webservices.netsuite.com}NetSuiteBinding', self._datacenter_url) + netsuite_binding_str, self._datacenter_url + ) # Parse all complex types specified in :const:`~netsuitesdk.netsuite_types.COMPLEX_TYPES` # and store them as attributes of this instance. Same for simple types. diff --git a/setup.py b/setup.py index eb4bb77..acf6709 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name='netsuitesdk', - version='2.21.4', + version='2.22.0', author='Siva Narayanan', author_email='siva@fyle.in', description='Python SDK for accessing the NetSuite SOAP webservice',