Search code examples
pythonsoapspyne

How to do flat array of elements in spyne?


How does one write a request handler for Spyne that handles a SOAP request like this:

<getUsers>
  <users>
    <username>foo</username>
    <username>bar</username>
    ...
  </users>
</getUsers>

I have tried this:

@rpc(Array(Unicode.customize(type_name='username'), min_occurs=1, nillable=False))
def getUsers(ctx, users):
    stuff

But it yields a schema like such:

  <xs:complexType name="getUsers">
    <xs:sequence>
      <xs:element name="users" type="tns:stringArray"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="stringArray">
    <xs:sequence>
      <xs:element maxOccurs="unbounded" minOccurs="0" name="string" nillable="true" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>

How do I change the element name string into username? And preferably also stringArray into something more meaningful? Is my approach completely wrong?


Solution

  • 2.10:

    SomeArrayType = Array(Unicode, min_occurs=1, 
                                   nillable=False, type_name='SomeArrayType')
    SomeArrayType._type_info['username'] = SomeArrayType._type_info['string']
    del SomeArrayType._type_info['string']
    
    @rpc(SomeArrayType)
    def some_call(ctx, some_array):
        # (...)
    

    2.11:

    from spyne import Mandatory as M
    SomeArrayType = M(Array(Unicode, type_name='SomeArrayType',
                                                    member_name='username'))
    
    @rpc(SomeArrayType)
    def some_call(ctx, some_array):
        # (...)
    

    Also, if you need the array to be non empty, you also need Unicode(min_len=1, min_occurs=1, nillable=False) inside the Array. i.e.:

    SomeArrayType = M(Array(M(Unicode), type_name='SomeArrayType',
                                                    member_name='username'))