Menu Close

Python Web Development with Flask — URL Processors and SQLite

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.

Posted in flask, Python