Web Development με Python Εισαγωγή στην Ανάπτυξη Εφαρμογών Web με Χρήση της Python, του Apache και του mod_python Βασίλης Παπαβασιλείου <el03020@mail.ntua.gr>, Κοινότητα Ελεύθερου Λογισμικού ΕΜΠ
Python Χαρακτηριστικά Interpreted Αντικειμενοστραφής Πολλαπλά Paradigms Δυναμικό Σύστημα Τύπων Αυτόματη Διαχείριση Μνήμης Πολλά Διαθέσιμα Modules Υλοποιήσεις Cpython Jython (Java Platform) IronPython (.NET)
Apache Τεχνολογίες Modules Υποστήριξη Γλωσσών Προγραμματισμού Server Side (Perl, Python, PHP,...) Authentication SSL/TLS Proxy Virtual Hosts 58.8% του Web Apache License (Ελεύθερη, όχι CopyLeft)
mod_python Φροντίζει για τη διασύνδεση του Apache με την Python, γρηγορότερα από CGI Υλοποιεί Handlers του Apache Publisher Handler: Υψηλού Επιπέδου, δεν ασχολούμαστε με τις λεπτομέρειες του HTTP Παράδειγμα: Αίτηση για το http://www.example.com/test.py/hello αντιστοιχεί σε κλήση της συνάρτησης hello στο αρχείο test.py
Διασύνδεση Χρήστης (Web Browser) HTTP/ HTTPS Apache (HTTP Server) mod_python Python DB-API DBMS
Ρύθμιση Apache # /etc/apache/httpd.conf LoadModule python_module libexec/apache2/mod_python.so <Directory /path/to/dir> SetHandler mod_python PythonHandler mod_python.publisher PythonDebug on </Directory>
Γειά σου, Κόσμε # hello_world.py header = <html><body> footer = </body></html> def index(req): return header + <p>hello world</p> + footer
Γειά σου, Κόσμε v2 # hello_world.py header = <html><body> footer = </body></html> def hello(req, name = None): if name: #!= None return %s<p>hello %s</p>%s % ( header, name, footer) # url: $SERVER/hello_world.py/hello?name=$NAME return %s<p>hello world</p>%s % ( header, footer)
Εισαγωγή Δεδομένων (i) <html> <body> <p>please provide feedback below:</p> <p> <form action="form.py/email" method="post"> Name: <input type="text" name="name"><br /> Email: <input type="text" name="email"><br /> Comment: <textarea name="comment" rows=4 cols=20> </textarea><br /> <input type="submit"> </form> </p> </body> </html>
Εισαγωγή Δεδομένων (ii) import smtplib WEBMASTER = "webmaster@localhost" # webmaster e-mail SMTP_SERVER = "localhost" # your SMTP server MAIL_FMT = """\ From: %s Subject: feedback To: %s I have the following comment: %s Thank You, %s """
Εισαγωγή Δεδομένων (iii) def email(req, name, email, comment): # make sure the user provided all the parameters if not (name and email and comment): return "A required parameter is missing, \ please go back and correct the error" # create the message text msg = MAIL_FMT % (email, WEBMASTER, comment, name) # send it out conn = smtplib.smtp(smtp_server) conn.sendmail(email, [WEBMASTER], msg) conn.quit() # provide feedback to the user return """<html><body> <p>dear %s, thank you for your input.</p> </body></html>""" % name
Authentication # hidden_page.py def auth (req, user, password): if user == admin and password == secret : return True return False def access (req, user): if user == admin : return True return False header = <html><body> footer = </body></html> def hello(req): return header + <p>this message is hidden</p> + footer
Διασύνδεση με DBMS Τυποποίηση DB-API MySQL: MySQLdb PostgreSQL PyGreSQL psycopg SQLite pysqlite Module connection.py, κλάση client
Simple Blog (i): SQL Table -- creating table CREATE TABLE stories ( number serial NOT NULL, title character varying(64) NOT NULL, published date DEFAULT ('now'::text)::date NOT NULL, message text ); -- new entry INSERT INTO stories (title, message) values ( title 1, message 1 ) -- table structure -- number title published message -- 1 Ημερίδα I.L.U.G. 20070604 Η ομάδα Χρηστών... -- 2 Συνάντηση Αύριο 20070604 Αύριο, Τρίτη... -- 3 Ανακοίνωση 20070607 Η κοινότητα...
Simple Blog (ii): connection.py $ python >>> from connection import client >>> cnx = client( lamp, vasilis, hidden ) >>> cnx.executea( select * from stories ) [[1, 'Ημερίδα I.L.U.G', '2007-06-04', 'Η ομάδα χρηστών...'], [2, 'Συνάντηση Αύριο', '2007-06-04', 'Αύριο, στις 15:00...'], [3, 'Ανακοίνωση', '2007-06-14', 'Η κοινότητα...']] >>> cnx.titles() ['number', 'title', 'published', 'message']
Simple Blog (iii): Python # simple_blog_lib.py import connection class generic_page: # snipped header, footer, return_html def init (self, **kwargs): self. dict.update(kwargs) def _post_to_html(id, title, date, text): return """<h4>%s</h4> <p class="post_date">%s</p> <div class="post_body">%s</div> """ % (title, date, text)
Simple Blog (iv): Python # simple_blog.py (continued) class blog_page(generic_page): def return_html(self, req): hdr = generic_page.header % (self.title, self.title, self.subtitle) entries_str =.join([_post_to_html(*a) for a in \ db.execute( select * from stories )]) return hdr + entries_str + generic_page.footer blog_obj = blog_page(title = title, subtitle = subtitle ) index = blog_obj.return_html
Σύνδεσμοι http://www.python.org http://www.byteofpython.info http://www.diveintopython.org http://httpd.apache.org http://www.modpython.org http://www.pygresql.org http://www.postgresql.org http://www.djangoproject.com