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.
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.
importosimportitertoolsimportjsonfromnetsuitesdkimportNetSuiteConnectiondefconnect_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,
#optional wsdl_version to use version other than '2019_1' wsdl_version='2023_2'
)
returnncnc=connect_tba()
# Use get_all methods to get all objects of certain typescurrencies=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= [aforainall_accountsifa['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
}
withopen('/tmp/netsuite.json', 'w') asoj:
oj.write(json.dumps(data, default=str, indent=2))
# There are also generator methods to iterate over potentially large listsforcinnc.currencies.get_all_generator():
print(c)
# Get a specific objectnc.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 Filesfile=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
Currently the code coverage is at 90%
To run integration tests on a newly added / modified file
python-mpytest-vvtest/integration/test_filename.py; To get code coverage report, run this command:
python-mpytest--cov=netsuitesdk<snippedoutput>NameStmtsMissCover----------------------------------------------------------------------------netsuitesdk/__init__.py40100%netsuitesdk/api/__init__.py00100%netsuitesdk/api/accounts.py60100%netsuitesdk/api/adv_inter_company_journal_entries.py70100%netsuitesdk/api/base.py90990%netsuitesdk/api/classifications.py60100%netsuitesdk/api/currencies.py100100%netsuitesdk/api/custom_record_types.py110100%netsuitesdk/api/custom_records.py170100%netsuitesdk/api/customers.py210100%netsuitesdk/api/departments.py60100%netsuitesdk/api/employees.py340100%netsuitesdk/api/expense_categories.py60100%netsuitesdk/api/expense_reports.py58297%netsuitesdk/api/files.py230100%netsuitesdk/api/folders.py170100%netsuitesdk/api/journal_entries.py410100%netsuitesdk/api/locations.py60100%netsuitesdk/api/price_level.py60100%netsuitesdk/api/projects.py60100%netsuitesdk/api/subsidiaries.py60100%netsuitesdk/api/tax_groups.py60100%netsuitesdk/api/tax_items.py60100%netsuitesdk/api/vendor_bills.py55198%netsuitesdk/api/vendor_payments.py46198%netsuitesdk/api/vendors.py210100%netsuitesdk/connection.py680100%netsuitesdk/internal/__init__.py00100%netsuitesdk/internal/client.py3057974%netsuitesdk/internal/constants.py40100%netsuitesdk/internal/exceptions.py16381%netsuitesdk/internal/netsuite_types.py20100%netsuitesdk/internal/utils.py40490%----------------------------------------------------------------------------TOTAL9509990%To get an html report, run this command:
python-mpytest--cov=netsuitesdk--cov-reporthtml:cov_htmlWe want to maintain code coverage of more than 90% 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
We are actively accepting contributions. Please mail shwetabh.kumar@fylehq.com if you wish to collaborate on this. (Please write test cases for new additions.)