Warning: This SDK is under active development and some of the contracts will likely evolve in the next couple of weeks. It is not yet production-ready. If you want to collaborate on this, please mail siva@fyle.in
Netsuite-sdk-py is a Python SDK. It uses the SOAP client library zeep(https://python-zeep.readthedocs.io/en/master/) for accessing NetSuite resources via the NetSuite SOAP web service SuiteTalk(http://www.netsuite.com/portal/platform/developer/suitetalk.shtml), but hides the complexity from the SDK user.
$ pip install netsuitesdk
There are two ways to access a NetSuite account via web services:
- Use token-based auth (TBA) (within each request). This is the mechanism supported by this SDK.
- Use email, password, role and account id to login and start a session. This is not supported by this SDK
First, setup TBA credentials using environment variables.
# TBA credentials
export NS_ACCOUNT=xxxx
export NS_CONSUMER_KEY=xxxx
export NS_CONSUMER_SECRET=xxxx
export NS_TOKEN_KEY=xxxx
export NS_TOKEN_SECRET=xxxx
The following snippet shows how to use TBA to initialize the SDK.
import os
import itertools
import json
from netsuitesdk import NetSuiteConnection
def connect_tba():
NS_ACCOUNT = os.getenv('NS_ACCOUNT')
NS_CONSUMER_KEY = os.getenv('NS_CONSUMER_KEY')
NS_CONSUMER_SECRET = os.getenv('NS_CONSUMER_SECRET')
NS_TOKEN_KEY = os.getenv('NS_TOKEN_KEY')
NS_TOKEN_SECRET = os.getenv('NS_TOKEN_SECRET')
nc = NetSuiteConnection(
account=NS_ACCOUNT,
consumer_key=NS_CONSUMER_KEY,
consumer_secret=NS_CONSUMER_SECRET,
token_key=NS_TOKEN_KEY,
token_secret=NS_TOKEN_SECRET
)
return nc
nc = connect_tba()
# Use get_all methods to get all objects of certain types
currencies = nc.currencies.get_all()
locations = nc.locations.get_all()
departments = nc.departments.get_all()
classifications = nc.classifications.get_all()
subsidiaries = nc.subsidiaries.get_all()
expense_categories = nc.expense_categories.get_all()
employees = nc.employees.get_all()
all_accounts = list(itertools.islice(nc.accounts.get_all_generator(), 100))
accounts = [a for a in all_accounts if a['acctType'] == '_expense']
vendor_bills = list(itertools.islice(nc.vendor_bills.get_all_generator(), 10))
vendors = list(itertools.islice(nc.vendors.get_all_generator(), 10))
vendor_payments = nc.vendor_payments.get_all()
data = {
'accounts': accounts,
'classifications': classifications,
'departments': departments,
'locations': locations,
'currencies': currencies,
'vendors': vendors,
'vendor_bills': vendor_bills,
'subsidiaries': subsidiaries,
'expense_categories': expense_categories,
'employees': employees,
'vendor_payments': vendor_payments
}
with open('/tmp/netsuite.json', 'w') as oj:
oj.write(json.dumps(data, default=str, indent=2))
# There are also generator methods to iterate over potentially large lists
for c in nc.currencies.get_all_generator():
print(c)
# Get a specific object
nc.currencies.get(internalId='1')
# Post operation is only supported on vendor_bills, expense_reports, journal_entries and vendor_payments currently (see tests on how to construct vendor bill, expense report and journal entry)
vb = {...}
nc.vendor_bills.post(vb)
er = {...}
nc.expense_reports.post(er)
je = {...}
nc.journal_entries.post(je)
vp = {...}
nc.vendor_payments.post(vp)
### Upsert Files
file = open('receipt.pdf', 'rb').read()
created_folder = nc.folders.post(
{
"externalId": 'new-folder',
"name": 'Receipts'
}
)
uploaded_file = nc.files.post({
"externalId": "receipt 1",
"name": 'receipt.pdf',
'content': file,
'fileType': '_PDF',
"folder": {
"name": None,
"internalId": 695,
"externalId": 'new-folder',
"type": "folder"
}
}
)
Note: NetSuite requires two-factor authentication (2FA) for all Administrator and other highly privileged roles in all NetSuite accounts. Instead, you can login with a non-highly privileged role or use token based authentication (TBA) with your requests. For TBA, see below.
If login fails, a NetSuiteLoginError is thrown.
For more information about NetSuite authentication, see: (https://docs.oracle.com/cloud/latest/netsuitecs_gs/NSATH/NSATH.pdf)
To run integration tests, you will set both login and TBA credentials for an actual Netsuite account with the right permissions.
# TBA credentials
export NS_ACCOUNT=xxxx
export NS_CONSUMER_KEY=xxxx
export NS_CONSUMER_SECRET=xxxx
export NS_TOKEN_KEY=xxxx
export NS_TOKEN_SECRET=xxxx
python -m pytest test/integration
To get code coverage report, run this command:
python -m pytest --cov=netsuitesdk
<snipped output>
Name Stmts Miss Cover
---------------------------------------------------
netsuitesdk/__init__.py 5 0 100%
netsuitesdk/client.py 343 198 42%
netsuitesdk/constants.py 3 0 100%
netsuitesdk/exceptions.py 14 5 64%
netsuitesdk/netsuite_types.py 2 0 100%
netsuitesdk/utils.py 47 19 60%
---------------------------------------------------
TOTAL 414 222 46%
To get an html report, run this command:
python -m pytest --cov=netsuitesdk --cov-report html:cov_html
We want to maintain code coverage of more than 95% for this project at all times.
Documentation can be found in the docs/_build/html folder (open index.html) and soon in readthedocs.
For contributors: to build the documentation (cd to /docs and) run make buildapi
as well as make html
This SDK is under active development. Once the contracts are well settled, we will be accepting contributions. Please mail siva@fyle.in if you wish to collaborate on this.