Flask is a micro - framework for Python. It is minimalistic, meaning it provides only the essential components for building web applications, such as routing, request handling, and response generation. This allows developers to have more control over the application’s structure and choose the additional libraries they need.
A RESTful API (Representational State Transfer) is a set of rules for creating web services. In the context of a social media app backend, a RESTful API allows clients (such as mobile apps or web browsers) to interact with the server by sending HTTP requests (GET, POST, PUT, DELETE) to specific endpoints. For example, a client can send a GET request to retrieve a list of posts or a POST request to create a new post.
A social media app requires a database to store user information, posts, and relationships between users. Flask can be integrated with various databases, such as SQLite, MySQL, or PostgreSQL. SQLite is a lightweight option suitable for development and testing, while MySQL and PostgreSQL are more robust and suitable for production environments.
Users need to create an account and log in to access the social media app. The backend should handle user registration by storing user information (such as username, password, and email) in the database and verify user credentials during login.
Users can create and share posts, which can include text, images, or links. The backend should handle the creation of posts, store them in the database, and provide endpoints for retrieving posts.
Users can follow other users to see their posts in their feed. The backend should manage the relationships between users and update the user’s feed accordingly.
Users can comment on and like posts. The backend should handle the creation and retrieval of comments and likes and update the post’s metadata accordingly.
python3 -m venv venv
source venv/bin/activate
pip install flask flask_sqlalchemy flask_bcrypt
# app.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'Hello, Social Media App!'
if __name__ == '__main__':
app.run(debug=True)
# app.py
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///social_media.db'
db = SQLAlchemy(app)
bcrypt = Bcrypt(app)
# User model
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
password = db.Column(db.String(120), nullable=False)
def __repr__(self):
return '<User %r>' % self.username
# Create tables
with app.app_context():
db.create_all()
# User registration
@app.route('/register', methods=['POST'])
def register():
data = request.get_json()
username = data.get('username')
password = data.get('password')
if not username or not password:
return jsonify({'message': 'Username and password are required'}), 400
hashed_password = bcrypt.generate_password_hash(password).decode('utf-8')
new_user = User(username=username, password=hashed_password)
try:
db.session.add(new_user)
db.session.commit()
return jsonify({'message': 'User registered successfully'}), 201
except:
return jsonify({'message': 'Username already exists'}), 400
# User login
@app.route('/login', methods=['POST'])
def login():
data = request.get_json()
username = data.get('username')
password = data.get('password')
user = User.query.filter_by(username=username).first()
if user and bcrypt.check_password_hash(user.password, password):
return jsonify({'message': 'Login successful'}), 200
else:
return jsonify({'message': 'Invalid username or password'}), 401
# app.py (continued)
# Post model
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
content = db.Column(db.Text, nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
user = db.relationship('User', backref=db.backref('posts', lazy=True))
def __repr__(self):
return '<Post %r>' % self.content
# Create tables
with app.app_context():
db.create_all()
# Create a new post
@app.route('/posts', methods=['POST'])
def create_post():
data = request.get_json()
content = data.get('content')
user_id = data.get('user_id')
if not content or not user_id:
return jsonify({'message': 'Content and user ID are required'}), 400
new_post = Post(content=content, user_id=user_id)
try:
db.session.add(new_post)
db.session.commit()
return jsonify({'message': 'Post created successfully'}), 201
except:
return jsonify({'message': 'Failed to create post'}), 400
# Get all posts
@app.route('/posts', methods=['GET'])
def get_posts():
posts = Post.query.all()
post_list = []
for post in posts:
post_data = {
'id': post.id,
'content': post.content,
'user_id': post.user_id
}
post_list.append(post_data)
return jsonify(post_list), 200
# app.py (continued)
# Follow model
class Follow(db.Model):
id = db.Column(db.Integer, primary_key=True)
follower_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
followed_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
follower = db.relationship('User', foreign_keys=[follower_id], backref=db.backref('following', lazy=True))
followed = db.relationship('User', foreign_keys=[followed_id], backref=db.backref('followers', lazy=True))
# Create tables
with app.app_context():
db.create_all()
# Follow a user
@app.route('/follow', methods=['POST'])
def follow_user():
data = request.get_json()
follower_id = data.get('follower_id')
followed_id = data.get('followed_id')
if not follower_id or not followed_id:
return jsonify({'message': 'Follower ID and followed ID are required'}), 400
new_follow = Follow(follower_id=follower_id, followed_id=followed_id)
try:
db.session.add(new_follow)
db.session.commit()
return jsonify({'message': 'Followed successfully'}), 201
except:
return jsonify({'message': 'Failed to follow user'}), 400
# Unfollow a user
@app.route('/unfollow', methods=['DELETE'])
def unfollow_user():
data = request.get_json()
follower_id = data.get('follower_id')
followed_id = data.get('followed_id')
follow = Follow.query.filter_by(follower_id=follower_id, followed_id=followed_id).first()
if follow:
try:
db.session.delete(follow)
db.session.commit()
return jsonify({'message': 'Unfollowed successfully'}), 200
except:
return jsonify({'message': 'Failed to unfollow user'}), 400
else:
return jsonify({'message': 'You are not following this user'}), 400
Creating a social media app backend with Flask is a challenging but achievable task. By understanding the core concepts, typical usage scenarios, and following best practices, you can build a robust and scalable backend for your social media app. Remember to pay attention to security, scalability, and error handling to ensure the reliability of your application.