This is a simple guide explaining how I managed to configure Apache 2.2 httpd server on a Windows platform so that it can serve a Python webapplication I wrote using the Flask micro-framework. The guide is valid, with a very little modification, also on Linux environments (you geeks know how to do)
Why I needed to to this
I developed this application at work and ‘ve been serving it from the beginning via the Flask’s built-in minimal webserver: unfortunately this is not enough for production stage as I need a more robust server with SSL capabilities, which Flask’s has not. This was my first time in deploying a Python webapp…So, after googling a bit and reading the Flask deployment notes, I came up with the answer: what I needed was a WSGI-compliant server running on my target platform, a Windows 2012 server. The natural choice to me was to enable the WSGI module on the “good ole” Apache webserver, which I’m experienced with.
We choose a folder in which we place the Python code. For instance,
In this folder we create the real Flask webapplication that we want to deploy (file “test.py”):
from flask import Flask, request app = Flask(__name__) @app.route('/hello') def hello_world(): name = request.args.get('name','') return 'Hello ' + name + '!' if __name__ == '__main__': app.run()
The Apache server won’t be aware of “test.py” at all. What you need to do now is to write in the same folder a Python file named “test.wsgi” that we will link into the webserver’s configuration: the code in this file will import the main Flask application object (built in our case as a singleton) and will be actually executed by the WSGI module of Apache. In the code, it is vital that you DON’T change the name of the “application” variable, as it is exactly what the server expects to find. Also please note that we are extending the Python classes path to include our own webapplication’s folder. This is “test.wsgi”:
import sys #Expand Python classes path with your app's path sys.path.insert(0, "d:/webapps/test") from test import app #Put logging code (and imports) here ... #Initialize WSGI app object application = app
As an additional remark, if you want to put any logging code (e.g: file/e-mail/console loggers) into your Flask app, you must put it before the if __name__ == ‘__main__’ block, otherwise it won’t log anything! Add your loggers to the app object.
Ok, what’s next? Now it’s all about installing and properly configuring Apache.
First: install Apache webserver. I downloaded and executed the .msi installer. Apache was installed at
"C:\Program Files (x86)\Apache Software Foundation\Apache2.2"
Second: install the WSGI Apache module. Pay attention to download the module compiled for your specific combination of platform and Python and Apache versions: I downloaded this module. Once downloaded, rename the .so file into “mod_wsgi.so” and put it under the “modules” subfolder of your Apache installation folder. Then you have to tell Apache to use it: open in a text editor the “httpd.config” file which is under the “conf” subfolder and add the following line at the bottom:
LoadModule wsgi_module modules/mod_wsgi.so
Third: restart Apache.
Now Apache is ready to serve WSGI webapplications. What is left is to tell about where our application is and match it to a URL alias. It’s child’s play: open in a text editor the “httpd.config” file we used before and add these lines to the bottom:
<Directory d:/webapps/test> Order allow,deny Allow from all </Directory> WSGIScriptAlias /flasktest d:/webapps/test/test.wsgi
(nevertheless, I prefer to place the per-virtual-host or per-alias configurations’ stuff into separate files and then use an Include directive into the main “httpd.conf”)
Now restart Apache again and if you open a browser and point it to:
and you should see the webapp’s greetings!