Welcome back, @name! Darwin here, ready to show you Flask - the most popular web microframework in Python! ππ
In the previous lesson you learned frontend basics (HTML, CSS, JavaScript). Now we'll combine that with Python using Flask! π
Safari Analogy: Flask is like a mobile research center - lightweight, flexible, you can easily move it anywhere and quickly start observations! You don't need a huge laboratory (Django) to begin research. ππ¬
Flask is a microframework for web development written in Python by Armin Ronacher in 2010.
Microframework = a minimalist framework with basic features that you can extend with plugins.
| Flask | Django | |-------|--------| | Microframework - minimalist | Full-stack framework - all-in-one | | Flexible, modular | Opinionated, conventions | | Great for small/medium projects | Great for large projects | | You choose components yourself | Everything out-of-the-box | | ~10 lines for Hello World | ~50 lines for Hello World | | Great for learning! | More complex |
Analogy: Flask is a research tent (quick setup), Django is a full laboratory (long configuration, but all tools included). ποΈπ’
β Simple - minimal learning curve β Flexible - you choose the components β Lightweight - small app, fast start β Pythonic - clean, readable code β Great documentation - easy to learn β Large community - plenty of plugins
Flask use cases:
Flask is installed via `pip` like any Python package.
Always use a virtual environment for Python projects!
1# Create project folder
2mkdir safari_web
3cd safari_web
4
5# Create virtual environment
6python -m venv venv
7
8# Activate environment
9# Windows:
10venv\\Scripts\\activate
11# Mac/Linux:
12source venv/bin/activateAnalogy: A virtual environment is like a separate enclosure for your project - libraries from one project won't conflict with others! π¦π
1# Install Flask
2pip install Flask
3
4# Check version
5flask --version
6# Output: Python 3.11.0
7# Flask 3.0.0
8# Werkzeug 3.0.0Flask automatically installs:
1# Save dependencies
2pip freeze > requirements.txt
3
4# Contents of requirements.txt:
5Flask==3.0.0
6Werkzeug==3.0.0
7Jinja2==3.1.2
8...Why? Other developers can install the same versions:
1pip install -r requirements.txtTime for your first Flask program! We'll create a page displaying "Hello Safari!" π¦
1# app.py
2from flask import Flask
3
4# Create Flask application instance
5app = Flask(__name__)
6
7# Define a route (URL address)
8@app.route('/')
9def hello():
10 return "Hello Safari! π¦"
11
12# Run the development server
13if __name__ == '__main__':
14 app.run(debug=True)What's happening?
`Flask(name)` - creates an application instance
`@app.route('/')` - decorator defining a route (URL path)
`def hello()` - view function
`app.run(debug=True)` - starts the development server
1python app.pyOutput:
1 * Serving Flask app 'app'
2 * Debug mode: on
3WARNING: This is a development server. Do not use it in a production deployment.
4 * Running on http://127.0.0.1:5000
5Press CTRL+C to quit
6 * Restarting with stat
7 * Debugger is active!Go to: http://localhost:5000/
You'll see: Hello Safari! π¦
Congratulations! You just created your first Flask application! π
Let's analyze in more detail how Flask works.
1from flask import Flask
2
3app = Flask(__name__)`Flask(name)` creates an application object:
Route = mapping URL β function
1@app.route('/species')
2def list_species():
3 return "List of all species"
4
5@app.route('/species/lion')
6def show_lion():
7 return "Lion details"How it works?
Analogy: A route is like a safari trail - each trail leads to a different habitat (view function)! π€οΈπ¦
View function = a function that returns an HTTP response
1@app.route('/')
2def home():
3 return "<h1>Safari Database</h1><p>Welcome to the system!</p>"What can you return?
1if __name__ == '__main__':
2 app.run(debug=True)Parameters of `app.run()`:
β οΈ IMPORTANT: NEVER use `debug=True` in production!
Let's create a simple Safari Database application with several routes! π¦π
1# app.py
2from flask import Flask
3
4app = Flask(__name__)
5
6# Test data
7species = [
8 {"id": 1, "name": "Lion", "scientific_name": "Panthera leo", "population": 120},
9 {"id": 2, "name": "African Elephant", "scientific_name": "Loxodonta africana", "population": 450},
10 {"id": 3, "name": "Cheetah", "scientific_name": "Acinonyx jubatus", "population": 7100},
11]
12
13# Route 1: Home page
14@app.route('/')
15def home():
16 html = """
17 <!DOCTYPE html>
18 <html>
19 <head>
20 <title>Safari Database</title>
21 <style>
22 body {
23 font-family: Arial, sans-serif;
24 max-width: 800px;
25 margin: 50px auto;
26 padding: 20px;
27 background-color: #f4f1de;
28 }
29 h1 { color: #2c5f2d; }
30 nav { margin: 20px 0; }
31 nav a {
32 margin-right: 15px;
33 color: #2c5f2d;
34 text-decoration: none;
35 font-weight: bold;
36 }
37 nav a:hover { text-decoration: underline; }
38 </style>
39 </head>
40 <body>
41 <h1>π¦ Safari Database π</h1>
42 <p>African species data management system</p>
43
44 <nav>
45 <a href="/">Home</a>
46 <a href="/species">Species list</a>
47 <a href="/about">About</a>
48 </nav>
49
50 <h2>Welcome to Safari Database!</h2>
51 <p>The database contains <strong>{} species</strong>.</p>
52 <p><a href="/species">See full species list β</a></p>
53 </body>
54 </html>
55 """.format(len(species))
56
57 return html
58
59# Route 2: Species list
60@app.route('/species')
61def list_species():
62 species_html = ""
63 for spec in species:
64 species_html += f"""
65 <div style="background: white; padding: 15px; margin: 10px 0; border-radius: 8px; border-left: 4px solid #2c5f2d;">
66 <h3>{spec['name']}</h3>
67 <p><strong>Scientific name:</strong> {spec['scientific_name']}</p>
68 <p><strong>Population:</strong> {spec['population']} individuals</p>
69 <a href="/species/{spec['id']}">See details β</a>
70 </div>
71 """
72
73 html = f"""
74 <!DOCTYPE html>
75 <html>
76 <head>
77 <title>Species list - Safari Database</title>
78 <style>
79 body {{
80 font-family: Arial, sans-serif;
81 max-width: 800px;
82 margin: 50px auto;
83 padding: 20px;
84 background-color: #f4f1de;
85 }}
86 h1 {{ color: #2c5f2d; }}
87 nav {{ margin: 20px 0; }}
88 nav a {{
89 margin-right: 15px;
90 color: #2c5f2d;
91 text-decoration: none;
92 font-weight: bold;
93 }}
94 nav a:hover {{ text-decoration: underline; }}
95 </style>
96 </head>
97 <body>
98 <h1>π¦ Species list</h1>
99
100 <nav>
101 <a href="/">Home</a>
102 <a href="/species">Species list</a>
103 <a href="/about">About</a>
104 </nav>
105
106 <p>Total: <strong>{len(species)} species</strong></p>
107
108 {species_html}
109
110 <p><a href="/">β Back to home page</a></p>
111 </body>
112 </html>
113 """
114
115 return html
116
117# Route 3: Species details (dynamic URL)
118@app.route('/species/<int:species_id>')
119def show_species(species_id):
120 # Find species by ID
121 spec = next((s for s in species if s['id'] == species_id), None)
122
123 if spec is None:
124 return "<h1>404 - Species not found</h1><a href='/species'>Back to list</a>", 404
125
126 html = f"""
127 <!DOCTYPE html>
128 <html>
129 <head>
130 <title>{spec['name']} - Safari Database</title>
131 <style>
132 body {{
133 font-family: Arial, sans-serif;
134 max-width: 800px;
135 margin: 50px auto;
136 padding: 20px;
137 background-color: #f4f1de;
138 }}
139 h1 {{ color: #2c5f2d; }}
140 .card {{
141 background: white;
142 padding: 30px;
143 border-radius: 12px;
144 border: 3px solid #2c5f2d;
145 }}
146 </style>
147 </head>
148 <body>
149 <h1>π¦ {spec['name']}</h1>
150
151 <div class="card">
152 <h2>{spec['name']}</h2>
153 <p><strong>Scientific name:</strong> <em>{spec['scientific_name']}</em></p>
154 <p><strong>Population:</strong> {spec['population']} individuals</p>
155 <p><strong>System ID:</strong> {spec['id']}</p>
156 </div>
157
158 <p style="margin-top: 20px;">
159 <a href="/species">β Back to species list</a> |
160 <a href="/">β Home page</a>
161 </p>
162 </body>
163 </html>
164 """
165
166 return html
167
168# Route 4: About the system
169@app.route('/about')
170def about():
171 html = """
172 <!DOCTYPE html>
173 <html>
174 <head>
175 <title>About - Safari Database</title>
176 <style>
177 body {
178 font-family: Arial, sans-serif;
179 max-width: 800px;
180 margin: 50px auto;
181 padding: 20px;
182 background-color: #f4f1de;
183 }
184 h1 { color: #2c5f2d; }
185 </style>
186 </head>
187 <body>
188 <h1>π¦ About Safari Database</h1>
189
190 <p><strong>Safari Database</strong> is an African species data management system.</p>
191
192 <h2>Technologies:</h2>
193 <ul>
194 <li>Flask 3.0 - web microframework</li>
195 <li>Python 3.11 - programming language</li>
196 <li>HTML/CSS - frontend</li>
197 </ul>
198
199 <h2>Features:</h2>
200 <ul>
201 <li>Browse species list</li>
202 <li>Details for each species</li>
203 <li>Population statistics</li>
204 </ul>
205
206 <p><a href="/">β Back to home page</a></p>
207 </body>
208 </html>
209 """
210
211 return html
212
213# Run development server
214if __name__ == '__main__':
215 print("π¦ Safari Database starting...")
216 print("π‘ Server available at: http://localhost:5000/")
217 app.run(debug=True)1python app.pyOpen in browser:
Also check errors:
Flask allows dynamic URLs with parameters:
1# Basic parameter (string)
2@app.route('/user/<username>')
3def show_user(username):
4 return f"User: {username}"
5
6# Int type parameter
7@app.route('/species/<int:species_id>')
8def show_species(species_id):
9 return f"Species ID: {species_id}"
10
11# Float type parameter
12@app.route('/price/<float:price>')
13def show_price(price):
14 return f"Price: {price:.2f}"
15
16# Path parameter (can contain /)
17@app.route('/file/<path:filepath>')
18def show_file(filepath):
19 return f"File: {filepath}"Converter types:
URL examples:
1/user/darwin β username="darwin"
2/species/42 β species_id=42
3/price/19.99 β price=19.99
4/file/images/lion.jpg β filepath="images/lion.jpg"Flask by default handles only GET requests. You can add other methods:
1from flask import request
2
3# GET only (default)
4@app.route('/species')
5def list_species():
6 return "Species list (GET)"
7
8# GET and POST
9@app.route('/species', methods=['GET', 'POST'])
10def species():
11 if request.method == 'POST':
12 # Handle form
13 name = request.form['name']
14 return f"Species added: {name}"
15 else:
16 # Display form
17 return """
18 <form method="POST">
19 <input type="text" name="name" placeholder="Species name">
20 <button type="submit">Add</button>
21 </form>
22 """
23
24# POST only
25@app.route('/api/species', methods=['POST'])
26def create_species():
27 return "Species created (POST only)"HTTP Methods:
Debug mode (`debug=True`) enables:
The server automatically restarts after code changes!
1app.run(debug=True)Test it:
When an error occurs, Flask shows an interactive debugger in the browser:
1@app.route('/error')
2def error():
3 result = 10 / 0 # Error: division by zero!
4 return "This won't be reached"Visit `/error` β you'll see a detailed traceback with the ability to inspect variables!
Flask shows exact error information instead of a generic "500 Internal Server Error".
β οΈ IMPORTANT: NEVER use `debug=True` in production - it shows source code and allows code execution!
Instead of `python app.py` you can use Flask CLI:
1# Set environment variable
2export FLASK_APP=app.py
3export FLASK_DEBUG=1 # Enable debug mode
4
5# Run server
6flask run
7
8# Run on different port
9flask run --port 8000
10
11# Accessible from other devices
12flask run --host=0.0.0.0Windows (PowerShell):
1$env:FLASK_APP = "app.py"
2$env:FLASK_DEBUG = "1"
3flask runA simple Flask project can look like this:
1safari_web/
2β
3βββ venv/ # Virtual environment (don't commit to git!)
4β
5βββ app.py # Main application
6β
7βββ requirements.txt # Dependencies (pip freeze)
8β
9βββ static/ # Static files (CSS, JS, images)
10β βββ css/
11β β βββ style.css
12β βββ js/
13β β βββ script.js
14β βββ images/
15β βββ logo.png
16β
17βββ templates/ # HTML templates (Jinja2)
18β βββ base.html
19β βββ home.html
20β βββ species.html
21β
22βββ .gitignore # Ignore venv/, __pycache__/, etc.In the next lesson we'll learn to use templates instead of hardcoded HTML strings! π¨
In this lesson you learned:
Final Safari Analogy: Flask is a mobile research center - lightweight, sets up quickly, you can start observations in minutes! You don't need a huge laboratory (Django) to begin Safari research! ππ¬
You created a functioning web application with:
Next lesson: Darwin will show you routing and view functions - advanced techniques for creating routes, redirects, error handlers! π€οΈπ