Zeep is great - but I'd like an option to specify a namespace or alternative lookup within the client. But this is the current (2023) way to access Netsuite with zeep, with the needed service address modification.
client.service._binding_options["address"] = (nsURL + nsURLPath)
The default "service" within the netsuite WSDL is the old "https://webservices.netsuite.com/..." instead of the required "https://{companyid}.suitetalk.api.netsuite.com/...".
def createNonce(length=20):
return ''.join([str(random.randint(0, 9)) for i in range(length)])
def createSignature(passport, tokenSecret, consumerSecret):
signatureKey = f"{urllib.parse.quote_plus(consumerSecret)}&{urllib.parse.quote_plus(tokenSecret)}"
baseString = f"{passport.account}&{passport.consumerKey}&{passport.token}&{passport.nonce}&{passport.timestamp}"
return base64.b64encode(hmac.digest(signatureKey.encode('utf-8'), baseString.encode('utf-8'), hashlib.sha256))
--------------------------------------------------------------------------------------
client = zeep.CachingClient(wsdl=netsuiteWSDL)
client.service._binding_options["address"] = (nsURL + nsURLPath)
#service = client.create_service(netsuiteBinding, address = (nsURL + nsURLPath) )
TokenPassport = client.get_type("ns0:TokenPassport");
tokenPassport = TokenPassport(
account = nsAccount,
consumerKey = consumerKey,
token = tokenKey,
nonce = createNonce(),
timestamp = str(int(datetime.now().timestamp()))
)
TokenPassportSignature = client.get_type("ns0:TokenPassportSignature")
hashAlgorithm = "HMAC-SHA256"
tokenPassport["signature"] = TokenPassportSignature(createSignature(tokenPassport, tokenSecret, consumerSecret), hashAlgorithm)
RecordType = client.get_type("ns1:RecordType")
RecordRef = client.get_type("ns0:RecordRef")
recordRef = RecordRef(
internalId = "14764193",
type = RecordType("customer")
)
print(client.service.get(recordRef, _soapheaders = { "tokenPassport": tokenPassport } ))
There are probably ways to take advantage of auto-binding, but I like clarity. Ironic, since I don't want to have to search the namespaces for types and methods.