Reputation: 46
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!
Upvotes: 0
Views: 106
Reputation: 46
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:
import os
import sys
sys.path.append('/var/www/my_project/')
os.chdir('/var/www/my_project/')
from soap_api import app as application
Third step: creating the separate virtual host for SOAP service in Apache's .conf file:
Listen 81
# already existed main virtual host for the Flask app
<VirtualHost *:80>
ServerName app-mod-wsgi
WSGIDaemonProcess my_project python-home=/var/www/my_project/venv threads=5
WSGIScriptAlias / /var/www/my_project/main.wsgi \
process-group=my_project application-group=%{GLOBAL}
<Directory /var/www/my_project>
WSGIProcessGroup my_project
WSGIApplicationGroup %{GLOBAL}
Require all granted
</Directory>
</VirtualHost>
# This virtual host I added for the Spyne's SOAP service
<VirtualHost *:81>
ServerName app-mod-wsgi-soap
WSGIDaemonProcess my_project_soap python-home=/var/www/my_project/venv threads=2
WSGIScriptAlias /soap /var/www/my_project/my_project_soap.wsgi \
process-group=my_project_soap application-group=%{GLOBAL}
<Directory /var/www/my_project>
WSGIProcessGroup my_project_soap
WSGIApplicationGroup %{GLOBAL}
Require all granted
</Directory>
</VirtualHost>
Final steps: restarting Apache web server (debian: systemctl restart apache2
) and check that WSDL-file is accessible in browser by localhost:81/soap/?wsdl
URL.
I will be glad if it turns out to be useful to someone.
Upvotes: 0