I'm new to zeep. I have the following that works very well:
import zeep
from zeep.cache import SqliteCache
from zeep.transports import Transport
wsdl = 'https://emaapitest.eset.com/Services/v2015_1/MSPService.svc?singleWsdl'
transport = Transport(cache=SqliteCache())
client = zeep.Client(wsdl=wsdl, transport=transport )
With the above I can use the defined API for most calls. For example:
data = {'Username': 'xxxx123', 'Password': 'Secretpassword'}
loginreq = client.service.Login(data)
data = {'LoginID': 'xxxyyy', 'Token': 'gregrwevds543', 'CompanyID': 123}
company_details = client.service.GetCompanyDetails(data)
That all works well. However the API call to UpdateSite needs a different format as below:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/" xmlns:msp="http://schemas.datacontract.org/2004/07/MSPApi.Services.v2015_1.Requests">
<soapenv:Header/>
<soapenv:Body>
<tem:UpdateSite>
<tem:request>
<msp:LoginID>123abc</msp:LoginID>
<msp:Token>hpjzncpduqyfreyakcsdilqv</msp:Token>
<msp:LicenseRequests>
<LicenseRequest xmlns:d7="http://schemas.datacontract.org/2004/07/MSPApi.Services.v2015_1.Requests"
i:type="d7:LicenseCreateRequest" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/MSPApi.Services.v2015_1.ViewModels">
<d7:ProductCode>112</d7:ProductCode>
<d7:Quantity>3</d7:Quantity>
<d7:Trial>false</d7:Trial>
</LicenseRequest>
</msp:LicenseRequests>
<msp:SiteID>123456</msp:SiteID>
</tem:request>
</tem:UpdateSite>
</soapenv:Body>
</soapenv:Envelope>
That is I need to change the namespace on the LicenseRequest. Is there any way I can generate this xml (say using etree maybe) and then pass this into zeep? Exact syntax would be a great help. Thanks for any help in advance.
Here's an example to format the SOAP Web Services XML message per the WSDL:
In this example, I found the namespace prefixes assigned by Zeep in client.wsdl.dump()
; see example of this near the bottom of the answer.
>>> import zeep
>>> client = zeep.Client('https://emaapitest.eset.com/Services/v2015_1/MSPService.svc?singleWsdl')
>>> # note - the namespace ns2 was assigned by zeep - see client.wsdl.dump() tip later in this answer
>>> license_create_type = client.get_type('ns2:LicenseCreateRequest')
>>> # Creating an empty object reminds me of the property names, so I don't have to guess
>>> license_create_type()
{
'Note': None,
'ProductCode': None,
'Quantity': None,
'ServerName': None,
'Trial': None
}
>>> my_create = license_create_type(ProductCode=112,Quantity=3,Trial=False)
>>> my_create
{
'Note': None,
'ProductCode': 112,
'Quantity': 3,
'ServerName': None,
'Trial': False
}
>>> my_type = client.get_type('ns2:SiteUpdateRequest')
>>> # Reference for specifying arrays in Zeep: https://github.com/mvantellingen/python-zeep/issues/145#issuecomment-321614947
>>> req = my_type(LoginID="123",Token="mytoken",LicenseRequests={'LicenseRequest':[my_create]})
>>> # To call the service: (assuming valid credentials?)
>>> # client.service.UpdateSite(req)
Here's the Python view of the web service request:
>>> req
{
'LoginID': '123',
'Token': 'mytoken',
'Active': None,
'LicenseRequests': {
'LicenseRequest': [
{
'Note': None,
'ProductCode': 112,
'Quantity': 3,
'ServerName': None,
'Trial': False
}
]
},
'Name': None,
'SecurityAdminRequests': None,
'SiteID': None,
'SupportLegacyKey': None
}
Here's the XML view of the web service request:
>>> # Debugging output to see raw XML...
>>> node = client.create_message(client.service, 'UpdateSite', req)
>>> from lxml import etree
>>> xml_str = etree.tostring(node, pretty_print=True).decode()
>>> print(xml_str)
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
<wsa:Action>http://tempuri.org/IMSPService/UpdateSite</wsa:Action>
<wsa:MessageID>urn:uuid:c3d7d838-6ce8-477b-ad7d-23e99e800a80</wsa:MessageID>
<wsa:To>https://emaapitest.eset.com/Services/v2015_1/MSPService.svc</wsa:To>
</soap-env:Header>
<soap-env:Body>
<ns0:UpdateSite xmlns:ns0="http://tempuri.org/">
<ns0:request>
<ns1:LoginID xmlns:ns1="http://schemas.datacontract.org/2004/07/MSPApi.Services.v2015_1.Requests">123</ns1:LoginID>
<ns2:Token xmlns:ns2="http://schemas.datacontract.org/2004/07/MSPApi.Services.v2015_1.Requests">mytoken</ns2:Token>
<ns3:LicenseRequests xmlns:ns3="http://schemas.datacontract.org/2004/07/MSPApi.Services.v2015_1.Requests">
<ns4:LicenseRequest xmlns:ns4="http://schemas.datacontract.org/2004/07/MSPApi.Services.v2015_1.ViewModels" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns3:LicenseCreateRequest">
<ns3:ProductCode>112</ns3:ProductCode>
<ns3:Quantity>3</ns3:Quantity>
<ns3:Trial>false</ns3:Trial>
</ns4:LicenseRequest>
</ns3:LicenseRequests>
</ns0:request>
</ns0:UpdateSite>
</soap-env:Body>
</soap-env:Envelope>
Tip: use client.wsdl.dump()
I usually start a project by reading client.wsdl.dump()
to see the mappings generated by Zeep, starting from the "Bindings" and "Operations" at the bottom, then working backwards through the types. This is usually all you need to get started.
>>> import zeep
>>> client = zeep.Client('https://emaapitest.eset.com/Services/v2015_1/MSPService.svc?singleWsdl')
>>> client.wsdl.dump()
Prefixes:
myprefix: http://schemas.datacontract.org/2004/07/MSPApi.Services.v2015_1.Requests
xsd: http://www.w3.org/2001/XMLSchema
ns0: http://tempuri.org/
ns1: http://schemas.microsoft.com/2003/10/Serialization/
ns3: http://schemas.datacontract.org/2004/07/MSPApi.Services.v2015_1.Responses
ns4: http://schemas.microsoft.com/2003/10/Serialization/Arrays
ns5: http://schemas.datacontract.org/2004/07/MSPApi.Services.v2015_1.ViewModels
Global elements:
<SNIP - VERY LONG OUTPUT>
Global types:
<SNIP - VERY LONG OUTPUT>
ns2:SiteUpdateRequest(LoginID: xsd:string, Token: xsd:string, Active: xsd:boolean, LicenseRequests: ns5:ArrayOfLicenseRequest, Name: xsd:string, SecurityAdminRequests: ns2:ArrayOfSecurityAdminRequest, SiteID: xsd:long, SupportLegacyKey: xsd:boolean)
<SNIP - VERY LONG OUTPUT>
Service: MSPService
Port: BasicHttpBinding_IMSPService (Soap11Binding: {http://tempuri.org/}BasicHttpBinding_IMSPService)
Operations:
<SNIP - VERY LONG OUTPUT>
UpdateSite(request: ns2:SiteUpdateRequest) -> UpdateSiteResult: ns3:SiteDetailsResponse
<SNIP - VERY LONG OUTPUT>
>>>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With