Es gibt viele Möglichkeiten eine Webanwendung zu gestalten. Bisher haben wir uns darauf verlassen, das Python auf dem Server Daten die wir benötigen zur Verfügung stellt, bzw. die Nutzereingaben verarbeitet. Aber wir haben uns noch nicht damit beschäftigt, wie der Nutzer mit dem Server kommuniziert.

Python

In Python schreiben wir eine einfache Funktion in einem file admin.py.

def hello(req, value):
    return 

Der Parameter req ist unser so genanntes „request object“. In diesem sind viele Informationen über den Fragenden gespeichert. Zum Beispiel finden wir in req.connection.remote_ip die IP Adresse unseres Clients. Das ist sehr nützlich für eine Sitzungsverwaltung oder einer Antwort in Landessprache.
„value“ sei erstmal ein beliebiger Parameter. Versuchen wir unseren ersten Aufruf mit: http://mein-server/admin.py/hello?value=mein-wert

Über das request Objekt können wir auf den Client zugreifen und ihm unsere Antwort mitteilen.

def hello(req, value):
    req.content_type = 'text/html'    
    req.write('<p>Du hast %s als Wert angegeben.\n</p>' %value)
return 

Immer noch ziemlich plump aber als Beispiel ausreichend. Es funktioniert auch text/plain als content_type.
Das reicht schon um komplette Webseiten via Python zu erstellen und anzuzeigen. Noch ein Beispiel.

def sum(req, v1, v2):
   req.content_type = 'text/html'
   req.write('<p>Die Summe aus %s und %s ist %d</p>' %(v1, v2, int(v1) + int(v2)))
   return

Der Aufruf erfolgt hier mit: http://mein-server/admin.py/sum?v1=2&v2=4

HTML-Form

Im request Object ist auch der Eintrag eines HTML-Form-Elements versteckt.

Python

if req.form.has_key("mein_key"):
    value = req.form["mein_key"]

HTML

<form id="id" action="admin.py/meineMethode" method="post">    
	<input type="hidden" name="mein_key" value="mein_wert">
	<input type="submit" value="Submit" name="submit"/> 
</form>

So funktioniert auch ein Dateiupload nach Python. In der Variablen file_t steht anschließend unsere Datei als String/ Binär. Beim Schreiben bitte aufpassen und je nach Fall ein ‘wb’ nutzen.

Python

if req.form.has_key('file'):
    file_t = req.form['file'].file.read()
    name = req.form['file'].filename
    type = name.split(".")
    type = type[len(type)-1]

HTML

<form id="fileUpload" action="admin.py/fileUpload" method="post" enctype="multipart/form-data">
    <input type="file" id="file" name="file"/>
	<input type="submit" value="Upload"/> 
</form>

Javascript

Mit Javascript können wir direkt auf die Parameter zugreifen. Längere Nachrichten oder große Objekte sollten am Besten als JSON verpackt versand werden. Auf diesem Wege können nur Strings versand werden, also den Typcast in Python nicht vergessen. Die Antwort von Python erfolgt als Rückgabewert. Diesen kann man mit dem Modul simplejson sehr komfortabel verpacken.

<script type="text/javascript">
    	
var request = null;

httpRequest("meineMethode", resultHandler, "argument1=wert1&argument2=wert2");

function resultHandler()
{
	if (request.readyState == 4)
	{	
		json = eval(request.responseText);
	}	
}

function httpRequest(method, resultHandler, params)
{
        var server = "admin.py";
	request = null;
	
	if (window.XMLHttpRequest) 
	{                     
		request = new XMLHttpRequest();              
	} 
	else 
	{                                      
		request = new ActiveXObject("Microsoft.XMLHTTP");
	} 
		    
	if (!request)
	{
		alert("Error initalizing HTTPRequest");
		return;
	} 
		    
	request.onreadystatechange = resultHandler;
        request.open( "POST", server + "/" + method, true);
		    
	request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	request.setRequestHeader("Content-length", params.length);
	request.setRequestHeader("Connection", "close"); 

	request.send(params);
}

</script>

Actionscript

Adobe hat sich mit Flex sehr viel Mühe gegeben. Dementsprechend gut ist auch der Actionscript httprequest. Hier ist es möglich beliebige Datentypen ohne Typcast an Python zu übertragen. Die Argumente werden in einem Dictionary an Python übertragen, deshalb bitte darauf achten, dass die Schlüssel stimmen. Um auf die Antwort zugreifen zu können, kann man den resultHandler von ResultEvent erben lassen.

package 
{
    import mx.rpc.AsyncToken;
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.http.HTTPService;
	
	public final class HTTPRequest
	{
		private var service:HTTPService = new HTTPService;
		
		// params = {arg:value}
		public function HTTPRequest(server:String, resultHandler:Function, errorHandler:Function, method:String, params:Object = null)
		{
			service.method = "POST";
			service.addEventListener(ResultEvent.RESULT, resultHandler);
			service.addEventListener(FaultEvent.FAULT, errorHandler);
			service.url = server + "/" + method;
			
			send(params);
		}
		
		private function send(params:Object):void
		{
			var at:AsyncToken = new AsyncToken(null);
			
			if (params)
				at = service.send(params);
			else
				at = service.send();	
		}
	}

	import mx.controls.Alert;
	import mx.core.Application;
	import mx.rpc.events.FaultEvent;
	
	public class Admin
	{
		private var request:HTTPRequest;
		private var server:String;
		
		public function Admin()
		{
			server = Application.application.url + "/admin.py";
		}
		
		
		public function meineMethode(resultHandler:Function, argument1:String, argument2:int):void
		{
			request = new HTTPRequest(server, resultHandler, errorHandler, "login", {argument1:argument1, argument2:argument2});
		}

}