I want to move some commonly used parts of my webapps to Flask blueprints for better reuse. But some of the routes will need functionality which is specific to a webapp. An example would be a simple form submission where everything is handled by the blueprint, only the form validation would have to be defined by the implementing app.
How can I tell a blueprint view to call a function of the app. With inheritance I would create a abstract function which would be filled out by them implementing webapp. But I am lost how to do something similar with a blueprint.
Edit:
I am using Class based views, but the following snippet trys to explain what I am looking for:
#my_blueprint.route('/submit')
def submit():
errors = current_app.check_for_errors(request.form) # <--- How to?
return render_template('result.html', errors=error)
The errors = current_app.check_for_errors(request.form) is the one I don't know ho to implement. Sub-classing flask.Flask is the only way I can come up with, but this doesn't feel right.
Related
I am building a very small API using Python and was wondering whether it is generally acceptable to place API code in a model class when using frameworks like Django or Flask (with an ORM like Peewee or Pony). Let me explain what I mean...
To illustrate what I mean, imagine I have a package with all my models and then another package with my API code which executes when a client pings a particular route that I have defined. As you know, the models are basically only for mapping objects to the database. Although, under certain circumstances, it personally makes more sense for some reason to place some of the API code in one of the model classes I have defined.
For example, I have a User model that maps a user to the database. Additionally, in the API code, I have a function to login the user. This function basically sets the cookies to login the user so it might make sense to place it in the API package. However, I feel like if I make this function a method and place it in the user model, it makes more sense semantically and might be easier to understand.
class UserModel(Peewee or Pony or Django.model...):
def login(self):
"""" Login code goes here. Set cookies, login the user, etc. """
add_cookies(self.username)
return jsonify({"logged_in": True}) # Flask example...
user = UserModel()
user.login()
One caveat of doing this, however, is that the models code and the API code are no longer decoupled and now strongly rely on each other.
Therefore, I guess my "objective" question is about the acceptability of each of these. Is keeping the models (database and ORM stuff) and the API routes decoupled better practice than combining them together? What are some of the advantages and disadvantages of doing each of these? What is the most common and recommended practice?
Thanks in advance.
TL;DR: it's fine to put a function within the model class however if you want secure logins you will need to pass the login information within a token using something like Flask-Login (I'm not sure what the equivalent extension is for django).
Putting a function within the class is fine, however this won't be very secure for a login, so I'd suggest following a tutorial for implementing a secure login extention.
For example, on one of my projects the views function for the login page is:
#user.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm(next=request.args.get('next'))
if form.validate_on_submit():
u = User.find_by_identity(request.form.get('identity'))
if u and u.authenticated(password=request.form.get('password')):
if login_user(u, remember=True) and u.is_active():
# Handle optionally redirecting to the next URL safely.
next_url = request.form.get('next')
if next_url:
return redirect(safe_next_url(next_url))
return redirect(url_for('user.settings'))
else:
flash('Identity or password is incorrect.', 'error')
return render_template('user/login.html', form=form)
Note that the u.authenticated is a function within my User model Class that checks the users password hash is correct:
def authenticated(self, with_password=True, password=''):
#Ensure a user is authenticated, and optionally check their password.
if with_password:
return check_password_hash(self.password, password)
return True
TL;DR : your login method - which is only about HTTP-related stuff - doesn't belong to the model layer, period.
Longest answer : adding logic to models is of course a good design, but this has to be domain logic, not UI-related stuff. The point (since you ask about "good practices") is to keep the domain layer (models) totally independant of the UI (views and controllers) so you can use the same domain layer with different UIs (remember that command-line scripts ARE a UI too).
I had to work with quite a few badly designed applications/frameworks that mixed concerns and actually required having a "request" (http request) and "response" object at hand whatever you wanted to do and those were a complete nightmare to deal with, so from experience the "separation of concerns" rule is not something you want to break.
Just note that this doesn't mean the UI layer should not know about the domain - this would make no sense, and would actually be just impossible from a technical POV.
I've read about blueprints in Flask but I think my app is too small to use it yet. However I would like to keep my code clear. Since my app has a user login I would like to keep several functions protected. Now I'm wondering if the following code is as safe as putting all the code into a route or is that not proper coding?
import scriptwithseveralfunctions.py
#app.route('/functionone')
#login_required
def do_something():
scriptwithseveralfunctions.myfunction()
Yes, it's definitely safe. Only functions with #app.route wrapper will be exposed to the user.
Is there a way to create Swagger-API UI documentation for a flask-potion based application?
I've tried using "flasgger", but it doesn't work for routes that are written with potion-type routes.
Flask-potion has a route specified in following manner-
#Route.GET('/num_products')
But "flasgger" expects a route in following manner-
#app.route('/num_products', methods=['GET'])
There is no clean way to do this. However, a hackish solution for the same exists-
Flasgger works for default flask routes. We can re-define the routes that were defined earlier using flask-potion, as default flask routes and make calls to the earlier flask-potion functions from the newly created functions. Note- Changing the existing routes to the new routes didn't work for me. I had to mask the old calls with new ones and call the old function from the new ones.
Note- This only works for custom routes that are written by the user and doesn't work for default routes that are generated from data model by flask potion.
Existing code-
class ProductResource(BaseModelResource):
#Route.GET('/num_products')
def product_count():
return product.query(...)
Refactored Code -
class ProductResource(BaseModelResource):
def product_count():
return product.query(...)
#app.route('/num_products', methods=['GET'])
def product_count_main():
output = product_count()
Response(str(output), content_type='application/json')
I have built flask apis in the past, but I've never had the luxury of being on a project where I was allowed to do test driven development while working on one. Now I am.
Every how-to I've ever read shows flask-apis being defined in a decidedly non-object-oriented style. This makes writing unit tests very difficult because one cannot pass optional or test-specific parameters into the instantiated api.
For example, this blog explains one method for creating unit tests for a flask-api:
http://mkelsey.com/2013/05/15/test-driven-development-of-a-flask-api/
The blog sets an environment variable when in test mode and the script watches for that variable, altering its behavior when it is found. This seems very inadvisable to me. There are a long list of reasons why letting your source code bleed into your OS environment is a Bad Idea. I'm a big believer in encapsulating functionality in order to maximize portability and to draw clear distinctions between where modules begin and end.
In order to satisfy my coding philosophy someone might suggest I just wrap the flask API up in a class. However, it isn't clear to me how one would do such a thing. For example, Flask uses decorators in order to define a route:
#app.route()
How could this be fit into a class?
I would greatly appreciate the guidance of anyone who has developed a flask api in an object oriented manner.
You can replace the use of #app.route with add_url_rule.
To put it in an example:
from flask import Flask
class MyFlaskApp:
def __init__(self):
self.app = Flask(__name__)
self.app.add_url_rule('/', 'index', self.index)
def index(self):
pass
Which is similar to:
from flask import Flask
app = Flask(__name__)
#app.route('/index')
def index():
pass
I have read the official Flask documentation on Blueprints and even one or two blog posts on using them.
I've even used them in my web app, but I don't completely understand what they are or how they fit into my app as a whole. How is it similar to an instance of my app but not quite? The documentation is comprehensive but I seek a layman explanation or an enlightening analogy to spark it for me. I was sufficiently perplexed when a colleague asked me to explain a Flask blueprint to them that I elected to ask here.
A blueprint is a template for generating a "section" of a web application. You can think of it as a mold:
You can take the blueprint and apply it to your application in several places. Each time you apply it the blueprint will create a new version of its structure in the plaster of your application.
# An example
from flask import Blueprint
tree_mold = Blueprint("mold", __name__)
#tree_mold.route("/leaves")
def leaves():
return "This tree has leaves"
#tree_mold.route("/roots")
def roots():
return "And roots as well"
#tree_mold.route("/rings")
#tree_mold.route("/rings/<int:year>")
def rings(year=None):
return "Looking at the rings for {year}".format(year=year)
This is a simple mold for working with trees - it says that any application that deals with trees should provide access to its leaves, its roots, and its rings (by year). By itself, it is a hollow shell - it cannot route, it cannot respond, until it is impressed upon an application:
from tree_workshop import tree_mold
app.register_blueprint(tree_mold, url_prefix="/oak")
app.register_blueprint(tree_mold, url_prefix="/fir")
app.register_blueprint(tree_mold, url_prefix="/ash")
Once it is created it may be "impressed" on the application by using the register_blueprint function - this "impresses" the mold of the blueprint on the application at the locations specified by url_prefix.
As pointed out in a comment by #Devasish, this article provides a good answer:
http://exploreflask.com/en/latest/blueprints.html
Quoting from the article:
An example of this would be Facebook. If Facebook used Flask, it might
have blueprints for the static pages (i.e. signed-out home, register,
about, etc.), the dashboard (i.e. the news feed), profiles
(/robert/about and /robert/photos), settings (/settings/security and
/settings/privacy) and many more. These components all share a general
layout and styles, but each has its own layout as well
This is a very good interpretation, especially the part "if Facebook used Flask". It gives us a concrete situation to visualize how Blueprint actually works.
For bigger projects, all your code shouldn't be in the same file.
Instead you can segment or split bigger codes into separate files, mostly based on functionality. Like bricks forming a wall.
A simple Flask app
app = Flask(__name__)
A blueprinted Flask app
import from_any_module.part_1
import from_other_module.part_2
app = Flask(__name__)
app.register_blueprint(part_1)
app.register_blueprint(part_2)
A blueprint in the above app
from flask import Blueprint
part_1 = Blueprint(part_1)
#part_1.route('/url')
def function()
return view
I too just stumbled up this myself and was confused after reading a few of the documentation sources. At first I thought it was like C#/Java OOP Interface Implementation style where you define some stuff but dont have to worry about it implementation details til later. However, I stumbled up this page which puts it in very very laymens (and quite hilarious present-day events) terms. https://hackersandslackers.com/flask-blueprints/
Essentially one benefit that is mentioned in the link and provides me a clear idea of it's real world usage is that I can effectively logically organize/divide the app into several parts that only need to be concerned with it's own affairs. So it provides some designed encapsulation.
Edit: I'm currently using it to segment out my webapps code. It was good decision too because I found the lead designer wants to make the frontend in Vue.js. Which I havent used yet but looking at it's project files would look far more messy and probably provide many naming collision prone instances due to files with similar names
A Flask blueprint helps you to create reusable instances of your application. It does so by organizing your project in modules. Those modules are then registered the main application. They help in creating an application factory.