Flask is a lightweight and powerful web framework for Python, designed to make web development simple and efficient. Whether you're a beginner or an experienced developer, Flask provides the flexibility to create scalable and maintainable web applications. In this blog, we'll explore the key concepts of Flask, from basic routing to advanced features like database integration and API development.
1. Getting Started with Flask
1.1 Installing Flask
Before you start, make sure you have Python installed. You can install Flask using pip:
pip install flask1.2 Creating a Simple Flask Application
Create a file named app.py and add the following code:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return "Hello, Flask!"
if __name__ == '__main__':
app.run(debug=True)Run the script using:
python app.pyOpen http://127.0.0.1:5000/ in your browser, and you’ll see "Hello, Flask!" displayed.
2. Flask Routing
Flask allows defining routes to handle different URLs.
@app.route('/about')
def about():
return "This is the About page."You can also add dynamic URL parameters:
@app.route('/user/<name>')
def user(name):
return f"Hello, {name}!"3. Flask Templates (Jinja2)
Flask uses Jinja2 for rendering HTML templates.
3.1 Creating a Template
Create a templates folder and add a file named index.html:
<!DOCTYPE html>
<html>
<head>
<title>Flask App</title>
</head>
<body>
<h1>Welcome to Flask</h1>
</body>
</html>3.2 Rendering Templates
Modify app.py to use the template:
from flask import render_template
@app.route('/')
def home():
return render_template('index.html')4. Handling Forms in Flask
Flask supports form handling with Flask-WTF.
4.1 Installing Flask-WTF
pip install flask-wtf4.2 Creating a Form
from flask import Flask, render_template, request
app = Flask(__name__)
app.secret_key = 'your_secret_key'
@app.route('/form', methods=['GET', 'POST'])
def form():
if request.method == 'POST':
name = request.form['name']
return f"Hello, {name}!"
return render_template('form.html')Create form.html in the templates folder:
<form method="post">
<input type="text" name="name" placeholder="Enter your name">
<button type="submit">Submit</button>
</form>5. Flask and Databases
Flask supports multiple databases, with SQLite being the easiest to start with.
5.1 Installing Flask-SQLAlchemy
pip install flask-sqlalchemy5.2 Configuring the Database
from flask_sqlalchemy import SQLAlchemy
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), nullable=False)
db.create_all()6. RESTful APIs with Flask
Flask makes it easy to build RESTful APIs using Flask-RESTful.
6.1 Installing Flask-RESTful
pip install flask-restful6.2 Creating an API Endpoint
from flask_restful import Resource, Api
api = Api(app)
class HelloWorld(Resource):
def get(self):
return {'message': 'Hello, World!'}
api.add_resource(HelloWorld, '/api')Visit http://127.0.0.1:5000/api to see the API response.
7. Deploying a Flask Application
You can deploy your Flask app using services like Heroku or AWS.
7.1 Deploying on Heroku
- Install Heroku CLI:
https://devcenter.heroku.com/articles/heroku-cli Initialize Git and create a
requirements.txtfile:pip freeze > requirements.txtCreate a
Procfile:web: gunicorn app:appDeploy with the following commands:
heroku create git push heroku main heroku open
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_restx import Api, Resource, fields
app = Flask(__name__)
# Configure MySQL Connection
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:root_mysql@localhost:3306/test_db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
# Initialize Flask-RESTx API
api = Api(app, title="User API", description="A simple User CRUD API", doc="/docs")
# Define Namespace
ns = api.namespace("users", description="User Operations")
# Define User Model for Swagger
user_model = api.model("User", {
"id": fields.Integer(readOnly=True, description="User ID"),
"name": fields.String(required=True, description="User Name"),
"email": fields.String(required=True, description="User Email"),
})
# Define User Model in Database
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
def __repr__(self):
return f"<User {self.name}>"
with app.app_context():
db.create_all()
# CRUD API Routes
@ns.route("/")
class UserList(Resource):
@ns.marshal_list_with(user_model)
def get(self):
"""Get all users"""
users = User.query.all()
return users, 200
@ns.expect(user_model)
@ns.marshal_with(user_model, code=201)
def post(self):
"""Create a new user"""
data = request.json
new_user = User(name=data["name"], email=data["email"])
db.session.add(new_user)
db.session.commit()
return new_user, 201
@ns.route("/<int:id>")
@ns.response(404, "User not found")
class UserResource(Resource):
@ns.marshal_with(user_model)
def get(self, id):
"""Get a user by ID"""
user = User.query.get_or_404(id)
return user
@ns.expect(user_model)
@ns.marshal_with(user_model)
def put(self, id):
"""Update a user"""
user = User.query.get_or_404(id)
data = request.json
user.name = data.get("name", user.name)
user.email = data.get("email", user.email)
db.session.commit()
return user
@ns.response(204, "User deleted")
def delete(self, id):
"""Delete a user"""
user = User.query.get_or_404(id)
db.session.delete(user)
db.session.commit()
return "", 204
if __name__ == "__main__":
app.run(debug=True)
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flasgger import Swagger
app = Flask(__name__)
# Swagger Configuration
app.config['SWAGGER'] = {
'title': 'User API',
'description': 'A simple CRUD API for managing users with Flask and SQLAlchemy.',
'uiversion': 3
}
swagger = Swagger(app)
# MySQL Connection
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:root_mysql@localhost:3306/test_db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
# Define User Model
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
def __repr__(self):
return f"<User {self.name}>"
with app.app_context():
db.create_all()
# Routes with Swagger Documentation
@app.route('/users', methods=['POST'])
def create_user():
"""
Create a new user
---
tags:
- Users
parameters:
- name: body
in: body
required: true
schema:
type: object
required:
- name
- email
properties:
name:
type: string
email:
type: string
responses:
201:
description: User created successfully
"""
data = request.get_json()
new_user = User(name=data['name'], email=data['email'])
db.session.add(new_user)
db.session.commit()
return jsonify({'message': 'User created successfully', 'user': {'id': new_user.id, 'name': new_user.name, 'email': new_user.email}}), 201
@app.route('/users', methods=['GET'])
def get_users():
"""
Get all users
---
tags:
- Users
responses:
200:
description: A list of all users
"""
users = User.query.all()
users_list = [{'id': user.id, 'name': user.name, 'email': user.email} for user in users]
return jsonify({'users': users_list})
@app.route('/users/<int:id>', methods=['GET'])
def get_user(id):
"""
Get a user by ID
---
tags:
- Users
parameters:
- name: id
in: path
required: true
type: integer
responses:
200:
description: User details
404:
description: User not found
"""
user = User.query.get(id)
if not user:
return jsonify({'error': 'User not found'}), 404
return jsonify({'id': user.id, 'name': user.name, 'email': user.email})
@app.route('/users/<int:id>', methods=['PUT'])
def update_user(id):
"""
Update a user
---
tags:
- Users
parameters:
- name: id
in: path
required: true
type: integer
- name: body
in: body
required: true
schema:
type: object
properties:
name:
type: string
email:
type: string
responses:
200:
description: User updated successfully
404:
description: User not found
"""
user = User.query.get(id)
if not user:
return jsonify({'error': 'User not found'}), 404
data = request.get_json()
user.name = data.get('name', user.name)
user.email = data.get('email', user.email)
db.session.commit()
return jsonify({'message': 'User updated successfully', 'user': {'id': user.id, 'name': user.name, 'email': user.email}})
@app.route('/users/<int:id>', methods=['DELETE'])
def delete_user(id):
"""
Delete a user
---
tags:
- Users
parameters:
- name: id
in: path
required: true
type: integer
responses:
200:
description: User deleted successfully
404:
description: User not found
"""
user = User.query.get(id)
if not user:
return jsonify({'error': 'User not found'}), 404
db.session.delete(user)
db.session.commit()
return jsonify({'message': 'User deleted successfully'})
if __name__ == '__main__':
app.run(debug=True)
