Let's say you want to serve 2 domains, example1.com and example2.com, from the same app (i.e., using host matching). You also want your static assets for each domain to be served from those domains, e.g., example1.com/static/ and example2.com/static/. You can almost achieve this in Flask, but not quite.
This code extends Flask's Blueprint class to make registering hostnames onto a blueprint painless and ensure static assets appear to be served from the appropriate hostname.
By default, Flask supports host matching at the app-level by passing host_matching=True and a hostname for static_host when initializing the app. However, there are drawbacks to the current support, especially when using blueprints:
- To match all routes on a blueprint to a host, you must pass the
hostparameter to every route decorator for that blueprint. - The app's static files will always be served from the
static_host, and trying to override the blueprintstatic_folderproduces some undefined behaviour. Even when you try to overridestatic_url_pathusing a secondary hostname, at best you'll be stuck with absolute paths.
With the above Blueprint and BlueprintSetupState classes, you can do the following:
- Register a
hostparameter at blueprint registration time. This applies the parameter to every route on that blueprint without anything extra in your code. It works withurl_prefix - Automatically get a blueprint static endpoint that generates a URL relative to the blueprint's hostname. By default, this will map to the app static folder—i.e.,
/static/foo.jpgwould be available to be served by bothlocalhost.foo:5000/foo.jpgandlocalhost.bar:5000/bar.jpg. So, there is no actual separation of the static assets. If you want to separate your assets, you can still passstatic_folderwhen instantiating the Blueprint option. Again, this will result in relative static URL paths being generated.