How to implement Flask Application Dispatching by Path with WSGI?

6.4k Views Asked by At

I would like to use a single domain as a Staging Environment for multiple flask applications that will eventually run on their own domains.

Something like:

  • example_staging.com/app1
  • example_staging.com/app2
  • example_staging.com/app3

where:

  • example_staging.com/app1 acts same as app1.example_staging.com
  • example_staging.com/app2 acts same as app2.example_staging.com
  • example_staging.com/app3 acts same as app3.example_staging.com

or:

  • example_staging.com/app1 acts same as app1.com
  • example_staging.com/app2 acts same as app2.com
  • example_staging.com/app3 acts same as app3.com

Starter app:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello from Flask!'

WSGI Starter Config File:

import sys

project_home = u'/home/path/sample1'

if project_home not in sys.path:
    sys.path = [project_home] + sys.path

from app import app as application

Refering to:

http://flask.pocoo.org/docs/0.10/patterns/appdispatch/

I don't know where to add the code given in the documents as an example and what create_app, default_app, get_user_for_prefix should look like.

Note: Using PythonAnywhere

SOLUTION

WSGI Config File after Glenns input:

import sys

# add your project directory to the sys.path
project_home = u'/home/path/app1'
if project_home not in sys.path:
    sys.path = [project_home] + sys.path

from werkzeug.wsgi import DispatcherMiddleware
from app import app as app1
from app2.app import app as app2
from app3.app import app as app3

application = DispatcherMiddleware(app1, {
    '/app2':    app2,
    '/app3':    app3
})

Folder Structure:

app1 folder
    app2 folder
    app3 folder
2

There are 2 best solutions below

1
On BEST ANSWER

The key thing to note, here, is that you'll actually have 4 apps (3 individual apps and one combined app). This is ignoring the staging/live distinction because staging and live are just copies of each other in different directories.

Create each of the individual apps and get them responding on their individual domains. Then create a new app that imports the application variables from the individual apps and combines them using the DispatcherMiddleware like the example under the heading "Combining Applications" on the doc page you link to.

1
On

This worked for me:

Folder structure

DISPATCHER (folder)
   dispatcher.py

   app1 (folder)
       __init__.py

   app2 (folder)
       __init__.py

   app3 (folder)
       __init__.py

dispatcher.py

from flask import Flask
from werkzeug.wsgi import DispatcherMiddleware #use the commented version below for Werkzeug >= v.1.0
#from werkzeug.middleware.dispatcher import DispatcherMiddleware
from werkzeug.exceptions import NotFound

from app1 import app as app1
from app2 import app as app2
from app3 import app as app3

app = Flask(__name__)

app.wsgi_app = DispatcherMiddleware(NotFound(), {
    "/app1": app1,
    '/app2': app2,
    '/app3': app3
})

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

app1 to app3 init.py

from flask import Flask

app = Flask(__name__)

@app.route("/")
def index_one():
    return "Hi im 1 or 2 or 3"

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

Working

python dispatcher.py

localhost:5000/app1 "Hi im one"
localhost:5000/app2 "Hi im two"
localhost:5000/app3 "Hi im three"

Another configuratiom

You can import another app, like app0 and add a menu to the apps, changing this with NotFound()

This helped

Application Dispatching