DispatcherMiddleware fabricates environments for your apps and especially SCRIPT_NAME. Django can deal with it with configuration varibale FORCE_SCRIPT_NAME = '' (docs).
With Webapp2 it's slightly more complicated. You can create subclass of webapp2.WSGIApplication and override __call__() method and force SCRIPT_NAME to desired value. So in your webapp2_app.py it could be like this
import webapp2
class WSGIApp(webapp2.WSGIApplication):
def __call__(self, environ, start_response):
environ['SCRIPT_NAME'] = ''
return super(WSGIApp, self).__call__(environ, start_response)
# app = WSGIApp(...)
Answer from twil on Stack OverflowSOLUTION:
I was using wrong tha same name for the dispacher and the app1.
dispacher.py should be edited as follows:
from flask import Flask
from werkzeug.wsgi import DispatcherMiddleware
from werkzeug.exceptions import NotFound
from app1 import app as app1
app = Flask(__name__)
app.wsgi_app = DispatcherMiddleware(NotFound(), {
"/prefix": app1
})
if __name__ == "__main__":
app.run()
Adding prefix to all routes is really simple if you opt for using Blueprints
https://flask.palletsprojects.com/en/1.0.x/tutorial/views/#create-a-blueprint
from flask import Flask, Blueprint
app = Flask(__name__)
prefixed = Blueprint('prefixed', __name__, url_prefix='/prefixed')
@app.route('/nonprefixed')
def non_prefixed_route():
return 'this is the nonprefixed route'
@prefixed.route('/route')
def some_route():
return 'this is the prefixed route'
app.register_blueprint(prefixed)
if __name__ == "__main__":
app.run()
Testing the routes:
> curl localhost:5000/
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>404 Not Found</title>
<h1>Not Found</h1>
<p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p>
> curl localhost:5000/nonprefixed
this is the nonprefixed route
> curl localhost:5000/prefixed/route
this is the prefixed route
Aptitude is often woefully out of date for Python packages, as it seems to be here. You are much better off using pip, Python's package management tool. Pip tells me that werkzeug is currently at version 0.8.1!
First install pip (if you don't have it already)
sudo easy_install pip
Then install werkzeug
sudo pip install werkzeug
Easy install is no longer the recommended way to do Python package - you should certainly be using pip.
These commands install the packages into your machine's global Python environment. You would do well to investigate virtualenv, which creates separate Python interpreters that can have their own packages installed.
Good luck!
I finally found the answer in the Werkzeug documentation. easy_install seems to get it from somewhere else:
sudo easy_install Werkzeug
I've come to the conclusion that this is a stupid idea that is very fragile and requires a lot of unnecessary complexity. I've instead just opted to write a bash script that starts all the apps as separate wsgi instances on their own port.
The Flask documentation on application dispatching contains no hint on port based dispatching. As you mentioned you can simply start separate wsgi instances, as far as I know this is the only possible way using Werkzeug.
Reference: http://flask.pocoo.org/docs/latest/patterns/appdispatch/