Witaj z powrotem, @name! Darwin tutaj, gotowy pokazać Ci Flask - najpopularniejszy mikroframework webowy w Pythonie! 🐍🌐
W poprzedniej lekcji poznałeś/aś podstawy frontendu (HTML, CSS, JavaScript). Teraz połączymy to z Pythonem używając Flask! 🔗
Analogia Safari: Flask to jak mobilne centrum badawcze - lekkie, elastyczne, możesz je łatwo przenieść w dowolne miejsce i szybko zacząć obserwacje! Nie potrzebujesz ogromnego laboratorium (Django), aby rozpocząć badania. 🚐🔬
Flask to mikroframework webowy napisany w Pythonie przez Armina Ronachera w 2010 roku.
Mikroframework = minimalistyczny framework z podstawowymi funkcjami, który możesz rozbudować wtyczkami.
| Flask | Django | |-------|--------| | Mikroframework - minimalistyczny | Full-stack framework - wszystko w jednym | | Elastyczny, modułowy | Opinionated, konwencje | | Świetny do małych/średnich projektów | Świetny do dużych projektów | | Musisz sam wybrać komponenty | Wszystko out-of-the-box | | ~10 linii dla Hello World | ~50 linii dla Hello World | | Świetny do nauki! | Bardziej skomplikowany |
Analogia: Flask to namiot badawczy (szybkie ustawienie), Django to pełne laboratorium (długa konfiguracja, ale wszystkie narzędzia). 🏕️🏢
✅ Prosty - minimalna krzywa uczenia ✅ Elastyczny - sam wybierasz komponenty ✅ Lekki - mała aplikacja, szybki start ✅ Pythonowy - czysty, czytelny kod ✅ Świetna dokumentacja - łatwo się uczyć ✅ Duża społeczność - mnóstwo wtyczek
Przykłady użycia Flask:
Flask instalujemy przez
pip jak każdy pakiet Pythona.Zawsze używaj wirtualnego środowiska dla projektów Pythona!
1# Stwórz folder projektu
2mkdir safari_web
3cd safari_web
4
5# Stwórz wirtualne środowisko
6python -m venv venv
7
8# Aktywuj środowisko
9# Windows:
10venv\Scripts\activate
11# Mac/Linux:
12source venv/bin/activateAnalogia: Wirtualne środowisko to jak odseparowana zagroda dla Twojego projektu - biblioteki z jednego projektu nie będą kolidować z innymi! 🦁🐘
1# Zainstaluj Flask
2pip install Flask
3
4# Sprawdź wersję
5flask --version
6# Output: Python 3.11.0
7# Flask 3.0.0
8# Werkzeug 3.0.0Flask automatycznie instaluje:
1# Zapisz zależności
2pip freeze > requirements.txt
3
4# Zawartość requirements.txt:
5Flask==3.0.0
6Werkzeug==3.0.0
7Jinja2==3.1.2
8...Po co? Inni developerzy mogą zainstalować te same wersje:
1pip install -r requirements.txtCzas na pierwszy program Flask! Stworzymy stronę wyświetlającą "Hello Safari!" 🦁
1# app.py
2from flask import Flask
3
4# Stwórz instancję aplikacji Flask
5app = Flask(__name__)
6
7# Zdefiniuj route (adres URL)
8@app.route('/')
9def hello():
10 return "Hello Safari! 🦁"
11
12# Uruchom serwer developerski
13if __name__ == '__main__':
14 app.run(debug=True)Co się dzieje?
- tworzy instancję aplikacjiFlask(__name__)
__name__ to nazwa modułu (Flask używa tego do lokalizacji zasobów)
- dekorator definiujący route (ścieżkę URL)@app.route('/')
/ = strona główna (home page)http://localhost:5000/, wykona się funkcja hello()
- view function (funkcja widoku)def hello()
- uruchamia serwer deweloperskiapp.run(debug=True)
debug=True włącza tryb debugowania (auto-reload, szczegółowe błędy)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!Przejdź do: http://localhost:5000/
Zobaczysz: Hello Safari! 🦁
Gratulacje! Właśnie stworzyłeś/aś pierwszą aplikację Flask! 🎉
Przeanalizujmy dokładniej, jak działa Flask.
1from flask import Flask
2
3app = Flask(__name__)
tworzy obiekt aplikacji:Flask(__name__)
__name__ = nazwa modułu (np. '__main__' lub 'app')Route = mapowanie URL → funkcja
1@app.route('/species')
2def list_species():
3 return "Lista wszystkich gatunków"
4
5@app.route('/species/lion')
6def show_lion():
7 return "Szczegóły lwa"Jak to działa?
/species → wykonuje się list_species()/species/lion → wykonuje się show_lion()Analogia: Route to jak szlak safari - każdy szlak prowadzi do innego siedliska (view function)! 🛤️🦁
View function = funkcja zwracająca odpowiedź HTTP
1@app.route('/')
2def home():
3 return "<h1>Safari Database</h1><p>Witaj w systemie!</p>"Co możesz zwrócić?
jsonify())1if __name__ == '__main__':
2 app.run(debug=True)Parametry
:app.run()
debug=True - tryb debugowania (auto-reload, debugger)host='0.0.0.0' - dostępny z innych urządzeńport=5000 - numer portu (domyślnie 5000)⚠️ WAŻNE: NIGDY nie używaj
debug=True w produkcji!Stworzymy prostą aplikację Safari Database z kilkoma route'ami! 🦁📊
1# app.py
2from flask import Flask
3
4app = Flask(__name__)
5
6# Dane testowe
7species = [
8 {"id": 1, "name": "Lew", "scientific_name": "Panthera leo", "population": 120},
9 {"id": 2, "name": "Słoń afrykański", "scientific_name": "Loxodonta africana", "population": 450},
10 {"id": 3, "name": "Gepard", "scientific_name": "Acinonyx jubatus", "population": 7100},
11]
12
13# Route 1: Strona główna
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>System zarządzania danymi o gatunkach afrykańskich</p>
43
44 <nav>
45 <a href="/">Strona główna</a>
46 <a href="/species">Lista gatunków</a>
47 <a href="/about">O systemie</a>
48 </nav>
49
50 <h2>Witaj w Safari Database!</h2>
51 <p>Baza danych zawiera <strong>{} gatunków</strong> afrykańskich.</p>
52 <p><a href="/species">Zobacz pełną listę gatunków →</a></p>
53 </body>
54 </html>
55 """.format(len(species))
56
57 return html
58
59# Route 2: Lista gatunków
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>Nazwa naukowa:</strong> {spec['scientific_name']}</p>
68 <p><strong>Populacja:</strong> {spec['population']} osobników</p>
69 <a href="/species/{spec['id']}">Zobacz szczegóły →</a>
70 </div>
71 """
72
73 html = f"""
74 <!DOCTYPE html>
75 <html>
76 <head>
77 <title>Lista gatunków - 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>🦁 Lista gatunków</h1>
99
100 <nav>
101 <a href="/">Strona główna</a>
102 <a href="/species">Lista gatunków</a>
103 <a href="/about">O systemie</a>
104 </nav>
105
106 <p>Łącznie: <strong>{len(species)} gatunków</strong></p>
107
108 {species_html}
109
110 <p><a href="/">← Powrót do strony głównej</a></p>
111 </body>
112 </html>
113 """
114
115 return html
116
117# Route 3: Szczegóły gatunku (dynamiczny URL)
118@app.route('/species/<int:species_id>')
119def show_species(species_id):
120 # Znajdź gatunek po 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 - Gatunek nie znaleziony</h1><a href='/species'>Powrót do listy</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>Nazwa naukowa:</strong> <em>{spec['scientific_name']}</em></p>
154 <p><strong>Populacja:</strong> {spec['population']} osobników</p>
155 <p><strong>ID w systemie:</strong> {spec['id']}</p>
156 </div>
157
158 <p style="margin-top: 20px;">
159 <a href="/species">← Powrót do listy gatunków</a> |
160 <a href="/">← Strona główna</a>
161 </p>
162 </body>
163 </html>
164 """
165
166 return html
167
168# Route 4: O systemie
169@app.route('/about')
170def about():
171 html = """
172 <!DOCTYPE html>
173 <html>
174 <head>
175 <title>O systemie - 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>🦁 O Safari Database</h1>
189
190 <p><strong>Safari Database</strong> to system zarządzania danymi o gatunkach afrykańskich.</p>
191
192 <h2>Technologie:</h2>
193 <ul>
194 <li>Flask 3.0 - mikroframework webowy</li>
195 <li>Python 3.11 - język programowania</li>
196 <li>HTML/CSS - frontend</li>
197 </ul>
198
199 <h2>Funkcje:</h2>
200 <ul>
201 <li>Przeglądanie listy gatunków</li>
202 <li>Szczegóły każdego gatunku</li>
203 <li>Statystyki populacji</li>
204 </ul>
205
206 <p><a href="/">← Powrót do strony głównej</a></p>
207 </body>
208 </html>
209 """
210
211 return html
212
213# Uruchom serwer deweloperski
214if __name__ == '__main__':
215 print("🦁 Safari Database startuje...")
216 print("📡 Serwer dostępny pod adresem: http://localhost:5000/")
217 app.run(debug=True)1python app.pyOtwórz w przeglądarce:
Sprawdź też błędy:
Flask pozwala na dynamiczne URL z parametrami:
1# Podstawowy parametr (string)
2@app.route('/user/<username>')
3def show_user(username):
4 return f"Użytkownik: {username}"
5
6# Parametr typu int
7@app.route('/species/<int:species_id>')
8def show_species(species_id):
9 return f"Gatunek ID: {species_id}"
10
11# Parametr typu float
12@app.route('/price/<float:price>')
13def show_price(price):
14 return f"Cena: {price:.2f} zł"
15
16# Parametr path (może zawierać /)
17@app.route('/file/<path:filepath>')
18def show_file(filepath):
19 return f"Plik: {filepath}"Typy konwerterów:
string - akceptuje tekst bez slasha (domyślny)int - akceptuje liczby całkowitefloat - akceptuje liczby zmiennoprzecinkowepath - jak string, ale akceptuje slasheuuid - akceptuje UUID stringsPrzykłady URL:
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 domyślnie obsługuje tylko GET requests. Możesz dodać inne metody:
1from flask import request
2
3# Tylko GET (domyślnie)
4@app.route('/species')
5def list_species():
6 return "Lista gatunków (GET)"
7
8# GET i POST
9@app.route('/species', methods=['GET', 'POST'])
10def species():
11 if request.method == 'POST':
12 # Obsługa formularza
13 name = request.form['name']
14 return f"Dodano gatunek: {name}"
15 else:
16 # Wyświetl formularz
17 return """
18 <form method="POST">
19 <input type="text" name="name" placeholder="Nazwa gatunku">
20 <button type="submit">Dodaj</button>
21 </form>
22 """
23
24# Tylko POST
25@app.route('/api/species', methods=['POST'])
26def create_species():
27 return "Utworzono gatunek (POST only)"Metody HTTP:
Debug mode (
debug=True) włącza:Serwer automatycznie restartuje się po zmianie kodu!
1app.run(debug=True)Testuj:
python app.pyGdy wystąpi błąd, Flask pokazuje interaktywny debugger w przeglądarce:
1@app.route('/error')
2def error():
3 result = 10 / 0 # Błąd: dzielenie przez zero!
4 return "This won't be reached"Wejdź na
/error → zobaczysz szczegółowy traceback z możliwością inspekcji zmiennych!Flask pokazuje dokładne informacje o błędach zamiast ogólnego "500 Internal Server Error".
⚠️ WAŻNE: NIGDY nie używaj
debug=True w produkcji - pokazuje kod źródłowy i pozwala wykonywać kod!Zamiast
python app.py możesz użyć Flask CLI:1# Ustaw zmienną środowiskową
2export FLASK_APP=app.py
3export FLASK_DEBUG=1 # Włącz debug mode
4
5# Uruchom serwer
6flask run
7
8# Uruchom na innym porcie
9flask run --port 8000
10
11# Dostępny z innych urządzeń
12flask run --host=0.0.0.0Windows (PowerShell):
1$env:FLASK_APP = "app.py"
2$env:FLASK_DEBUG = "1"
3flask runProsty projekt Flask może wyglądać tak:
1safari_web/
2│
3├── venv/ # Wirtualne środowisko (nie commituj do git!)
4│
5├── app.py # Główna aplikacja
6│
7├── requirements.txt # Zależności (pip freeze)
8│
9├── static/ # Pliki statyczne (CSS, JS, obrazy)
10│ ├── css/
11│ │ └── style.css
12│ ├── js/
13│ │ └── script.js
14│ └── images/
15│ └── logo.png
16│
17├── templates/ # Szablony HTML (Jinja2)
18│ ├── base.html
19│ ├── home.html
20│ └── species.html
21│
22└── .gitignore # Ignoruj venv/, __pycache__/, etc.W następnej lekcji nauczymy się używać templates zamiast hardcoded HTML strings! 🎨
W tej lekcji nauczyłeś/aś się:
pip install Flask)Analogia Safari finalna: Flask to mobilne centrum badawcze - lekkie, szybko się ustawia, możesz zacząć obserwacje w kilka minut! Nie potrzebujesz ogromnego laboratorium (Django), żeby rozpocząć badania Safari! 🚐🔬
Stworzyłeś/aś funkcjonującą aplikację webową z:
/species/<int:species_id>)Następna lekcja: Darwin pokaże Ci routing i view functions - zaawansowane techniki tworzenia routes, redirects, error handlers! 🛤️🔀