Python and Flask: Building a Social Network

Table of Contents

  1. Introduction
  2. Prerequisites
  3. Setup
  4. Creating a Flask App
  5. Designing the Database
  6. Creating User Registration
  7. Implementing User Authentication
  8. Creating the User Profile
  9. Building the News Feed
  10. Adding Friendships
  11. Conclusion

Introduction

In this tutorial, we will build a social network using Python and Flask. By the end of this tutorial, you will have a functional social network application that allows users to register, authenticate, create a profile, post updates, and connect with friends.

Prerequisites

Before starting this tutorial, you should have a basic understanding of Python programming. Familiarity with web development concepts such as HTML, CSS, and JavaScript would be beneficial but not required.

Setup

To begin, make sure you have Python installed on your machine. You can download the latest version of Python from the official website.

Next, create a new directory for your project and navigate to that directory in your terminal. $ mkdir social-network-app && cd social-network-app Create a virtual environment for your project to isolate the dependencies. $ python -m venv env Activate the virtual environment.

On macOS and Linux: $ source env/bin/activate On Windows: $ .\env\Scripts\activate Install the required Flask library. $ pip install Flask You are now ready to start building your social network app with Flask!

Creating a Flask App

  1. Create a new Python file app.py in your project directory.

  2. Import the necessary Flask modules.

    from flask import Flask, render_template, request, redirect, url_for
    
  3. Create an instance of the Flask app.

    app = Flask(__name__)
    
  4. Define a route for the home page.

    @app.route('/')
    def home():
        return 'Welcome to the Social Network!'
    
  5. Run the app.

    if __name__ == '__main__':
        app.run(debug=True)
    
  6. Open your browser and visit http://localhost:5000. You should see the message “Welcome to the Social Network!”.

Congratulations! You have successfully created a basic Flask app. Now let’s move on to designing the database.

Designing the Database

Before we can start implementing the features of a social network, we need to design the database structure. In this tutorial, we will use SQLite as our database system.

  1. Create a new Python file models.py in your project directory.

  2. Import the necessary modules.

    import sqlite3
    from flask import g
    
  3. Define the database connection.

    def get_db():
        if 'db' not in g:
            g.db = sqlite3.connect('social_network.db')
            g.db.row_factory = sqlite3.Row
        return g.db
    
  4. Create the necessary tables.

    def init_db():
        db = get_db()
        cursor = db.cursor()
       
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS users (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                username TEXT NOT NULL UNIQUE,
                password TEXT NOT NULL
            )
        ''')
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS posts (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                user_id INTEGER NOT NULL,
                content TEXT NOT NULL,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                FOREIGN KEY (user_id) REFERENCES users (id)
            )
        ''')
       
        db.commit()
       
    if __name__ == '__main__':
        init_db()
    

    This script creates two tables: users and posts. The users table stores information about registered users, including their usernames and passwords. The posts table stores the content of each post, along with the user who created it and the timestamp.

Run the models.py script to create the database and tables. $ python models.py You have now designed the database for your social network app. In the next section, we will implement user registration.

Creating User Registration

Allowing users to register is an essential part of any social network. Let’s implement the user registration feature.

  1. Modify the app.py file to import the necessary modules.

    from flask import Flask, render_template, request, redirect, url_for, flash
    from werkzeug.security import generate_password_hash, check_password_hash
    
  2. Create a route for the registration page.

    @app.route('/register', methods=['GET', 'POST'])
    def register():
        if request.method == 'POST':
            username = request.form['username']
            password = request.form['password']
            confirm_password = request.form['confirm-password']
       
            if password != confirm_password:
                flash('Passwords do not match', 'error')
                return redirect(url_for('register'))
       
            db = get_db()
            cursor = db.cursor()
            cursor.execute('SELECT id FROM users WHERE username = ?', (username,))
            user = cursor.fetchone()
       
            if user is not None:
                flash('Username already exists', 'error')
                return redirect(url_for('register'))
       
            password_hash = generate_password_hash(password)
            cursor.execute('INSERT INTO users (username, password) VALUES (?, ?)', (username, password_hash))
            db.commit()
       
            flash('Registration successful', 'success')
            return redirect(url_for('login'))
       
        return render_template('register.html')
    
  3. Create a template file register.html in a new templates directory.

       
    <!DOCTYPE html>
    <html>
       
    <head>
        <title>Register</title>
    </head>
       
    <body>
        <h1>Register</h1>
       
        {% with messages = get_flashed_messages() %}
            {% if messages %}
                <ul>
                    {% for message in messages %}
                        <li>{{ message }}</li>
                    {% endfor %}
                </ul>
            {% endif %}
        {% endwith %}
       
        <form action="{{ url_for('register') }}" method="POST">
            <label for="username">Username:</label>
            <input type="text" id="username" name="username" required><br>
       
            <label for="password">Password:</label>
            <input type="password" id="password" name="password" required><br>
       
            <label for="confirm-password">Confirm Password:</label>
            <input type="password" id="confirm-password" name="confirm-password" required><br>
       
            <input type="submit" value="Register">
        </form>
    </body>
       
    </html>
       
    
  4. Run the app and visit http://localhost:5000/register. You should see the registration form.

    $ python app.py
    

    Congratulations! You have implemented user registration in your Flask app. Users can now register with a username and password, which will be stored in the database.

In the next section, we will implement user authentication to allow registered users to log in.

Implementing User Authentication

Authenticating users is crucial to ensure that only registered users can access the social network’s features. Let’s implement user authentication.

  1. Modify the app.py file to import the necessary module.

    from flask_login import LoginManager, login_user, login_required, current_user, logout_user
    
  2. Create a route for the login page.

    @app.route('/login', methods=['GET', 'POST'])
    def login():
        if request.method == 'POST':
            username = request.form['username']
            password = request.form['password']
       
            db = get_db()
            cursor = db.cursor()
            cursor.execute('SELECT * FROM users WHERE username = ?', (username,))
            user = cursor.fetchone()
       
            if user is None or not check_password_hash(user['password'], password):
                flash('Invalid username or password', 'error')
                return redirect(url_for('login'))
       
            login_user(user)
            return redirect(url_for('profile'))
       
        return render_template('login.html')
    
  3. Create a template file login.html in the templates directory.

       
    <!DOCTYPE html>
    <html>
       
    <head>
        <title>Login</title>
    </head>
       
    <body>
        <h1>Login</h1>
       
        {% with messages = get_flashed_messages() %}
            {% if messages %}
                <ul>
                    {% for message in messages %}
                        <li>{{ message }}</li>
                    {% endfor %}
                </ul>
            {% endif %}
        {% endwith %}
       
        <form action="{{ url_for('login') }}" method="POST">
            <label for="username">Username:</label>
            <input type="text" id="username" name="username" required><br>
       
            <label for="password">Password:</label>
            <input type="password" id="password" name="password" required><br>
       
            <input type="submit" value="Login">
        </form>
    </body>
       
    </html>
       
    
  4. Initialize the login manager in the app.py file.

    login_manager = LoginManager(app)
    login_manager.login_view = 'login'
       
    @login_manager.user_loader
    def load_user(user_id):
        db = get_db()
        cursor = db.cursor()
        cursor.execute('SELECT * FROM users WHERE id = ?', (user_id,))
        user = cursor.fetchone()
        return user
    
  5. Add a logout route.

    @app.route('/logout')
    @login_required
    def logout():
        logout_user()
        return redirect(url_for('home'))
    
  6. Run the app and visit http://localhost:5000/login. You should see the login form.

    $ python app.py
    

    Congratulations! You have implemented user authentication in your Flask app. Users can now register, log in, and log out of the social network.

In the next section, we will create the user profile page.

Creating the User Profile

Every social network needs a user profile page where users can view and update their information. Let’s create the user profile page.

  1. Create a route for the user profile page.

    @app.route('/profile')
    @login_required
    def profile():
        return render_template('profile.html', user=current_user)
    
  2. Create a template file profile.html in the templates directory.

       
    <!DOCTYPE html>
    <html>
       
    <head>
        <title>Profile</title>
    </head>
       
    <body>
        <h1>Welcome, {{ user.username }}!</h1>
       
        <h2>Profile Information</h2>
        <p>Username: {{ user.username }}</p>
       
        <h2>Update Profile</h2>
        <form action="{{ url_for('update_profile') }}" method="POST">
            <label for="new-username">New Username:</label>
            <input type="text" id="new-username" name="new-username" required><br>
       
            <input type="submit" value="Update">
        </form>
    </body>
       
    </html>
       
    
  3. Create a route for updating the user profile.

    @app.route('/update-profile', methods=['POST'])
    @login_required
    def update_profile():
        new_username = request.form['new-username']
       
        db = get_db()
        cursor = db.cursor()
        cursor.execute('UPDATE users SET username = ? WHERE id = ?', (new_username, current_user['id']))
        db.commit()
       
        flash('Profile updated', 'success')
        return redirect(url_for('profile'))
    
  4. Run the app and log in. Visit http://localhost:5000/profile to view the user profile page.

    $ python app.py
    

    Congratulations! You have created the user profile page in your Flask app. Users can now view their profile information and update their username.

In the next section, we will build the news feed feature.

Building the News Feed

One of the main features of a social network is the ability to post updates and view them in a news feed. Let’s build the news feed feature.

  1. Create a route for the news feed.

    @app.route('/news-feed')
    @login_required
    def news_feed():
        db = get_db()
        cursor = db.cursor()
        cursor.execute('SELECT * FROM posts ORDER BY created_at DESC')
        posts = cursor.fetchall()
       
        return render_template('news_feed.html', posts=posts)
    
  2. Create a template file news_feed.html in the templates directory.

       
    <!DOCTYPE html>
    <html>
       
    <head>
        <title>News Feed</title>
    </head>
       
    <body>
        <h1>News Feed</h1>
       
        <h2>Create New Post</h2>
        <form action="{{ url_for('create_post') }}" method="POST">
            <textarea id="post-content" name="post-content" rows="4" cols="50" required></textarea><br>
       
            <input type="submit" value="Post">
        </form>
       
        <h2>Recent Posts</h2>
        {% for post in posts %}
            <div>
                <h3>{{ post['username'] }}</h3>
                <p>{{ post['content'] }}</p>
                <p>{{ post['created_at'] }}</p>
            </div>
        {% endfor %}
    </body>
       
    </html>
       
    
  3. Create a route for creating a new post.

    @app.route('/create-post', methods=['POST'])
    @login_required
    def create_post():
        post_content = request.form['post-content']
       
        db = get_db()
        cursor = db.cursor()
        cursor.execute('INSERT INTO posts (user_id, content) VALUES (?, ?)', (current_user['id'], post_content))
        db.commit()
       
        return redirect(url_for('news_feed'))
    
  4. Run the app and log in. Visit http://localhost:5000/news-feed to view the news feed.

    $ python app.py
    

    Congratulations! You have built the news feed feature in your Flask app. Users can now post updates and view them in the news feed.

In the final section, we will add the ability to connect with friends.

Adding Friendships

A crucial aspect of any social network is the ability to connect and interact with friends. Let’s implement the feature to add and view friends.

  1. Modify the app.py file to add routes for adding friends and viewing friends.

    ```python @app.route(‘/add-friend/') @login_required def add_friend(user_id): db = get_db() cursor = db.cursor() cursor.execute('SELECT id FROM users WHERE id = ?', (user_id,)) user = cursor.fetchone()

    if user is None:
        flash('User not found', 'error')
        return redirect(url_for('news_feed'))
       
    if user['id'] == current_user['id']:
        flash('You cannot add yourself as a friend', 'error')
        return redirect(url_for('profile'))
       
    cursor.execute('INSERT INTO friendships (user_id, friend_id) VALUES (?, ?)', (current_user['id'], user['id']))
    db.commit()
       
    flash('Friend added', 'success')
    return redirect(url_for('profile'))
    

    @app.route(‘/friends’) @login_required def friends(): db = get_db() cursor