Package: netsuitesdk
netsuite-sdk-pyNetsuite-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.Installation$ pip install netsuitesdkGet StartedThere 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 SDKToken-based AuthFirst, 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=xxxxThe following snippet shows how to use TBA to initialize the SDK.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)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"}})Remarks and possible errors regarding authenticationNote: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)Integration TestsTo 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/integrationCurrently the code coverage is at 90%To run integration tests on a newly added / modified filepython-mpytest-vvtest/integration/test_filename.py;Code coverageTo 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.DocumentationDocumentation 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) runmake buildapias well asmake htmlContributionsWe are actively accepting contributions. Please mailshwetabh.kumar@fylehq.comif you wish to collaborate on this. (Please write test cases for new additions.)