Most companies use an ERM tool these days to manage their finances and core business processes, and Oracle’s NetSuite has been one of the business leaders in ERM tools for the past few decades. However, these tools are used and managed by a few select individuals while the data stored can be of use to multiple teams. Which is why it makes sense to have an automated pipeline to ingest data from these tools using their native APIs to the primary databases/data warehouses, which can be later piped into different BI tools. Show NetSuite has inbuilt support for SOAP APIs and RESTlet APIs. At Funding Societies, we decided to go ahead with the newly introduced RESTlet API solely because our codebase was in Python and were very quickly blocked and surprised with the lack of documentation and examples of implementation of NetSuite Restlet API with Python. NetSuite provides many types of REST mechanisms to connect to NetSuite.
Here we will discuss the end-to-end implementation of NetSuite Query Language (NQL) and Saved Search capabilities and extracting data from it using RESTlet API using Python. Our Use CaseThe finance team regularly posts data of the company’s earnings and expenditure on NetSuite using the UI tool. These expenditures can have multiple reasons such as vendor bill payments, rent, salaries, business operation expenses, etc. The data team was approached with the use case of fetching this data for end-of-month and end-of-year calculations to be done in the data warehouse and presenting it to C-level executives using a dashboard. Our Proposed SolutionAfter some research, the data engineering team proposed a solution that we can ingest the data from NetSuite using regular API requests and ingest it to restricted access tables in our Snowflake Data Cloud warehouse from where we could build dashboards in Periscope, our BI tool, and share the dashboard. Challenges We FacedAfter spending some time working on the solution and trying to find relevant documentation and surfing several stackoverflow pages, we realized that this implementation is not as straightforward as it seems and will require more work. To summarize, these are the challenges we faced when implementing this integration:
In this article, we will be discussing the first challenge. OAuth Authentication. Steps to follow before implementing OAuth Authentication
To enable the token-based authentication feature:
2. Set Up Token-based Authentication Roles and Token-based Authentication (TBA) Permissions We have created a new Role dedicated for Token Based Permissions. Then we have added token-based authentication permissions to this role then assign users to this role. List of TBA Roles & Permissions3. Assign Users to Token-based Authentication Roles 4. Create Integration Records for Applications to Use TBA
In some cases, more than one method of authentication can be specified on an integration record.
We need to fetch the following values from NetSuite.
3. Token ID & Token Secret: Once consumer details are stored, we need to create the tokens for the application. The user with the above credentials needs to login on NetSuite and go to Manage Access Tokens link available on the home dashboard under settings. Create a new token and select the Application Name that corresponds to the associated integration record created earlier. Once done, the Token ID and Token Secret will be provided. Just like the previous step, these tokens will not be visible later, so it is important to store them. 4. Role ID: Go to Setup -> Integration -> Web Services Preferences and copy the Account ID. Select the username from the drop-down menu and select the role of the corresponding account. This is the Role ID. Now that we have all our required credentials, we can start with the creation of the authentication process. OAuth Authentication ProcessImplementing the authentication was perhaps the most difficult and time consuming aspect of the entire project. We found and tested various python libraries and packages (some of which seemed to have been created especially for NetSuite authentication) but none of them worked for us. This led to us taking a more hands on approach and deciding to implement the full OAuth structure by code. NetSuite’s OAuth requires the following steps:
Creating a cryptographic nonceA cryptographic nonce is an arbitrary number that can be used just once in a cryptographic communication. It is used to make a request unique. NetSuite uses an 11 character alpha-numeric nonce, which needs to be created in a random fashion. For our case, we have used the random and math packages to implement the nonce. def getAuthNonce(): Creating a UNIX TimestampThis is perhaps the most straightforward part of the entire signature creation process. It can be easily implemented using python’s inbuilt time package. import time Create the Authentication SignatureIn this step, we will require all the values and tokens we previously collected. Another value that we will need in this step is the SIGNATURE METHOD value which can be hardcoded to HMAC-SHA256. We also need the value of the API request method we are going to use. If getting data from saved search, then use GET or else if getting data from NQL (NetSuite Query Language [SuiteSQL]) then POST This step requires multiple rounds of encoding and hashing. For this step, we preferred using all basic libraries and packages by python since a specific url encoding of a special package was producing the wrong signature which caused an error in our authentication process. Create a simple data string having all values fetched above in the following order:
For the next step, we will need the BASE URL of the API call, which can be one of the following: In case of Saved Search: https://<ACCOUNT_ID>.restlets.api.netsuite.com/app/site/hosting/restlet.nlIn case of SuiteSQL: https://<ACCOUNT_ID>.suitetalk.api.netsuite.com/services/rest/query/v1/suiteql In order to create the main signature, we will need to create the Signature Value and the Signature Key to encrypt the said value with. Signature Value: This value needs to be encoded to be understood by URLs. Python’s urllib package can help with that. Concat the API Request Method with the encoded base url and finally encoded data string created above. Signature Key: For this, we need to concatenate encoded Consumer Secret and Token Secret. When the above steps are completed, we need to hash the binary version of the above key and value data and then encode the result with base64 encoding and decode it back from binary to normal string. Once done, we need to encode again using urllib. This is how the signature is created. When fetching data using NetSuite SQL: def getSignature(BASE_URL, HTTP_METHOD, OAUTH_NONCE, TIME_STAMP): When fetching data using Saved Search: def getSignature(BASE_URL, HTTP_METHOD, OAUTH_NONCE, TIME_STAMP):Creating Authentication Header Finally, we need to create the authentication header to send to the API request. For this, we need to follow the following steps:
The Authentication Header for both, SuiteSQL and Saved Search, will be the same. Only the signature creation will be different. def createHeader(): Finally once this is done, we are ready to call the Saved Search or query the tables of NetSuite to fetch the required data. ConclusionI hope that this was beneficial in understanding the creation of the OAuth steps and procedure for NetSuite. This authentication can be used for various types of integrations with NetSuite. Stay tuned for more chapters of this series. In the next chapter we will see how to find and query relevant tables from NetSuite’s database. Huge thanks to my co-author Sankar A for working with me tirelessly to put this detailed guide together! How to generate HMAC SHA256 signature in Python?Python generate HMAC-SHA-256 from string. import hashlib.. import hmac.. key = '8oe0i89o7es243t5s234'. message = 'Body text for the hash. ';. # Generate the hash.. signature = hmac. new(. message,. What is HMAC SHA256 signature?HMAC stands for Keyed-Hashing for Message Authentication. It's a message authentication code obtained by running a cryptographic hash function (like MD5, SHA1, and SHA256) over the data (to be authenticated) and a shared secret key. HMAC is specified in RFC 2104. HMACs are almost similar to digital signatures.
What is HMAC in Python?Source code: Lib/hmac.py. This module implements the HMAC algorithm as described by RFC 2104. hmac. new(key, msg=None, digestmod='')
|