Python's Flask framework offers a powerful way to create web applications and APIs effortlessly. When combined with flask_restful for API creation and flask_sqlalchemy for database management, it becomes a robust toolkit for developing RESTful APIs with ease.

This article is a continuation of my previous article, Building APIs with Flask and flask_restful in Python, where I explained how to use flask_restful in a Python application. So, I will not repeat the same here. Let's continue from the previous article.

Install the required packages using pip.

pip install Flask flask_restful flask_sqlalchemy

Initializing Flask and Creating API Endpoints

Let's create a simple Flask application and define an API using flask_restful.

from flask import Flask
from flask_restful import Api, Resource, reqparse, abort, fields, marshal_with
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
api = Api(app)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db'
db = SQLAlchemy(app)

class UserModel(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(100), nullable=False)
    name = db.Column(db.String(100), nullable=False)
    age = db.Column(db.Integer, nullable=False)
    gender = db.Column(db.String, nullable=False)

    def __repr__(self):
        return f"User(email = {email}, name = {name}, age = {age}, gender = {gender})"

# db.create_all() - This will be executed only once when the db needs to be initialised. It should be commented post that

users_put_args = reqparse.RequestParser()
users_put_args.add_argument(
    "email", type=str, help="Email is required", required=True)
users_put_args.add_argument(
    "name", type=str, help="Name is required", required=True)
users_put_args.add_argument(
    "age", type=int, help="Age is required", required=True)
users_put_args.add_argument(
    "gender", type=str, help="Gender is required", required=True)


def abort_if_user_already_exists(user_id):
    result = UserModel.query.filter_by(id=user_id).first()
    if result:
        abort(409, message="This user already exists..")


def abort_if_user_does_not_exists(user_id):
    result = UserModel.query.filter_by(id=user_id).first()
    if not result:
        abort(404, message="User does not exist..")


resource_fields = {
    'id': fields.Integer,
    'email': fields.String,
    'name': fields.String,
    'age': fields.Integer,
    'gender': fields.String
}


class Users(Resource):
    @marshal_with(resource_fields)
    def get(self, user_id):
        abort_if_user_does_not_exists(user_id)
        result = UserModel.query.filter_by(id=user_id).first()
        return result, 200

    @marshal_with(resource_fields)
    def put(self, user_id):
        abort_if_user_already_exists(user_id)
        args = users_put_args.parse_args()
        user = UserModel(
            id=user_id, email=args['email'], name=args['name'], age=args['age'], gender=args['gender'])
        db.session.add(user)
        db.session.commit()
        return user, 201

    def delete(self, user_id):
        abort_if_user_does_not_exists(user_id)
        user = UserModel.query.filter_by(id=user_id).first()
        db.session.delete(user)
        db.session.commit()

        return "User deleted successfully", 204


api.add_resource(Users, "/api/users/<int:user_id>")


if __name__ == "__main__":
    app.run(debug=True)

Explanation of Key Concepts

I also created another notebook with sample http requests to handle the methods created above. Attaching it to the post.

Conclusion

Combining Flask with flask_restful and flask_sqlalchemy provides a streamlined approach to building powerful APIs. The use of resources, request parsing, error handling, serialization, and marshaling simplifies the development process and creates scalable and maintainable APIs.

This article has covered the basics of these functionalities, providing a foundation for creating robust RESTful APIs in Python. Explore further to enhance and customize your API based on your specific project requirements.

Happy coding! 🚀