user13411047
user13411047

Reputation:

Different link prefix in development and production server on flask

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')

Upvotes: 1

Views: 519

Answers (2)

Helder Daniel
Helder Daniel

Reputation: 411

This thread is a bit old, but I found this page while searching info on the same issue.

I found that there is no need to use blueprint. We can use regular @app.route and generate dynamically the url.

Just replace:

<a href="{url}">System Information</a>

with:

<a href="{{ url_for('info') }}">System Information</a>

Note that 'info' in {{ url_for('info') }} is the name of the function: info(), not the route @app.route('/info/').

The full 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="{{ url_for('info') }}">System Information</a>
    """

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

Upvotes: 0

Walnut
Walnut

Reputation: 71

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='/')

Upvotes: 1

Related Questions