Introduction to Flask Framework

Introduction to Flask Framework

So, you’re diving into web development with Python? Good choice! One of the best tools you can pick up early is Flask. It’s a lightweight, flexible, and beginner-friendly web framework that helps you build web applications quickly and with minimal overhead. If you're coming from another language or just starting out, Flask’s simplicity and modular design make it an ideal starting point.

Let’s get you set up. First things first—you’ll need Python installed. I’m assuming you already have it. Next, install Flask using pip. Open your terminal or command prompt and type:

pip install Flask

That’s it! Flask is now ready to use.

Let’s write your first Flask application—a classic "Hello, World!" example. Create a new Python file (let’s call it app.py) and type the following:

from flask import Flask
app = Flask(__name__)

@app.route('/')
def home():
    return 'Hello, World!'

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

Save the file and run it with:

python app.py

Open your browser and go to http://127.0.0.1:5000. You should see "Hello, World!" displayed. Congratulations—you’ve just built your first web app with Flask!

In that snippet, a few important things happened: - We imported the Flask class. - We created an instance of a Flask application. - We defined a route for the root URL (/) that returns a simple string. - We started the development server with debug=True, which is useful during development because it automatically reloads the app when you make changes.

Now, let’s unpack some core concepts.

Routing and Views

In Flask, routes map URLs to Python functions. These functions are called view functions. Each time a user visits a URL, the corresponding view function runs and returns a response—usually HTML, but it can be plain text, JSON, or anything else.

You can add more routes easily. For example:

@app.route('/about')
def about():
    return 'This is the about page.'

Now, visiting http://127.0.0.1:5000/about will show the about page.

You can also create dynamic routes by using variable rules. For instance:

@app.route('/user/<username>')
def show_user(username):
    return f'Hello, {username}!'

If you visit /user/Alice, the page will display "Hello, Alice!". The <username> part is a variable that gets passed to your function.

HTTP Method Common Use Case
GET Retrieve data
POST Submit data
PUT Update data
DELETE Remove data

By default, routes only respond to GET requests. You can specify others using the methods parameter:

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        # Handle login logic
        return 'Logging in...'
    else:
        return 'Show login form'

This brings us to handling user input.

Handling Requests and Responses

To work with data sent by users (e.g., form submissions), you need to import request from Flask:

from flask import request

Let’s create a simple form handler:

@app.route('/submit', methods=['POST'])
def submit():
    name = request.form['name']
    return f'Thanks, {name}!'

Of course, in a real application, you’d want to validate and sanitize input—always important for security.

You can also return more than just strings. Flask allows you to return tuples, dictionaries (which are converted to JSON), or even use the jsonify function for cleaner JSON responses:

from flask import jsonify

@app.route('/api/data')
def return_json():
    return jsonify({'name': 'Alice', 'age': 30})

This is great for building APIs!

Templates with Jinja2

Returning plain strings or JSON is useful, but most web apps need to render HTML. Instead of embedding HTML in your Python code (which gets messy fast), Flask uses a templating engine called Jinja2 to separate presentation from logic.

First, create a folder named templates in your project directory. Inside, create an HTML file—let’s call it index.html:

<!DOCTYPE html>
<html>
<head>
    <title>My Flask App</title>
</head>
<body>
    <h1>Hello, {{ name }}!</h1>
</body>
</html>

Notice the {{ name }} part—this is a Jinja2 variable that will be replaced with actual data.

Now, update your view function to render this template:

from flask import render_template

@app.route('/hello/<name>')
def hello(name):
    return render_template('index.html', name=name)

When you visit /hello/Bob, Jinja2 inserts "Bob" into the template, and the browser displays "Hello, Bob!".

Jinja2 also supports: - Control structures like {% for item in items %} loops and {% if condition %} statements. - Template inheritance, letting you create a base template and extend it in other files, reducing repetition.

Here’s a quick example of template inheritance:

base.html:

<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}Default Title{% endblock %}</title>
</head>
<body>
    {% block content %}
    {% endblock %}
</body>
</html>

home.html:

{% extends "base.html" %}

{% block title %}Home Page{% endblock %}

{% block content %}
    <h1>Welcome to the home page!</h1>
{% endblock %}

Then in your view:

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

This keeps your code organized and maintainable.

Working with Static Files

Web apps aren’t just HTML—they need CSS, JavaScript, and images. Flask serves these static files from a folder named static. Create a static folder in your project directory, and place your files there (e.g., style.css).

Reference them in your templates like this:

<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">

The url_for function generates the correct URL for the static file.

Let’s talk about managing application state.

Sessions and Cookies

Sometimes you need to remember information about the user between requests—like whether they’re logged in. Flask supports sessions, which use cookies to store data securely on the client side.

To use sessions, you need to set a secret key (used to sign the cookies for security):

app.secret_key = 'your_secret_key_here'  # Make this random and secure!

Then, you can use the session object:

from flask import session

@app.route('/set')
def set_session():
    session['user'] = 'Alice'
    return 'Session set!'

@app.route('/get')
def get_session():
    return session.get('user', 'Not set')

Sessions are encrypted, so users can’t tamper with them—but always use a strong, random secret key in production.

Database Integration

Most applications need to store data. Flask doesn’t include a database layer by default, but it works well with many libraries. A common choice is SQLAlchemy for relational databases or MongoEngine for MongoDB.

Here’s a minimal example using SQLAlchemy with Flask-SQLAlchemy:

First, install it:

pip install Flask-SQLAlchemy

Then, in your app:

from flask_sqlalchemy import SQLAlchemy

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mydatabase.db'
db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), unique=True, nullable=False)

    def __repr__(self):
        return f'<User {self.name}>'

Create the database and table:

with app.app_context():
    db.create_all()

Now you can add and query users:

new_user = User(name='Alice')
db.session.add(new_user)
db.session.commit()

users = User.query.all()

This is just a glimpse—databases are a deep topic, but Flask’s ecosystem makes integration straightforward.

Error Handling

Things don’t always go right. You can define custom error pages for different HTTP status codes:

@app.errorhandler(404)
def page_not_found(error):
    return render_template('404.html'), 404

Create a 404.html template in your templates folder, and whenever a 404 error occurs, users will see your custom page.

Organizing Larger Applications

As your app grows, you’ll want to organize it better. Instead of putting everything in one file, you can use Blueprints to modularize your application.

Create a blueprint for, say, a blog feature:

blog.py:

from flask import Blueprint

bp = Blueprint('blog', __name__)

@bp.route('/blog')
def blog_home():
    return "Blog home page"

In your main app:

from blog import bp
app.register_blueprint(bp)

Now all blog-related routes are organized separately. This is especially useful for large applications with multiple components.

Deployment

Once your app is ready, you’ll want to deploy it. For production, don’t use Flask’s built-in server—it’s not designed for heavy traffic. Instead, use a production WSGI server like Gunicorn or uWSGI, often behind a reverse proxy like Nginx.

Install Gunicorn:

pip install gunicorn

Then run your app with:

gunicorn -w 4 app:app

This starts four worker processes to handle requests.

Here are three things to remember for deployment: - Set debug=False in production. - Use environment variables for configuration (like secret keys). - Consider using a platform like Heroku, AWS, or DigitalOcean for hosting.

Useful Extensions

One of Flask’s strengths is its extensibility. Here are some popular extensions:

  • Flask-Login: Handles user authentication.
  • Flask-WTF: Simplifies form creation and validation.
  • Flask-Mail: Sends emails from your app.
  • Flask-RESTful: Helps build REST APIs.

To use an extension, usually you install it with pip and initialize it with your app:

from flask_login import LoginManager

login_manager = LoginManager()
login_manager.init_app(app)

Always check the extension’s documentation for detailed usage.

Best Practices

As you build with Flask, keep these tips in mind: - Keep your application instance in a separate file (like app.py) and import it elsewhere to avoid circular imports. - Use configuration classes or environment variables to manage settings for development, testing, and production. - Validate and sanitize all user input to prevent security issues like SQL injection or XSS. - Write unit tests for your views and logic. Flask provides a test client that makes this easier.

Example of a simple test:

def test_home_page():
    with app.test_client() as client:
        response = client.get('/')
        assert response.status_code == 200
        assert b'Hello, World!' in response.data

Testing might seem like extra work, but it pays off by catching bugs early.

Extension Name Primary Use Case
Flask-Login User session management
Flask-SQLAlchemy Database integration
Flask-WTF Form handling
Flask-Mail Email functionality
Flask-RESTful Building REST APIs

Flask is powerful because it gives you the freedom to choose the tools you need. You can start small and add functionality as your project grows.

I hope this introduction helps you get started with Flask. It’s a fantastic framework that balances simplicity with flexibility. Remember, the best way to learn is by building—so try creating a small project, like a personal blog or a to-do list app. Experiment, make mistakes, and most importantly, have fun coding!

If you run into issues, the Flask documentation is excellent, and there’s a large community ready to help. Happy Flask building