Skip to main content

Python SDK for accessing the NetSuite SOAP webservice

Project description

netsuite-sdk-py

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.

Installation

$ pip install netsuitesdk 

Get Started

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

Token-based Auth

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. From version 3.0.0, the default wsdl_version will be 2024_1.

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,
        #optional wsdl_version to use version other than '2019_1' 
        wsdl_version='2023_2'
    )
    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"
            }
    }
)

Remarks and possible errors regarding authentication

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)

Integration Tests

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 -m pytest -vv test/integration/test_filename.py; 

Code coverage

To get code coverage report, run this command:

python -m pytest --cov=netsuitesdk

<snipped output>
Name                                                   Stmts   Miss  Cover   
----------------------------------------------------------------------------
netsuitesdk/__init__.py                                    4      0   100%
netsuitesdk/api/__init__.py                                0      0   100%
netsuitesdk/api/accounts.py                                6      0   100%
netsuitesdk/api/adv_inter_company_journal_entries.py       7      0   100%
netsuitesdk/api/base.py                                   90      9    90%   
netsuitesdk/api/classifications.py                         6      0   100%
netsuitesdk/api/currencies.py                             10      0   100%
netsuitesdk/api/custom_record_types.py                    11      0   100%
netsuitesdk/api/custom_records.py                         17      0   100%
netsuitesdk/api/customers.py                              21      0   100%
netsuitesdk/api/departments.py                             6      0   100%
netsuitesdk/api/employees.py                              34      0   100%
netsuitesdk/api/expense_categories.py                      6      0   100%
netsuitesdk/api/expense_reports.py                        58      2    97%   
netsuitesdk/api/files.py                                  23      0   100%
netsuitesdk/api/folders.py                                17      0   100%
netsuitesdk/api/journal_entries.py                        41      0   100%
netsuitesdk/api/locations.py                               6      0   100%
netsuitesdk/api/price_level.py                             6      0   100%
netsuitesdk/api/projects.py                                6      0   100%
netsuitesdk/api/subsidiaries.py                            6      0   100%
netsuitesdk/api/tax_groups.py                              6      0   100%
netsuitesdk/api/tax_items.py                               6      0   100%
netsuitesdk/api/vendor_bills.py                           55      1    98%  
netsuitesdk/api/vendor_payments.py                        46      1    98%   
netsuitesdk/api/vendors.py                                21      0   100%
netsuitesdk/connection.py                                 68      0   100%
netsuitesdk/internal/__init__.py                           0      0   100%
netsuitesdk/internal/client.py                           305     79    74%   
netsuitesdk/internal/constants.py                          4      0   100%
netsuitesdk/internal/exceptions.py                        16      3    81%   
netsuitesdk/internal/netsuite_types.py                     2      0   100%
netsuitesdk/internal/utils.py                             40      4    90%   
----------------------------------------------------------------------------
TOTAL                                                    950     99    90%

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 90% for this project at all times.

Documentation

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

Contributions

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.)

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

netsuitesdk-3.3.0.tar.gz (30.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

netsuitesdk-3.3.0-py3-none-any.whl (44.4 kB view details)

Uploaded Python 3

File details

Details for the file netsuitesdk-3.3.0.tar.gz.

File metadata

  • Download URL: netsuitesdk-3.3.0.tar.gz
  • Upload date:
  • Size: 30.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.6

File hashes

Hashes for netsuitesdk-3.3.0.tar.gz
Algorithm Hash digest
SHA256 0af6bd6d4390779aa4f1cc0ffc2a71e49972427132d0db4881f2e3f4f490317e
MD5 5e1964077cb1721fd12313f49d4a62c7
BLAKE2b-256 738d39e6cdd671765abdc136206530236d531a9327ad691f49bd2a120a1b6626

See more details on using hashes here.

File details

Details for the file netsuitesdk-3.3.0-py3-none-any.whl.

File metadata

  • Download URL: netsuitesdk-3.3.0-py3-none-any.whl
  • Upload date:
  • Size: 44.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.6

File hashes

Hashes for netsuitesdk-3.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 dd93b9b6bdcc4a3cc2b288848d7fb239c5aa7d1eb44dde4ec76cea1fec3f1d17
MD5 931837a7e53a99d2a5062492d4ff46f7
BLAKE2b-256 bc66a373cf8688b56788928e9a3187a53f68bb5630a4d8e4860af8d2c9baf415

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page