Categories
Flask

Python Web Development with Flask — URL Processors and SQLite

Spread the love

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.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *