anonymous frog
anonymous frog

Reputation: 31

Multithreaded Flask application on Apache server

I have a python script. Main thread (if name=='main', etc): when the main thread initiates, it runs several threads to listen to data streams, events, and to process them. The main thread then starts running the Flask application (app.run()). Processing and data is sent to the front-end Flask app (no issues here)

The Apache Server and mod_wsgi requires me to directly import the app, meaning that my other threads won't run.

My dilemma. In the examples I've seen, the .wsgi script from someapp imports app as application. This would only run the flask application. If I managed to somehow run the python script instead as main, the flask application would be ran on localhost:5000 by default and is not recommended in production to change or use .run().

First of all, is it possible to get this application on a server in this current structure? How would I get the whole application to work on a server? Would I need to completely restructure it? Is it not possible to specify host: 0.0.0.0 port:80 then run the python script instead of just importing the app? Any help is appreciated, any forwarding to other documentations.

Edit: for the sake of testing, I will be using AWS Ubuntu (any other linux distro can be used/switched to if needed).

Upvotes: 1

Views: 4156

Answers (3)

Scragglez
Scragglez

Reputation: 143

I had a similar issue where there was a thread I wanted to constantly monitor data using an API. I ended up importing the function(s) I wanted threaded to my WSGI file and kicked them off there.

Example

    import threading
    from main import <threaded_function>

    my_thread = threading.Thread(target=<threaded_function>)
    my_thread.start()

Upvotes: 0

anonymous frog
anonymous frog

Reputation: 31

I managed to find an answer to this without diverging too far from guides on how to get a Flask application working with Python3 and Apache2.

In short, when you initialise Flask, you most likely do something like this:

from flask import Flask
app = Flask(__name__)`

The proposed solution:

import atexit #for detecting flask exit
import threading
from flask import Flask

shareddata = 0
running = False
def init_app():
    global shareddata
    global running
    running = True
    app = Flask(__name__)
    # some threading goes here
    # e.g.

    def jointhread():
        running=False
        t.join()

    def MyThread1():
        while(running):
            #do something

    t1 = threading.Thread(target=MyThread1, args=[])
    t1.start()
    atexit.register(jointhread)
    return app

app = init_app()

Threading might not work, whichever's applicable.

Upvotes: 1

mdegis
mdegis

Reputation: 2428

Sort and misleading answer is yes, it is possible (make sure there is any other program that uses port 80 such as apache etc):

if __name__ == '__main__':
      app.run(host='0.0.0.0', port=80)

However, you should not do that. Not recommended as it states in the documentation:

You can use the builtin server during development, but you should use a full deployment option for production applications. (Do not use the builtin development server in production.)

Proxy HTTP traffic through apache2 to Flask is much better.

This way, apache2 can handle all your static files and act as a reverse proxy for your dynamic content, passing those requests to Flask.

To have threads check the documentation of WSGIDaemonProcess.

Example of Apache/mod_wsgi configuration should looks like this:

WSGIDaemonProcess mysite processes=3 threads=2 display-name=mod_wsgi
WSGIProcessGroup mysite
WSGIScriptAlias / /some/path/wsgi.py

Upvotes: 2

Related Questions