I need to deploy SOAP-service based on Spyne framework on Apache + Gunicorn + Flask.
I already have REST-service and it works fine.
My apache virtualHost configuration:
<VirtualHost *:80>
ServerAdmin root@ubuntu
ErrorLog ${APACHE_LOG_DIR}/flaskrest-error.log
CustomLog ${APACHE_LOG_DIR}/flaskrest-access.log combined
<Location />
ProxyPass unix:/var/www/app_on_mod_wsgi/flaskrest.sock|http://localhost/
ProxyPassReverse unix:/var/www/app_on_mod_wsgi/flaskrest.sock|http://localhost/
</Location>
</VirtualHost>
Gunicorn's configuration file:
import multiprocessing
workers = multiprocessing.cpu_count() * 2 + 1
bind = 'unix:flaskrest.sock'
umask = 0o007
reload = True
#logging
accesslog = '-'
errorlog = '/var/log/gunicorn/error_log_archive'
I have my main python module where I initialize Flask and REST-service:
import soap_api # import my soap_api module
app = Flask(__name__) # init Flask app
api = Api(app) # init Flask_restful.Api
And I wrote soap_api.py module like in example:
import logging
import main_archive # my main module
from lxml import etree
from spyne import Application, rpc, ServiceBase, Integer, Unicode
from spyne import Iterable
from spyne.protocol.json import JsonDocument
from spyne.protocol.soap import Soap11
from spyne.server.wsgi import WsgiApplication
from wsgiref.simple_server import make_server
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s %(levelname)s - %(message)s')
file_handler = logging.FileHandler("/var/www/app_on_mod_wsgi/logs/" + 'info_logs.log')
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
logger.info("SOAP service successfuly started")
class HelloWorldService(ServiceBase):
@rpc(Unicode, Integer, _returns=Iterable(Unicode))
def say_hello(ctx, name, times):
for i in range(times):
yield 'Hello, %s' % name
application = Application([HelloWorldService],
tns='spyne.examples.hello',
in_protocol=JsonDocument(validator='soft'),
out_protocol=Soap11()
)
wsgi_app = WsgiApplication(application)
server = make_server('0.0.0.0', 8000, wsgi_app) # OSError: [Errno 98] Address already in use
server.serve_forever()
So if I keep line server = make_server('0.0.0.0', 8000, wsgi_app), python returns OSError: [Errno 98] Address already in use. If I remove this line and the next one the server successfully run but I don't see wsdl file when I call localhost:80?wsdl, instead I get the main page (index) of my project.
The question is: what am I doing wrong and how I can deploy my SOAP-service and get access to wsdl file?
Thank you in advance!
Finally I have found the solution. The problem was the incorrect Apache2.4 configuration. I post the answer in case if someone else runs into the similar problem.
First of all I replaced Gunicorn with mod_wsgi because I understood better how to configure it.
Second step: I already had .wsgi file for my Flask app, so I create additional .wsgi file for the SOAP service:
Third step: creating the separate virtual host for SOAP service in Apache's .conf file:
Final steps: restarting Apache web server (debian:
systemctl restart apache2) and check that WSDL-file is accessible in browser bylocalhost:81/soap/?wsdlURL.I will be glad if it turns out to be useful to someone.