I can do tutorials me.
Merk trouwens op dat ik klasses declareer om te laten zien hoe de klasse er uit ziet, en welke functie's en variabelen het heeft. Het is wel belangrijk om te weten dat die stukjes code niet syntax correct zijn, het is alleen maar om aan te geven hoe de klasses er ongeveer uit zien(ik heb namelijk ook een heleboel functie's weggelaten).
CGI
De Common Gateway Interface, of kortweg CGI is een al lang bestaande standaard voor serverside programmeren. Met CGI kan je inprincipe elke script- en programmeertaal de data van een webserver verwerken. CGI werkt best simpel, je zorgt dat je een webserver hebt met CGI support(bijvoorbeeld Apache met de CGI module), en dan zorg je dat de webserver weet waar je scripts zijn(moeten meestal in een cgi-bin map zitten). Met je script zorg je er dan bijvoorbeeld voor dat je de data die je via GET of de POST methode binnenkrijgt, verwerkt. Om tekst op je webpagina te krijgen, hoef je alleen maar text te printen naar stdout.
De output moet er uiteindelijk zo uitzien:
Citaat:headerproperty#1
headerproperty#2
[..]
headerproperty#n
webpagina tekst#1
webpagina tekst#2
[..]
webpagina tekst#x
Oftewel, op de eerste regels komen alle MIME headers(je moet minimaal de header
Content-Type: mijncontenttype hebben(waar mijncontenttype bijvoorbeeld text/html is)), dan heb je een lege regel, en dan komen alle regels die je in je broncode van je html/xml/whatever pagina wilt hebben.
Pyhon en CGI
Om dus een hele webpagina te genereren, hoef je alleen maar te printen naar stdout. Je kan dus met print hele pagina's genereren.
Maar je wilt waarschijnlijk ook communiceren met de webpagina gebruiker(doordat de gebruiker bijvoorbeeld velden invult of checkboxen aanklikt). Dat kan op twee manieren, via elementen uit de HTML pagina(die een waarde hebben) en cookies(en sessions? die kon ik iig niet op doc.python.org vinden). Daar gaan de volgende twee sectie's ook over(merkop dat ik niet probeer een reference of compleet probeer te zijn, ik sla(zoals je zal zien) een hele hoop functie's over, omdat het veel te veel werk is om het uit te leggen, en/of niet relevant zijn).
FieldStorage
De module cgi, bevat de klasse FieldStorage(en nog wat andere functie's, die je
hier kunt vinden), waarmee je waardes van variabelen kunt uitlezen die via de methode POST of GET zijn verstuurd.
Code:
class FieldStorage(dict):
__init__(self, keep_blank_values=0)
def getfirst(self, key, default=None)
def getlist(self, key)
Note dat ik alleen de belangrijke functie's heb toegevoegd(bijvoorbeeld de verouderde functie getvalue heb ik niet toegevoegd).
Je kan FieldStorage zien als een soort dictionary(het heeft ook , je kan de elementen accessen door hun naam als key te gebruiken. Als de variabele
keep_black_values waar is, dan worden variabelen met een lege string ook toegevoegd als elementen.
De functie getfirst uit de klasse FieldStorage geeft de waarde van het element key terug(het geeft geen list terug als er meerdere variabelen met dezelfde key zijn). Als er geen element is is met key
key, dan wordt de parameter default gereturned.
De functie getlist is ongeveer hetzelfde, maar geeft dan een list terug(en een lege list([ ]) als er geen element is met key
key).
Merkop dat de klasse FieldStorage geen informatie geeft over of de variabelen via methode POST of GET zijn verkregen.
Cookies
Cookies stel je in door het in de headers van de pagina(met Set-Cookie) te zetten. Om het instellen van cookies wat eenvoudiger te maken bestaat er de module cookie. De twee belangrijkste klassen uit de module cookie zijn Morsel en SimpelCookie:
Code:
class Morsel():
coded_value # de waarde van de cookie als een string
key # de naam van de cookie
value # een python object die de waarde van de cookie heeft
def output(self, attrs=None, header='Set-Cookie') # Een string met de waarde van de cookie
def set(self, key, value, coded_value) # stel de waardes van de respectievelijke variabelen in
def OutputString(self, attrs=None): # Hetzelfde als output maar dan zonder omringende javascript of HTTP
# SimpleCookie is ook een dictionary, de key(een string) is de naam van de cookie en de waarde is de waarde van de cookie
class SimpleCookie():
def __init__(self, input=None)
de parameter attrs is een list die er zo uit ziet: ['path', 'comment', 'domain', 'max-age', 'secure', 'version', 'expires']
Verder heeft de de module Cookie nog de functie's js_output en output, beide geven ze de waarde van de cookie terug, maar de ene is een HTTP header, en de andere is een stukje javascript code. En dan heeft de module ook nog de functie load, die laad een cookie, en geeft een nieuwe instance van morsel terug.
Errors
Normaal gesproken wordt alle output van stderr opgevangen door de webserver, en waarschijnlijk naar de logfiles gestuurd, en je zal dan geen syntax error krijgen op je webpagina. Als je geen rechten hebt tot bijvoorbeeld de logfile, dan is dat een probleem. Gelukkig is er een module genaamd cgitb(cgi traceback), die error voor zorgt dat een error op je webpagina komt(dat is ook een stuk makkelijker dan steeds in je log files te kijken). Inprincipe heb je van de module alleen maar de functie enable nodig, die ervoor zorgt dat de errors op je webpagina komen:
Code:
def enable(display=true, logdir=None, context=5)
Als display true is, dan komt de traceback op het scherm. De traceback wordt ook geschreven naar logdir. En er wordt maximaal
context regels aan broncode per frame uitgeprint.
Broncode voorbeeldje
De volgende broncode genereert een webpagina, met links naar alle bestanden uit de huidige map en laat alle elementen zien, die via een POST of GET methode is gegeven:
Code:
#!/usr/bin/python
import cgitb
import cgi
cgitb.enable()
print "Content-Type: text/html"
print
print "<html>"
print "\t<head>"
print "\t\t<title>CGI-BIN directory</title>"
print "\t</head>"
print "\t<body>"
print "\t\t<div style=\"width: 80%; margin-left: auto; margin-right: auto;\">"
print "\t\t\tThis page displays the contents of this directoy, so you can checkout the files."
print "\t\t\t<br /><br />"
print "\t\t\t<b>Files:</b><br />"
import os
for file in os.listdir(os.getcwd()):
print "\t\t\t<a href=\"" + file + "\">" + file + "</a><br />"
print "<br /><br />"
print "<b>Argumenten die je mij hebt gepaast:</b><br />"
argumenten = cgi.FieldStorage()
for arg in argumenten:
print arg, "met waarde", argumenten.getfirst(arg) + "<br />"
print "\t\t</div>"
print "\t</body>"
print "</html>"
Vanuit gaant dat je je python intepreter in /usr/bin hebt staan(de webserver weet welke interpreter hij moet gebruiken aan de hand van de eerste regel).
En nu hoef je alleen nog maar de execute bit op 1 te hebben(en de file in de juiste map zetten, zoals bij apache in een cgi-bin map) zodat je je file kan draaien:
chmod +x mijnfile.py
CGI en Apache
Omdat de meeste mensen Apache hebben, hier ffies in het kort hoe je scripts met CGI moet draaien.
Om scripts uit te kunnen voeren met Apache, moet je als eerste natuurlijk de cgi module hebben geinstalleerd. Verder moet je nog aangeven in je httpd.conf waar je hoofd cgi-bin map is met:
Code:
ScriptAlias /cgi-bin/ /usr/local/apache2/cgi-bin/
Oftewel, als je naar
mijndomein.nl/cgi-bin/jeuj surft zal er in de map /usr/local/apache2/cgi-bin/ gezocht worden naar het bestand jeuj.
Als je wilt dat je ook in bijvoorbeeld mappen van users ook een cgi-bin map kunnen hebben, dan moet je het volgende in je httpd.conf bestand hebben:
Code:
<Directory /home/*/public_html/cgi-bin>
Options ExecCGI
SetHandler cgi-script
</Directory>
En dan moet je alleen nog de volgende code hebben om aan te geven welke scripts cgi-scripts zijn:
Code:
AddHandler cgi-script .py .cgi .pl
There ya go. Nu ben je klaar om je python files uit te voeren.
Voor meer info over cgi en apache, bekijk eens:
http://httpd.apache.org/docs/2.0/howto/cgi.html