home > Φροντιστήριο για το web.py 0.2

Φροντιστήριο για το web.py 0.2

Ξεκινώντας

Αν γνωρίζετε Python και θέλετε να φτιάξετε ένα σάιτ, το web.py παρέχει τον κώδικα ώστε να το φτιάξετε εύκολα.

Για να παρακολουθήσετε ολόκληρο το φροντιστήριο, θα πρέπει να έχετε εγκατεστημένα τα εξής: Python, web.py, flup, psycopg2 και Postgres (ή κάποια αντίστοιχη βάση δεδομένων και τον οδηγό της). Για οδηγίες, κοιτάχτε εδώ.

Αν έχετε ήδη ένα υπάρχον πρότζεκτ γραμμένο σε web.py, ρίχτε μια ματιά στην σελίδα αναβάθμισης για πληροφορίες μεταφοράς.

Ας ξεκινήσουμε.

Διαχείριση των URL

Το πιο σημαντικό κομμάτι κάθε σάιτ είναι η δομή των URL του. Τα URL σας δεν είναι μόνο αυτά που βλέπουν οι επισκέπτες σας, και τα οποία στέλνουν με μέηλ στους φίλους τους, αλλά επίσης παρέχουν ένα νοητό μοντέλο του πως δουλεύει το σάιτ. Σε δημοφιλή σάιτ όπως το del.icio.us, τα URL είναι κομμάτι του user interface. Το web.py σας βοηθά να φτιάχνετε καλά URL.

Για να ξεκινήσετε την εφαρμογή σας, ανοίξτε ένα νέο αρχείο κειμένου (ας το πούμε code.py) και γράψτε:

import web.py

Έτσι αποκτούμε πρόσβαση στον κώδικα του web.py.

Τώρα, χρειαζόμαστε να πούμε στο web.py την δομή των URL μας. Ας βάλουμε κάτι απλό για αρχή:

urls = (
  '/', 'index',
  '',  'index'    )

Το πρώτο μέρος είναι μια κανονική έκφραση που ταιριάζει ένα URL, όπως τα /, /help/faq, /item/(\d+), κτλ (σημ: το \d+ ταιριάζει μια ακολουθία αριθμών). Οι παρενθέσεις σώζουν το κείμενο που ταιριάχτηκε με τα δεδομένα για περαιτέρω χρήση. Το δεύτερο μέρος είναι το όνομα της κλάσης στην οποία στέλνουμε το αίτημα, όπως: index, view, welcomes.hello (η οποία παίρνει την κλάση hello από το welcomes) ή get_\1. Το \1 αντικαθίσταται από το πρώτο μέρος της κανονικής έκφρασης που σώθηκε νωρίτερα· τα υπόλοιπα κομμάτια της κανονικής έκφρασης που σώθηκαν περνάνε στην συνάρτησή σας.

Η γραμμή μας λέει πως θέλουμε το URL / (σημ: η πρώτη σελίδα) να το χειρίζεται η κλάση με όνομα index.

Τώρα πρέπει να γράψουμε την κλάση index. Παρόλο που οι περισσότεροι άνθρωποι δεν το προσέχουν καθώς κινούνται στο δίκτυο, ο μπράουζερ χρησιμοποιεί μια γλώσσα γνωστή ως HTTP για επικοινωνία με το Παγκόσμιο Ιστό. Οι λεπτομέρειες δεν είναι σημαντικές, αλλά η βασική ιδέα είναι πως οι επισκέπτες του Ιστού ζητάνε από τους σέρβερ να εκτελέσουν καθορισμένες λειτουργίες (όπως GET ή POST) πάνω σε URL (όπως / ή /foo?f=1).

Το GET είναι αυτό με το οποίο είμαστε όλοι εξοικειωμένοι, αυτό που χρησιμοποιούμε όταν ζητάμε μια ιστοσελίδα. Όταν γράφετε harvard.edu στο μπράουζερ, αυτός ουσιαστικά ζητά από τον σέρβερ του Χάρβαρντ να φέρει (GET) το /. Το δεύτερο πιο γνωστό, το POST, συχνά χρησιμοποιείται όταν υποβάλουμε κάποιες φόρμες, όπως μια αίτηση για αγορά. Χρησιμοποιούμε το POST όταν η πράξη της υποβολής ενός αιτήματος κάνει κάτι (χρεώνει την πιστωτική μας κάρτα και εκτελεί την παραγγελία). Αυτό είναι ουσιώδες, καθώς τα URL που τα κάνουμε GET μπορούμε να τα χρησιμοποιήσουμε εδώ κι εκεί, ακόμη και να τα ταξινομήσουμε σε μια μηχανή αναζήτησης, που είναι αυτό που θέλουμε για τις περισσότερες σελίδες, αλλά οπωσδήποτε όχι για πράγματα όπως η διαχείριση μιας παραγγελίας (σκεφτείτε το Google να προσπαθεί να αγοράσει τα πάντα από το σάιτ σας!).

Στον κώδικά μας με το web.py, κάνουμε αυτή την διάκριση σαφή:

class index:
  def GET(self):
      print "Hello, world!"

Αυτή η συνάρτηση GET θα κληθεί από το web.py κάθε φορά που κάποιος κάνει μια αίτηση GET για το /.

Ωραία, τώρα χρειάζεται να το τελειώσουμε με μια τελική γραμμή που να λέει στο web.py να αρχίζει να εξυπηρετεί τις σελίδες.

if __name__ == "__main__": web.run(urls, globals())

Αυτό λέει στο web.py να σερβίρει τα URL που του δώσαμε παραπάνω, ψάχνοντας στις κλάσεις από τον καθολικό χώρο ονομάτων (namespace) του αρχείου.

Τώρα, προσέξτε, πως ενώ μιλάω πολύ, έχουμε γράψει μόνο πέντε γραμμές κώδικα. Μόνο αυτό χρειάζεστε για να φτιάξετε μια πλήρη web application. Αν πάτε στον φλοιό και γράψετε:

$ python code.py
Launching server: http://0.0.0.0:8080/

θα έχετε την εφαρμογή σας να τρέχει σ' έναν πραγματικό σέρβερ στον υπολογιστή σας. Επισκεφθείτε το URL και θα δείτε το "Hello, world!" (Μπορείτε να προσθέσετε μια διεύθυνση IP και μια θύρα μετά το "code.py" για να ρυθμίσετε που θα τρέξει το web.py τον σέρβερ. Μπορείτε επίσης να διαλέξετε να τρέξετε έναν fastcgi σέρβερ ή έναν cgi.)

Σημείωση: Μπορείτε να ορίσετε τον αριθμό θύρας αν δεν σας αρέσει ο προκαθορισμένος:

$ python code.py 1234

Κατά την ανάπτυξη

Το web.py έχει μερικά εργαλεία που μας βοηθάνε στο debbuging. Πριν το if __name__ στην τελευταία γραμμή, προσθέστε:

web.webapi.internalerror = web.debugerror

Αυτό μας δίνει κάπως πιο βοηθητικά μηνύματα σφαλμάτων. Και στην τελευταία γραμμή προσθέστε web.reloader ώστε να είναι έτσι:

if __name__ == "__main__": web.run(urls, globals(), web.reloader)

Αυτό λέει στο web.py να χρησιμοποιήσει το "ενδιάμεσο" κομμάτι κώδικα web.reloader (το ενδιάμεσο είναι ένα κομμάτι κώδικα, σαν περίβλημα, που προσθέτει κάποιες λειτουργίες στον σέρβερ μας), που φορτώνει τα αρχεία μας όταν τα αλλάζουμε, ώστε να βλέπουμε τις αλλαγές στον μπράουζερ απευθείας. (Για σημαντικές αλλαγές όμως, χρειάζεται να ξαναξεκινάμε τον σέρβερ). Μάλλον θα θέλετε να το βγάλετε όταν κάνετε το σάιτ σας δημόσιο, αλλά είναι σπουδαίο κατά την ανάπτυξη. Υπάρχει επίσης ο web.profiler, που εκτυπώνει πληροφορίες για το πόση ώρα έκανε κάθε συνάρτηση κατά την εκτέλεση, στο τέλος της σελίδας, ώστε να κάνετε τον κώδικά σας πιο γρήγορο.

Πρότυπα

Το να γράφουμε HTML μέσα από την Python είναι επίπονο· έχει περισσότερο γούστο να γράφουμε Python μέσα σε HTML. Ευτυχώς, το web.py το καθιστά εύκολο αυτό.

Σημείωση: Παλαιότερες εκδόσεις του web.py χρησιμοποιούσαν τα Πρότυπα Cheetah. Είναι, βεβαίως, στην ευχέρειά σας να χρησιμοποιήσετε αυτό ή οποιοδήποτε άλλο πρόγραμμα με το web.py, αλλά δεν υποστηρίζετε πλέον επίσημα.

Ας φτιάξουμε έναν νέο κατάλογο για τα πρότυπά μας (θα τον λέμε templates). Εκεί μέσα, θα φτιάξουμε ένα αρχείο που το όνομά του τελειώνει σε HTML (ας πούμε index.html). Τώρα, μέσα στο αρχείο αυτό, μπορούμε να γράψουμε απλή HTML:

<em>Hello</em>, world!

Ή, μπορούμε να χρησιμοποιήσουμε την γλώσσα προτύπου του web.py για να προσθέσουμε κώδικα στην HTML:

$def with (name)

$if name:
    I just wanted to say <em>hello</em> to $name.
$else:
    <em>Hello</em>, world!

Σημείωση: για τώρα, απαιτούνται τέσσερα ακριβώς κενά.

Όπως βλέπετε, το πρότυπο μοιάζει αρκετά με αρχείο Python, εκτός της δήλωσης def with στην κορυφή (που λέει με τι καλείται το πρότυπο) και τα δολλάρια που προστίθενται στην αρχή κάθε γραμμής κώδικα. Για την ώρα, το template.py απαιτεί η δήλωσω $def να είναι στην πρώτη γραμμή του αρχείου. Επίσης, προσέξτε πως το web.py αυτόματα κρύβει κάθε μεταβλητή που χρησιμοποιείται, ούτως ώστε αν για κάποιο λόγο το name περιέχει HTML, αυτό θα εμφανιζόταν κανονικά ως κείμενο. Αν δεν θέλετε αυτή την λειτουργία, γράψτε $:name αντί για $name.

Τώρα, πίσω στο code.py. Υπό την πρώτη γραμμή, προσθέστε:

render = web.template.render('templates/')

Αυτό λέει στο web.py να ψάξει για πρότυπα στον κατάλογο templates. Μετά, αλλάξτε το index.GET σε:

name = 'Bob'
print render.index(name)

('index' είναι το όνομα του προτύπου και 'name' το όρισμα που του περνάμε).

Πηγαίντε στο σάιτ σας και τώρα πρέπει να λέει γεια τον Μπομπ.

Συμβουλή ανάπτυξης: Προσθέστε cache=False στο τέλος της κλήσης του render ώστε το web.py να φορτώνει αυτόματα όποιες αλλαγές έχετε κάνει στην σελίδα.

Αλλά, ας υποθέσουμε πώς θέλουμε οι άνθρωποι να βάζουν το δικό τους όνομα. Αντικαταστήστε τις δύο παραπάνω γραμμές με τις παρακάτω:

i = web.input(name=None)
print render.index(i.name)

Πηγαίντε στο / και πρέπει να χαιρετάει τον κόσμο. Πηγαίντε στο /?name=Joe και θα χαιρετάει τον Τζο.

Βέβαια, έχοντας το ? στο URL είναι κάθως απωθητικό. Γι' αυτό αλλάξετε τα URL στην κορυφή με:

'/(.*)', 'index'

και αλλάξτε τον ορισμό του index.GET σε:

def GET(self, name):
    print render.index(name)

και διαγράψτε την γραμμή που ορίζει το όνομα. Τώρα πηγαίντε στο /Joe και θα χαιρετάει τον Τζο.

Αν θέλετε να μάθετε περισσότερα για τα πρότυπα στο web.py, επισκεφτείτε την σελίδα templetor.

Βάσεις

...