Skip to content

Instantly share code, notes, and snippets.

@nicholjy
Created June 11, 2016 03:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nicholjy/436ae857c30ae6a5bf8cafdeb7921ca3 to your computer and use it in GitHub Desktop.
Save nicholjy/436ae857c30ae6a5bf8cafdeb7921ca3 to your computer and use it in GitHub Desktop.
Patch Zeep support for sub-types in sequences
from collections import OrderedDict
import pprint
import zeep.xsd
from zeep.xsd.types import Choice, ComplexType, Element, process_signature
__ALL__ = ['patch_zeep']
def patch_zeep():
zeep.xsd.types.CompoundValue = _CompoundValue
zeep.xsd.elements.ListElement = _ListElement
def _convert_value(value, field):
if isinstance(field, Choice):
return value
if isinstance(value, dict):
value = field(**value)
elif isinstance(value, list):
if isinstance(field.type, ComplexType):
value = [_convert_value(v, field.type) for v in value]
else:
value = [field.type(v) for v in value]
return value
class _CompoundValue(object):
def __init__(self, *args, **kwargs):
fields = self._xsd_type.fields()
# Set default values
for key, value in fields:
if isinstance(value, _ListElement):
value = []
else:
value = None
setattr(self, key, value)
items = process_signature(fields, args, kwargs)
fields = OrderedDict([(name, elm) for name, elm in fields])
for key, value in items.items():
if key in fields:
field = fields[key]
value = _convert_value(value, field)
setattr(self, key, value)
def __repr__(self):
return pprint.pformat(self.__dict__, indent=4)
class _ListElement(Element):
def __call__(self, *args, **kwargs):
return [self.type(*args, **kwargs)]
def serialize(self, value):
if value:
return [self.type.serialize(val) for val in value]
return []
def render(self, parent, value):
for val in value:
super().render(parent, val)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment