CodeToLive

Building RESTful APIs with Flask

Flask is excellent for building REST APIs. You can use core Flask or extensions like Flask-RESTful for more structure.

Basic API Endpoint


from flask import jsonify

@app.route('/api/users')
def get_users():
    users = User.query.all()
    return jsonify([user.serialize() for user in users])
            

Flask-RESTful


from flask_restful import Api, Resource

api = Api(app)

class UserAPI(Resource):
    def get(self, user_id):
        user = User.query.get_or_404(user_id)
        return user.serialize()

    def put(self, user_id):
        # Update user
        pass

    def delete(self, user_id):
        # Delete user
        pass

api.add_resource(UserAPI, '/api/users/<int:user_id>')
            

Request Parsing


from flask_restful import reqparse

parser = reqparse.RequestParser()
parser.add_argument('username', type=str, required=True)
parser.add_argument('email', type=str, required=True)

class UserListAPI(Resource):
    def post(self):
        args = parser.parse_args()
        # Create new user with args
            

Authentication for APIs


from flask_httpauth import HTTPBasicAuth

auth = HTTPBasicAuth()

@auth.verify_password
def verify_password(username, password):
    user = User.query.filter_by(username=username).first()
    if user and check_password_hash(user.password, password):
        return user

class PrivateAPI(Resource):
    @auth.login_required
    def get(self):
        return {'message': 'Hello, %s!' % auth.current_user().username}
            

JWT Authentication


from flask_jwt_extended import JWTManager, jwt_required, create_access_token

app.config['JWT_SECRET_KEY'] = 'super-secret'
jwt = JWTManager(app)

@app.route('/api/login', methods=['POST'])
def login():
    username = request.json.get('username')
    password = request.json.get('password')
    user = User.query.filter_by(username=username).first()
    if user and check_password_hash(user.password, password):
        access_token = create_access_token(identity=username)
        return jsonify(access_token=access_token)
    return jsonify({"msg": "Bad credentials"}), 401

@app.route('/api/protected')
@jwt_required()
def protected():
    return jsonify(logged_in_as=current_user), 200
            

API Documentation


from flask_swagger_ui import get_swaggerui_blueprint

SWAGGER_URL = '/api/docs'
API_URL = '/static/swagger.json'

swaggerui_blueprint = get_swaggerui_blueprint(
    SWAGGER_URL,
    API_URL,
    config={'app_name': "My API"}
)

app.register_blueprint(swaggerui_blueprint, url_prefix=SWAGGER_URL)
            

API Best Practices

Next: Deployment