La capa de interfaz HTTP

A continuación se presenta el listado íntegro del módulo que implementa el servidor de aplicaciones.

Figura 2. La interfaz web

from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer,test
import cgi
import string


class AgendaHTTP(BaseHTTPRequestHandler):
	def do_GET(self):
		self.do_HEAD()
		if self.response==404:
			self.wfile.write('404 El método no existe' )
			return
		if self.metodo=='/busca':
			try:
				ret=db.busca(self.dicParams['param'][0])
			except:
				ret=[]
			retHTML=''
			for elem in ret:
				retHTML=retHTML+'<li>%s = %s-%s' % (elem[0],elem[1][0],elem[1][1])
			self.wfile.write('''<html><body>
					<form><input name="param"> <input type="submit"></form>
					<p>Resultados</p>
					<ul>%s</ul>
					</body></html>''' % retHTML)
	def do_HEAD(self):
		if '?' in self.path:
			self.metodo, params=string.split(self.path,'?')
		else:
			self.metodo, params= self.path,''
		self.dicParams=cgi.parse_qs(params)
		if self.metodo in ['/busca']:
			self.response=200
		else:
			self.response=404
		self.send_response(self.response)
		self.send_header("Content-type", 'text/html')
		self.end_headers()
def run(db,host='localhost',port=8000):
    httpd = HTTPServer( (host, port) , AgendaHTTP)
    print "Serving HTTP on port", port, "..."
    httpd.serve_forever()

if __name__=='__main__':
    import sys
    if sys.argv==['sql']:
        import agendaSQL
        import PoPy
        db=agendaSQL.agenda(PoPy,'dbname=template1')
    else:
        import agendadb	
        db=agendadb.agenda()
    run(db)
    

Comentarios al listado

El operador % inserta las variables indicadas en la cadena de plantilla. Las cadenas pueden abarcar varias líneas si se encierran entre comillas triples. Esto resulta tremendamente útil para copiar y pegar código HTML o SQL, presentar pantallas de ayuda de consola, etc.

Python dispone de módulos muy potentes, listos para usar, en la distribución estándar. Es especialmente potente en todo tipo de aplicaciones relacionadas con internet, XML, HTTP, CGI, etc.

El código presentado es compatible con la versión 1.5.2 (considerada un poco antigua, pero aún frecuente en entornos de producción). Python 2 permite una sintaxis más elegante en algunos aspectos.

El atributo db, al que se hace referencia dentro del método do_GET, no se asigna hasta el final del todo. En Python no hay ningún problema en una variable inexistente en la definición de las funciones, con tal de que la variable exista en el momento de ejecutar el código.

Zope es como el servidor que acabamos de hacer, en versión mastodóntica. Zope incluye controles de seguridad, mecanismos de herencia y adquisición complejos, base de datos de objetos propia, gestión por la web, un sistema de plantillas, servidores virtuales, gestión de caches y equilibrado de carga entre servidores. Salvo esto, es prácticamente lo mismo... :-)

Más cercano resultaría Webware. Webware no se aleja de la programación en Python tanto como Zope. Da unos servicios más limitados y mucho más ligeros. Resumiendo burdamente, si lo que deseas hacer lo puedes hacer en Zope, es posible que tardes un tiempo sorprendentemente corto. En el momento en que algo no se adapte a Zope, es mejor abandonar y echar mano de Webware.