Spyne - Multiple services with multiple target namespaces, returns 404 with WsgiMounter

259 Views Asked by At

I have two services that are part of one application, Hello and Auth, and each has its own target namespace, as such:

from spyne import (
    Application, ServiceBase, rpc,
    Unicode,
)
from spyne.protocol.soap import Soap11
from spyne.server.wsgi import WsgiApplication
from spyne.util.wsgi_wrapper import WsgiMounter
from wsgiref.simple_server import make_server
import logging


class Hello(ServiceBase):
    @rpc(_returns=Unicode)
    def hello(ctx):
        return "Hello, World!"

class Auth(ServiceBase):
    @rpc(_returns=Unicode)
    def authenticate(ctx):
        return "authenticated!"

I can see that each of these services work fine individually, like this:

hello = Application(
    [Hello],
    tns="hello_tns",
    name="hello",
    in_protocol=Soap11(validator="lxml"),
    out_protocol=Soap11(),
)

auth = Application(
    [Auth],
    tns="auth_tns",
    name="auth",
    in_protocol=Soap11(validator="lxml"),
    out_protocol=Soap11(),
)

hello_app = WsgiApplication(hello)
auth_app = WsgiApplication(auth)


if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    logging.getLogger("spyne.protocol.xml").setLevel(logging.DEBUG)

    server = make_server("0.0.0.0", 8000, hello_app)
    # server = make_server("0.0.0.0", 8000, auth_app)
    server.serve_forever()

I can see the wsdl in http://0.0.0.0:8000/?wsdl.

But I want to use them together as part of one application.

In this issue on GitHub and this accepted answer, it's been mentioned that I should create two instances of spyne.Application and use spyne.util.wsgi_wrapper.WsgiMounter to put them together. So I did the same:

wsgi_mounter = WsgiMounter({
    "hello": hello,
    "auth": auth,
})

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    logging.getLogger("spyne.protocol.xml").setLevel(logging.DEBUG)

    server = make_server("0.0.0.0", 8000, wsgi_mounter)
    server.serve_forever()

But now when I look at http://0.0.0.0:8000/?wsdl, I see nothing. And the server code gives me a 404 error response:

$ python server.py
127.0.0.1 - - [09/Apr/2022 12:52:22] "GET /?wsdl HTTP/1.1" 404 0

How can I fix this?

1

There are 1 best solutions below

0
On BEST ANSWER

Okay first, what a nicely written question! Thanks!

If you want both services under the same app, pass them to the same app:

hello = Application(
    [Hello, Auth],
    tns="hello_tns",
    name="hello",
    in_protocol=Soap11(validator="lxml"),
    out_protocol=Soap11(),
)

When using HTTP, you can't use more than one app under the same URL.

If you want services under different URLs (which is WsgiMounter's use case) you must do like you did:

wsgi_mounter = WsgiMounter({
    "hello": hello,
    "auth": auth,
})

but you will find your apps under their respective URLs:

  • http://localhost:8000/hello/?wsdl
  • http://localhost:8000/auth/?wsdl