0

I'm a little bit rusted with Python but I need to set up a SOAP call with zeep client. I managed to successfully call a couple of methods by passing in only a dictionary object but I don't have luck setting this one part and I'm not sure if it's even possible using this technique.

This is the part of the envelope I have trouble with:

<xs:complexType name="setupParameter">
    <xs:sequence />
    <xs:attribute name="key" type="xs:string" use="required" />
    <xs:attribute name="value" type="xs:string" use="required" />
</xs:complexType>

which is embedded inside:

<xs:complexType name="transportSettings">
    <xs:sequence>
        <xs:element maxOccurs="unbounded" minOccurs="0" name="setupParameter" type="tns:setupParameter" />
    </xs:sequence>
</xs:complexType>

I tried passing this params like this:

'transportSettings': {
    [
        {'setupParameter': {'key': 'key1', 'value': 'val1'}},
        {'setupParameter': {'key': 'key2', 'value': 'val2'}}
    ]
 }

inside the envelope but it seems that it's not working. Since the SOAP method does not have great validation it does create two items of setupParameter type but they both are missing key and value values.

Shed some light onto this for me, please.

Edit1

This is the output from SoapUI (part of the request) that I'm trying to replicate:

<transportSettings>
    <!--Zero or more repetitions:-->
    <setupParameter key="?" value="?"/>
</transportSettings>

Edit2

So, I've added a plugin to zeep client (as described in their documentation) that prints out SOAP requests and responses and this is the request:

<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
  <soap-env:Body>
    <ns0:provisionService xmlns:ns0="http://ntc.nms.slm.hub.provisioning">
      <service>
        <vn>test</vn>
        <serviceClass>Satellite Internet Access - 3100 Forward</serviceClass>
        <linkType>MULTIPLE_ACCESS</linkType>
        <channelCarrier>false</channelCarrier>
        <transportSettings>
          <setupParameter key="" value=""/>
        </transportSettings>
        <multicastRequired>false</multicastRequired>
        <linkTopology>POINT_TO_POINT</linkTopology>
        <serviceGuiOptions>
          <enableBooking>true</enableBooking>
          <enableUnManagedTransmitter>false</enableUnManagedTransmitter>
          <enableCustomSetupParameters>true</enableCustomSetupParameters>
        </serviceGuiOptions>
        <qosParameters>
          <bestEffortPirFixed>0</bestEffortPirFixed>
          <bestEffortPirPct>0</bestEffortPirPct>
          <criticalData1CirFixed>0</criticalData1CirFixed>
          <criticalData1CirPct>0</criticalData1CirPct>
          <criticalData1PirFixed>0</criticalData1PirFixed>
          <criticalData1PirPct>0</criticalData1PirPct>
          <criticalData2CirFixed>0</criticalData2CirFixed>
          <criticalData2CirPct>0</criticalData2CirPct>
          <criticalData2PirFixed>0</criticalData2PirFixed>
          <criticalData2PirPct>0</criticalData2PirPct>
          <criticalData3CirFixed>0</criticalData3CirFixed>
          <criticalData3CirPct>0</criticalData3CirPct>
          <criticalData3PirFixed>0</criticalData3PirFixed>
          <criticalData3PirPct>0</criticalData3PirPct>
          <realTime1CirFixed>6000</realTime1CirFixed>
          <realTime1CirPct>0</realTime1CirPct>
          <realTime2CirFixed>0</realTime2CirFixed>
          <realTime2CirPct>0</realTime2CirPct>
          <realTime3CirFixed>0</realTime3CirFixed>
          <realTime3CirPct>80</realTime3CirPct>
        </qosParameters>
      </service>
    </ns0:provisionService>
  </soap-env:Body>
</soap-env:Envelope>

that is created from this input dictionary (by passing in like this - client.service.serviceName(inputDict)):

{
    'serviceClass': '${serviceName}',
    'vn': '${testVnName}',
    'linkType': 'MULTIPLE_ACCESS',
    'linkTopology': 'POINT_TO_POINT',
    'serviceGuiOptions': {
        'enableBooking': 1, 
        'enableUnManagedTransmitter': 0, 
        'enableCustomSetupParameters': 1
    }, 
    'multicastRequired': 0, 
    'channelCarrier': 0, 
    'qosParameters': {
        'realTime1CirFixed': 6000,
        'realTime1CirPct': 0, 
        'realTime2CirFixed': 0, 
        'realTime2CirPct': 0, 
        'realTime3CirFixed': 0, 
        'realTime3CirPct': 80,
        'criticalData1CirFixed': 0, 
        'criticalData1CirPct': 0, 
        'criticalData1PirFixed': 0, 
        'criticalData1PirPct': 0, 
        'criticalData2CirFixed': 0, 
        'criticalData2CirPct': 0, 
        'criticalData2PirFixed': 0, 
        'criticalData2PirPct': 0, 
        'criticalData3CirFixed': 0, 
        'criticalData3CirPct': 0, 
        'criticalData3PirFixed': 0, 
        'criticalData3PirPct': 0, 
        'bestEffortPirFixed': 0, 
        'bestEffortPirPct': 0
    }, 
    'transportSettings': [
        {'setupParameter': {'key': 'forwardGateway', 'value': 'dialog'}}, 
        {'setupParameter': {'key': 'referenceServiceProfileDomainName', 'value': 'hno'}}
    ]
}

And what I want is (just the problematic part):

        <transportSettings>
          <setupParameter key="key1" value="val1"/>
          <setupParameter key="key2" value="val2"/>
          <setupParameter key="key3" value="val3"/>
        </transportSettings>
mmesnjak
  • 169
  • 4
  • 14

1 Answers1

1

Not sure if you already managed to find the solution yourself.

However take a look here: http://docs.python-zeep.org/en/master/datastructures.html

<element name='ElementName'>
 <complexType xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <choice maxOccurs="unbounded">
    <sequence>
        <element name="item_1_a" type="string"/>
        <element name="item_1_b" type="string"/>
    </sequence>
    <element name="item_2" type="string"/>
  </choice>
</complexType>

And than nesting your info by adding them to the element itself. _value_1 refers to the first choice in the parent.

element = client.get_element('ns0:ElementName')
obj = element(_value_1={'item_1_a': 'foo', 'item_1_b': 'bar'})

Hope this helps!