Pawel Decowski
Pawel Decowski

Reputation: 1612

How to access SOAP headers in Spyne

I can’t get to read even the simplest SOAP header.

I’ve been following the documentation which gives this example:

class RequestHeader(ComplexModel):
    user_name = Mandatory.Unicode
    session_id = Mandatory.Unicode

class UserService(ServiceBase):
    __tns__ = 'spyne.examples.authentication'
    __in_header__ = RequestHeader

    @rpc(_returns=Preferences)
    def some_call(ctx):
        username = ctx.in_header.user_name

But it doesn’t say what the request should look like. I’ve tried:

<soap:Header>
    <user_name>test</user_name>
    <session_id>123</session_id>
</soap:Header>

But ctx.in_header is None. However, ctx.in_header_doc is there, so it tells me it’s the parsing the XML into Python object that fails.

The header I’m trying to parse looks like this:

<soap:Header>
    <credentials>
        <loginToken>
            <token>12345678</token>
            <key>123456789</key>
            <householdId>46345435</householdId>
        </loginToken>
        <deviceId>345345345</deviceId>
        <deviceProvider>aaa</deviceProvider>
  </credentials>
</soap:Header>

How would I go about getting this in ctx.in_header? I tried creating nested objects for each XML element but it doesn’t work. Which doesn’t surprise me since the basic example from the docs doesn’t work either.

Upvotes: 0

Views: 1520

Answers (1)

Burak Arslan
Burak Arslan

Reputation: 8001

You're getting ctx.in_header as None because the incoming document does not fit the object description.

Your current header could be parsed by something along the lines of:

class UserService(ServiceBase):
    __in_header__ = Unicode, Integer

... which does not seem to be what you want.

Your definition would work for the following input:

<soap:Header>
  <tns:RequestHeader>
    <tns:user_name>test</user_name>
    <tns:session_id>123</session_id>
  </tns:RequestHeader>
</soap:Header>

... where the tns: prefix is defined up there somewhere as the namespace of the RequestHeader object. The namespaces are important -- you need to learn how to work with them if you want your SOAP stuff to work.

Finally, to parse the credentials tag, you need at least something like a following definition (plus namespace qualifications):

class LoginToken(ComplexModel):
    _type_info = [
        ('token', Integer),
        ('key', Integer),
        ('householdId', Integer),
    ]

class Credentials(ComplexModel):
    __type_name__ = 'credentials'
    _type_info = [
        ('loginToken', LoginToken),
        ('deviceId', Integer),
        ('deviceProvider', Unicode),
    ]

I hope that helps.

Upvotes: 3

Related Questions