Running a Flask application under the Apache WSGI module

Python is a fantastic programming language and Flask is an equally fantastic microframework for Python… at least as far as I can tell from my experiences so far. However, as I’m sure you are already aware, Python just like Ruby, is not a native web language, like PHP is. So to get your Python code running on a production web server can be tricky.

The Flask website does detail ways of getting your code deployed on Apache, CGI, Fast CGI and multiple standalone WSGI containers. However, I found the Flask documentation to be incomplete and not very helpful. Clearly, from the number of complaints on stack overflow, I’m not the only one. So today I’m focusing on deploying to an Apache server, for all you lovely people.

Development Environment

First I’m going to start by creating a development environment, the Flask docs cover this fine, however, I’m going to reiterate here as well for completeness.

First we need to install Python, which I hope you have already done. If you haven’t it’s dead simple, here is a quick and simple guide.

We also need to make sure the Apache WSGI module and it’s prerequisites are installed and then restart Apache.

$ sudo aptitude install apache2 apache2.2-common apache2-mpm-prefork apache2-utils libexpat1 ssl-cert

$ sudo aptitude install libapache2-mod-wsgi

$ /etc/init.d/apache2 restart

Next you need to install Pip, this is a dependency manager tool and this is what we will use to install Flask. It’s so simple, here is another quick and simple guide.

Next we want to install Flask

$ pip install Flask

For the purpose of keeping this tutorial focused, I’m only showing how to install the Flask package globally on your system. If you want to create separate environments with different dependencies I recommend using the virtualenvwrapper tool

If the Pip install command fails, it means you have permission issues, you can either fix these or if you’re really lazy, you can run as sudo.

So now Pip is installed globally on your system lets create a simple application in the form of a single Python script. You can put this script anywhere you like. However for this example I have put mine here: /var/www/flask-dev/__init__.py

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello world!"

if __name__ == "__main__":
    app.run(debug=True)

This is all pretty simple stuff, the import at the top is importing the Flask package that we just installed with Pip. Flask is then creating starting a web server, by default this will be on port 5000. It’s also binding the hello function to the base directory.

If you now execute this Python script by running

$ python /var/www/flask-dev/__init__.py

Your console will tell you the web server has been started and if you point your browser now to localhost:5000 you will see the hello function is executed and the browser will display the text “Hello World”…… Simples.

Production Environment

Now let’s assume you have finished building your new, awesome, world-changing application. You don’t want to have to tell everyone, “Go check out my awesome new tool @ www.someawesometool.com:5000” that would be pretty lame, right. Not to mention other drawbacks of using a development environment in production.

Here I am going to show how we can use an Apache module called WSGI (Web Server Gateway Interface), to point a hostname to your Flask application.

First things first, lets create the exact same application file but this time here: /var/www/flask-prod/webtool.py, I’m also turning debug mode off.

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello world!"

if __name__ == "__main__":
    app.run()

Next you want to create a new host record in your hosts file (/etc/hosts)

127.0.0.1 my.webtool

Now all requests sent to my.webtool (e.g. from your browser), will be sent to localhost – 127.0.0.1, which Apache will pick up and handle accordingly, using virtualhosts.

Next we are going to create a WSGI file, this is a file which Apache will use to access your Flask application. Like I was saying earlier, Python isn’t natively a web language and so this WSGI file allows Apache to interact with Python as if it’s native. It’s a simple script. You can put it anywhere, but for the sake of simplicity, I am going to put it in the web root. Lets call it /var/www/flask-prod/webtool.wsgi

import sys

sys.path.append('/var/www/flask-prod')

from webtool import app as application

Yes that’s it, the first line is simply importing the system module. Line 2 we are adding the web root path (where the Flask application is located) into the system path. Line 3 is essentially importing the app variable we created in webtool.py and aliasing it to the application namespace. Apache executes this file after getting a request to our new virtualhost and then does it’s magic from there. It is very important that whatever you name the webtool.py file, you must use the same name in the from the area on line 5 in you WSGI file. “from webtool” is really saying “from webtool.py”

Lastly let’s create your virtual host, this should go here: /etc/apache2/sites-available/my.webtool.conf

<virtualhost *:80>
    ServerName my.webtool

    WSGIDaemonProcess webtool user=www-data group=www-data threads=5 home=/var/www/flask-prod/
    WSGIScriptAlias / /var/www/flask-prod/webtool.wsgi

    <directory /var/www/flask-prod>
        WSGIProcessGroup webtool
        WSGIApplicationGroup %{GLOBAL}
        WSGIScriptReloading On
        Order deny,allow
        Allow from all
    </directory>
</virtualhost>

This will capture all “my.webtool” requests on your server and redirect them to the WSGI file that we just created. The WSGI file is then sending the request to the Flask application which produces a HTTP response.

Some important points to consider in this virtual host file are:

  1. The first argument of the WSGIDaemonProcess command (webtool) should have the same value as WSGIProcessGroup in the Directory block. These are the name of the process and process group and should be unique on your system.
  2. You should set the home attribute of the WSGIDeamonProcess to be the path of you WSGI file, the same path should also be provided in the Directory block.
  3. The user and group which are specified in WSGIDaemonProcess are a Unix user and group, the user and group you specify should have execute privileges on the WSGI script.

Now just enable the new virtual host and restart apache

$ sudo a2ensite my.webtool

$ /etc/init.d/apache2 restart

Now you can simply point your browser to http://my.webtool/ and you should get the response “Hello World!”. If you get an internal server error then you, unfortunately, have done something wrong. Your best bet is to check the Apache error logs which can usually be located at /var/log/apache2/error.log. Alternatively, you can start over and take things a little slower. Don’t rush it, this does work.

Conclusion

That just about sums up everything you need to know about getting Flask to run in a production environment. If you have any questions I’ll be happy to try and help. I’ve not tried these steps on OS X yet, however, I’m pretty sure the process is going to be almost identical. Python is installed by default, however, you may need to use a packaging tool like Homebrew of MacPorts to install the WSGI Apache module.

Thanks for reading

82 Love This

79 Comments Running a Flask application under the Apache WSGI module

  1. Pingback: Running a Flask application under the Apache WS...

  2. Simon

    Hi, my.webtool is the hostname/virtualhost for your Flask application. You can think of it like a domain, in a sense. The only difference is that instead of having a FQDN, you have a host which is internal to your machine. Without creating separate virtualhosts like my.webtool, you wouldn’t be able to run multiple websites from a single Apache instance, because Apache wouldn’t know where to forward the traffic it is receiving. Hope that helps.

    Reply
    1. Nguyen

      Dear Sir,

      I cannot use any words to describe my feeling rightnow. It really hard to choose words to express my feeling.
      Only one simple phrase I can write down here is “thanks for your tutorial.”

      Wish you best!

      Reply
  3. Simon

    Hi Evan, sorry for my incredibly slow reply. I’ve had a lot of personal issues the last few months.

    If you haven’t solved this already, which I’m sure you have. Double check you have a file called my.webtool inside the /etc/apache2/sites-available directory. You may have accidentally put the file inside /etc/apache2/sites-enabled.

    That would have the same effect as running the a2ensite command.

    I hope that helps.

    Reply
  4. psudo

    Hey so is this process only for a production server then? Im starting developing locally on mac osx and using pyvenv (python3.5). In the venv I have pip(by default), flask, and mod_wsgi installed. I have macs apache2 set up to serve from the ~/user/Sites directory, and mysql installed. I guess right now Im a little confused on figuring out how to tie all this together. I can get all 3 servers to work by themselves, but if Im not mistaken I need to get modwsgi to point the flask server to the apache one via .conf files? Also, from the docs:

    https://pypi.python.org/pypi/mod_wsgi

    says that with modwsgi-express it auto sets up configuration for you, which with that and pyvenv it really makes things convenient. I feel Im close to figuring this out. I guess my question would be how do I know if Im routing the flask app through apache with wsgi properly? Thanks

    Reply
    1. Simon

      Hi, firstly I’v really sorry about replying to your question so late. I’m sure you’ve solved this problem now. I actually wrote an article on setting flask up on OSX – http://www.jakowicz.com/setting-up-apache-wsgi-module-on-osx-10-9/

      Both articles are for setting up production systems.However there is nothing wrong with using this approach in development, so it mirrors production more accurately.

      Ae you still having a problem here? Again, sorry for the incredibly slow reply.

      Reply
  5. Paul Huygen

    Thanks for this tutorial!

    One remark:

    The browser on my (Ubuntu 16.04) computer can only find the site my.webtool if it is listed in /etc/hosts as:

    127.0.0.1 my.webtool

    (i.e. IP-addres first).

    Cheers,

    Paul

    Reply
    1. Simon

      Hi Paul,

      You’re welcome and thank you for pointing out that error. My example hosts file entry was the wrong way round. I’ve fixed this now. Cheers.

      Reply
  6. anon

    2 years after your blog post: your procedure is still extremely helpful. documentation of flask+apache2 connection is still sketchy.

    Reply
    1. Simon

      I’ll be completely honest, I never would have thought this article would be so popular. It was a painful process 2 years ago and it’s a shame the official documentation is still below par, but I’m glad you and everyone else is still finding the content useful 🙂

      Reply
  7. rory

    This was great. It was an immense help for me to get flask up and running locally (on my mac) and on a remote dev server (linux)

    Reply
  8. Tomax

    I just finish it and worked very nicely. You have a really nice tutorial there! 🙂

    Just a minor repair in my opinion, I guess you could also tell that you are using the user flask with group www-data on the virtual host, I end up using www-data as the user also for this test.

    One nice upgrade would be, how to use it from outside the deploying machine lets say test it on another PC on the network, I think it would be good for the people out there giving the 1st steps.

    Reply
    1. Simon

      Hi Tomax, thank you for the nice words and for the feedback. www-data is just an apache convention, so it doesn’t strictly matter, however conventions are never a bad thing, so I’ll be updating this. Thanks.

      Accessing an Apache host from somewhere else on the network, isn’t any different for Flask, than it is for other frameworks or apache modules. However it’s something I’ll certainly consider writing about. Is it something you need help with?

      Reply
      1. Tomax

        No mate, that I actually know. Thank you a lot for this initial and nice help. It was just a suggestion for other people follow the tutorial If you still want to work on it. 😉

        Reply
          1. Peter Raeth

            Simon has done a superior job with this tutorial.

            How I do wish Tomax and Simon had said how to get access to my.webtool from some other machine on the network, and remotely through the internet.

            For instance, if I try http://192.168.1.159/my.webtool, that does not work. A 404, not found, error results. Not sure how else to proceed.

            If there is now a link to another article on this topic, I would be most grateful to hear about it.

            Thanks again for a clear and concise tutorial.

          2. Simon

            Hi Peter, sorry for my incredibly slow reply, the last few months life has really got on top of me, but I’m back now.

            Did you solve this problem? I can walk you through it on Skype or something, if you’re still wrestling with it.

          3. Filippo

            Hi, I have exactly the same problem as PETER RAETH. I found your tutorial very very helpful to create a flask app and reach to it from the computer and I succeeded in following all the steps. The only problem is that I would like to access to the app from another machine on the internet.

            Thank you so much again for your help,
            Filippo

          4. Simon

            Hi Filippo,

            I’m glad that you found this guide useful. Do you mean you are trying to run you Flask app in production? Or you’re just trying to access the app from another machine on the network?

          5. Matthias Jürges

            Hello Simon,
            i have the same problem as Filippo and Peter Raeth, i can’t access my application form an other machine on the intranet/network.

            I can access the webserver, but i couldn’t access my webtool…

            Do you have a tip for me?

          6. Simon

            Hi Matthias,

            Have you updated your hosts file on the client machine, to point my.webtool to the IP of the machine hosting the application?

            192.168.x.x my.webtool

            Replace “192.168.x.x” with private IP of machine serving the application.

      2. toby121

        Thanks Simon for your helpful tutorial. I have the same question like Tomax as I am struggling with accessing my.webtool from outside the host either on the same LAN or beyond.

        Having said that I was able to access my apache page upon installation from outside my LAN through the modem port forwarding but I cannot access my.webtool in a similar way. Other than that it works fine on the host.

        I might be missing something stupid.

        Thanks for you help and useful information. This tutorial helped me to get back on track after I have been chasing my tail for a bit.

        Reply
        1. Simon

          Hi Toby, I hope you fixed this as my reply is abysmally slow. What you need to do is point the DNS A record at the IP address of the server running the Apache server. It’s hard to say how to do this without knowing who you’re registrar is, or where your NS records are pointed. If you’re still having troubles let me know and I’ll find you a guide.

          Reply
    2. toby121

      Hi Tomax , I have same query like you. How did you manage to use it outside the host pc please?

      thanks for your time.

      Reply
  9. helge

    First, thank you for the really clear and short explanations.

    But I have one “Sorry!” for you, your script won’t run in production. Simply because it fails to append the necessary python-path for your webtool.py.

    I think it is irresponsible to use global python installations for anything that gets deployed. so virtualenv is a *must have*.

    Sure as long as you start things from the console, your webtool.py knows where the Flask-modules are located, assuming you did a “source bin/activate” from within your virtualenv folder.

    BUT in deployment, no one is on the console. Instead apache will trigger your webtool.py and it does not ave a clue where to find your Flask-modules you installed earlier.

    you really need to add following lines BEFORE everything else in your webtool.py:
    import sys
    sys.path.append("/var/www/flask-prod/lib/python2.7/site-packages")

    assuming you created that folder as a virtualenv which one should clearly do.

    just my 2 cents.

    Reply
    1. Simon

      Hi Helge, thank you for the nice word and even more so, for a great discussion point.

      Firstly I’d like to say that although this point never really come to mind when I write this, I’m glad it never. I suspect most Python developers are aware of virtualenv. I wanted this guide to be as concise as possible, setting all this up is a tedious process so the less fluff the better, if that makes sense. Otherwise the initial point gets lost in the blurb.

      Irrespective of that, it’s certainly an interesting point and depending on you infrastructure you do have a point. The web is evolving rapidly and with the likes of Docker and dirt cheap cloud services at our disposal, it’s rare to ever have two or more applications running on the same machine or container. I find using the likes of virtualenv to be over-engineering a problem, that isn’t really there.

      If someone out there is running multiple production applications on the same machine, it’s very likely they’re going to need to use your solution, so thank you for posting it, as I’m sure it will be useful.

      Cheers again

      Reply
  10. tom

    Hey Simon,

    thank you for this guide. I was kind of lost in the beginning because I had no idea about Apache, virtual hosts and so on.

    You helped me a lot and I just wanted to say one thing: thank you!

    Reply
  11. Nguyen

    Hello Simon,

    Thanks for your tutorial. It is really awesome!
    I am just confused a little bit regarding the usages of ” and “” in python.
    Could you explain the meaning of these signs as well as the usage of them to me?

    Thanks,

    Reply
    1. Simon

      Hi Nguyen,

      Thank you for you kind words, I’m really glad you found this guide useful. As for the quotes, these are just use to define strings in Python. Does that answer your question? Thanks

      Reply
      1. Nguyen

        Hallo Simon,

        Thanks for your reply. It answers my question, but just a half. I guess my question is not clear, and I am quite sure it makes you confused 🙂

        I’d like to ask about the difference between the single quote, ‘-‘, and the double quote, “-“, in python. When should we use ‘-‘ and when should we use “-“.

        Thanks

        Reply
  12. Basak

    Hello,

    Thank you very much for the tutorial. I have been struggling with web development using Flask. This one seems to be the most clear one. I followed every step easily. However, I still have some questions because it does not work for some reason, although I tried many times. I would be more than happy if you can help.

    I am developing a remote controlled pet feeder. I want to create a website to stream video from the camera on Pi and dispense food with the button on this website.

    – Project folder: /var/www/PetFeeder

    – Python script: /var/www/PetFeeder/PetFeeder.py
    *My python script calls other scripts (for camera etc.) which are again located under the folder ‘PetFeeder’. When I run this script through Terminal it starts publishing my html and buttons etc. works just fine. However it is only on the IP address of the Pi on port :5000. No access from outside of the local network.

    – Html file for my web page:/var/www/PetFeeder/templates/index.html

    – WSGI file: /var/www/PetFeeder/PetFeeder.wsgi

    – Conf. file: /etc/apache2/sites-available/my.PetFeeder.conf
    * 127.0.0.1 in the /etc/hosts was already in the file written ‘localhost’ in front of it. So, I just changed it to my.PetFeeder.

    – Content of /var/www/PetFeeder/PetFeeder.wsgi:

    import sys
    sys.path.append(‘/var/www/PetFeeder’)
    from PetFeeder import app as application

    – Content of /etc/apache2/sites-available/my.PetFeeder.conf:

    ServerName my.PetFeeder
    WSGIDaemonProcess PetFeeder user=www-data group=www-data threads=5 home=/var/www/PetFeeder/
    WSGIScriptAlias / /var/www/PetFeeder/PetFeeder.wsgi
    WSGIProcessGroup PetFeeder
    WSGIApplicationGroup %{GLOBAL}
    WSGIScriptReloading On
    Order deny,allow
    Allow from all

    *a2ensite my.PetFeeder returns ‘Site .. already enabled’
    *.. restart successfully returns [ok] Restarting apache2 ..

    I could not reach my page through any of the following:

    http://my.PetFeeder/
    http://IP_of_Pi/my.PetFeeder

    Reply
    1. Simon

      Hi there, glad you found the tutorial useful. Have you updated your hosts file with:

      127.0.0.1 my.PetFeeder

      Reply
      1. Basak

        Yes, actuallly 127.0.0.1 in the /etc/hosts was already in the file written ‘localhost’ in front of it. So, I just changed it to my.PetFeeder.

        Reply
          1. Basak

            Actually that was the action I have already done as I wrote in my original post. I just repeated it to emphasise that I have already done that. So the problem is still there.

  13. John

    Hey Simon – great tutorial! The WSGI module is now far less intimidating. I especially like the comment “Don’t rush it, this does work.” – I misspelled a file and resolved this on second run through. Thanks for sharing.

    Reply
    1. Simon

      Hey John, great to hear this worked for you. I always found the small subtle details to be the parts I made a mistake on too. There is a lot to be said for taking your time. Have fun with Flask!

      Reply
  14. Xilon

    Hey Simon! I’ve found some very similar tutorials around the web, but yours is the only one which cares to explain to details what each step is really doing, so thanks bro. However, it still couldn’t answer one question, so I’ll ask here:
    What if the machine I’m trying to deploy is a production amazon ec2 instance running ubuntu 16.04, how should be configured the host file so my web server could be accessed via internet? I’m asking it because I don’t know if the “127.0.0.1 my.webtool” would be enough to allow it? Thanks!

    Reply
    1. Simon

      Hey Xilon,

      Sorry for such for the belated reply. I need a new way to block spam, as I’m missing real comments.

      For your answer, once the app is hosted on ec2, you’ll be provided with a public IP. First, you have to make sure the IP is static, AWS call these Elastic IPs. Then you have to update your DNS record so that you have an A record for your domain and it’s pointing to your EC2 Elastic IP. Unless of course, you are using a load balancer, in which case the A record should be pointing at the load balancer. There is no need to update the hosts file on a production environment.

      I hope that helps.

      Reply
  15. Zach

    I followed the tutorial on a server that I have used ssh to access over vpn. The server has an ip address, but no domain name. How would I go about viewing the page to determine if I have followed the steps correctly?

    Reply
    1. Simon

      Hi Zach, if you just go to the IP address of the server, your application should load. Apache by default will select a virtualhost in alphabetical order, when one isn’t directly matched.

      Reply
  16. mingch

    Thanks for the great tutorial, I’ve one question, should it be removed from the following code when deploy into production?

    if __name__ == “__main__”:
    app.run(debug=True)

    Reply
  17. Robert

    Hey Simon!
    Thank you for awesome post. This is still one of the best posts that explains clearly as how to configure Apache with Python.

    I am facing one of the issues and was thinking if you can help me.

    I am running my flask app using Apache 2.4 on Windows Server 2008.
    My server name is Testserver

    If I go to url, http://Testserver (apache is running on port 80), I can successfully see my flask app when I am in the server and from outside (The app will be internally deployed, so, when I say outside, I mean outside of the test server)

    I want to change the name of the url as it contains name of the server. I want to change it to something else. Can you please help as how to do that?

    If I go to hosts file in my server and define a mapping as
    127.0.0.1

    Then, http:// successfully works from inside of my server, but not from outside.

    What I need to do so that I can access my app using http:// url from outside of my server?

    My server is resolving names using a DNS server and not by using hosts file.

    God Bless!

    Reply
    1. Simon

      Hi Robert,

      Firstly I hope you resolved this already, due to my incredibly slow reply. I’m not sure I completely understand your problem. You have the setup working, but you want to change the hostname? but when you do it doesn’t work from outside the host server?

      If that’s the case, it may sound silly, but have you configured (vias hosts file or DNS) to point the hostname you want, at the IP address of the Apache server?

      Best

      Reply
  18. Jon Kokko

    As old as this post is, I’m amazed that the flask documentation hasn’t been updated to include these fundamentals. Thank you for the post!

    Reply
  19. Anuj

    Hi,

    My Python script is expecting 3 arguments . Could you please tell me , how to pass 3 arguments in wsgi

    from webtool import app as application

    Thanks,
    Anuj

    Reply
  20. Pingback: Flask app running on apache resulting in 404 error – program faq

  21. Vineet

    Hi,
    I am getting error in the log file:
    [Sun Apr 29 15:20:17.460264 2018] [wsgi:error] [pid 2975] [remote 127.0.0.1:51472] mod_wsgi (pid=2975): Target WSGI script ‘/var/www/flask-prod/webtool.wsgi’ cannot be loaded as Python module.
    [Sun Apr 29 15:20:17.460447 2018] [wsgi:error] [pid 2975] [remote 127.0.0.1:51472] mod_wsgi (pid=2975): Exception occurred processing WSGI script ‘/var/www/flask-prod/webtool.wsgi’.
    [Sun Apr 29 15:20:17.460546 2018] [wsgi:error] [pid 2975] [remote 127.0.0.1:51472] Traceback (most recent call last):
    [Sun Apr 29 15:20:17.460913 2018] [wsgi:error] [pid 2975] [remote 127.0.0.1:51472] File “/var/www/flask-prod/webtool.wsgi”, line 5, in
    [Sun Apr 29 15:20:17.461160 2018] [wsgi:error] [pid 2975] [remote 127.0.0.1:51472] from webtool import app as application
    [Sun Apr 29 15:20:17.461221 2018] [wsgi:error] [pid 2975] [remote 127.0.0.1:51472] File “/var/www/flask-prod/webtool.py”, line 1, in
    [Sun Apr 29 15:20:17.461352 2018] [wsgi:error] [pid 2975] [remote 127.0.0.1:51472] from flask import Flask
    [Sun Apr 29 15:20:17.461418 2018] [wsgi:error] [pid 2975] [remote 127.0.0.1:51472] ImportError: No module named flask

    I have python 2.3 and 3.5 in my laptop . I have installed flask in both python versions but still I am getting error ‘No module named flask ‘ in error log file.
    I am not using virtualenv ,I just followed the tutorial and stuck here.

    Reply
    1. Simon

      Hello Vineet,

      Did you run

      pip install Flask

      I would recommend using virtualenv, this way you can ensure the version of Python you’re using is looking in the directory that pip has installed into.

      Best,
      Simon

      Reply
  22. saibal dasgupta

    Hi Simon,

    I followed steps. but on ubuntu 16.04. python script with the flask is working ok through python file.py.
    When I am trying to access through wsgi I am getting following error.
    Can you please help me to know the reason why this error is coming?

    [Tue May 01 16:27:15.634322 2018] [wsgi:error] [pid 8437:tid 140487397693184] [remote 127.0.0.1:28355] mod_wsgi (pid=8437): Target WSGI script ‘/var/www/flask/webtool.wsgi’ cannot be loaded as Python module.
    [Tue May 01 16:27:15.634426 2018] [wsgi:error] [pid 8437:tid 140487397693184] [remote 127.0.0.1:28355] mod_wsgi (pid=8437): Exception occurred processing WSGI script ‘/var/www/flask/webtool.wsgi’.
    [Tue May 01 16:27:15.634485 2018] [wsgi:error] [pid 8437:tid 140487397693184] [remote 127.0.0.1:28355] Traceback (most recent call last):
    [Tue May 01 16:27:15.634553 2018] [wsgi:error] [pid 8437:tid 140487397693184] [remote 127.0.0.1:28355] File “/var/www/flask/webtool.wsgi”, line 5, in
    [Tue May 01 16:27:15.634672 2018] [wsgi:error] [pid 8437:tid 140487397693184] [remote 127.0.0.1:28355] from webtool import app as application
    [Tue May 01 16:27:15.634689 2018] [wsgi:error] [pid 8437:tid 140487397693184] [remote 127.0.0.1:28355] File “/var/www/flask/webtool.py”, line 1, in
    [Tue May 01 16:27:15.634710 2018] [wsgi:error] [pid 8437:tid 140487397693184] [remote 127.0.0.1:28355] from flask import Flask
    [Tue May 01 16:27:15.634776 2018] [wsgi:error] [pid 8437:tid 140487397693184] [remote 127.0.0.1:28355] ImportError: No module named flask

    Thanks
    Saibal

    Reply
    1. Simon

      Hello Saibal,

      Did you run

      pip install Flask

      I would recommend using virtualenv, this way you can ensure the version of Python you’re using is looking in the directory that pip has installed into.

      Best,
      Simon

      Reply
  23. Stefan Lucian Tincu

    The file my.webtool must finish with .conf as all the files in folder
    /etc/apache2/sites-available/my.webtool.conf

    Reply
  24. Dhiraj Shetty

    Our Flask script has following structure

    …..
    if __name__ == “__main__”:

    If boolean-condition:
    app.run()

    Where do I write the initialisation code (with mod-wsgi). This needs to be executed only once. Variables initialised need to be accessible in other REST API calls.

    Depending on boolean-condition, the server may not run (with suitable log massages indicating reason for failure ). How do we achieve this using mod-wsgi.

    Regards,
    Dhiraj.

    Reply
    1. Simon

      Hi Dhiraj, I’m not sure I understand your question, but if you’re looking to store data in memory, which can be read by multiple connections, you might want to have a look at a memory store like redis or memcache.

      Reply
  25. Dhiraj Shetty

    Thanks Simon. We are using Redis for persisting our data in the server. Sorry if the question was not clear. We need to do some initialization before starting accepting REST based requests to our Web Application. Where is the best place to keep such code. Currently we have written the code in the start of the python flask script file (before implementing the REST requests).

    Reply
  26. Clinton

    Simon, you made a great article! But I have a problem. How can I access the web app from another computer on the network? If I try http://192.168.43.114/my.webtool, that does not work.

    This is what my /etc/hosts file looks like:

    127.0.0.1 localhost
    127.0.1.1 kwansodan
    127.0.0.1 my.webtool

    # The following lines are desirable for IPv6 capable hosts
    ::1 ip6-localhost ip6-loopback
    fe00::0 ip6-localnet
    ff00::0 ip6-mcastprefix
    ff02::1 ip6-allnodes
    ff02::2 ip6-allrouters

    Reply
  27. Apache

    Thanks for a lovely article !!

    I tried to run this on docker so here are some of my feedback to make this work on docker.
    run webtool.py with
    app.run(host=’0.0.0.0′,port=8000)
    Do port mapping while starting a docker image with -p 5000:8000 remember 5000 is host port and 8000 is docker port on which the app is starting.
    It is important to use 0.0.0.0 as ip instead of 127.0.0.1 to make it visible to host.
    For production same steps just modify /etc/hosts in both docker and host
    docker
    0.0.0.0 my.webtool
    Host
    (172.17.0.1 )Docker IP my.webtool

    Apart from this use virtualenv which i was not aware of but is a very nice concept.

    Have a wonderful day !!

    Reply
  28. Aditya

    Hi,

    If I have to include my static file and templates. I meed to midify my wsgi file?
    Also where exactly do I keep them if i am using apache?
    Currently all i get is “templateNotFound” error 🙁
    I can post my code if you can help to debug.

    Reply
  29. Manoj

    Hi Smon,

    I have deployed a Python rest webservice app on Linux using mod_wsgi+Apache.
    The logs from the Python app are written in the Apache error file also.
    How can I avoid logs being written in the Apache file.
    Here is the example line from Apache file.

    [Thu Oct 18 17:23:56.420614 2018] [wsgi:error] [pid 2992537:tid 140332276639488] [2018-10-18 17:23:56,420] INFO in exception_queue: Number of log Message:: 14464

    Reply

Leave a Reply to Tom Cancel reply

Your email address will not be published.