1

The links in my development server are relative to '/', while in production they are relative to '/flask/'. How do I write the links in the flask application so that it can work on both servers changing as little as possible?

An example:

import sys
import platform

from flask import Flask, __version__
app = Flask(__name__)

@app.route("/")
def hello():
    return """
        Hello World!<br><br>
        <a href="/info/">System Information</a>
    """

@app.route("/info/")
def info():
    return f"""
        Platform: {platform.platform()}<br>
        Python version {sys.version}<br>
        Flask version: {__version__}
    """

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

That would work in development, but to work on production it would be:

<a href="/flask/info/">System Information</a>

I've tried using a blueprint to prefix the routes instead of the links as proposed in Add a prefix to all Flask routes, but it isn't working:

website/__init__.py

from flask import Flask, Blueprint

bp = Blueprint('myapp', __name__, template_folder='templates')
app = Flask(__name__)
app.register_blueprint(bp, url_prefix='/flask'

website/main.py

import sys
import platform
from flask import __version__

from website import app

@app.route('/')
def hello():
    return f"""
        Hello World!<br><br>
        <a href="/info/">System Information</a>
    """

@app.route('/info/')
def info():
    return f"""
        Platform: {platform.platform()}<br>
        Python version: {sys.version}<br>
        Flask version: {__version__}
    """

Edit. The correct way to use the bluepring I think that is like this, moving register_blueprint after the route definitions. But the link is still broken because it doesn't go to /flask/info, it goes to /info.

website/main.py

import sys
import platform
from flask import url_for, __version__

from website import bp, app

@bp.route("/")
def hello():
    return f"""
        url = url_for('myapp.info')
        Hello World!<br><br>
        <a href="{url}">System Information</a>
    """

@bp.route("/info/")
def info():
    return f"""
        Platform: {platform.platform()}<br>
        Python version {sys.version}<br>
        Flask version: {__version__}
    """

app.register_blueprint(bp, url_prefix='/flask')

1 Answers1

1

Blueprint should work fine for your requirement of adding different route on different environment. According to the given code, you might forgot to change the route decorator when using blueprint. Change @app.route('/') to @bp.route('/') and @app.route('/info') to @bp.route('/info') should work. (Of course you will need to import bp first)

For my project I used environmental variable to decide the blueprint prefix (which is not definite, you can always try something that can fit into your requirement better). Say FLASK_ENV, it has different value of "development" and "production" in different environment, the corresponding code would be:

if os.environ.get("FLASK_ENV")=="production":
    app.register_blueprint(bp, url_prefix='/flask')
elif os.environ.get("FLASK_ENV")=="development":
    app.register_blueprint(bp, url_prefix='/')
Walnut
  • 71
  • 5