Flask is a simple web framework written in Python.
In this article, we’ll look at how to develop simple Python web apps with Flask.
Decorating Views
We can add decorators to view classes with the decorators
property.
For example, we can write:
from flask import Flask, request, session, abort
from flask.views import MethodView
app = Flask(__name__)
app.secret_key = b'secret'
def user_required(f):
def decorator(*args, **kwargs):
if 'username' not in session:
abort(401)
return f(*args, **kwargs)
return decorator
class UserAPI(MethodView):
decorators = [user_required]
def get(self):
return 'get'
def post(self):
return 'post'
class LoginAPI(MethodView):
def get(self):
session['username'] = 'username'
return 'logged in'
class LogoutAPI(MethodView):
def get(self):
session.pop('username', None)
return 'logged out'
app.add_url_rule('/users/', view_func=UserAPI.as_view('users'))
app.add_url_rule('/login/', view_func=LoginAPI.as_view('login'))
app.add_url_rule('/logout/', view_func=LogoutAPI.as_view('logout'))
We add the LoginAPI
and LogoutAPI
to and add the get
methods to them to add the username
session key and remove it respectively.
In UserAPI
, we user the user_required
decorator to check whether the 'username'
key in the session
object.
If it’s not, we return 401.
Otherwise, we call the method that we’re requesting in the class.
Method Views for APIs
We can get URL parameters in our route methods.
For example, we can write:
from flask import Flask, request, session, abort
from flask.views import MethodView
app = Flask(__name__)
class UserAPI(MethodView):
def get(self, user_id):
print(user_id)
if user_id is None:
return 'users'
else:
return str(user_id)
def post(self):
return 'post'
def delete(self, user_id):
return str(user_id)
def put(self, user_id):
return 'put'
user_view = UserAPI.as_view('user_api')
app.add_url_rule('/users/', defaults={'user_id': None},
view_func=user_view, methods=['GET', ])
app.add_url_rule('/users/', view_func=user_view, methods=['POST', ])
app.add_url_rule('/users/<int:user_id>', view_func=user_view,
methods=['GET', 'PUT', 'DELETE'])
We have the UserAPI
class that has the get
, post
, delete
and put
methods.
The user_id
parameter is the URL parameter.
The defaults
parameter is set on the GET route to set the user_id
with a default value.
We also accept the user_id
URL parameter in the PUT and DELETE routes.
Application Context
We can use the application context to keep track of the app0level data during a request, CLI command, or other activity.
We can access the global context with the g
variable.
For example, we can write:
from flask import Flask, g
from flask.views import MethodView
app = Flask(__name__)
def connect_to_database():
pass
def get_db():
if 'db' not in g:
g.db = connect_to_database()
return g.db
@app.teardown_appcontext
def teardown_db(response_or_exc):
db = g.pop('db', None)
if db is not None:
db.close()
@app.route('/')
def hello_world():
return 'hell world'
We set the g.db
property if 'db'
isn’t in the g
variable.
In the teardown_db
function, then we call g.pop
method to remove the 'db'
property from the object.
Request Context
Flask automatically pushes a request context when handling a request.
For example, if we have:
from flask import Flask, request
app = Flask(__name__)
@app.route('/')
def hello():
print('during view')
return 'Hello, World!'
@app.teardown_request
def show_teardown(exception):
print('after with block')
with app.test_request_context():
print('during with block')
with app.test_client() as client:
client.get('/')
print(request.path)
We get the context with the app.test_request_context()
method.
The show_teardown
method is run after the with
blocks are run.
So we get:
during with block
after with block
during view
/
after with block
logged when we run the app.
Conclusion
We can decorate method views. Also, we can get the app context and use it to request data with Flask.