Flask, Blueprint, current_app - python

I am trying to add a function in the Jinja environment from a blueprint (a function that I will use into a template).
Main.py
app = Flask(__name__)
app.register_blueprint(heysyni)
MyBluePrint.py
heysyni = Blueprint('heysyni', __name__)
#heysyni.route('/heysyni'):
return render_template('heysyni.html', heysini=res_heysini)
Now in MyBluePrint.py, I would like to add something like :
def role_function():
return 'admin'
app.jinja_env.globals.update(role_function=role_function)
I will then be able to use this function in my template. I cannot figure out how I can access the application since
app = current_app._get_current_object()
returns the error:
working outside of request context
How can I implement such a pattern ?

The message error was actually pretty clear :
working outside of request context
In my blueprint, I was trying to get my application outside the 'request' function :
heysyni = Blueprint('heysyni', __name__)
app = current_app._get_current_object()
print(app)
#heysyni.route('/heysyni/')
def aheysyni():
return 'hello'
I simply had to move the current_app statement into the function. Finally it works that way :
Main.py
from flask import Flask
from Ablueprint import heysyni
app = Flask(__name__)
app.register_blueprint(heysyni)
#app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run(debug=True)
Ablueprint.py
from flask import Blueprint, current_app
heysyni = Blueprint('heysyni', __name__)
#heysyni.route('/heysyni/')
def aheysyni():
# Got my app here
app = current_app._get_current_object()
return 'hello'

Related

Extend a blueprint in Flask, splitting it into several files

In flask, I have a blueprint that is getting a bit too long and I'd like to split it into several files, using the same route /games
I tried extending the class, but it doesn't work?
# games.py
from flask import Blueprint
bp = Blueprint('games', __name__, url_prefix='/games')
#bp.route('/')
def index():
...
.
# games_extend.py
from .games import bp
#bp.route('/test')
def test_view():
return "Hi!"
Am I doing something wrong or is there a better way?
You can make it work using absolute path names (packages), here's how:
app.py
from __future__ import absolute_import
from flask import Flask
from werkzeug.utils import import_string
api_blueprints = [
'games',
'games_ext'
]
def create_app():
""" Create flask application. """
app = Flask(__name__)
# Register blueprints
for bp_name in api_blueprints:
print('Registering bp: %s' % bp_name)
bp = import_string('bp.%s:bp' % (bp_name))
app.register_blueprint(bp)
return app
if __name__ == '__main__':
""" Main entrypoint. """
app = create_app()
print('Created app.')
app.run()
bp/init.py
bp/games.py
from __future__ import absolute_import
from flask import Blueprint, jsonify
bp = Blueprint('games', __name__, url_prefix='/games')
#bp.route('/')
def index():
return jsonify({'games': []})
bp/games_ext.py
from .games import bp
#bp.route('/test')
def test_view():
return "Hi!"
Start your server using: python -m app
Then send Get queries to /games/ and /games/test/ endpoints. Worked for me.
Cheers !
In latest version of Flask, it supports Nested Blueprints
They can now be successfully divided into multiple files and imported into the parent one. Additionally, note the url_prefix parameter which can be used to divide files based on functionality but with same routes in different files.

Key Error in Flask Sessions

So I have been using sessions to pass data from one decorator to another. But now every time I make a new session variable, I get a KeyError from page to page. Meaning, I had a session error from my third to fourth page; but I had the same issue adding a new session variable from my second to third page even though I have four other session variables that give me no error.
My code is similar to the one #laila posted below:
from flask import Flask, render_template
from flask import request, session, url_for,abort,redirect
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret'
#app.route('/'):
def first():
session['this_one']='hello'
render('template.html')
#app.route('/second')
def second():
it=session['this_one']
render('other_page.html')
if __name__ == '__main__':
app.run(debug=True)
it seems like the code has some syntax error.Please try the code below, it should be ok:
from flask import Flask, render_template
from flask import request, session, url_for, abort, redirect
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret'
#app.route('/')
def first():
session['this_one'] = 'hello'
return render_template('template.html')
#app.route('/second')
def second():
it = session.get('this_one', 'not found')
return render_template('other_page.html')
if __name__ == '__main__':
app.run(debug=True)

Flask blueprint doesn't work without prefix

Hi I have a Flask app structured in following way and I have problem with blueprints setup. Whatever I do, they only work with url_prefix set up. It works currently as /main/verify but as it is a small app I would love to have an endpoint like /verify. What's interesting I managed to make it work with / route, but for the same configuration it didn't work for the /verify. I am pretty clueless right now, I can live with it as it is, but I really wonder what am I doing wrong.
Here is the code:
__init__.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from config import config
db = SQLAlchemy()
def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config[config_name])
config[config_name].init_app(app)
db.init_app(app)
from main import main
app.register_blueprint(main)
return app
main/__init__.py
from flask import Blueprint
main = Blueprint('main', __name__, url_prefix='/main')
from . import views
main/views.py
from flask import request, jsonify
from . import main
#main.route('/')
def index():
return "Hello world"
#main.route('/verify')
def verify():
url = request.args['url']
query = request.args['query']
return jsonify({ ... })
As I see you didn't register blueprint without prefix. If you need to register endpoints without prefix you must create a new instance of Blueprint
main = Blueprint('main', __name__, url_prefix='/main')
# main endpoints(with prefix /main)...
#main.route('/')
def index_main():
return "Hello world from /main/"
# routes without any prefix
default = Blueprint('default', __name__)
#default.route('/')
def index():
return "Hello world from /"
app = Flask(__name__)
app.register_blueprint(main)
app.register_blueprint(default)
Hope this helps.

Flask URL not found when using blueprint [duplicate]

This question already has an answer here:
register_blueprint doesn't add route to Flask app
(1 answer)
Closed 5 years ago.
This is really strange but am facing this problem. Everything was working and i was almost done with the app but out of a sudden it stopped. I have isolated the code and i realized that when i register a blueprint and use it on a route, it fails to return saying no URL found. Here is the isolated code:
from flask import Flask, render_template, Blueprint
app = Flask(__name__)
home = Blueprint('home', __name__, static_folder='static', template_folder='template')
app.register_blueprint(home)
#home.route('/') #<---This one does not work
# #app.route('/') <--- This one works
def index():
return "This is the index route."
# return render_template('layer.html')
if __name__ == '__main__':
app.run()
Move the app.register_blueprint(home) after route defined.
from flask import Flask, Blueprint
app = Flask(__name__)
home = Blueprint('home', __name__, static_folder='static', template_folder='template')
#home.route('/')
def index():
return "This is the index route."
app.register_blueprint(home)
if __name__ == '__main__':
app.run()

Serving static json data to flask

I have json data in demo_data.json that I'd like to bring into a Flask app. I'm receiving a 404 on the file which I've placed in the static directory, my code is below, thanks for any thoughts in advance:
from flask import Flask, render_template
from flask import url_for
app = Flask(__name__, static_url_path='/static/')
#app.route('/')
def home():
return render_template('home.html')
#app.route('/welcome')
def welcome():
return render_template('welcome.html')
if __name__ == '__main__':
app.run()
return send_from_directory('/static', 'demo_data.json')
You would need to define the view to send the data.
Something similar to :
from flask import Flask, render_template
from flask import url_for
app = Flask(__name__, static_url_path='/static/')
#app.route('/')
def home():
return render_template('home.html')
#app.route('/welcome')
def welcome():
return render_template('welcome.html')
#app.route('data/<filename>')
def get_json(filename):
return send_from_dir
if __name__ == '__main__':
app.run()
So, you are trying to send a file? Or show a file in an url?
I assumed the later. Notice the use of url_for.
This creates a link that will show your static file.
http://127.0.0.1:5000/send and http://127.0.0.1:5000/static/demo_data.json
from flask import Flask, render_template
from flask import url_for
app = Flask(__name__, static_url_path='/static')
#app.route('/')
def home():
return render_template('home.html')
#app.route('/send')
def send():
return "<a href=%s>file</a>" % url_for('static', filename='demo_data.json')
if __name__ == '__main__':
app.run()
But you also might want to check out https://github.com/cranmer/flask-d3-hello-world
It looks like you have a trailing slash on your static_url_path. Removing the extra character resolved the issue. Also note the removed last line. The return call wasn't necessary and the function call after the return was a syntax error.
from flask import Flask, render_template
from flask import url_for
app = Flask(__name__, static_url_path='/static')
#app.route('/')
def home():
return render_template('home.html')
#app.route('/welcome')
def welcome():
return render_template('welcome.html')
if __name__ == '__main__':
app.run()

Categories

Resources