Skip to content

Commit

Permalink
take nameless types as element arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
baverman committed Aug 21, 2014
1 parent cbdefa1 commit 0965393
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 54 deletions.
4 changes: 2 additions & 2 deletions dropthesoap/schema/model.py
Expand Up @@ -11,7 +11,7 @@ def __get__(_self, _instance, cls):

class TypeNameDescriptor(object):
def __get__(_self, instance, cls):
return instance.attributes['name'] if instance else cls.tag
return instance.attributes.get('name') if instance else cls.tag


def resolve_type(etype):
Expand Down Expand Up @@ -202,4 +202,4 @@ def get_prefixed_tag(self, namespace, tag):
return '{}:{}'.format(self.get_prefix(namespace), tag)

def __call__(self, namespace, tag, *args, **kwargs):
return etree.Element(self.get_prefixed_tag(namespace, tag), *args, **kwargs)
return etree.Element(self.get_prefixed_tag(namespace, tag), *args, **kwargs)
53 changes: 30 additions & 23 deletions dropthesoap/schema/soap.py
@@ -1,32 +1,39 @@
from . import xs
from .model import Namespace
from .model import Namespace, get_root, etree

namespace = Namespace('http://schemas.xmlsoap.org/soap/envelope/', 'soap')

Header = xs.element('Header', minOccurs=0)(
xs.complexType()(
xs.sequence()(
xs.any(minOccurs=0, maxOccurs=xs.unbounded))))
schema = xs.schema(namespace)(
xs.element('Envelope', xs.cts(
xs.element('Header', xs.optional(xs.cts(
xs.any(minOccurs=0, maxOccurs=xs.unbounded)))),
xs.element('Body', xs.optional(xs.cts(
xs.any(minOccurs=0, maxOccurs=xs.unbounded)))),
)),
xs.element('Fault', xs.cts(
xs.element('faultcode', xs.string),
xs.element('faultstring', xs.string),
xs.element('faultactor', xs.optional(xs.string)),
xs.element('detail', xs.optional(xs.string)),
)),
)

Body = xs.element('Body', minOccurs=0)(
xs.complexType()(
xs.sequence()(
xs.any(minOccurs=0, maxOccurs=xs.unbounded))))
Envelope = schema['Envelope']
Fault = schema['Fault']

Envelope = xs.element('Envelope')(
xs.complexType()(
xs.sequence()(
Header,
Body)))

Fault = xs.element('Fault')(xs.cts(
xs.element('faultcode', xs.string),
xs.element('faultstring', xs.string),
xs.element('faultactor', xs.string, minOccurs=0),
xs.element('detail', xs.string, minOccurs=0)))
def make_envelope(response=None, header=None):
envelope = {}
if response:
envelope['Body'] = {'_any': [response]}
if header:
envelope['Header'] = {'_any': [header]}

return Envelope.normalize(envelope)

schema = xs.schema(namespace)(
Envelope
)

schema.update_schema([Fault])
def response_tostring(response=None, header=None):
renvelope = make_envelope(response, header)
tree = get_root(renvelope)
tree.attrib['soap:encodingStyle'] = 'http://www.w3.org/2001/12/soap-encoding'
return etree.tostring(tree, encoding='utf-8')
22 changes: 14 additions & 8 deletions dropthesoap/schema/xs.py
Expand Up @@ -23,6 +23,7 @@ def process_attributes(self, attributes):
attributes = {k: v for k, v in attributes.iteritems()
if v is not None and k != 'self'}

after = None
type = attributes.pop('type', None)
if type is not None:
if isinstance(type, customize):
Expand All @@ -34,8 +35,11 @@ def process_attributes(self, attributes):
if isinstance(type, basestring):
type = Type.alias(self, type)

attributes['type'] = type
self.type = extract_type(type)
if type.type_name:
attributes['type'] = type
self.type = extract_type(type)
else:
after = type

for k, v in attributes.items():
if k == 'type':
Expand All @@ -47,7 +51,7 @@ def process_attributes(self, attributes):
else:
attributes[k] = str(v)

return attributes
return attributes, after


class customize(Type):
Expand Down Expand Up @@ -145,8 +149,9 @@ def __init__(self, name=None, type=None, ref=None, substitutionGroup=None, defau
fixed=None, form=None, maxOccurs=None, minOccurs=None, nillable=None, abstract=None,
block=None, final=None):

attributes = process_attributes(self, locals())
attributes, after = process_attributes(self, locals())
Node.__init__(self, **attributes)
after and self(after)

def create_node(self, creator):
return creator(self.schema.targetNamespace, self.name)
Expand Down Expand Up @@ -200,8 +205,9 @@ def __repr__(self):
class attribute(Node):
namespace = namespace
def __init__(self, name=None, type=None, default=None, use=None, ref=None, form=None, fixed=None):
attributes = process_attributes(self, locals())
attributes, after = process_attributes(self, locals())
Node.__init__(self, **attributes)
after and self(after)

def instance(self, *args, **kwargs):
return self.type.instance_class(self, *args, **kwargs)
Expand Down Expand Up @@ -366,7 +372,7 @@ class complexType(Type, _DelegateType):
type_counter = 0

def __init__(self, name=None):
attributes = process_attributes(self, locals())
attributes, _ = process_attributes(self, locals())
Type.__init__(self, **attributes)

def __call__(self, *children):
Expand Down Expand Up @@ -398,7 +404,7 @@ class simpleType(Type, _DelegateType):
type_counter = 0

def __init__(self, name=None):
attributes = process_attributes(self, locals())
attributes, _ = process_attributes(self, locals())
Type.__init__(self, **attributes)

@classmethod
Expand Down Expand Up @@ -551,7 +557,7 @@ def from_node(node):
class any(element):
namespace = namespace
def __init__(self, minOccurs=None, maxOccurs=None, namespace=None, processContents=None):
attributes = process_attributes(self, locals())
attributes, _ = process_attributes(self, locals())
self.name = '_any'
self.type = anyType
Node.__init__(self, **attributes)
Expand Down
15 changes: 1 addition & 14 deletions dropthesoap/service.py
@@ -1,7 +1,3 @@
import traceback
import logging
logger = logging.getLogger('dropthesoap.request')

from .schema import xs, wsdl, soap
from .schema.model import Namespace, get_root, etree

Expand Down Expand Up @@ -49,10 +45,7 @@ def make_message_element(name, obj):
if isinstance(obj, xs.element):
return obj
else:
if isinstance(obj, xs.Type) and not hasattr(obj, 'name'):
return xs.element(name)(obj)
else:
return xs.element(name, obj)
return xs.element(name, obj)


class Service(object):
Expand Down Expand Up @@ -198,9 +191,3 @@ def call(self, transport_request, xml):
response = soap.Fault.instance(faultcode=e.code, faultstring=e.message)

return response

def response_to_string(self, response):
renvelope = soap.Envelope.instance(Body=soap.Body.instance(_any=[response]))
tree = get_root(renvelope)
tree.attrib['soap:encodingStyle'] = 'http://www.w3.org/2001/12/soap-encoding'
return etree.tostring(tree, encoding='utf-8')
2 changes: 1 addition & 1 deletion dropthesoap/wsgi.py
Expand Up @@ -22,7 +22,7 @@ def __call__(self, environ, start_response):
result = soap.Fault.instance(faultcode='Server', faultstring=e.message,
detail=traceback.format_exc())

response = Response(self.service.response_to_string(result))
response = Response(soap.response_tostring(result))
response.content_type = 'text/xml'
else:
response = HTTPNotFound()
Expand Down
2 changes: 1 addition & 1 deletion tests/helpers.py
Expand Up @@ -40,4 +40,4 @@ def send(self, request):
result = soap.Fault.instance(faultcode='Server', faultstring=e.message,
detail=traceback.format_exc())

return Reply('200 OK', {}, self._service.response_to_string(result))
return Reply('200 OK', {}, soap.response_tostring(result))
9 changes: 4 additions & 5 deletions tests/test_soap.py
Expand Up @@ -3,16 +3,15 @@

from .helpers import tostring

def test_soap_envelope_construction():
Request = xs.element('Request', xs.int)

def test_soap_envelope_construction():
schema = xs.schema(Namespace('http://boo'))(
Request
xs.element('Request', xs.int)
)

envelope = soap.Envelope.instance(Body=soap.Body.instance(_any=[Request.instance(50)]))
envelope = soap.make_envelope(schema['Request'].instance(50))

envelope = soap.schema.fromstring(tostring(envelope))
request = schema.from_node(envelope.Body._any[0])

assert request == 50
assert request == 50

0 comments on commit 0965393

Please sign in to comment.