Web2py ja Google App Engine
Tutustutaan web2py-frameworkin ja Google App Enginen perusteisiin. Käytä apunasi web2py-kirjaa ja App Enginen ohjeita.
Web2py ja Google App Engine käyttöönotto
- Asenna koneellesi Python 2.7 (https://www.python.org/ftp/python/2.7.11/python-2.7.11.msi ). Älä asenna uudempaa Pythonin versiota. Jos olet jo asentanut Anacondan niin sen pitäisi riittää. Agoran mikroluokkien koneille Python 2.7 on jo asennettu.
- Asenna koneellesi Google App Engine SDK for Python https://cloud.google.com/appengine/docs/standard/python/download. Älä asenna Googlen sivun ehdottamaa Google Cloud SDK:ta vaan sivulta alempaa löytyvä App Engine SDK for Python Agoran mikroluokkiin App Engine SDK on jo asennettu. Jos haluat käyttää App Enginea Linuxissa niin vilkaise ohje: Installing and Running Google App Engine on a Linux System
- Kopioi itsellesi web2py lähdekoodiversio osoitteesta http://www.web2py.com/examples/static/web2py_src.zip
- Pura web2py.zip-paketti ja tee kaikki seuraavat muutokset paketissa olevaan web2py-kansioon ja sen alikansioihin.
-
Google App Engine launcherilla suoritettaessa web2py-sovellusta on web2py-kansiorakenteen juureen lisättävä appengine_config.py-niminen tiedosto josta löytyvät seuraavat rivit:
import sys sys.platform = 'linux3'
- Nimeä web2py/applications/welcome-kansio haluamaksesi (sovelluksesi nimi)
- Kopioi web2py/examples-kansiosta routes.parametric.example.py suoraan web2py-kansion juureen ja muuta tiedoston nimeksi routes.py. Muuta routes.py-tiedoston sisältä:
routers = dict( # base router BASE=dict( default_application='oman kansion nimi', ), )
vastaamaan omaa kansiotasi. Jos myöhemmin muutat routes.py-tiedoston sisältöä niin www-palvelin (App Engine Launcher) on käynnistettävä uudelleen jotta muutokset tulevat voimaan. Voi myös kokeilla admin-liittymän Reload routes-painiketta osoitteessa http://localhost:8080/admin/site. - Kopioi web2py/examples-kansiosta app.example.yaml-tiedosto suoraan web2py-kansion juureen ja muuta tiedoston nimeksi app.yaml
- Muuta seuraava kohta app.yaml-tiedostoon. Keksi ohjelmallesi jokin oma
uniikki tunniste esim. kayttajatunnus-1. Tunniste ei saa alkaa numerolla eikä siinä saa olla välilyöntejä.
application: tunnus-1 version: 1 api_version: 1
- Kopioi web2py/handlers-kansiosta gaehandler.py suoraan web2py-kansion juureen
- Käynnistä Google App Engine Launcher.
Jos App Enginea ei löydy Start-valikosta niin kokeile käynnistämistä suoraan polusta: C:\Program Files (x86)\Google\google_appengine\launcher\GoogleAppEngineLauncher.exe. Älä käytä appengine_launcher.bat:ia.
Jos App Engine Launcher valittaa, että ei löydä python-tulkkia niin lisää oikea polku komentotulkkiin (python.exe) App Engine Launcherin asetuksiin Edit|Preferences|Python Path -kohtaan.
Linux-ympäristössä ei ole erillistä GUI-sovellusta vaan käynnistäminen pitää tehdä komentoriviltä. Siirry kansioon johon purit googlelta hakemasi paketin ja suorita sieltä dev_appserver.py-ohjelma:
./dev_appserver.py /polku/oman/sovelluksen/kansioon/omasovellus
- Lisää Launcheriin edellä luomasi sovelluksen web2py-kansio valinnalla File|Add Existing Application
- Valitse sovelluksesi Launcherin listasta ja käynnistä sovellus Run-painikkeella
- Kokeile Browse-painikkeella toimiiko sovelluksesi. Selaimeen pitäisi aueta sivu, jonka osoite on muotoa
http://localhost:8080/welcome/default/index ja jossa lukee hello.
Huomaa, että osoitteessa
näkyvä portti (8080) on todennäköisesti jokaisella koneella eri ja pitää siis korvata omalla koneella pyörivän App Engine Launcherin tarjoamalla porttinumerolla.
- Jos sovellus ei toimi niin kokeile Launcherin Logs-painiketta niin näet mitä viestejä virhelokiin on tullut
- Jos sovellus ei suostu käynnistymään (Browse-painike ei aktivoidu) niin varmista, että web2py-sovelluksesi hakemistopolussa ei esiinny erikoismerkkejä, skandinaavisia merkkejä eikä välilyöntejä. Varmista myös, että omassa kotihakemistossasi ei ole skandinaavisia merkkejä. Esim. polku c:\users\käyttäjä\ hajottaa launcherin.
Jos sovellus ei suostu toimimaan App Engine Launcherilla niin sen voi ajaa myös web2pyn omalla palvelimella.
- Sulje App Engine Launcher
- Avaa komentokehote ja siirry kansioon jossa web2py-sovelluksesi sijaitsee
- Käynnistä web2py-palvelin:
python web2py.py
- Keksi jokin admin-salasana ja valitse Start Server
- Kokeile myös miltä App Enginen admin-näyttää osoitteessa http://localhost:8000/instances Tarkista oikea portti App Engine Launcherin ikkunasta.
- Sovelluksen testaaminen ja kehittäminen on hyvä tehdä App Engine Launcherin avulla omalla koneella. Valmis sovellus
pitää kuitenkin julkaista Googlen palvelimella:
- Luo itsellesi uusi sovellus App Enginen sivulla Anna projektille sama id kuin aiemmin keksit!
- Käytä aiemmin app.yaml-tiedostoon kirjoittamaasi tunnistetta (Project ID)
- Keksi sovellukselle myös nimi (Project Name)
- Mene appenginen ylläpitosivulle. Jos google ehdottaa ensimmäisen sovelluksen luomista niin tee tämä googlen ohjeiden mukaisesti. Valitse sovelluksen kieleksi Python ja sovelluksen sijoituspaikaksi europe-west. Jos haluat niin voit käydä läpi koko googlen tarjoaman tutoriaalin mutta se ei ole välttämätöntä. Managing Cloud Platform Projects, App Engine Applications, and Billing .
- Julkaise sovelluksesi App Launcherin Deploy-painikkeella. App Launcher pyytää google-tunnuksesi ja salasanasi ja avaa selaimeen kirjautumissivun. Valitse Allow
Jos kaikki menee kuten Strömsössä niin luvan jälkeen App Engine Launcher päivittää sovelluksesi Googlen palvelimelle.
Jos mitään ei kuitenkaan tapahtu niin autentikointi on tehtävä seuraavalla tavalla:
- Katso App Engine Launcherin lokiin tullut viesti:
Your browser has been opened to visit: https://accounts.google.com/o/oauth2/auth?scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fappengine.admin+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2F&response_type=code&client_id=550516889912.apps.googleusercontent.com&access_type=offline If your browser is on a different machine then exit and re-run this application with the command-line parameter --noauth_local_webserver
- Avaa Command Prompt, siirry kansioon, jonka alla on sovelluksesi kansio, ja käynnistä komentoriviltä appcfg.py-ohjelma:
"C:\Program Files (x86)\Google\google_appengine\appcfg.py" --noauth_local_webserver update u:\polku\sovelluksen_kansio
- Ohjelma pyytää käymään seuraavanlaisessa osoitteessa:
Go to the following link in your browser: https://accounts.google.com/o/oauth2/auth?scope=https%3A%2F%2Fwww.googleapis .com%2Fauth%2Fappengine.admin+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-pl atform+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&redirect_uri=urn %3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=code&client_id=550516889912.apps. googleusercontent.com&access_type=offline Enter verification code:
Käy sivulla, valitse Allow ja kopioi talteen saamasi koodi:
ja liitä koodi command promptissa odottavalle ohjelmalle:
Enter verification code: 4/Ex34XvQlw1NZjin6xxKy_r91FnNNTPndbHzoy6QI39w
Jatkossa tätä tunnistautumista ei tarvitse enää tehdä.
- Jos appcfg.py herjaa, että antamaasi tunnistetta vastaava sovellusta ei löydy niin varmista, että loit appenginen sivulla python-ohjelman ja appengine-sovelluspohja on sinulle valmisteltu.
- Jatkossa voit sovelluksesi päivittää komennolla:
"C:\Program Files (x86)\Google\google_appengine\appcfg.py" update u:\polku\sovelluksen_kansio
Periaatteessa myös App Engine Launcherin pitäisi nyt osata tehdä päivittäminen salasanaa kysymättä mutta jostain syystä tämä ei aina onnistu. Kokeile.
- Katso App Engine Launcherin lokiin tullut viesti:
- Kokeile sovellustasi osoitteessa http://oma_tunniste.appspot.com
- Sovelluksesi resursseja ja muita tietoja voit silmäillä App Enginen Admin-sivun kautta
- Kokeile nyt myös osoitetta https://oma_tunniste.appspot.com/admin/. Joudut kirjautumaan sisään google-tunnuksella. Tutki mitä kaikkea löytyy wep2pyn ylläpitoliittymästä. Kokeile samaa sivua mutta omalla koneellasi toimivan palvelimen eli App Launcherin kautta osoitteessa: http://localhost:8080/admin/.
- Tutki mitä löytyy applications/omasovellus/Controllers-kansion default.py-tiedostosta. Tiedostossa oleva index-funktio suoritetaan sovelluksen sivulle tultaessa. T-funktio hoitaa sisällön kääntämisen eri kielille. Muuta funktion asettamia ja palauttamia tietoja ja kokeile miten www-sivun sisältö muuttuu
- Tutki mitä löytyy applications/omasovellus/views/default/index.html-tiedostosta. Tämä on index-funktiota vastaava näkymä (template) ja vastaa varsinaisen HTML-koodin tuottamisesta. Muuta tiedoston sisältöä ja testaa miten www-sivu muuttuu.
- Lisää default.py-tiedostoon uusi palaute-funktio:
def palaute(): response.flash = "Kokeilen web2py-juttuja" return dict(palaute='Hyvä', arvosana=5)
- Kokeile osoitetta http://localhost:8080/palaute. Sivun pitäisi käyttää oletusnäkymää (generic.html). Oletusnäkymä toimii vain omalla koneella testattaessa eli jos julkaiset sovelluksen Googlen palvelimille niin tämä sivu ei toimisi.
- Luo views/default-kansioon uusi tiedosto palaute.html ja kirjoita tiedoston sisällöksi:
<!DOCTYPE HTML> <html> <head> <title>web2py-kokeilu</title> </head> <body> <p>{{=palaute}}</p> <p><strong>{{=arvosana}}</strong></p> </body> </html>
- Kokeile nyt uudelleen osoitetta http://localhost:8080/palaute. Sivun sisällön pitäisi muuttua.
- Tutki mitä applications/omasovellus/models-kansion tiedostot sisältävät. Luo models-kansioon uusi tiedosto omat.py ja kirjoita siihen:
# oman tietokannan määrittelyt käyttäen web2pyn DAL-rajapintaa db.define_table('palaute', Field('palaute', 'text', required=False), Field('arvosana', 'integer', required=False))
- Mene tutkimaan mitä löytyy web2pyn tietokanta-admin-sivulta osoitteesta http://localhost:8080/appadmin/index. Taululistauksessa pitäisi näkyä yllä määritelty palaute-taulu. Yritä lisätä admin-liittymän kautta muutama rivi palaute-tauluun. Voit kokeilla myös laajempaa Admin-sovellusta osoitteessa http://localhost:8080/admin. Jos et pääse appadminiin vaan saat virheilmoituksen Admin is disabled because insecure channel niin varmista, että käyttämäsi osoite on localhost-alkuinen.
- Muuta määrittelyjä seuraavasti:
db.define_table('palaute', Field('palaute', 'text', required=False), Field('arvosana', 'integer', required=False, requires=IS_IN_SET([0, 1, 2, 3, 4, 5])))
Ylläoleva ottaa käyttöön validaattorifunktion, joka rajaa syötteet tietyksi listaksi. Kokeile nyt lisätä uusi palaute admin-sivulta. Lomakkeen pitäisi olla nyt erinäköinen. Muihin käytettävissä oleviin tietotyyppeihin ja validaattoreihin voi tutustua web2py-ohjeessa.
- Muuta palaute-funktio seuraavanlaiseksi:
def palaute(): response.flash = "Kokeilen web2py-juttuja" # haetaan tietokannasta kaikki palautteet palautteet = db().select(db.palaute.ALL) # palautetaan näkymälle yksittäinen palaute ja tietokannasta haetut return dict(palaute='Hyvä', arvosana=5, palautteet=palautteet)
Vastaava näkymä eli palaute.html täytyy muuttaa seuraavanlaiseksi. Nyt tarvitaan silmukka, joka osaa tulostaa kaikki palautteet. Huomaa pass-avainsana, joka kertoo missä vaiheessa silmukkakoodi loppuu. Pythonin normaali sisennyskäytäntö ei toimi näkymissä. Web2pyn näkymät ymmärtävät kaikki tavalliset python-kielen rakenteet. Lisätietoa: web2py views.<!DOCTYPE HTML> <html> <head> <title>web2py-kokeilu</title> </head> <body> <p>{{=palaute}}</p> <p><strong>{{=arvosana}}</strong></p> <h2>Listaus</h2> <ul> {{for pl in palautteet:}} <li>{{=pl.palaute}} / {{=pl.arvosana}}</li> {{pass}} </ul> </body> </html>
- Lisätään sivulle vielä lomake (SQLFORM) jolla voi lisätä uusia palautteita. Muuta palaute-funktio seuraavanlaiseksi:
def palaute(): response.flash = "Kokeilen web2py-juttuja" palautteet = db().select(db.palaute.ALL) form = SQLFORM(db.palaute) if form.process().accepted: response.flash = 'Palaute on lisätty' elif form.errors: response.flash = 'Lomakkeen tiedoissa on virheitä' else: response.flash = 'Täytä lomake lisätäksesi uuden palautteen' return dict(palaute='Hyvä', arvosana=5, palautteet=palautteet, lomake=form)
- Lisää palaute.html-näkymään rivi:
{{=lomake}}
- Kokeile lisätä uusi palaute lomakkeella. Toimiiko? Ilmestyykö uusi palaute listaan? Kokeile ladata sivu uudelleen hetken kuluttua. Hajautettu tietokanta tekee tepposia ja lisäys ei näy samantien...
- Piilota lomakkeella näkyvä id-kenttä lisäämällä SQLFORMille parametri showid=False:
form = SQLFORM(db.palaute, showid=False)
- Muutetaan sivua vielä sen verran, että voidaan myös muokata palautteita. Muuta näkymän palautelistauskoodia:
<li><a href="?id={{=pl.id}}">{{=pl.palaute}} / {{=pl.arvosana}}</a></li>
Kokeile miten sivu muuttuu. - Käsittelijää pitää vielä muokata huomaamaan mahdollisesti valittu palaute. Muuta käsittelijässä lomakkeen luominen
seuraavaksi:
if request.get_vars['id'] != None: palaute = db.palaute( request.get_vars['id'] ) form = SQLFORM(db.palaute, palaute, deletable=True) else: form = SQLFORM(db.palaute)
Tutustu web2pyn request-objektiin
- Kokeile nyt sivua. Onnistuuko palautteen muokkaaminen? Muista hajautetun tietokannan aiheuttama viive.
- Tee ohjelmakoodiin kirjoitusvirhe ja kokeile miten sivu toimii. Sinun pitäisi saada virheilmoitus ja linkki tikettiin. Katso App Engine Launcherin Logs-painikkeella tarkka virheilmoitus. Käy tutkimassa admin-sivulta sovelluksen virheitä.
- Testataan vielä sessioiden toimintaa ja laitetaan sivulle pieni laskuri. Lisää käsittelijään seuraavat rivit
ja palauta session.laskuri-muuttuja näkymälle:
if not session.counter: session.counter = 1 else: session.counter += 1
- Lisää näkymään tarvittava koodi, että saat laskurin näkyviin. Kokeile kasvaako laskuri sivua uudelleen ladattaessa.
- Otetaan vielä näkymässä käyttöön pohjanäkymä josta olisi hyötyä jos sovelluksessa olisi useita sivuja ja halutaan
pitää ne samannäköisinä. Lisää views-kansioon, eli samaan kansioon missä on myös generic.html, uusi tiedosto pohja.html, jonka sisältö on seuraava:
<!DOCTYPE HTML> <html> <head> <title>{{=response.title}}</title> </head> <body> <p>Tämä teksti tulee yhteisestä pohjasta</p> {{include}} <p>Tämä teksti tulee yhteisestä pohjasta</p> </body> </html>
- Poista nyt palaute.html-tiedostosta kaikki se mitä pohja.html-tiedostossa jo lukee ja kirjoita tiedoston alkuun rivi:
{{extend 'pohja.html'}}
- Kokeile miten sivun ulkoasu muuttui
- Lisää sivustolle autentikointi. Lisää models-kansion omat.py-tiedoston alkuun rivit:
from gluon.contrib.login_methods.gae_google_account import GaeGoogleAccount auth.settings.login_form = GaeGoogleAccount()
Lisää käsittelijään uusi funktio (ellei siellä jo ole):def user(): return dict(form=auth())
ja viimeiseksi lisää autentikointia vaativien funktioiden eteen rivi @auth.requires_login(). Esimerkiksi:@auth.requires_login() def palaute(): ...
- Poista web developer toolbarin avulla kaikki domain-cookiet (poistaa mahdollisen kirjautumisen ja session) ja kokeile sen jälkeen mennä palautesivulle. Sovelluksen pitäisi pyytää kirjautumaan Google-tunnuksella.
Debuggaus
Web2py-sovellusten debuggaamiseen on monia vaihtoehtoja ja tasoja:
- Aseta näkymässä näkyville debuggaus-palkki:
{{=response.toolbar()}}
- Tutki Google App Engine Launcher virhelogia (Logs-painike)
- Tutki Admin-sivun Errors-listausta
- Käytä web2pyn omaa www-palvelinta ja sen debuggausominaisuuksia
- Käytä Eclipseä ja PyDev:iä
Käyttäjien kommentit