from flask import Flask # Importing the Flask module from the flask package
app = Flask(__name__) # Creating an instance of the Flask class
@app.route('/') # View function for endpoint '/'
def hello():
return "Hello, World!
"
# Starting a web application at 0.0.0.0.0:5000 with debug mode enabled
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5000, debug=True, use_reloader=False)
Dále vytvoříme soubor ''%%requirements.txt%%'' který bude obsahovat seznam všech Python balíčků. Soubor můžeme vytvořit manuálně, nebo automaticky pomocí příkazu ''%%pip freeze > requirements.txt%%'' (viz první cvičení - Moduly a balíčky, Správa balíčků pomocí PIPu, Instalace balíčků pomocí requirements.txt).
Jako layout projektu zvolíme následující strukturu:
/home/user/Projects/flask-tutorial
├── app.py
├── templates/
│ └── index.html
├── static/
│ └── style.css
└── venv/
''%%Static%%'' bude obsahovat statické soubory jako CSS a JavaScript. ''%%Templates%%'' bude obsahovat šablony HTML pro různé stránky aplikace.
==== Zobrazování HTML stránek ====
Aby naše funkce ''%%hello()%%'' pracovala s HTML, stačí ji změnit takto:
from flask import Flask # Importing the Flask module from the flask package
app = Flask(__name__) # Creating an instance of the Flask class
@app.route('/') # View function for endpoint '/'
def hello():
return "Hi there! Hello, World!", 200
# Starting a web application at 0.0.0.0.0:5000 with debug mode enabled
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5000, debug=True, use_reloader=False)
V tomto případě ''%%hello()%%'' vrací řetězec ve formátu HTML a číslo. Řetězec bude ve výchozím nastavení analyzován jako HTML, zatímco 200 je nepovinný kód HTTP označující úspěšnou odpověď. Ve výchozím nastavení je vrácen kód 200.
Tento přístup k zobrazování HTML komponent je ovšem velmi limitující. Navíc definování HTML šablony uvnitř funkce, která zpracovává odpověď je z hlediska přístupu MVC nepřípustné.
''%%app.py%%'' by z hlediska MVC architektury měl fungovat jako kontrolér. Pohledy budeme definovat pomocí HTML šablon uvnitř složky ''%%templates%%''. Ve složce ''%%templates%%'' vytvoříme šablonu ''%%index.html%%'':
NSI App
Hello World!
A ''%%app.py%%'' upravíme následovně:
from flask import Flask, render_template
app = Flask(__name__) # Creating an instance of the Flask class
@app.route('/') # View function for endpoint '/'
def hello():
return render_template('index.html')
# Starting a web application at 0.0.0.0.0:5000 with debug mode enabled
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5000, debug=True, use_reloader=False)
''%%render_template%%'' umožňuje načítat šablony ze složky templates/ (výchozí pro Flask) a stačí je vykreslit pomocí vrácení výstupu.
Nyní přidáme několik JavaScript a CSS stylů. Vestavěný vývojový server Flask ve výchozím nastavení obsluhuje všechny soubory ve složce projektu, které se nacházejí v podsložce ''%%static%%''. V této složce vytvoříme soubory ''%%styles.css%%'' a ''%%script.js%%''
body {
display: flex;
justify-content: center;
align-items: center;
margin: 0;
}
h1 {
font-size: 2em;
}
function getRandomColor() {
let letters = '0123456789ABCDEF';
let color = '#';
for (let i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
let helloWorld = document.getElementById('hello-world');
helloWorld.style.color = getRandomColor();
Pro použití těchto souborů je ještě musíme zahrnout v ''%%index.html%%'':
NSI App
Hello, World!
==== Knihovna Bootstrap ====
Pro použití dalších, složitějších grafických prvků je vhodné použít CSS knihovnu jako Bootstrap, Foundation, … CSS knihovna se v podstatě skládá z několika souborů CSS stylů připravených k použití vývojáři a návrháři webových stránek. Soubory stylů jsou připraveny pro standardní funkce webového designu: nastavení barev, rozvržení, písem, navigačních panelů atd. Obecně jsou soubory stylů podporovány a rozšiřovány o další skriptovací technologie, jako je SASS a JavaScript.
S CSS knihovnou má uživatel k dispozici hotový soubor stylů CSS a k vytvoření webové stránky mu stačí napsat HTML s přesnými třídami, strukturou a ID. Knihovna má již zabudované třídy pro běžné prvky webových stránek - zápatí, posuvník, navigační panel, rozvržení založené na sloupcích atd.
Import CSS Knihovny Bootstrap:
Odkazy jsou dostupné z: [[https://getbootstrap.com/|Bootstrap · The most popular HTML, CSS, and JS library in the world. (getbootstrap.com)]]
NSI app
Toto je text v těle karty.
==== Šablony ve Flasku ====
Hlavní balíček, který se ve Flasku stará o pohledy - šablony je Jinja2 ([[https://jinja.palletsprojects.com/en/3.1.x/|Jinja — Documentation]]), pomocí kterého lze vytvářet formátovaný text s integrovanou logikou. Na rozdíl od funkce formátování v jazyce Python, která umožňuje pouze nahradit značky proměnným obsahem, lze uvnitř šablony řetězce mít řídicí strukturu, například for cyklus.
Šablona může obsahovat proměnné a výrazy, které se při vykreslení šablony nahradí hodnotami, které řídí logiku šablony. Syntaxe šablony je do značné míry inspirována jazykem Django a Python.
Existuje několik druhů oddělovačů. Výchozí oddělovače Jinja jsou nakonfigurovány takto:
* ''%%{% ... %}%%'' - pro výrazy
* ''%%{{ ... }}%%'' - pro výrazy, které se mají vypisovat na výstup šablony
* ''%%{# ... #}%%'' - pro komentáře, které se do výstupu šablony nezahrnují.
Více informací: [[https://jinja.palletsprojects.com/en/3.0.x/templates/#list-of-control-structures|Template Designer Documentation — Jinja Documentation (3.0.x) (palletsprojects.com)]]
=== Oddělení dynamických části od statických ===
V naší webové aplikaci jsou komponenty, které se budou zobrazovat stejně na jakékoli URL - např. ''%%navbar%%''. Místo definování ''%%navbaru%%'' v každé HTML Jinja šabloně můžeme využít **dědičnost šablon**. Ta umožňuje vytvořit základní “kostru” šablony, která obsahuje všechny společné prvky webu a definuje bloky, které mohou podřízené šablony přepisovat.
=== Proměnné v šablonách ===
Proměnné v šablonách jsou definovány kontextovým slovníkem předaným šabloně.
===== Zadání 1. miniprojektu =====
Navrhněte Flask aplikaci pro sledování teploty s pomocí knihovny Bootstrap a template enginu Jinja. Projekt vytvořte s pomocí virtuálního prostředí (viz cv01) a následně jej nahrajte na [[https://gitlab.fel.cvut.cz|fakultní Gitlab]]. Do [[https://cw.felk.cvut.cz/brute|BRUTE]] následně nahrajte odkaz na tento repozitář, který bude mít nastavenou viditelnost buď ''internal'' nebo ''public''.
* V aplikaci budou existovat tři stránky: přihlašovací formulář, registrační formulář, dashboard.
* Aplikace bude využívat [[https://jinja.palletsprojects.com/en/3.0.x/templates/#template-inheritance|dědičnost šablon]] pro ''navbar'' a tělo stránky.
* V navbaru bude uveden: název stránky, název přihlášeného uživatele (zatím libovolný text, který se bude předávat šablon jako proměnná), tlačítko pro odhlášení.
* Na stránce dashboard vytvořte layout z komponent knihovny Bootstrap. V layoutu musí být zohledněna oblast pro:
* výpis poslední naměřené hodnoty s časem zápisu,
* výpis tabulky ''X'' posledních naměřených hodnot s časem zápisu a ovládacím prvkem pro proměnnou ''X'',
* ovládací prvek pro smazání ''Y'' prvních (nejstarších) hodnot,
* další komponenty dle vašeho uvážení (např. graf průběhu teploty v závislosti na čase, zobrazení počtu dat, apod.)
* Naměřené hodnoty simulujte [[https://pythonexamples.org/python-list-of-dictionaries/|Python slovníkovým seznamem]] definovaným v serverové aplikaci (alespoň 5 záznamů ''{"timestamp": value, "temp": value}'').