Building a Simple Portfolio Website with Flask

Hello there, aspiring web developers! Have you ever wanted to showcase your projects, skills, and experience online but felt overwhelmed by complex web development tools? Building a personal portfolio website is a fantastic way to introduce yourself to the world, and today, we’re going to make that process simple and fun using a powerful yet easy-to-learn Python framework called Flask.

In this guide, we’ll walk through creating a basic portfolio website from scratch. We’ll cover everything from setting up your development environment to displaying your content using Flask and simple HTML. By the end, you’ll have a foundational understanding of how web applications work and a personal website you can proudly share!

What is Flask?

Before we dive into the code, let’s understand what Flask is.

Flask is a “micro-framework” for building web applications in Python. Think of a web framework as a toolkit that provides all the necessary components and structures to help you build websites or web services more efficiently. Flask is called “micro” because it starts with a minimal core and lets you add only the features you need. This makes it lightweight, flexible, and perfect for beginners or small to medium-sized projects like our portfolio website.

Prerequisites

To follow along with this tutorial, you’ll need a few things installed on your computer:

  • Python: Make sure you have Python 3 installed. You can download it from the official Python website (python.org).
  • pip: This is Python’s package installer, which usually comes bundled with Python. We’ll use it to install Flask.
  • A Text Editor or IDE: Tools like VS Code, Sublime Text, Atom, or PyCharm are excellent choices for writing code.
  • Basic Terminal/Command Line Knowledge: You’ll need to know how to navigate directories and run commands.

Setting Up Your Development Environment

The first step in any Python project is setting up a clean environment. We’ll use a virtual environment to keep our project’s dependencies separate from other Python projects you might have.

What is a Virtual Environment?

A virtual environment (often just called a “venv”) is an isolated Python environment that allows you to install packages (like Flask) specific to a project without affecting your global Python installation or other projects. This prevents conflicts and keeps your project dependencies tidy.

Creating and Activating a Virtual Environment

  1. Create a Project Directory:
    First, create a folder for your portfolio website. Open your terminal or command prompt and run:

    bash
    mkdir my_portfolio_website
    cd my_portfolio_website

  2. Create the Virtual Environment:
    Inside your my_portfolio_website folder, create the virtual environment. We’ll name it .venv (it’s a common convention, and the dot makes it hidden on some systems).

    bash
    python3 -m venv .venv

    (Note: On Windows, you might just use python -m venv .venv)

  3. Activate the Virtual Environment:
    Now, activate it. The command differs slightly between operating systems:

    • macOS/Linux:
      bash
      source .venv/bin/activate
    • Windows (Command Prompt):
      bash
      .venv\Scripts\activate
    • Windows (PowerShell):
      bash
      .venv\Scripts\Activate.ps1

    You’ll know it’s activated when you see (.venv) or a similar name appear at the beginning of your terminal prompt.

Installing Flask

With your virtual environment active, you can now install Flask:

pip install Flask

This command downloads and installs Flask and its necessary components into your virtual environment.

Your First Flask Application

Let’s create a very basic Flask application to make sure everything is working.

  1. Create app.py:
    In your my_portfolio_website directory, create a file named app.py. This will be the main file for our Flask application.

  2. Add the Basic Flask Code:
    Open app.py in your text editor and add the following code:

    “`python
    from flask import Flask

    Create a Flask application instance

    app = Flask(name)

    Define a route for the home page (“/”)

    @app.route(‘/’)
    def home():
    return “Hello, this is my portfolio homepage!”

    Run the application if this script is executed directly

    if name == ‘main‘:
    app.run(debug=True)
    “`

    Explanation:
    * from flask import Flask: This line imports the Flask class from the flask library.
    * app = Flask(__name__): This creates an instance of your Flask application. __name__ helps Flask locate resources like templates and static files.
    * @app.route('/'): This is a decorator. It tells Flask that whenever a user navigates to the root URL (e.g., http://127.0.0.1:5000/), the home() function should be executed. A URL associated with a function is called a route.
    * def home():: This is the function that runs when the / route is accessed. It simply returns a string.
    * if __name__ == '__main__':: This ensures the app.run() command only executes when you run app.py directly (not when it’s imported as a module).
    * app.run(debug=True): This starts the Flask development server. debug=True is very helpful during development because it automatically reloads the server when you make changes and provides detailed error messages. Remember to set debug=False for production applications!

  3. Run Your Flask Application:
    Save app.py and go back to your terminal (with the virtual environment activated). Run your application:

    bash
    python app.py

    You should see output similar to this:

    * Serving Flask app 'app'
    * Debug mode: on
    WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
    * Running on http://127.0.0.1:5000
    Press CTRL+C to quit
    * Restarting with stat
    * Debugger is active!
    * Debugger PIN: ...

    Open your web browser and go to http://127.0.0.1:5000. You should see “Hello, this is my portfolio homepage!” Congratulations, your Flask app is running!

Structuring Your Project with Templates and Static Files

A real website needs more than just text returned from Python functions. It needs HTML files for structure, CSS files for styling, and possibly images or JavaScript. Flask makes this easy with special folders.

  1. Create templates Folder:
    Flask looks for HTML files in a folder named templates within your project directory. Create this folder:

    bash
    mkdir templates

  2. Create static Folder:
    Flask serves CSS, JavaScript, and image files from a folder named static. Create this folder inside your project:

    bash
    mkdir static

    And inside static, it’s good practice to create subfolders for different asset types:
    bash
    mkdir static/css
    mkdir static/img

Your project structure should now look something like this:

my_portfolio_website/
├── .venv/
├── static/
│   ├── css/
│   └── img/
├── templates/
└── app.py

Creating HTML Templates

Now, let’s create some actual web pages using HTML.

What is a Template Engine?

A template engine (like Jinja2, which Flask uses by default) allows you to write HTML files with special placeholders and logic. Flask can then “render” these templates, filling in the placeholders with data from your Python code, making dynamic web pages.

  1. index.html (Home Page):
    Create templates/index.html:

    “`html
    <!DOCTYPE html>




    My Portfolio – Home

    Welcome to My Portfolio!

    <main>
        <section>
            <h2>Hi, I'm [Your Name]</h2>
            <p>I'm an aspiring [Your Profession/Skill] passionate about [Your Interest]. This is where I showcase my projects and skills.</p>
            <p>Explore my work and learn more about me using the navigation above.</p>
        </section>
    </main>
    
    <footer>
        <p>&copy; {{ 2023 }} [Your Name]. All rights reserved.</p>
    </footer>
    



    ``
    **Notice:**
    *
    {{ url_for(‘static’, filename=’css/style.css’) }}: This is a Jinja2 template function.url_for()is a Flask helper that generates URLs for you. Here, it creates the correct path to ourstyle.cssfile in thestatic/cssfolder.
    *
    {{ url_for(‘home’) }}: This generates a URL to the function namedhomein ourapp.py.
    *
    {{ 2023 }}`: A simple example of displaying dynamic data (though a static year is fine here too).

  2. about.html (About Me Page):
    Create templates/about.html:

    “`html
    <!DOCTYPE html>




    My Portfolio – About

    About Me

    <main>
        <section>
            <h2>My Story & Skills</h2>
            <p>I graduated from [Your University/Program] where I specialized in [Your Field]. I'm proficient in:</p>
            <ul>
                <li>Python (Flask, Django)</li>
                <li>HTML, CSS, JavaScript</li>
                <li>[Another Skill, e.g., Database Management]</li>
            </ul>
            <p>I'm passionate about [Your Passion] and constantly looking for new challenges.</p>
        </section>
    </main>
    
    <footer>
        <p>&copy; {{ 2023 }} [Your Name]. All rights reserved.</p>
    </footer>
    



    “`

  3. contact.html (Contact Page):
    Create templates/contact.html:

    “`html
    <!DOCTYPE html>




    My Portfolio – Contact

    Contact Me

    <main>
        <section>
            <h2>Get in Touch!</h2>
            <p>Feel free to reach out to me via email or connect on social media.</p>
            <ul>
                <li>Email: <a href="mailto:your.email@example.com">your.email@example.com</a></li>
                <li>LinkedIn: <a href="https://linkedin.com/in/yourprofile" target="_blank">Your LinkedIn Profile</a></li>
                <li>GitHub: <a href="https://github.com/yourusername" target="_blank">Your GitHub Profile</a></li>
            </ul>
        </section>
    </main>
    
    <footer>
        <p>&copy; {{ 2023 }} [Your Name]. All rights reserved.</p>
    </footer>
    



    “`

Adding Basic Styles

Let’s add a super simple CSS file to static/css/style.css to give our pages a little visual flair.

Create static/css/style.css:

body {
    font-family: 'Arial', sans-serif;
    line-height: 1.6;
    margin: 0;
    padding: 0;
    background: #f4f4f4;
    color: #333;
}

header {
    background: #333;
    color: #fff;
    padding: 1rem 0;
    text-align: center;
}

header h1 {
    margin: 0;
}

nav ul {
    padding: 0;
    list-style: none;
}

nav ul li {
    display: inline;
    margin-right: 20px;
}

nav a {
    color: #fff;
    text-decoration: none;
}

main {
    padding: 20px;
    max-width: 800px;
    margin: auto;
    background: #fff;
    box-shadow: 0 0 10px rgba(0,0,0,0.1);
    margin-top: 20px;
}

footer {
    text-align: center;
    padding: 20px;
    background: #333;
    color: #fff;
    margin-top: 20px;
}

Connecting Flask with Templates

Now we need to update our app.py to render these HTML templates instead of just returning plain strings. We’ll use Flask’s render_template function.

Modify app.py:

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def home():
    return render_template('index.html')

@app.route('/about')
def about():
    return render_template('about.html')

@app.route('/contact')
def contact():
    return render_template('contact.html')

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

Explanation:
* from flask import Flask, render_template: We now import render_template which is essential for serving our HTML files.
* return render_template('index.html'): Instead of a string, each route now calls render_template() with the name of the HTML file it should display. Flask automatically looks for these files in the templates folder.

Save app.py and ensure your Flask application is still running (if not, restart it with python app.py).

Now, open your browser and navigate to:
* http://127.0.0.1:5000/ (Home page)
* http://127.0.0.1:5000/about (About Me page)
* http://127.0.0.1:5000/contact (Contact page)

You should see your HTML pages rendered with the basic styles applied, and you can click the navigation links to move between pages!

Next Steps and Further Improvements

You’ve built a basic, functional portfolio website with Flask! This is just the beginning. Here are some ideas for what you can do next:

  • Add More Pages: Create projects.html or resume.html to showcase your work and experience in more detail.
  • Dynamic Content: Instead of hardcoding text in HTML, you could pass variables from your Flask routes to your templates. For example:
    python
    @app.route('/')
    def home():
    name = "Your Name"
    profession = "Web Developer"
    return render_template('index.html', name=name, profession=profession)

    And in index.html: <h2>Hi, I'm {{ name }}</h2><p>I'm an aspiring {{ profession }}...</p>
  • Add Images: Place images in static/img and reference them in your HTML using url_for('static', filename='img/your_image.jpg').
  • CSS Frameworks: Integrate a CSS framework like Bootstrap or Tailwind CSS for more professional-looking designs without writing a lot of custom CSS.
  • Forms: Implement a real contact form that can send emails.
  • Database Integration: For larger sites, you might use a database (like SQLite with SQLAlchemy) to store project details or blog posts, making your site truly dynamic.
  • Deployment: Learn how to deploy your Flask application to a web server so others can access it online (e.g., Heroku, Render, Vercel, PythonAnywhere).

Conclusion

Building a website might seem daunting, but by breaking it down into smaller steps and using beginner-friendly tools like Flask, it becomes an achievable and rewarding process. You’ve learned how to set up a Python project, create a basic Flask application, use HTML templates, integrate CSS, and navigate between different pages. This foundation will serve you well as you continue your journey in web development. Keep experimenting, keep building, and soon you’ll be creating even more impressive web applications!


Comments

Leave a Reply