Permalink
Browse files

add: element instances can be created via dicts

  • Loading branch information...
1 parent aa2b461 commit 3abd545b512e5d172241bba97c676782e0d75f12 @baverman committed Apr 18, 2012
Showing with 65 additions and 21 deletions.
  1. +6 −3 dropthesoap/schema/xs.py
  2. +19 −10 dropthesoap/service.py
  3. +35 −0 tests/test_schema.py
  4. +5 −8 tests/test_service.py
@@ -175,7 +175,10 @@ def element_dict(self):
def element_list(self):
return [c for c in self.children if isinstance(c, element)]
- def init(self, instance, **kwargs):
+ def init(self, instance, *args, **kwargs):
+ if args:
+ kwargs = args[0]
+
elements = self.element_dict
for name, value in kwargs.iteritems():
if name not in elements:
@@ -298,8 +301,8 @@ def fill_node(cls, node, instance, creator):
cls.realtype.fill_node(node, instance, creator)
@classmethod
- def init(cls, instance, **kwargs):
- cls.realtype.init(instance, **kwargs)
+ def init(cls, instance, *args, **kwargs):
+ cls.realtype.init(instance, *args, **kwargs)
@classmethod
def from_node(cls, node):
@@ -3,7 +3,7 @@
logger = logging.getLogger('dropthesoap.request')
from .schema import xs, wsdl, soap
-from .schema.model import Namespace, get_root, etree, Instance, TypeInstance
+from .schema.model import Namespace, get_root, etree
class customize(object):
def __init__(self, type, minOccurs=None, maxOccurs=None, default=None, nillable=None):
@@ -56,6 +56,12 @@ def __init__(self, name, tns):
self.schema = xs.schema(Namespace(tns))
def expose(self, returns):
+ if callable(returns) and not isinstance(returns, (xs.Type, xs.element, customize)) and type(returns) is not type:
+ decorated_func = returns
+ returns = None
+ else:
+ decorated_func = None
+
def inner(func):
name = func.__name__
defaults = func.__defaults__
@@ -80,21 +86,24 @@ def inner(func):
self.schema(request)
rname = name + 'Response'
- if isinstance(returns, xs.element):
- response = returns
- response.name = rname
- response.attributes['name'] = rname
- elif isinstance(returns, customize):
- response = returns.get_element(rname)
+ if returns is None:
+ response = self.schema[rname]
else:
- response = xs.element(rname, returns)
+ if isinstance(returns, xs.element):
+ response = returns
+ response.name = rname
+ response.attributes['name'] = rname
+ elif isinstance(returns, customize):
+ response = returns.get_element(rname)
+ else:
+ response = xs.element(rname, returns)
- self.schema(response)
+ self.schema(response)
self.methods[name] = Method(func, names, response)
return func
- return inner
+ return inner(decorated_func) if decorated_func else inner
def wraps(self, original_func):
name = original_func.__name__
View
@@ -147,3 +147,38 @@ def test_none_values_should_be_wrapped_into_empty_element():
assert validate(schema, request)
assert '<boo:foo />' in tostring(request)
+
+def test_dict_intances():
+ schema = xs.schema(Namespace('http://boo', 'boo'))(
+ xs.element('Request')(xs.cts(
+ xs.element('foo')(xs.cts(
+ xs.element('x', xs.string),
+ xs.element('y', xs.int),
+ ))
+ ))
+ )
+
+ request = schema['Request'].instance(foo={'x':'boo', 'y':100})
+ assert validate(schema, request)
+
+ obj = schema.fromstring(tostring(request))
+ assert obj.foo.x == 'boo'
+ assert obj.foo.y == 100
+
+def test_type_aliases():
+ schema = xs.schema(Namespace('http://boo', 'boo'))(
+ xs.complexType(name='fooType')(
+ xs.sequence()(
+ xs.element('x', xs.string),
+ xs.element('y', xs.int))),
+
+ xs.element('Request')(xs.cts(
+ xs.element('foo', 'tns:fooType')))
+ )
+
+ request = schema['Request'].instance(foo={'x':'boo', 'y':100})
+ assert validate(schema, request)
+
+ obj = schema.fromstring(tostring(request))
+ assert obj.foo.x == 'boo'
+ assert obj.foo.y == 100
View
@@ -4,7 +4,7 @@
from dropthesoap.service import Service, optional, Fault
from dropthesoap.schema import xs
-from .helpers import DirectSudsTransport, tostring
+from .helpers import DirectSudsTransport
def test_simple_service():
service = Service('Boo', 'http://boo')
@@ -37,18 +37,15 @@ def add(x=xs.int, y=optional(xs.int)):
def test_complex_return_type():
service = Service('Boo', 'http://boo')
- ResponseType = xs.complexType(name='ResponseType')(
- xs.sequence()(
+ service.schema(
+ xs.element('addResponse')(xs.cts(
xs.element('foo', xs.string),
xs.element('bar', xs.string)))
-
- service.schema(
- ResponseType
)
- @service.expose(returns=ResponseType)
+ @service.expose
def add(x=xs.int, y=xs.int):
- return ResponseType.instance(foo=str(x+y), bar=str(x-y))
+ return {'foo': str(x+y), 'bar': str(x-y)}
#open('/tmp/wow.xml', 'w').write(service.get_wsdl('http://localhost/'))

0 comments on commit 3abd545

Please sign in to comment.