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.
URL Processors
We can add a URL processor to let us share resources with similar URLs.
With it, we don’t have to specify different routes that map to similar URLs.
For example, we can write:
from flask import Flask, g, request
app = Flask(__name__)
@app.url_defaults
def add_language_code(endpoint, values):
if 'lang_code' in values or not g.lang_code:
return
if app.url_map.is_endpoint_expecting(endpoint, 'lang_code'):
values['lang_code'] = g.lang_code
@app.url_value_preprocessor
def pull_lang_code(endpoint, values):
g.lang_code = values.pop('lang_code', None)
@app.route('/<lang_code>/')
def index():
return 'index %s' % g.lang_code
@app.route('/<lang_code>/about')
def about():
return 'about %s' % g.lang_code
to add a URL preprocessor, which is run before the route functions are run.
The add_language_code
function is run to set the lang_code
from the g.lang_code
property if it exists.
The app.url_map.is_endpoint_expecting
method is used to check if the lang_code
URL parameter is expected.
The URL preprocessor function is the pull_lang_code
function.
We use the @app.url_value_preprocessor
decorator to register the URL preprocessor function.
values
has the URL parameters.
Then we call values.pop
to get the value of the 'lang_code'
URL parameter and set that as the value of g.lang_code
.
Then in our route functions, we can omit the lang_code
parameter.
We get the value for lang_code
from the g.lang_code
property instead.
So when we go to http://127.0.0.1:5000/en/about, we see ‘about en’.
And when we go to http://127.0.0.1:5000/en/, we see ‘index en’.
Internationalized Blueprint URLs
We can add URL preprocessors for blueprints.
For example, we can write:
from flask import Flask, g, request, Blueprint
app = Flask(__name__)
bp = Blueprint('frontend', __name__, url_prefix='/<lang_code>')
@bp.url_defaults
def add_language_code(endpoint, values):
if 'lang_code' in values or not g.lang_code:
return
if app.url_map.is_endpoint_expecting(endpoint, 'lang_code'):
values['lang_code'] = g.lang_code
@bp.url_value_preprocessor
def pull_lang_code(endpoint, values):
g.lang_code = values.pop('lang_code', None)
@bp.route('/')
def index():
return 'index %s' % g.lang_code
@bp.route('/about')
def about():
return 'about %s' % g.lang_code
app.register_blueprint(bp)
We create the bp
blueprint with the Blueprint
constructor.
It has the url_prefix
parameter to make it accept the lang_code
URL parameter as the prefix.
Then we add the same URL preprocessor function as we do before to get the lang_code
parameter and set it as the value of the g.lang_code
property.
The difference is that we use the @bp.url_value_preprocessor
decorator to register the URL preprocessor.
The @bp.url_defaults
decorator is used to setting the default value of the lang_code
URL parameter.
Then the bp
blueprint routes can be used the same way as we do before.
After defining the routes, we call app.register_blueprint
to register the bp
blueprint.
SQLite 3 with Flask
We can use SQLite 3 with Flask.
To do this, we can write:
from flask import Flask, g
import sqlite3
app = Flask(__name__)
DATABASE = './database.db'
def get_db():
db = getattr(g, '_database', None)
if db is None:
db = g._database = sqlite3.connect(DATABASE)
return db
@app.teardown_appcontext
def close_connection(exception):
db = getattr(g, '_database', None)
if db is not None:
db.close()
def query_db(query, args=(), one=False):
cur = get_db().execute(query, args)
rv = cur.fetchall()
cur.close()
return (rv[0] if rv else None) if one else rv
@app.route('/')
def index():
names = []
for person in query_db('select * from people'):
names.append(person[0])
return ','.join(names)
We create the get_db
function to connect to the database.
close_connection
closes the connection.
It’s run when we stop the app as indicated by the @app.teardown_context
decorator.
The query_db
function queries the data with the get_db
function to make the connection.
Then we fetch all the items returned by the query
.
It returns the result, and we use that in our index
route function.
We created a people
table with the name
text column.
So person[0]
returns the value of the name
column.
Conclusion
We can add URL processors to make managing similar URLs easier.
Also, we can use SQLite with our app.