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?
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: