12.2 Flask: Python kā web serveris
Stundas uzdevums: Uzbūvēt savu pirmo Flask web serveri ar vairākām maršrutēm un atgriezt JSON datus.
70 min plāns: Teorija un paraugs (~10 min) · 1. uzdevums (~15 min) - palaid pirmo Flask serveri · 2. uzdevums (~25 min) - atgriez JSON no maršruta · 3. uzdevums (~20 min) - pieņem datus ar POST. Papildu uzdevumu sāc tikai tad, ja pārējie trīs ir gatavi.
Pirms sāc: aktivizē virtuālo vidi un izpildi pip install flask. Serveri apturēsi ar Ctrl+C terminālī.
Teorija: Flask pamatkomponenti
Flask ir mikro-ietvars Python - tikai 100 KB, bet pietiekams reāliem projektiem. Instalācija: pip install flask.
from flask import Flask, jsonify, request
app = Flask(__name__)
# Vienkārša maršruta
@app.route("/")
def home():
return "<h1>Sveiks!</h1>"
# JSON atbilde
@app.route("/api/speletaji")
def saraksts():
return jsonify([
{"vards": "Anna", "punkti": 120},
{"vards": "Jānis", "punkti": 95}
])
# Maršruta ar parametru
@app.route("/api/speletajs/<int:id>")
def viens(id):
return jsonify({"id": id, "vards": "Anna"})
# POST pieprasījums
@app.route("/api/saglabat", methods=["POST"])
def saglabat():
dati = request.json
return jsonify({"status": "ok", "saņēmu": dati}), 201
if __name__ == "__main__":
app.run(debug=True, port=5000)
Palaiž ar python app.py → atver http://localhost:5000/.
Praktiskie uzdevumi
1. uzdevums -
Palaid pirmo Flask serveri
Beigās tavs Python kods atbildēs pārlūkam.
- Izveido failu
serveris.pyun ierakstifrom flask import Flask. - Ieraksti
app = Flask(__name__). - Pievieno dekoratoru
@app.route("/"). - Uzraksti zem tā funkciju, kas atgriež
"<h1>Sveiks!</h1>". - Pievieno faila beigās
app.run(debug=True). - Palaid un atver pārlūkā
http://localhost:5000.
Gatavs, kad: pārlūkā redzams liels uzraksts Sveiks!, un terminālī parādās ieraksts par pieprasījumu.
2. uzdevums -
Atgriez JSON no maršruta
Beigās serveris atdos datus, nevis tekstu.
- Importē
jsonifyno Flask. - Pievieno maršrutu
@app.route("/api/speletaji"). - Atgriez tajā
jsonify([{"vards": "Anna", "punkti": 120}]). - Atver pārlūkā
/api/speletajiun apskati rezultātu. - Atgriez to pašu bez
jsonifyun pieraksti, kas notiek. - Ieliec
jsonifyatpakaļ. - Pārbaudi F12 Network cilnē, kāds ir atbildes
Content-Type.
Gatavs, kad: atbildes Content-Type ir application/json, nevis text/html.
3. uzdevums -
Pieņem datus ar POST
Beigās serveris varēs saņemt jaunu ierakstu.
- Izveido sarakstu
SPELETAJI = []faila augšā. - Pievieno maršrutu ar
methods=["POST"]. - Nolasi tajā
dati = request.json. - Pievieno datus sarakstam un atgriez tos ar statusa kodu 201.
- Izmēģini to ar
curl -X POST -H "Content-Type: application/json" -d '{"vards":"Jānis"}' http://localhost:5000/api/speletaji. - Atver GET maršrutu un pārbaudi, ka jaunais ieraksts tur ir.
- Pieraksti vienu secinājumu: kāpēc dati pazūd, kad serveri restartē.
Gatavs, kad: pēc POST pieprasījuma GET maršruts rāda jauno spēlētāju, bet pēc servera restarta saraksts atkal ir tukšs.
Papildu uzdevums - Pievieno maršrutu ar parametru
Ja pamatdarbs ir gatavs, ļauj pieprasīt vienu konkrētu spēlētāju.
- Pievieno maršrutu
@app.route("/api/speletaji/<int:id>"). - Atrodi sarakstā spēlētāju ar šo
id. - Atgriez to kā JSON.
- Atgriez statusa kodu 404, ja spēlētājs nav atrasts.
- Pārbaudi abus gadījumus pārlūkā.
Gatavs, kad: esošs id atgriež spēlētāju, bet neesošs - kodu 404, nevis servera kļūdu.
Biežākās kļūdas
- Aizmirsts
jsonify(): Bez tā Flask atgriež dictionary kā string, ne JSON. - Ports aizņemts:
OSError: Address already in use- nogalini iepriekšējo procesu vai mainī portu. - JSON parametra trūkums:
request.jsonirNone, ja klients nesūtaContent-Type: application/json.
Koda piemērs
from flask import Flask, jsonify, request
app = Flask(__name__)
SPELETAJI = [{"id": 1, "vards": "Anna", "punkti": 120}]
@app.route("/api/speletaji")
def visi():
return jsonify(SPELETAJI)
@app.route("/api/speletaji", methods=["POST"])
def pievienot():
d = request.json
if not d or "vards" not in d:
return jsonify({"kluda": "Trūkst vārds"}), 400
jauns = {"id": len(SPELETAJI) + 1, "vards": d["vards"], "punkti": d.get("punkti", 0)}
SPELETAJI.append(jauns)
return jsonify(jauns), 201
if __name__ == "__main__":
app.run(debug=True)
POST /api/speletaji → 201 Created