Buscando la solución perfecta...
Probando distintos frameworks ( marcos ) de Python ( Bottle, Flask, CherryPy, Twistted, Tornado, ...) he comprobado que no existe una solución perfecta que pueda aprender en poco tiempo, en definitiva, que comprenda lo que estoy haciendo.
Cuando existe un problema a resolver, lo separo en partes más pequeñas, que luego puedo resolver fácilmente. Este es el procedimiento que seguiré para explicar como realizar una Web que funcione en un servidor Apache, con Python + Web Server Gateway Interface ó Python+WSGI.
Configurar httpd.conf de Apache con mod_wsgi
Compruebe si en el fichero /etc/httpd/conf/httpd.conf existe una línea comoLoadModule wsgi_module modules/mod_wsgi.so
Si no la encuentra, compruebe también si existe otra como :
Include conf.d/*.conf
que el servidor utilizará para cargar configuraciones de otros ficheros, en este caso del directorio /conf.d y compruebe si en el directorio indicado existe algún fichero que cargue la línea mencionada anteriormente.
Si la comprobación ha sido negativa. Puede instalar mod_wsgi.so, para Centos 5.6 se puede instalar con :
# yum install mod_wsgi
ó
# cd /usr/src
# wget http://modwsgi.googlecode.com/files/mod_wsgi-3.4.tar.gz
# tar zxvf mod_wsgi-3.4.tar.gz
# cd mod_wsgi-3.4
# ./configure
Nota : Si obtiene un error 'apxs: command not found ', le indica que no existe el paquete para instalar módulos en apache, necesitará...
yum install httpd-devel
Después de descomprimir el paquete tar.gz compilamos e instalamos
# make
# make install
y agregamos la línea para cargar el módulo en el httpd.conf junto a las rentantes líneas de carga de módulos :
LoadModule wsgi_module lib/apache/mod_wsgi.so
Y reiniciamos el Apache
# service httpd restart
Si esta instalacón no fuera correcta para su distribución, debe buscar una solución para instalarlo, antes de continuar.
Configurar el Virtual Host en Apache
De forma habitual ( hablando de Linux ), Apache servirá las páginas que se crean en /var/www/htmlPara esta prueba, crearemos la siguiente estructura :
/var/www/web_de_prueba/
|--- app
| |-------modulos
|
|---- html
|-----log
|-----error
Traduciendo esta información a un Virtual Host de Apache será :
AllowOverride None
Order Deny,Allow
Deny from all
DocumentRoot /var/www/web_de_prueba/html
ServerName web_de_prueba
WSGIScriptAlias / /var/www/web_de_prueba/app/app.wsgi
ServerAlias web_de_prueba
ServerAdmin web_de_prueba@web_de_prueba.es
ErrorLog /var/www/web_de_prueba/log/error.log
CustomLog /var/www/web_de_prueba/log/access.log combined
ErrorDocument 400 /error/400.html
ErrorDocument 401 /error/401.html
ErrorDocument 403 /error/403.html
ErrorDocument 404 /error/404.html
ErrorDocument 405 /error/405.html
ErrorDocument 500 /error/500.html
ErrorDocument 503 /error/503.html
Options FollowSymLinks
AllowOverride All
Order Allow,deny
Allow from all
Además, es necesario añadir en el fichero /etc/hosts :
127.0.0.1 web_de_pruebas
No olvide cada vez que realice una modificación, rearrancar el servidor Web :
# service httpd restart
No aguanto 'Hola Mundo !'
Ya sé que es lo habitual, pero he comprobado tantos 'Hola Mundo!' que necesito hacer alguna prueba que aporte más energía para perder el miedo a un mundo que se programará fuera de un framework. Donde obtendremos un control completo sobre el programa :
En /var/www/web_de_prueba/app creamos el fichero app.wsgi con el siguiente código :
# -*- coding: utf-8 -*-
import os
import sys
sys.path.append('/var/www/web_de_prueba/app')
def application(environ, start_response):
''' Para los que añoran el Hola Mundo! ''' output = "Hola Mundo"+"<br>"
try:
''' Y comprobamos los valores que nos proporcionan los items de '''
for tup in environ.items():
output += str(tup) + "
"
for tup in environ.items():
output += str(tup) + "
"
except Exception as e:
output += "%s \n" % e
output += "%s \n" % e
start_response('200 OK',[('Content-Type','text/html;charset=utf-8')])
return output
# service httpd restart
y comprobar en el navegador http://web_de_prueba
verá algo parecido a lo siguiente ....
Hola Mundo
('mod_wsgi.listener_port', '80')
('mod_wsgi.listener_host', '')
('SERVER_SOFTWARE', 'Apache/2.2.15 (CentOS)')
('SCRIPT_NAME', '')
('mod_wsgi.handler_script', '')
('SERVER_SIGNATURE', '
Apache/2.2.15 (CentOS) Server at web_de_prueba Port 80
\n')
('REQUEST_METHOD', 'GET')
('PATH_INFO', '/')
('SERVER_PROTOCOL', 'HTTP/1.1')
('QUERY_STRING', '')
('HTTP_USER_AGENT', 'Mozilla/5.0 (X11; Linux x86_64; rv:10.0.7) Gecko/20120829 Firefox/10.0.7')
('HTTP_CONNECTION', 'keep-alive')
('SERVER_NAME', 'web_de_prueba')
('REMOTE_ADDR', '127.0.0.1')
('mod_wsgi.request_handler', 'wsgi-script')
('wsgi.url_scheme', 'http')
('PATH_TRANSLATED', '/var/www/web_de_prueba/app/app.wsgi/')
('SERVER_PORT', '80')
('wsgi.multiprocess', True)
('mod_wsgi.input_chunked', '0')
('SERVER_ADDR', '127.0.0.1')
('DOCUMENT_ROOT', '/var/www/web_de_prueba/html')
('mod_wsgi.process_group', '')
('SCRIPT_FILENAME', '/var/www/web_de_prueba/app/app.wsgi')
('SERVER_ADMIN', 'web_de_prueba@web_de_prueba.es')
('wsgi.input', )
('HTTP_HOST', 'web_de_prueba')
('wsgi.multithread', False)
('mod_wsgi.callable_object', 'application')
('HTTP_CACHE_CONTROL', 'max-age=0')
('REQUEST_URI', '/')
('HTTP_ACCEPT', 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8')
('wsgi.version', (1, 1))
('GATEWAY_INTERFACE', 'CGI/1.1')
('wsgi.run_once', False)
('wsgi.errors', )
('REMOTE_PORT', '42954')
('HTTP_ACCEPT_LANGUAGE', 'es-es,es;q=0.8,en-us;q=0.5,en;q=0.3')
('mod_wsgi.version', (3, 2))
('mod_wsgi.application_group', 'web_de_prueba|')
('mod_wsgi.script_reloading', '1')
('wsgi.file_wrapper', )
('HTTP_ACCEPT_ENCODING', 'gzip, deflate')
Si observa la aplicación ...
def application(environ, start_response)
comprobamos que tiene dos parámetros y :
start_response(status, response_headers, exc_info=None)
Para la siguiente prueba, crearemos un sencillo formulario, con el mismo código, aunque un poco cambiada la notación, en vez de usar += hemos usado .append( para construir el html :
# -*- coding: utf-8 -*-
import os
import sys
import string
sys.path.append('/var/www/web_de_prueba/app')
def application(environ, start_response):
# crear el html
output = ['<html><head></head><body>']
import os
import sys
import string
sys.path.append('/var/www/web_de_prueba/app')
def application(environ, start_response):
# crear el html
output = ['<html><head></head><body>']
# crear un formulario sencillo
output.append('<form method="post">')
output.append('<input type="text" name="test1">')
output.append('<input type="text" name="test2">')
output.append('<input type="submit">')
output.append('</form>')
try:
for tup in environ.items():
output.append(str(tup) + "<br>")
except Exception as e:
output.append("%s \n" % e)
# cuando recibimos un valor del formulario, lo mostramos
if environ['REQUEST_METHOD'] == 'POST':
# datos recibidos a traves de POST:
output.append('<h1>DATOS DEL FORMULARIO</h1>')
if environ['wsgi.input'] != None:
output.append(environ['wsgi.input'].read())
if environ['REQUEST_METHOD'] == 'POST':
# datos recibidos a traves de POST:
output.append('<h1>DATOS DEL FORMULARIO</h1>')
if environ['wsgi.input'] != None:
output.append(environ['wsgi.input'].read())
output.append('</body></html>')
# enviar resultados
output_len = len(' '.join(output))
start_response('200 OK', [('Content-type', 'text/html'),
('Content-Length', str(output_len))])
# creamos un string con toda la lista
# enviar resultados
output_len = len(' '.join(output))
start_response('200 OK', [('Content-type', 'text/html'),
('Content-Length', str(output_len))])
# creamos un string con toda la lista
return ' '.join(output)
Compruebe el código de ...
start_response('200 OK', [('Content-type', 'text/html'),
('Content-Length', str(output_len))])
('Content-Length', str(output_len))])
se incorpora la información de la longitud de los datos a mostrar.
Reiniciar el servidor
# service httpd restart
y comprobar en el navegador http://web_de_prueba podrá jugar con su formulario.
Avanzamos un poco más comprobando el parámetro 'REQUEST_URI', en el código anterior, sustituya la parte que hace referencia al formulario (# crear un formulario sencillo) por estos dos formularios:
if environ['REQUEST_URI'].endswith('prueba1'):
output.append('<form method="post">')
output.append('<input type="text" name="test1">')
output.append('<input type="text" name="test2">')output.append('<form method="post">')
output.append('<input type="text" name="test1">')
output.append('<input type="submit">')
output.append('</form>')
if environ['REQUEST_URI'].endswith('prueba2'):
output.append('<form method="post">')
output.append('<input type="text" name="test3">')
output.append('<input type="submit">')
output.append('</form>')
He incorporado una comprobación, para saber a qué formulario nos estamos refiriendo, cuando se indique http://web_de_prueba/prueba1 ó http://web_de_prueba/prueba2 veremos distintos resultados.
Con /prueba1
DATOS DE FORMULARIO
test1=varios+cosas&test2=nada+de+naday con /prueba2
DATOS DE FORMULARIO
test3=varios+cosasPara próximas entregas, quedará cómo cargar templates externos, guardar datos en una bb.dd., sessiones, cookies, autenticación, ... y comprendiendo lo que escribimos.
Hasta pronto !!!
Entorno de las pruebas :
CENTOS 6.2 + PYTHON 2.6.6 + APACHE 2.2.15
En el siguiente artículo hablaré sobre los generadores/importadores de plantillas o TEMPLATE.py
En el siguiente artículo hablaré sobre los generadores/importadores de plantillas o TEMPLATE.py