Politik

Lennarts MOOC och datorkurs 4: Vi vidareutvecklar vår lilla app i Python Flask, Jinja2 och MongoDB

Detta har hänt: jag har startat en liten MOOC och Datorkurs här på bloggen. Så jag började första lektionen med att installera den populära Öppna Kod-databasen MongoDB på Windows 7. Egentligen vore det mer logiskt att köra Linux men eftersom de flesta använder Windows så gör även jag det för den här kursen.

MongoDB är en s.k. NoSQL-database och jag visade hur vi använder den från ett DOS-fönster på Windows.

Andra lektionen följde och där installerade vi dataspråket Python och kopplade ihop det med MongoDB genom att använda ett gränssnitt som heter PyMongo.

Så nu kan vi manipulera data i MongoDB från Python. Men bara via ett DOS-fönster. Och säga vad man vill om DOS-fönster, men dom är inget man kan skryta för sina föräldrar med att man använder.

Så i den tredje lektionen visade vi hur vi kan få våra data ut på webben genom ett mycket populärt s.k. ramverk för Python som heter Flask.

Och vad gör vi nu? Jo vi vidareutvecklar vår lilla app i Flask så att vi kan manipulera data i MongoDB direkt från Webben. Och vi introducerar Jinja 2, en s.k. template engine som är inbakat i Flask och som gör det enkelt att skapa dynamiska HTML-sidor.

Låt oss börja med att titta på hur vår Flask-app nu ser ut:

#—————————————————————————————————————–
#
#—————————————————————————————————————–
from flask import Flask, render_template, request, redirect, url_for
import pymongo
from pymongo import Connection

connection = Connection(‘localhost’, 27017)
db = connection.testdb

app = Flask(__name__)

#—————————————————————————–
#Soekall
#—————————————————————————–

def soekall(person):
print (“soekall”)
connection = Connection(‘localhost’, 27017)
db = connection.testdb
collection = db.testcollection
temp1=””

for post in collection.find({}, {‘_id’: False}).sort(u’namn’, 1):
temp=str(post)
print (temp)
temp1=temp1+”
“+temp
user = { ‘nickname’: temp1 } # fake user
return user

#—————————————————————————–
#Soek på en person
#—————————————————————————–

def soek(person):
print (“soek”)
connection = Connection(‘localhost’, 27017)
db = connection.testdb
collection = db.testcollection
temp1=””
for post in collection.find({‘namn’: person}, {‘_id’: False }):
temp=str(post)
temp1=temp1+”
“+temp
user = { ‘nickname’: temp1 } # fake user
return user

#—————————————————————————–
# Index
#—————————————————————————–

@app.route(‘/’)
def index():
return render_template(“index.html”)

#——————————————————————————
#
#——————————————————————————
person = “Lennart”
@app.route(‘/temp/’)

def temp():
user = soekall(person)
return render_template(“index1.html”, title = ‘Home’, user = user)

#————————————————————-
# Input
# We first launch the html page and then when the user presses the OK button there we come
# in at the @app.route /postinput
#————————————————————-
@app.route(‘/tempin’)

def tempin():
return render_template(“postinput.html”)

@app.route(‘/postinput’, methods = [‘POST’])
def postProcessing():
person = request.form[‘person’]
value = request.form[‘value’]

collection = db.testcollection
insert_id = collection.insert({“namn”: person, “value”: value })
return “data enterered”
#return redirect(url_for(‘temp’))

#————————————————————-
# Search Input
#————————————————————-
@app.route(‘/searchin’)

def searchin():
return render_template(“searchinput.html”)

@app.route(‘/searchinput’, methods = [‘POST’])
def searchProcessing():
person = request.form[‘person’]
user= soek(person)
return render_template(“index1.html”, title = ‘Home’, user = user)

#—————————————————————————–
#
#—————————————————————————–

if __name__ == “__main__”:
app.run(debug=True)

Låt oss sen titta på vilka HTML-filer vi har på disken.

Vi har en mapp för vårt projekt och i den mappen har vi ovanstående fil med filtypen .py
sen har vi två undermappar.
Den ena heter templates och de andra heter static
I static-mappen har vi en enda fil som heter style.css.

Vår style.css-fil ser ut så här:

body { font-family: sans-serif; background: #eee; }
a, h1, h2 { color: #377ba8; }
h1, h2 { font-family: ‘Georgia’, serif; margin: 0; }
h1 { border-bottom: 2px solid #eee; }
h2 { font-size: 1.2em; }

.page { margin: 2em auto; width: 35em; border: 5px solid #ccc;
padding: 0.8em; background: white; }
.entries { list-style: none; margin: 0; padding: 0; }
.entries li { margin: 0.8em 1.2em; }
.entries li h2 { margin-left: -1em; }
.add-entry { font-size: 0.9em; border-bottom: 1px solid #ccc; }
.add-entry dl { font-weight: bold; }
.metanav { text-align: right; font-size: 0.8em; padding: 0.3em;
margin-bottom: 1em; background: #fafafa; }
.flash { background: #cee5F5; padding: 0.5em;
border: 1px solid #aacbe2; }
.error { background: #f0d6d6; padding: 0.5em; }

Men ni kan givetvis använda vilken css-fil som helst.

I templates-mappen har vi följande huvudfil: index.html.
Och den ser ut såhär:

<html>
<head>
<title>Menu</title>
<link rel=stylesheet type=text/css href=”{{ url_for(‘static’, filename=’style.css’) }}”>
</head>

<body>
<h1>Menu</h1><hr>
<a href=”/tempin”>Input</a><p>
<a href=”/searchin”>Search</a> <p>
<a href=”/temp”>Output</a>
</body>

</html>

Ni kan se hur vi länker till CSS-filen på ett litet udda sätt. Det är den syntax från Jinja2 som vi använder.

Index.html-sidan startas från Flask-filen på följande sätt: (från flask-filen längst upp)

@app.route(‘/’)
def index():
return render_template(“index.html”)

Som ni ser börjar vi alltid med att definiera en s.k. rutt, dvs det URL som användaren skriver för att komma till vår webbsajt, i det här fallet är ‘/’.

Eftersom jag kör Flask på http://127.0.0.1:5000/, dvs på port 5000 på min bärbara dator, (du kan använde vilken port du vill) så syftar @app.route(‘/’) på det ‘/’ alldeles efter 5000 som avslutar http://127.0.0.1:5000/.

Så om en användare skriver in http://127.0.0.1:5000/ i sin webbläsare så läser vår Flask-app detta, ser det avslutande ‘/’, och ser att då ska han göra return render_template(“index.html”), dvs ladda filen index.html. Vilket också sker.

Sidan kan vi se här:

Om vi nu klickar på Input så får vi se följande sida:

De filen ser ut såhär och skickar sina data till /postinput i Flaskfilen.

{% autoescape false %}
<head>
<title>Input</title>
<link rel=stylesheet type=text/css href=”{{ url_for(‘static’, filename=’style.css’) }}”>
</head>

<h1>Input data </1>

<form action=”/postinput” method=”post”>

<br>Person:<input type=”text” name=”person”><br>
<br>Value: <input type=”text” name=”value”><br>

<input type=”submit” value=”Publish”>
{% endautoescape %}
</form>

Och vad sker där, jo det är bara att läsa koden:

@app.route(‘/postinput’, methods = [‘POST’])
def postProcessing():
person = request.form[‘person’]
value = request.form[‘value’]

collection = db.testcollection
insert_id = collection.insert({“namn”: person, “value”: value })
return “data enterered”
#return redirect(url_for(‘temp’))

Tänk på @app.route som att man definierar spår eller plattformar på en järnvägsstation.
Så användaren klickar på 127.0.0.1:5000/postinput med en POST- begäran. Dvs han skickar data till just den här plattformen. Och då hämtar vi datan som kommer, dvs en ‘person’ och ett ‘value’ och stoppar in i det i vår databas i MongoDB. Svårare är det inte.

Nu kan vi titta på de resterande html-filerna i vår templates-mapp:

{% autoescape false %}
<head>
<title>Input</title>
<link rel=stylesheet type=text/css href=”{{ url_for(‘static’, filename=’style.css’) }}”>
</head>

<h1>Sök data </1>

<form action=”/searchinput” method=”post”>

<br>Person:<input type=”text” name=”person”><br>

<input type=”submit” value=”Publish”>
{% endautoescape %}
</form>

Och den filen är kopplad till /searchinput i Flaskfilen.
Och om användaren klickar på Output i index.html-filen så kopplas han direkt till routen http://127.0.0.1:5000/temp/

som helt enkelt skriver ut alla data vi har i den här samlingen. Så här ser det ut på min dator:

Det är alltså data som jag har skrivit in för hand.

Det här är alltså en fullt fungerande app med en massa nyttiga komponenter. En NOSQL-databas som kommunicerar med Python, och med webben via Flask. Alla mycket matnyttiga komponenter.

Vad är det som saknas. Ja ett steg som vi bör ta är att flytta hela rasket upp i datormolnen. Ett annat är att nu skriva en mobil klient till vår lilla app. Så att man istället för att skriva in datan på en HTML-sida på en dator kan göra det från sin mobil.

Vi får se vad vi gör nästa vecka. Och om någon har någon nytta av den här lilla kursen eller har några frågor så säg gärna till.

Pressklipp:

[tags] Lennarts Datakurs, MongoDB, Python Mongo, MongoDB Python, Lennart Silicon Valley , Flask, Python Flask, Python Jinja2 [/tags]

2 thoughts on “Lennarts MOOC och datorkurs 4: Vi vidareutvecklar vår lilla app i Python Flask, Jinja2 och MongoDB

  1. Ante

    Tänkte bara säga att du får gärna fortsätta med den här lilla kursen. Är själv nyfiken på programmering men saknar väl de specifika egenskaper som man bör ha för att egentligen lyckas.

    Men tänkte ändå försöka mig på det här till helgen. Om inte så bara för att få mer förståelse för det hela med utveckling av appar och hur man skapar program som körs i webbläsare. Intressant samhällsutveckling och ska man leva i 60 år till så bör man ju känna till sin omgivning.

    Tycker (tror) mängden information du har i inläggen är på en bra nivå. Bättre att man ser resultatet än läser något diffust som man ändå inte greppar förrän man har sett det.

    En fråga har jag. Hur får man en bra översikt över ett utvecklingsprojekt, eller det finns kanske inga direkta genvägar. Hur är det med olika IDE, underlättar dem?

    1. Lennart

      Ante: Vad kul, det gläder mig verkligen att någon tittar på kursen! Säg gärna till om det är något som är oklart så uppdaterar jag materialet.

      Eftersom det här projektet är baserad på Python-språket så är det bäst att använda den editor som kommer mer Python och som heter Idle.

      Om du går in i den mapp på Windows där du har lagt din pyton-fil. Alltså inte i DOS-boxen, den använder du endast när du ska köra filen, utan i Windows, och högerklickar på filen, som alltid ska sluta med .py, så ser du en s.k. popup hoppa upp som ser ut så här: http://farm3.staticflickr.com/2858/11205726706_1f8fa80404.jpg.

      Klicka på “Idle” så har du en editor som är anpassad till Python. Ett annat alternativ är http://notepad-plus-plus.org/

Comments are closed.