Search
Pro uložení dat můžeme využít SQLite databázi. Její výhodou je, že pracuje s lokálním binárním souborem a má minimální nároky na paměť a výkon počítače - veškerá potřebná funkcionalita je totiž vytvářena knihovnou, která pracuje s binárním souborem.
Pro jednoduchost můžete využít modul nsidb, který umožňuje vytvořit databázi a tabulku pro ukládání dvou hodnot typu float reprezentující teplotu a vlhkost přečtenou z hypotetického senzoru. Hodnoty jsou funkci pro zápis předávány jako datový typ tuple. Následující kód uložte do pracovního adresáře jako nsidb.py.
nsidb
float
tuple
nsidb.py
import sqlite3 from sqlite3 import Error def db_conn(file): """ Create a database connection : param file: name of database file : return: """ conn = None try: conn = sqlite3.connect(file) except Error as e: print("Error", e) return conn def db_exec(conn, sql, data = None): """ execute a SQL command :param conn: Connection object :param sql: SQL statement """ try: c = conn.cursor() if data is not None: c.execute(sql, data) else: c.execute(sql) except Error as e: print(e) return c def db_create(conn): sql = """CREATE TABLE IF NOT EXISTS hodnoty (id integer PRIMARY KEY, timestamp integer NOT NULL, temperature integer NOT NULL, humidity integer NOT NULL);""" cur = db_exec(conn, sql) def db_insert(conn, data): """ Create a new record :param conn: Connection object :param data: tuple of data :return: ID of last inserted row """ sql = """ insert into hodnoty (timestamp, temperature, humidity) values (datetime(), ?, ?); """ cur = db_exec(conn, sql, data) conn.commit() return cur.lastrowid def db_fetch(conn): """ Fetch data from table :param conn: the Connection object :return: """ cur = db_exec(conn, "SELECT * FROM hodnoty") return cur.fetchall()
V hlavním programu je importován modul nsidb a volány přislušné funkce z modulu. Program pro uložení dat může vypadat třeba takto:
from nsidb import * conn = db_conn("iot.db") db_create(conn) db_insert (conn, (3.14, 25.5)) rows = db_fetch (conn) for row in rows: print(row)
from flask import Flask, redirect, url_for app = Flask(__name__) @app.route('/') def main(): return redirect(url_for('hello', username='Peter')) # Also pass an optional URL variable @app.route('/hello/<username>') def hello(username): return 'Hello, {}'.format(username) if __name__ == '__main__': app.run(debug=True)
Pro správu šablon se v prostředí Flask implicitně používá engine jinja. Pro využití možností engine je třeba importovat z Flask submodul render_template a dodržet strukturu, kterou engine předpokládá:
render_template
project-directory | +-- templates (for Jinja2 HTML templates) +-- static | +-- css +-- js +-- img
Jednoduchá šablona může vypadat třeba takto:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Response Page</title> </head> <body> <h1>Hello, {{ username }}</h1> </body> </html>
Na místo username se do šablony dosadí hodnota, která byla předána při volání funkce render_template
username
@app.route('/name/<name>') def process(name): return render_template('name.html', username=name)
Kromě dosazování hodnot a případně vyhodnocování výrazů je možné pracovat i s běžnými algoritmickými konstrukty.
Podmínka:
{% if ...... %} ...... {% elif ...... %} ...... {% else %} ...... {% endif %}
Cyklus:
{% for item in list %} ...... {% endfor %}
Stávající aplikaci rozšiřte o zpracování URL /login
/login
from flask import Flask, render_template, redirect, url_for, request # ... @app.route('/login', methods=['GET', 'POST']) def login(): error = None if request.method == 'POST': if request.form['username'] != 'admin' or request.form['password'] != 'admin': error = 'Invalid Credentials. Please try again.' else: return redirect(url_for('main')) return render_template('login.html', error=error)<<
V pracovním adresáři vytvořte podadresář templates a do něj umístěte následující soubor login.html. Na stejné úrovni vytvořte ještě další adresář static a do něj rozbalte obsah bootstrap.min.zip.
templates
login.html
static
<html> <head> <title>NSI application - login page</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href="/static/bootstrap.min.css" rel="stylesheet" media="screen"> </head> <body> <div class="container"> <h1>Please login</h1> <br> <form action="" method="post"> <input type="text" placeholder="Username" name="username" value="{{ request.form.username }}"> <input type="password" placeholder="Password" name="password" value="{{ request.form.password }}"> <input class="btn btn-primary" type="submit" value="Login"> </form> {% if error %} <div class="alert alert-warning" role="alert"> <strong>Error:</strong> {{ error }} </div> {% endif %} </div> </body> </html>
Rozšiřte aplikaci vytvořenou v rámci 1. miniprojektu tak, aby byla propojena s SQL databází. Hlavním úkolem je zobrazení nasbírané časové řady, která je uložena v databázi. Pokud máte chuť a čas, rozšiřte databázi o tabulku s uživateli a zobrazujte data jen po autorizaci.
sqlite3
Flasku