Pilnvērtīga //
izstrāde un deploy
Apvieno visu kursu: Flask + PostgreSQL + mākonis. Kursa beigās: publicēta web lietotne internetā.
6 stundas - full-stack un publicēšana
Front-end un back-end arhitektūra
Klienta-servera modelis, HTTP pieprasījumi, REST API dizains, koda organizācija slāņos.
Flask kā web serveris
Maršrutu organizēšana ar Blueprints, request/response, Flask-SQLAlchemy integrācija.
REST API izstrāde
RESTful endpoint dizains, HTTP statusa kodi, jsonify(), CORS.
Front-end + API integrācija
JS fetch() → Flask POST → DB → JSON atbilde → DOM atjaunošana.
Izvietošana mākonī un drošība
Render vai Railway deploy, environment variables, HTTPS, requirements.txt.
Noslēguma projekts: Daudzspēlētāju Krustiņi
Flask + PostgreSQL + JS - pilna publicēta web lietotne. Kursa noslēgums un portfolio gabals.
12. tēmas špikeris - tīmekļa izstrāde
Klients-serveris, Flask, REST API, fetch un izvietošana. Katrs bloks atbilst vienai stundai.
12.1 Klients un serveris
PĀRLŪKS (frontend) SERVERIS (backend)
HTML / CSS / JavaScript Python / Flask
lietotāja datorā tavā vai mākoņa datorā
│ │
│──── GET /api/rezultati ─────────────►│
│ │ lasa datubāzi
│◄─── 200 OK + JSON ───────────────────│
│ │
│──── POST /api/rezultati + JSON ─────►│ pārbauda un saglabā
│◄─── 201 Created ─────────────────────│
Statusa kodi:
200 OK viss kārtībā
201 Created jauns ieraksts izveidots
400 Bad Request lietotājs atsūtīja sliktus datus
404 Not Found nav tādas adreses
500 Server Error servera kods avarēja
GALVENAIS LIKUMS: serveris NEKAD neuzticas pārlūka datiem.
Uzvaras pārbaude, cena, tiesības - viss serverī, jo pārlūku var apiet.
Pārlūkā drīkst pārbaudīt ērtībai, bet serverī pārbaudīt ir obligāti.
12.2 Flask serveris
from flask import Flask, jsonify, request
app = Flask(__name__)
SPELETAJI = []
@app.route("/")
def home():
return "<h1>Sveiks!</h1>"
@app.route("/api/speletaji") # GET pēc noklusējuma
def visi():
return jsonify(SPELETAJI) # bez jsonify nav JSON
@app.route("/api/speletaji", methods=["POST"])
def pievienot():
dati = request.json
SPELETAJI.append(dati)
return jsonify(dati), 201 # 201 = izveidots
@app.route("/api/speletaji/<int:id>")
def viens(id):
for s in SPELETAJI:
if s["id"] == id: return jsonify(s)
return jsonify({"kluda": "nav atrasts"}), 404
app.run(debug=True) # debug=True TIKAI izstrādē!
Sarakstā glabātie dati pazūd, restartējot serveri - pastāvīgai glabāšanai vajag failu vai datubāzi.
12.3 REST API ar validāciju
@app.route("/api/rezultati", methods=["GET"])
def saraksts():
limit = request.args.get("limit", 100, type=int) # ?limit=5
sakartoti = sorted(REZULTATI, key=lambda r: r["punkti"], reverse=True)
return jsonify(sakartoti[:limit])
@app.route("/api/rezultati", methods=["POST"])
def pievienot():
dati = request.json
if not dati or "vards" not in dati:
return jsonify({"kluda": "Trūkst lauks 'vards'"}), 400
if not isinstance(dati.get("punkti"), int) or dati["punkti"] < 0:
return jsonify({"kluda": "'punkti' jābūt pozitīvam skaitlim"}), 400
dati["id"] = len(REZULTATI) + 1
REZULTATI.append(dati)
return jsonify(dati), 201
# REST likumi: viena adrese = viens resurss
# GET /api/rezultati saraksts
# POST /api/rezultati izveido jaunu
# DELETE /api/rezultati/5 dzēš vienu
type=int pasargā no ?limit=abc - bez tā serveris atgrieztu 500.
12.4 fetch() - pārlūks runā ar serveri
async function ielade() {
const r = await fetch("http://localhost:5000/api/rezultati");
if (!r.ok) { // vienmēr pārbaudi
console.error("Kļūda:", r.status);
return;
}
const dati = await r.json();
let html = "";
for (const x of dati) {
html += `<tr><td>${x.vards}</td><td>${x.punkti}</td></tr>`;
}
document.getElementById("saraksts").innerHTML = html;
}
document.getElementById("forma").addEventListener("submit", async (e) => {
e.preventDefault(); // BEZ ŠĪ lapa pārlādējas!
await fetch("http://localhost:5000/api/rezultati", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ vards: vards.value, punkti: +punkti.value })
});
ielade(); // atjauno tabulu
});
CORS kļūda konsolē? Serverī: pip install flask-cors un CORS(app).
12.5 Izvietošana un drošība
import os
from flask import Flask
app = Flask(__name__)
# NEKAD neraksti paroli kodā - lasi no vides mainīgā
DATABASE_URL = os.environ.get("DATABASE_URL")
SECRET_KEY = os.environ.get("SECRET_KEY", "dev-only-key")
# .env fails (LOKĀLI, .gitignore sarakstā):
# DATABASE_URL=postgres://...
# SECRET_KEY=...
# Pirms izvietošanas:
# app.run(debug=False) debug=True publiski rāda tavu kodu!
# pip install gunicorn
# pip freeze > requirements.txt
# Procfile: web: gunicorn app:app
# .gitignore satur .env un venv/
# Render / Railway: pieslēdz GitHub krātuvi, vides mainīgos ievadi
# mājaslapas Environment sadaļā, nevis failā.
Parole, kas vienreiz nonākusi GitHub, ir uzskatāma par nopludinātu - to jāmaina, ne tikai jāizdzēš.