Flask (Pallets Project)
CLI
## Set
export FLASK_APP=hello.py
# $env.FLASK_APP=hello.py
## Debug mode
export FLASK_ENV=development
## Run
flask run # python -m flask run
Views
A function to respond to requests.
@app.route("/hello")
def hello():
return "Hello!"
Valid response:
string
-
json
from flask import jsonify def hello(): return jsonify({"time": time.time()})
-
render_template()
def hello(): return render_template("hello.html")
Blueprint
A way to organize a group of views. (Modularization)
from flask import Blueprint, request, redirect, url_for
bp = Blueprint('auth', __name__, url_prefix='/auth')
# register: app.register_blueprint(bp)
# add views
@bp.route('/register', methods=('GET', 'POST'))
def register():
# request is imported
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
...
return redirect(...)
#elif request.method == 'GET':
return render_template(...)
@bp.route('/login', methods=('GET', 'POST'))
def login():
pass
# other utils
def login_required(view):
@functools.wraps(view)
def wrapped_view(**kwargs):
if g.user is None:
return redirect(url_for('auth.login'))
return view(**kwargs)
return wrapped_view
Context
**How flask handle request: **
- Create APP Context
- Create Request Context
- Do some Logic
- Destroy Request Context
- Destroy APP Context
Difference:
APP context is cheap, and can be created without a request, for accessing current_app
and g
.
Request context is expensive.
URL arguments
-
simple arguments
fetch("api/a/1");
@app.route("api/<arg1>/<arg2>") def func(arg1, args): return jsonify({ 'arg1': arg1, 'arg2': arg2, })
-
form
let formData = new FormData(); formData.append('username', 'John'); formData.append('password', '123'); fetch("api/form", { method: "POST", body: formData, });
@app.route("api/form", methods=('GET','POST')) def login(): if request.method == 'POST': username = request.form.get('username') password = request.form.get('password')
-
URL parameters
fetch("login?username=alex&password=pw1")
@app.route("login", methods=("GET",)) def login(): username = request.args.get('username') password = request.args.get('password')
-
JSON
fetch("test", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({name:"Alex"}) })
@app.route("test", methods=('GET','POST')) def login(): if request.method == 'POST': username = request.json.get('username') password = request.json.get('password')
-
files
request.files
flask.session
Store data in different requests from the same client. (signed cookies)
It is like a dict
.
session['user_id'] = user['id']
session.clear()
flask.g
Store data in the same request.
It works like a dict
.
g.user = user
if g.user is not None:
pass
Usual way to manage resource:
def get_db():
if 'db' not in g:
g.db = connect_to_database()
return g.db
@app.teardown_appcontext
def teardown_db():
db = g.pop('db', None)
if db is not None:
db.close()
Jinja
A template library.
{% ... %}
for Statements{{ ... }}
for Expressions to print to the template output{# ... #}
for Comments not included in the template output# ... ##
for Line Statements