Has anyone been able to get the suds soap library to work with the NetSuite WSDL?

前端 未结 5 652
礼貌的吻别
礼貌的吻别 2021-01-20 21:35

Has anyone been able to get the suds soap library to work with the NetSuite WSDL? I get this error when I try to create a client.

from suds.client import Cli         


        
相关标签:
5条回答
  • 2021-01-20 21:56

    Yes, suds can connect to NetSuite, but it takes a long time to process the WSDL.

    Here's some sample code:

    # Open NetSuite Session
    wsdlNetSuite = 'https://webservices.netsuite.com/wsdl/v2010_1_0/netsuite.wsdl'
    client = Client(wsdlNetSuite)
    
    # Login
    passport = client.factory.create('ns4:Passport')
    passport.email = 'username@web.com'
    passport.password = 'ABC123'
    passport.account = 123
    loginResponse = client.service.login(passport)
    print 'Login Response: '
    print loginResponse.status
    
    # Get a record
    recordRef = client.factory.create('ns4:RecordRef')
    recordRef._internalId = 127842
    recordRef._type = 'invoice'
    record = client.service.get(recordRef)
    print record
    

    You might also need to try various combinations of Python and SUDS versions. It's not a particularly reliable library.

    0 讨论(0)
  • 2021-01-20 21:58

    If you want to do a one-off fix on a saved WSDL instead of doing the fix every time (which takes a while) here is a VIM substitution command that I used

    :%s/RequestLimitFault">\n\t*<soap\:fault name=\"ExceededRecordCountFault/RequestLimitFault\"\>\r\t\t\t\t<soap\:fault name=\"Exce   ededRequestLimitFault/gc
    

    This works on the 2010 Netsuite WSDL and also had to do it for the 2012 Netsuite WSDL (you think they would have fixed it after two years)

    0 讨论(0)
  • 2021-01-20 22:03

    It is a bit late, but for the record I attach a way of how one can work with NetSuite SuiteTalk SOAP API using Python Zeep.

    Example of NetSuite SOAP login with Python and Zeep followed by adding a customer.

    # pip3 install zeep
    from zeep import Client
    
    WSDL_URL = 'https://webservices.sandbox.netsuite.com/wsdl/v2016_1_0/netsuite.wsdl'
    NS_EMAIL = 'admin@example.com'
    NS_PASSWORD = '*********'
    NS_ROLE = '1111'
    NS_ACCOUNT = '1111111'
    NS_APPID = 'FFFFFFFF-FFFF-0000-0000-FFFFFFFFFFFF'
    
    
    def login_client():
        client = Client(WSDL_URL)
        Passport = client.get_type('ns1:Passport')
        AppInfo = client.get_type('ns5:ApplicationInfo')
        passport = Passport(email=NS_EMAIL, password=NS_PASSWORD, account=NS_ACCOUNT)
        app_info = AppInfo(applicationId=NS_APPID)
        login = client.service.login(passport=passport,
                                     _soapheaders={'applicationInfo': app_info})
        print('Login Response: ', login.status)
        return client
    
    
    # Example usage
    client = login_client()
    
    # add a customer
    Customer = client.get_type('ns14:Customer')
    customer = Customer(
        lastName='Joe',
        firstName='Bloggs',
        email='joe@example.com'
    )
    response = client.service.add(customer)
    print(response)
    

    See also: https://github.com/fmalina/python-netsuite

    0 讨论(0)
  • 2021-01-20 22:07

    https://webservices.netsuite.com/wsdl/v2010_2_0/netsuite.wsdl

    I found that it was failing on a validation between this part:

    <operation name="checkAsyncStatus">
        <input name="checkAsyncStatusRequest" message="tns:checkAsyncStatusRequest"/>
        <output name="checkAsyncStatusResponse" message="tns:checkAsyncStatusResponse"/>
        <fault name="InvalidSessionFault" message="tns:InvalidSessionFault"/>
        <fault name="InvalidCredentialsFault" message="tns:InvalidCredentialsFault"/>
        <fault name="ExceededRequestLimitFault" message="tns:ExceededRequestLimitFault"/> -- mismatch
        <fault name="UnexpectedErrorFault" message="tns:UnexpectedErrorFault"/>
        <fault name="AsyncFault" message="tns:AsyncFault"/>
    </operation>
    

    and this part:

    <operation name="checkAsyncStatus">
        <soap:operation soapAction="checkAsyncStatus"/>
        <input name="checkAsyncStatusRequest">
            <soap:header message="tns:headers" part="passport" use="literal"/>
            <soap:header message="tns:headers" part="applicationInfo" use="literal"/>
            <soap:header message="tns:headers" part="partnerInfo" use="literal"/>
            <soap:header message="tns:headers" part="preferences" use="literal"/>
            <soap:body use="literal"/>
        </input>
        <output name="checkAsyncStatusResponse">
            <soap:header message="tns:headers" part="documentInfo" use="literal"/>
            <soap:body use="literal"/>
        </output>
        <fault name="InvalidSessionFault">
            <soap:fault name="InvalidSessionFault" use="literal"/>
        </fault>
        <fault name="InvalidCredentialsFault">
            <soap:fault name="InvalidCredentialsFault" use="literal"/>
        </fault>
        <fault name="ExceededRequestLimitFault">
            <soap:fault name="ExceededRecordCountFault" use="literal"/> -- mismatch
        </fault>
        <fault name="UnexpectedErrorFault">
            <soap:fault name="UnexpectedErrorFault" use="literal"/>
        </fault>
        <fault name="AsyncFault">
            <soap:fault name="AsyncFault" use="literal"/>
        </fault>
    </operation>
    

    I changed this:

    <fault name="ExceededRequestLimitFault">
        <soap:fault name="ExceededRecordCountFault" use="literal"/>
    </fault>
    

    to this:

    <fault name="ExceededRequestLimitFault">
        <soap:fault name="ExceededRequestLimitFault" use="literal"/>
    </fault>
    

    The modification allows Suds to create the client. Like John mentioned, it does take forever to parse(more than two minutes). I haven't tried using checkAsyncStatus to see if it works.

    0 讨论(0)
  • 2021-01-20 22:16

    Though not the best way to do things, if you're desperate, you can keep trying different versions of their wsdl. I was getting the same error message, so I kept trying until one worked. I went in this order:

    'https://webservices.netsuite.com/wsdl/v2010_2_0/netsuite.wsdl'
    'https://webservices.netsuite.com/wsdl/v2010_1_0/netsuite.wsdl'
    'https://webservices.netsuite.com/wsdl/v2009_2_0/netsuite.wsdl'
    'https://webservices.netsuite.com/wsdl/v2009_1_0/netsuite.wsdl'
    

    'https://webservices.netsuite.com/wsdl/v2009_1_0/netsuite.wsdl' finally worked for me

    EDIT: Based on tponthieux's answer, I realize now that you can use the suds plugin feature to fix the wsdl (I would simply comment on his answer, but I don't have the reputation yet :( ):

    import re
    
    from suds.client import Client
    from suds.plugin import DocumentPlugin
    
    NetSuite_wsdl = 'https://webservices.netsuite.com/wsdl/v2010_2_0/netsuite.wsdl'
    
    
    class Fix_NS_wsdl(DocumentPlugin):
        bad_fault = re.compile(r"(ExceededRequestLimitFault)"
                r"(\">\s*<soap:fault name=\")(ExceededRecordCountFault)")
    
        def loaded(self, context):
            if context.url == NetSuite_wsdl:
                context.document = self.bad_fault.sub(r"\1\2\1", context.document)
    
    client = Client(NetSuite_wsdl, plugins=[Fix_NS_wsdl()])
    
    0 讨论(0)
提交回复
热议问题