Field Validation for Backend APIs with Python, Flask, and SQLAlchemy

Ed Nunes
Ed Nunes
Mar 8, 2018 · 4 min read
license: CC0 1.0

Validation Options for Flask Applications

Validating with SQLAlchemy

from configparser import ConfigParser 
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
# import config file to global object
config = ConfigParser()
config_file = '../config.ini'
config.read(config_file)
# instantiate flask app
app = Flask(__name__)
app.config['SECRET_KEY'] = config.get('flask', 'secret_key') app.config['SQLALCHEMY_DATABASE_URI'] = \
config.get('flask','database_uri')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
from app import routes, models
import re 
from werkzeug.security import (generate_password_hash,
check_password_hash)
from sqlalchemy.orm import validates
from app import db
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), index=True, unique=True,
nullable=False)
email = db.Column(db.String(120), index=True, nullable=False)
password_hash = db.Column(db.String(128))
role = db.Column(db.Enum('basic', 'admin', name='user_roles'),
default='basic')
def set_password(self, password):
self.password_hash = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.password_hash, password)
@validates('username') 
def validate_username(self, key, username):
if not username:
raise AssertionError('No username provided')
if User.query.filter(User.username == username).first():
raise AssertionError('Username is already in use')
if len(username) < 5 or len(username) > 20:
raise AssertionError('Username must be between 5 and 20 characters')
return username @validates('email') def validate_email(self, key, email):
if not email:
raise AssertionError('No email provided')
if not re.match("[^@]+@[^@]+\.[^@]+", email):
raise AssertionError('Provided email is not an email address')
return email
$ user = User(username='Sam', email='sseaborn@example.com')   
$ db.session.add(user)
AssertionError: Username must be between 5 and 20 characters
def set_password(self, password):
if not password:
raise AssertionError('Password not provided')
if not re.match('\d.*[A-Z]|[A-Z].*\d', password):
raise AssertionError('Password must contain 1 capital letter and 1 number')
if len(password) < 8 or len(password) > 50:
raise AssertionError('Password must be between 8 and 50 characters')
self.password_hash = generate_password_hash(password)
from flask import jsonify, request 
from app import app, db
from app.model import User
@app.route('/api/create_user', methods=['POST'])
def create_user():
data = request.get_json()
username = data['username']
password = data['password']
email = data['email']
user = User(username=username, email=email)
user.set_password(password)
try:
db.session.add(user)
db.session.commit()
return jsonify(msg='User successfully created', user_id=user.id), 200
except AssertionError as exception_message:
return jsonify(msg='Error: {}. '.format(exception_message)), 400

Ed Nunes

Written by

Ed Nunes

A data engineer interested in exploring how we can use data enabled tech to improve our lives.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade