Flask Basics: Your First Web App
Flask is a lightweight Python web framework. It lets you build web applications quickly with minimal boilerplate. Flask is perfect for beginners because it is easy to learn but powerful enough for production use.
This tutorial covers installing Flask, creating your first application, defining routes, using templates, and handling forms.
Installing Flask
Flask is installed via pip. Create a virtual environment first to keep dependencies isolated.
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install flask
Verify the installation.
flask --version
Your First Flask Application
Create a file named app.py. This is your application entry point.
from flask import Flask
app = Flask(__name__)
@app.route("/")
def home():
return "Hello, Flask!"
if __name__ == "__main__":
app.run(debug=True)
Run the application.
python app.py
Open your browser and visit http://127.0.0.1:5000. You should see “Hello, Flask!”.
The @app.route("/") decorator maps the root URL to the home function. When someone visits /, Flask calls home() and returns its response.
Understanding Routes
Routes define URL patterns and which functions handle them. Flask uses decorators to define routes.
@app.route("/about")
def about():
return "This is the about page."
@app.route("/contact")
def contact():
return "Contact us at hello@example.com"
You can also capture variables from the URL.
@app.route("/user/<username>")
def user_profile(username):
return f"Hello, {username}!"
@app.route("/post/<int:post_id>")
def show_post(post_id):
return f"Showing post #{post_id}"
The <username> and <int:post_id> are dynamic segments. Flask converts int: segments to integers automatically.
Using Templates
Returning raw strings is fine for learning, but real applications use HTML templates. Flask looks for templates in a templates folder.
Create this directory structure:
project/
├── app.py
└── templates/
└── index.html
Create templates/index.html:
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>{{ heading }}</h1>
<p>{{ message }}</p>
</body>
</html>
Update app.py to render the template:
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def home():
return render_template(
"index.html",
title="Welcome",
heading="Hello, Flask!",
message="Building web apps with Python is fun."
)
if __name__ == "__main__":
app.run(debug=True)
The render_template function finds the HTML file in the templates folder and substitutes the variables.
Handling Forms
Forms let users submit data to your application. Flask provides the request object to access form data.
Create templates/form.html:
<!DOCTYPE html>
<html>
<head>
<title>Contact Form</title>
</head>
<body>
<h1>Contact Us</h1>
<form method="POST" action="/submit">
<label>Name: <input type="text" name="name" required></label><br>
<label>Email: <input type="email" name="email" required></label><br>
<button type="submit">Send</button>
</form>
</body>
</html>
Create templates/success.html:
<!DOCTYPE html>
<html>
<head>
<title>Success</title>
</head>
<body>
<h1>Thank You!</h1>
<p>We received your message, {{ name }}.</p>
<a href="/form">Send another</a>
</body>
</html>
Update app.py:
from flask import Flask, render_template, request
app = Flask(__name__)
@app.route("/form")
def form():
return render_template("form.html")
@app.route("/submit", methods=["POST"])
def submit():
name = request.form.get("name")
email = request.form.get("email")
return render_template("success.html", name=name)
if __name__ == "__main__":
app.run(debug=True)
The methods=["POST"] argument tells Flask to accept POST requests. Access form data with request.form.get().
The Request-Response Cycle
Understanding how Flask processes requests helps you debug issues.
- A user visits a URL
- Flask matches the URL to a route
- Flask calls the view function
- The view function returns a response
- Flask sends the response to the browser
You can inspect the request object in your views:
from flask import request
@app.route("/debug")
def debug_info():
return {
"method": request.method,
"path": request.path,
"args": request.args,
"headers": dict(request.headers)
}
Debug Mode
Setting debug=True enables auto-reload and the interactive debugger. Changes to your code restart the server automatically.
app.run(debug=True)
In production, always set debug=False. The debugger exposes your code to attackers.
Conclusion
Flask makes web development accessible. You installed Flask, created routes, rendered templates, and handled form submissions. These fundamentals apply to every Flask application.
The next tutorial in this series covers Django, a more feature-complete framework. For now, experiment with Flask — add more routes, create new templates, and explore Flask extensions.