Reputation:
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
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
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