Issue
I have two Flask apps app1 and app2. I want to run app1 on the root domain (ie. domain.com) and app2 in a different url path (ie. domain.com/app2).
Right now my folder structure looks like this: myapps/ myapps/templates myapps/static myapps/app1.py myapps/app2/templates myapps/app2/static myapps/app2/app2.py
How can I organize/configure my Flask apps so that they properly access the correct template and static folders? I've looked at application dispatching, but I can't seem to figure it out.
Solution
There's perhaps two ways you might go about this. Application dispatching (as you mentioned in your question) or using blueprints. If your apps are truly separate and you just want to combine them on the same server on different paths, application dispatching works well for handling that at the WSGI layer.
If your "apps" are actually two logical pieces of the same larger application, you should probably consider blueprints instead.
Application Dispatching
The application dispatching pattern works at the WSGI layer and lets you combine multiple WSGI apps. These could even be used to combine non-flask WSGI apps (like, say a Django app) and Flask apps.
This exact scenario is covered by the werkzeug DispatcherMiddleware
middleware.
In the documentation, they give the following example:
For example you could have your main application run on / and your backend interface on /backend.
from werkzeug.middleware.dispatcher import DispatcherMiddleware
from frontend_app import application as frontend
from backend_app import application as backend
application = DispatcherMiddleware(frontend, {
'/backend': backend
})
This is basically the same as your case, except you would use app1
instead of frontend
and app2
instead of backend
.
As far as structuring your apps, I suggest treating them as separate applications, so that everything works the 'normal' way by default:
app_root/
app.py # <-- apply the dispatch pattern here, importing other apps
app1/
__init__.py
app.py
templates/
index.html
static/
main.css
app2/
__init__.py
app.py
templates/
index.html
static/
main.css
# app_root/app.py
from werkzeug.middleware.dispatcher import DispatcherMiddleware
from app1.app import app as app1
from app2.app import app as app2
application = DispatcherMiddleware(app1, {
'/app2': app2
})
if __name__ == '__main__':
application.run()
# or, from app_root, run:
# `FLASK_APP="app:application" flask run`
Though, a particular structure is not strictly necessary. You can always explicitly configure things like the template path on the application object itself. For example:
# app2/app.py
app = Flask(__name__, template_folder='../../somewhere/else/templates')
So, if you wanted, you could use the same templates/static dirs for both apps.
Blueprints
Alternatively, instead of having two completely separate app objects, you could also look at factoring your "apps" into blueprints instead. Similar to app dispatching, blueprints can be registered as specific path prefixes or subdomains.
from app1 import app1_blueprint
from app2 import app2_blueprint
app = Flask(__name__)
app.register_blueprint(app1)
app.register_blueprint(app2, url_prefix='/app2')
This has some advantages because you manage both apps at the "flask" layer, rather than at the higher WSGI layer with application. You're also able to make references between apps, such as building URLs with cross-references between your blueprints.
The documentation provides specific recommendations for project structure for blueprints.
See also: large applications as packages
Reverse proxy / webserver
Besides separating apps at the WSGI layer or Flask blueprints, you can of course also configure a reverse proxy for this situation. You could run both your apps as separate WSGI applications, listening on different ports (or even different hosts altogether) and bind them together how you want with a reverse proxy. Most popular webservers or proxies support this, like NGINX, HAProxy, Apache, IIS, etc.
This is a bit trickier to do correctly and involves more moving parts outside of your Python code, and may require extended configuration of your apps, but is at least worth mentioning.
For example, you could run app1
on a WSGI server serving at 127.0.0.1:5000
and another WSGI server instance running app2
on 127.0.0.1:6000
. Then you run your reverse proxy server (e.g., nginx) on port 80/443 and create reverse proxy rules to route to the correct underlying application server based on the path.
As a very simple nginx configuration example:
location /app2/ {
proxy_pass http://127.0.0.1:6000/;
}
location / {
proxy_pass http://127.0.0.1:5000/;
}
Webservers like IIS or Apache can even run your Python apps 'directly' through modules within the webserver (e.g. wsgi module, fastcgi, wfastcgi, etc.) but I won't go into detail on that here.
Answered By - sytech
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.