Una Web en Python sobre Apache, sin frameworks y en solo 3 pasos

Frecuentemente, todos los pythoneros nos llenamos la boca diciendo que “sin un framework, crear una WebApp en Python es imposible”. Pero claro, que esa frase no es menos exagerada que decir “si pierde mi equipo de fútbol me mato”. Son “formas de decir”.

La pregunta es ¿qué sucede si no tienes necesidad de crear una gran app? En ese caso ¿no es un desperdicio utilizar un framework como Django, por ejemplo?

Aquí es entonces, cuando surge la idea de este simple y sencillo tuto, para que en solo 3 pasos, tengas tu Web en Python, sobre Apache y por qué no, conviviendo con otras App en PHP.

Paso 1: Instalar mod_wsgi

mod_wsgi es un módulo de Apache que provee una interfaz WSGI para correr aplicaciones Web en Python sobre Apache. Y esto, es todo lo que necesitas para que tus archivos .py se ejecuten por medio de un navegador Web. Asumiendo que YA tienes instalado Python y Apache, solo debes descargar el paquete libapache2-mod-wsgi para ejecutar archivos en Python 2+ o libapache2-mod-wsgi-py3 para Python 3+.

apt-get install libapache2-mod-wsgi

Paso 2: Configurar el virtual host

En el virtual host, está la clave para correr aplicaciones Web en Python sobre Apache.

El DocumentRoot -al igual que se hace tradicionalmente con cualquier Web Site-, deberá ser un directorio servido pero, aquí NO colocaremos nuestra Python App. Este directorio, solo almacenará archivos estáticos o cualquier otro que no sea .py

El truco, estará entonces, en una variable: WSGIScriptAlias a la cual le indicaremos que cualquier petición que llegue a nuestra Web, deberá ser procesada por el script WSGI de nuestra Python App (la cuál, deberá almacenarse en un directorio no servido).

Antes de configurar el virtual host, tengamos en claro como será la estructura de directorios:

misitio.com/
├── <strong>application/ (a)</strong>
│   ├── <strong>application.wsgi (b)</strong>
│   └── modulos_python_de_mi_app/
└── <strong>public_html/ (c)</strong>

(a) Directorio application: directorio NO servido que almacenará toda nuestra app en Python

(b) Archivo application.wsgi: script wsgi que manejará todas las peticiones del usuario a través de la URI

(c) Directorio public_html: directorio SERVIDO que solo almacenará archivos estáticos, nada o vaya uno a saber que cosa mientras que no sea nuestra Python App

Con esto en claro, solo quedará crear y configurar el virtual host para nuestra nueva Web:

1) Crear el archivo virtual host

echo "" &gt; /etc/apache2/sites-available/misitio.com

2) Configurar el virtual host

<virtualhost *:80&gt;
    ServerName misitio.com

    DocumentRoot /ruta/a/public_html
    <strong>WSGIScriptAlias / /ruta/a/application/application.wsgi
    ErrorLog /ruta/a/logs/py_errors.log
    CustomLog /ruta/a/logs/py_access.log combined

    &lt;Directory /&gt;
        Options FollowSymLinks
        AllowOverride All
    &lt;/Directory&gt;
&lt;/VirtualHost>

2.1) Agregar el nuevo host

Si estás trabajando localmente, para no sobreescribir tu virtual host por defecto (archivo default), creando un nuevo virtual host, tienes la posibilidad de agregarlo al /etc/hosts para que en vez de correrlo mediante http://localhost puedas correrlo a través de http://mi_otro_host, por ejemplo:

127.0.0.1 misitio.com

3) Habilitar el nuevo sitio y el módulo rewrite de Apache

a2enmod rewrite | a2ensite misitio.com

4) Reiniciar Apache

service apache2 restart

Paso 3: Crear el archivo application.wsgi

Este archivo, recordemos que estará alojado en nuestra carpeta no servida, application. En este archivo necesitaremos una función application la cual tomará dos parámetros: environ del módulo os, que provee de un diccionario de las peticiones HTTP estándar y la función start_response, encargada de entregar la respuesta HTTP al usuario. Veamos un ejemplo sencillo:

# -*- coding: utf-8 *-*

import os, sys

sys.path.append('/ruta/a/application')

def application(environ, start_response):
    output = "&lt;b&gt;Hola Mundo!&lt;/b&gt;"
    start_response('200 OK', 
                   [('Content-Type', 
                     'text/html; charset=utf-8')])

    return output

Si ingresas a tu sitio Web (el configurado anteriormente), podrás ver la frase “Hola Mundo!” en negritas.

Como puedes ver, la variable temporal output es quien almacenará todo el contenido HTML (ya con el render hecho). Esto significa, que dicha variable, podría por ejemplo, obtener su valor desde la llamada a un módulo propio de nuestra Python App:

from mipaquete.mimodulo import mi_funcion
output = mi_funcion()

Incluso, podría ser aún más dinámico, switcheando la petición de REQUEST_URI:

peticion = environ['REQUEST_URI']

if peticion == '/':
    from mipaquete.mimodulo import mi_funcion_por_defecto
    output = mi_funcion_por_defecto()
elif peticion == '/contacto':
    from mipaquete.contacto import mostrar_form_de_contacto
    output = mostrar_form_de_contacto()
else:
    output = "No se a dónde quieres acceder!!"

Es importante aclarar que con cada cambio que se haga a la aplicación, se debe reiniciar Apache para que los cambios se reflejen sin conflictos.

Otro aspecto a tener en cuenta, es que cuando se produzcan errores 500 (Internal Server Errors) hay que acostumbrarse a mirar los logs en el archivo py_errors.log que configuramos en el virtual host, para conocer el error producido y así poder resolverlo.

Puedes además, descargar una mini-python-app de muestra, desarrollada con este tuto.

Espero que les haya servido y ¡hasta la próxima!

17 ideas sobre “Una Web en Python sobre Apache, sin frameworks y en solo 3 pasos”

Los comentarios están cerrados.