Datastructures¶
Creating objects¶
Most of the times you need to pass nested data to the soap client. These
Complex types can be retrieved using the client.get_type()
method.
from zeep import Client
client = Client('http://my-enterprise-endpoint.com')
order_type = client.get_type('ns0:Order')
order = order_type(number='1234', price=99)
client.service.submit_order(user_id=1, order=order)
However instead of creating an object from a type defined in the XSD you can also pass in a dictionary. Zeep will automatically convert this dict to the required object (and nested child objects) during the call.
from zeep import Client
client = Client('http://my-enterprise-endpoint.com')
client.service.submit_order(user_id=1, order={
'number': '1234',
'price': 99,
})
Using factories¶
When you need to create multiple types the Client.get_type()
calls to
retrieve the type class and then instantiating them can be a bit verbose. To
simplify this you can use a factory object.
from zeep import Client
client = Client('http://my-enterprise-endpoint.com')
factory = client.type_factory('ns0')
user = factory.User(id=1, name='John')
order = factory.Order(number='1234', price=99)
client.service.submit_order(user=user, order=order)
New in version 0.22.
xsd:choice¶
Mapping the semantics of xsd:choice elements to code is unfortunately pretty difficult. Zeep tries to solve this using two methods:
- Accepting the elements in the xsd:choice element as kwargs. This only works for simple xsd:choice definitions.
- Using the special kwarg
_value_N
where the N is the number of the choice in the parent type. This method allows you to pass a list of dicts (when maxOccurs != 1) or a dict directly.
The following examples should illustrate this better.
Simple method¶
<?xml version="1.0"?>
<schema xmlns:tns="http://tests.python-zeep.org/"
targetNamespace="http://tests.python-zeep.org/">
<element name='ElementName'>
<complexType xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<choice>
<element name="item_1" type="string"/>
<element name="item_2" type="string"/>
</choice>
</complexType>
</element>
</schema>
element = client.get_element('ns0:ElementName')
obj = element(item_1='foo')
Nested using _value_1¶
<?xml version="1.0"?>
<schema xmlns:tns="http://tests.python-zeep.org/"
targetNamespace="http://tests.python-zeep.org/">
<element name='ElementName'>
<complexType xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<choice maxOccurs="1">
<sequence>
<element name="item_1_a" type="string"/>
<element name="item_1_b" type="string"/>
</sequence>
</choice>
</complexType>
</element>
</schema>
element = client.get_element('ns0:ElementName')
obj = element(_value_1={'item_1_a': 'foo', 'item_1_b': 'bar'})
Nested list using _value_1¶
<?xml version="1.0"?>
<schema xmlns:tns="http://tests.python-zeep.org/"
targetNamespace="http://tests.python-zeep.org/">
<element name='ElementName'>
<complexType xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<choice maxOccurs="unbounded">
<element name="item_1" type="string"/>
<element name="item_2" type="string"/>
</choice>
</complexType>
</element>
</schema>
element = client.get_element('ns0:ElementName')
obj = element(_value_1=[{'item_1': 'foo'}, {'item_2': 'bar'}])
Any objects¶
Zeep offers full support for xsd:any elements. xsd:any elements are used as a
kind of wildcard and basically allows any element to be used. Zeep needs to
know the element name you want to serialize, so the value needs to be wrapped
in a special object. This is the AnyObject
. It takes two
parameters, the xsd Element first and the value as the second arg.
from zeep import Client
from zeep import xsd
client = Client('http://my-entrprisy-endpoint.com')
order_type = client.get_element('ns0:Order')
order = xsd.AnyObject(
order_type, order_type(number='1234', price=99))
client.service.submit_something(user_id=1, _value_1=order)
AnyType objects¶
xsd:anyType is used as a wildcard type. Where the xsd:Any element allows any
element the xsd:anyType allows any type for a specific element. The usage from
zeep is almost the same. Instead of passing an Element
class
to the AnyObject an xsd type is passed.
from zeep import Client
from zeep import xsd
client = Client('http://my-entrprisy-endpoint.com')
value = xsd.AnyObject(xsd.String(), 'foobar')
client.service.submit_something(user_id=1, my_string=value)
SkipValue¶
Zeep will automatically validate that all the required values are set when
calling an operation. If you want to force a value to be ignored and left out
of the generated XML then you can assign the zeep.xsd.SkipValue
constant.
from zeep import Client
from zeep import xsd
client = Client('http://my-entrprisy-endpoint.com')
client.service.submit_something(user_id=1, my_string=xsd.SkipValue)