Quijost

Webmaster => Desarrollo Web => Mensaje iniciado por: shakaran en Agosto 12, 2010, 19:26:27 pm

Título: Ejemplo de prueba index.py para Django y MySQL con mod_wsgi
Publicado por: shakaran en Agosto 12, 2010, 19:26:27 pm
Debido al reciente auge de cuentas que usan Django en nuestro servidor y algunas dudas que han ido enviadas al email de soporte, publicamos el código de un ejemplo base para mejor comprensión del funcionamiento y como punto de partida para nuevos usuarios.

Por defecto en los servidores de Quijost se utiliza mod_wsgi para servir páginas Python con Apache, anteriormente utilizábamos mod_python (http://quijost.com/foro/desarrollo-web/ejemplo-de-prueba-index-py-para-django/), pero debido a que no recibe actualizaciones de sus autores desde 2008 y esta desmantenido se producen varios errores con las nuevas versiones de Apache y es por este motivo por el que se utiliza mod_wsgi que es más eficiente y novedoso.

Paso 1: Crear un archivo index.py con el siguiente contenido de prueba:
Código: [Seleccionar]
#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Add the project to the python path
import os, sys
sys.path.append('/home/usuarioquijost/public_html/mydjangoapp/')
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))

# Prevent mod_wsgi from erroring on stdout access (WSGIRestrictStdout Off)
sys.stdout = sys.stderr

os.environ['PYTHON_EGG_CACHE']       = '/home/usuarioquijost/tmp/trac-eggs/'
os.environ['DJANGO_SETTINGS_MODULE'] = 'mydjangoapp.settings'

import django.core.handlers.wsgi

application = django.core.handlers.wsgi.WSGIHandler()

# Debug middleware
if settings.DEBUG:
    print >> sys.stderr, "Using Paste error middleware"
    from paste.exceptions.errormiddleware import ErrorMiddleware
    application = ErrorMiddleware(application, debug=True, show_exceptions_in_wsgi_errors=True)

# Create session directory if not present
if settings.SESSION_FILE_PATH:
    try:
     os.makedirs(settings.SESSION_FILE_PATH)
    except OSError:
        pass

def application(environ, start_response):
   
    import sys
    output = 'Python version: ' + str(sys.version) + '<br/>'

    import django
    output += 'Django version: ' + str(django.VERSION) + '<br/>'
   
    status = '200 OK'
    response_headers = [('Content-type', 'text/html;charset=UTF-8'),
                        ('Content-Length', str(len(output)))]
    start_response(status, response_headers)

    return [output]

Nota: Si usas MySQLdb o requieres de un directorio trac-eggs, en esta configuración básica no esta habilitado y te dara un error 500, lee al final del post, para conocer como configurarlo.

Paso 2: Para que el fichero sera interpretado por el servidor de mod_wsgi de Apache, es necesario definir un archivo .htaccess como por ejemplo el siguiente:
Código: [Seleccionar]
SetHandler wsgi-script
DirectoryIndex index.py

Importante: NO usar la directiva "PythonHandler". Esta directiva es sólo para mod_python y no para mod_wsgi, por lo que su uso esta obsoleto y producirá un error 500 al no estar soportada en mod_wsgi.

Para ver este mismo ejemplo funcionando (algo más avanzado), visitad: http://quijost.com/sandbox/index.py (http://quijost.com/sandbox/index.py)

Paso 3:: Crear un proyecto Django

Es necesario crear un proyecto Django para ejecutar este ejemplo. Observa que en nuestro index.py estamos sobreescribiendo la aplicación "application" para mostrar siempre nuestro index.py (con la versión  de Python y Django). Para configurar un proyecto Django más avanzado con vistas y múltiples direcciones se debe usar la técnica del fichero dwsgi.py redireccionando con el .htaccess

El proyecto Django puede crearse en el pc local del usuario y subirse por FTP en caso de no disponer de acceso SSH (por ejemplo en planes efree). Sin embargo si dispones de acceso SSH (para planes ebasic y superiores) puedes acceder por ssh y utilizar el comando:

Código: [Seleccionar]
cd ~/public_html/; django-admin.py startproject mydjangoapp
Esto creará un directorio mydjangoapp en public_html con el contenido del proyecto. Dentro de la carpeta mydjangoapp existirá otra carpeta mydjangoapp (la aplicación) con su fichero settings.py. Por ello previamente en el paso 1, hemos añadido la ruta (path) con la línea

Código: [Seleccionar]
sys.path.append('/home/usuarioquijost/public_html/mydjangoapp/')
Gestión de errores

Primero te aconsejamos leer nuestro post Gestionar errores 500 con manejadores Django (http://quijost.com/foro/python/gestionar-errores-500-con-manejadores-django/) para entender la forma de gestión de errores en Django.

Si recibes un error 500, lo más probable es que Django este lanzando alguna excepción de ImproperlyConfigured, que se traduce como un error 500 que es registrado en el error_log general de Apache. Puesto que en servidores compartidos no puede concederse acceso regular al error_log general por motivos de seguridad, puedes optar por envolver tu código entre try/catch para capturar la excepción y conocer el mensaje de error que origina tu problema.

Por ejemplo:

Código: [Seleccionar]
import traceback
filename = '/home/usuarioquijost/public_html/error_log.txt'
f = open(filename, 'w')
try:
  import django.core.handlers.wsgi
  application = django.core.handlers.wsgi.WSGIHandler()
  f.write('Ok')
except:
  traceback.print_exc(file=f) 
f.close()

Es importante recalcar que la ruta del archivo "filename" debe ser absoluta para evitar confusiones (y adaptarla al usuario propio de Quijost). Por ejemplo, si se establece como ruta sólo el nombre "error_log.txt" provocará un intento de registrar errores en "/error_log.txt" (la raíz del servidor, no la del directorio de usuario) y se obtendrá un Permission Denied ya que no existen permisos root.

Para establecer los permisos de escritura en el archivo de error_log.txt y evitar un error 500, ejecutar:

Código: [Seleccionar]
chmod 777 /home/usuarioquijost/public_html/error_log.txt
También puede usar algunos manejadores (handlers) más avanzados para la depuración de errores: http://www.davidcramer.net/code/502/debugging-django-errors.html (http://www.davidcramer.net/code/502/debugging-django-errors.html)

Otra opción es redirigir la salida estandar de error de WSGI a un fichero de excepciones, con el que podras acceder a tus error_log generados.

Debes crear una clase para las excepciones. Puedes encontrar más información en este artículo (en inglés):
http://lucumr.pocoo.org/2007/5/21/getting-started-with-wsgi (http://lucumr.pocoo.org/2007/5/21/getting-started-with-wsgi)

Solución de errores 500 - Directorio trac-eggs

Uno de los errores más frecuentes es poner una ruta trac-eggs incorrecta. Esta ruta, debe estar en un directorio accesible por el usuario y con permisos de escritura.

Para ello puedes ponerla como:
Código: [Seleccionar]
import os
os.environ['PYTHON_EGG_CACHE'] = '/home/USUARIO/tmp/trac-eggs'

Es importante que este directorio disponga de permisos de escritura para mod_wsgi, de lo contrario no podrá descomprimir los egg, por ejemplo de MySQL y resultará otro error 500 al arrojar una excepción de ExtractionError:

Código: [Seleccionar]
ExtractionError: Can't extract file(s) to egg cache
 
 The following error occurred while trying to extract file(s) to the Python egg
 cache:
 
   [Errno 13] Permission denied: '/home/usuario/tmp/MySQL_python-1.2.3-py2.7-linux-x86_64.egg-tmp'

Si tienes algún problema adicional, no dudes en abrir un tema en el foro y te ayudaremos con el despliegue de tu aplicación. Te aconsejamos antes revisar algunos post de nuestro foro y faqs por si es  una duda previamente resuelta.
Título: Re:Ejemplo de prueba index.py para Django y MySQL con mod_wgsi
Publicado por: fiachett en Agosto 18, 2010, 17:23:04 pm
shakaran, cómo estás?. Estoy probando el ejemplo, pero no funciona ni el que hice yo, ni  http://quijost.com/sandbox/index.py

El error que sale es el siguiente:

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator, webmaster@fiachett.quijost.com and inform them of the time the error occurred, and anything you might have done that may have caused the error.

More information about this error may be available in the server error log.

Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.


Muchas gracias
Título: Re:Ejemplo de prueba index.py para Django y MySQL con mod_wgsi
Publicado por: shakaran en Agosto 18, 2010, 18:43:33 pm
Gracias por aviso. Parece ser que con la migración el modulo de mysql no estaba recompilado para python y ese era el error, ahora ya carga la página de ejemplo y debería cargar la tuya a menos que tengas algun error (te aconsejo mirar los error_log de tu cuenta para ver posibles errores).

Dejanos saber si aún sigues teniendo problemas.
Título: Re:Ejemplo de prueba index.py para Django y MySQL con mod_wgsi
Publicado por: impulse en Septiembre 01, 2010, 01:00:16 am
Hola, estoy intentando ejecutar el script como has explicado en este hilo, pero recibo un error 500.

Lo estoy intentando probar en www.josejimenez.net/prueba/index.py

Por otra parte, he visto que en mi home tengo un enlace al fichero access.log de Apache. Habría posibilidad de tener otro enlace al fichero error.log?

Gracias.

Título: Re:Ejemplo de prueba index.py para Django y MySQL con mod_wgsi
Publicado por: shakaran en Septiembre 01, 2010, 12:12:38 pm
Hola, el fichero error_log de apache es general de todo el server, con información sensible de todos los usuarios y no puedo darte acceso al mismo (unicamente si tuvieras tu propio VPS podrías gestionarlo). Pero en realidad no te hace falta acceso al mismo. ya que lo unico que necesitas es redirigir la salida estandar de error de WSGI a un fichero de excepciones y evitar el error 500.

Para ello simplemente debes crear una clase para las excepciones. Puedes encontrar más información en este artículo (en inglés):
http://lucumr.pocoo.org/2007/5/21/getting-started-with-wsgi

Otro artículo util podría ser (en inglés): http://www.davidcramer.net/code/502/debugging-django-errors.html

Nuestro post, es un ejemplo básico sin gestión de excepciones, por eso se escribe alguna línea mal, fallará dando un error 500 al no tener manejador de excepciones implementado.

En tu caso aparece lo siguiente en el error_log:

Código: [Seleccionar]
[Wed Sep 01 12:04:46 2010] [error] [client 83.*.*.*] mod_wsgi (pid=31878): Exception occurred processing WSGI script '/home/josejime/public_html/prueba/index.py'.
[Wed Sep 01 12:04:46 2010] [error] [client 83.*.*.*] Traceback (most recent call last):
[Wed Sep 01 12:04:46 2010] [error] [client 83.*.*.*]   File "/home/josejime/public_html/prueba/index.py", line 10, in application
[Wed Sep 01 12:04:46 2010] [error] [client 83.*.*.*]     output += 'Python version: ' + str(sys.version) + '<br/>'
[Wed Sep 01 12:04:46 2010] [error] [client 83.*.*.*] UnboundLocalError: local variable 'output' referenced before assignment

Parece todo indica a que parece ser que no has declarado la variable output.
Título: Re:Ejemplo de prueba index.py para Django y MySQL con mod_wgsi
Publicado por: jyr en Septiembre 05, 2010, 03:20:49 am
Hola,

Ya he realizado varias pruebas de configuracion de django, pero como no funcionan me fui a lo basico a revisar el ejemplo que se muestra arriba, tengo un mensaje de error de apache que dice

Forbidden

You don't have permission to access / on this server.

Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.

Tendre en mi vhost o http.conf en directoryIndex algo como index.py o Options ... +Indexes?

Ahora si ejecuto mi index.py desde la url me manda el error 500 que comentan arriba, creo que falta configurar algo en apache para poder trabajar con el wsgi, lo del articulo de expeciones que comentas no servira hasta que se solucionen los errores de apache.

Si logro algun avance, regresare ...
Título: Re:Ejemplo de prueba index.py para Django y MySQL con mod_wgsi
Publicado por: shakaran en Septiembre 05, 2010, 04:30:12 am
Solucionado, era un error con la variable output que estaba inicialmente con += y debia ser el primero un = sólo. Como nuestro código de ejemplo online es algo distinto no fallaba, pero este que estaba puesto en el foro si contenia el error.
Título: Re:Ejemplo de prueba index.py para Django y MySQL con mod_wgsi
Publicado por: jyr en Septiembre 05, 2010, 06:40:07 am
Pasando a la configuracion de django tengo en un archivo llamando django.wsgi en el raiz de mi proyecto.

import os, sys
sys.path.append('/home/pythonco/public_html')
os.environ['DJANGO_SETTINGS_MODULE'] = 'pythoncocoa.settings'
os.environ['PYTHON_EGG_CACHE'] = '/tmp/trac-eggs'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

y en mi htaccess

SetHandler wsgi-script
PythonHandler wsgi_handler

RewriteEngine On
RewriteBase /
RewriteRule ^(media/.*)$ - [L]
RewriteRule ^(admin/.*)$ - [L]
RewriteCond %{REQUEST_URI} !(django.wsgi)
RewriteRule ^(.*)$ django.wsgi/$1 [L]

No me manda ningun error en el navegador, pero en la barra de estado dice:

"Esperando a pythoncocoa.com..."

y ahi se queda, si puedo obtener mi log error si es que lo hay, me seria de ayuda para saber por donde seguir.
Título: Re:Ejemplo de prueba index.py para Django y MySQL con mod_wgsi
Publicado por: jyr en Septiembre 05, 2010, 08:50:32 am
Hola, de nuevo...

Como les dije, ya regrese con la solución. Se tiene que modificar un 90% el htaccess y agregar un archivo al que llame django.wsgi al directorio del proyecto de django que se tenga. Los archivos se pueden ver en

http://gist.github.com/565775
http://gist.github.com/565777
http://gist.github.com/565795

También escribi un post al respecto en http://jyr.tumblr.com/post/1068266972/dpress-y-django-cms-sobre-wsgi y para muestra un botón (http://pythoncocoa.com/)
Título: Re:Ejemplo de prueba index.py para Django y MySQL con mod_wgsi
Publicado por: shakaran en Septiembre 05, 2010, 14:32:27 pm
Perfecto, gracias jyr por tu colaboración.

Preparemos un post it fijo explicando un tutorial mas avanzado con archivos .wsgi de proyecto.
Título: Re:Ejemplo de prueba index.py para Django y MySQL con mod_wgsi
Publicado por: Sam en Octubre 07, 2010, 22:59:41 pm
habra alguna manera de acceder a mas logs?

en mi django.wsgi estoy haciendo

Código: [Seleccionar]
...
try:
  .....
  import django.core.handlers.wsgi
  application = django.core.handlers.wsgi.WSGIHandler()
   
  f.write('Ok')
except:
  traceback.print_exc(file=f) 
f.close()

en el archivo me sale 'Ok',
pero en el log me sale todas las veces:

Código: [Seleccionar]
[Thu Oct 07 22:47:04 2010] [error] [client xxxxxxx] mod_wsgi (pid=32049): Exception occurred processing WSGI script '/home/myuser/public_html/django.wsgi'.
y la aplicacion en el browser se queda "esperando" y nunca carga

incluso probé hacer raise intencional de un error, a ver si aparecia en el archivo y efectivamente, asi fue, con lo que pareciera que no se esta produciendo ninguna excepcion....supuestamente, mi script se corrio bien hasta la ultima linea, pero el log del panel de control me dice lo contrario

Seguramente es alguna tontería en otro lado, pero me esta costando mucho encontrar el error sin ninguna informacion adicional  ... alguna otra alternativa para debuggear?
Título: Re:Ejemplo de prueba index.py para Django y MySQL con mod_wgsi
Publicado por: shakaran en Octubre 08, 2010, 16:01:56 pm
En esta url hablan sobre un middleware que actua como handler para los errores:

http://www.davidcramer.net/code/502/debugging-django-errors.html
Título: Re:Ejemplo de prueba index.py para Django y MySQL con mod_wgsi
Publicado por: Sam en Octubre 08, 2010, 21:25:14 pm
Gracias por el link! Me resolvio el problema
Título: Re:Ejemplo de prueba index.py para Django y MySQL con mod_wgsi
Publicado por: shakaran en Octubre 08, 2010, 22:16:14 pm
Genial, ¿te importaría poner tu código o un ejemplo similar en el subforo de python (http://www.quijost.com/foro/python/) con el fin de que futuros usuarios puedan beneficiarse de la ayuda?
Título: Re:Ejemplo de prueba index.py para Django y MySQL con mod_wgsi
Publicado por: Sam en Octubre 19, 2010, 20:16:03 pm
Estaba viendo de armar un post con este ejemplo de mod_wsgi incluyendo el debugger, cuando tenga un tiempito para subirlo paso el link
Título: Re:Ejemplo de prueba index.py para Django y MySQL con mod_wgsi
Publicado por: shakaran en Octubre 20, 2010, 01:49:32 am
Estaba viendo de armar un post con este ejemplo de mod_wsgi incluyendo el debugger, cuando tenga un tiempito para subirlo paso el link

Se agradecerá bastante tu aportación ;) La esperamos.
Título: Re:Ejemplo de prueba index.py para Django y MySQL con mod_wgsi
Publicado por: JCeb en Noviembre 11, 2010, 20:33:04 pm
He seguido al pie de la letra los pasos y me da errores al intentar poner un proyecto con la plantilla base :S

http://ecoproject.quijost.com/hola/

Alguien sabe porqué pudiera ser?, es más en el cpanel he agregado un nuevo handler para wsgi y ni así, desconozco la razón, alguién pudiera ayudarme?

Saludos.
Título: Re:Ejemplo de prueba index.py para Django y MySQL con mod_wgsi
Publicado por: lol en Noviembre 11, 2010, 23:22:33 pm
JCeb no funciona el link
Título: Re:Ejemplo de prueba index.py para Django y MySQL con mod_wgsi
Publicado por: ernestmego en Noviembre 12, 2010, 18:02:50 pm
Jceb, revisa tu archivo .htaccess, no esta encontrando bien la ruta del fichero django.wgsi

Te muestra un 404 en:
/django.wsgi/

Tu fichero .htaccess tiene:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !(django.wsgi)
RewriteRule ^(.*)$ django.wsgi/$1 [L]

Porque tienes un RewriteBase / que hace que la ruta sea en / y tu lo tienes en /hola, subelo todo en public_html o cambia a RewriteBase /hola


Título: Re:Ejemplo de prueba index.py para Django y MySQL con mod_wgsi
Publicado por: carlosvin en Diciembre 16, 2010, 12:01:57 pm
Hola a todos, estoy instalando una aplicación que he hecho utilizando django. He seguido este hilo y lo único que consigo es que se quede cargando la página de forma indefinida (http://carlosvin.quijost.com/ (http://carlosvin.quijost.com/)), a continuación os pego los ficheros.

/home/carlosvi/public_html/.htaccess
Código: [Seleccionar]
# htaccess for wsgi
SetHandler wsgi-script
PythonHandler wsgi_handler

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !(django.wsgi)
RewriteRule ^(.*)$ django.wsgi/$1 [L]

/home/carlosvi/public_html/django.wsgi
Código: [Seleccionar]
#django.wsgi
import os, sys
sys.path.append('/home/carlosvi/public_html/modules')
sys.path.append('/home/carlosvi/public_html/modules/django')
sys.path.append('/home/carlosvi/public_html')
os.environ['DJANGO_SETTINGS_MODULE'] = 'cmsdj.settings'
os.environ['PYTHON_EGG_CACHE'] = '/tmp/trac-eggs'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

Un saludo
Título: Re:Ejemplo de prueba index.py para Django y MySQL con mod_wgsi
Publicado por: pythoner en Abril 06, 2011, 13:33:20 pm
Después de unas cuantas horitas dedicándole a configurar esto y otras cuantas a leer documentación (y traducirla) he podido hacer que funcione Django con mod_wsgi. Me he basado en las configuraciones de los compañeros de hosting y he modificado un par de cositas, eso era lo único necesario (además de tener un poco más de experiencia en Django, pues aun sigue siendo bastante poca). Os expongo mi experiencia y espero que ayude a otros novatos.

Como bien se sabe en tu ordenador local estableces proyectos Django mediante la secuencia:

Código: [Seleccionar]
django-admin.py stratproject nombre_proyecto
Donde
Código: [Seleccionar]
nombre_proyecto es el nombre del proyecto que vas a empezar con Django, ya puede llamarse pythonerpythoncocoa, etc. Esto parece trivial, pero no lo es, ahora se verá el motivo.

Una vez establecido el proyecto, hemos desarrollado nuestro sitio web usando el servidor de desarrollo Django o bien en un servidor Apache/mod_wsgi en nuestro ordenador local, procedemos a subir el directorio que ha sido creado por
Código: [Seleccionar]
django-admin.py directamente al directorio
Código: [Seleccionar]
public_html de nuestra cuenta de hosting.

Una vez subido creamos en el directorio
Código: [Seleccionar]
public_html un archivo con el nombre de django.wsgi (este puede llamarse como se quiera, pero lo vamos a dejar así, pues parece que está puesto en este hosting de esta manera) con el siguiente contenido:

Código: [Seleccionar]
import os, sys

sys.path.append('/home/USUARIO/public_html/DIRECTORIO_PROYECTO_DJANGO')
sys.path.append('/home/USUARIO/public_html')

os.environ['DJANGO_SETTINGS_MODULE'] = 'DIRECTORIO_PROYECTO_DJANGO.settings'
os.environ['PYTHON_EGG_CACHE'] = '/tmp/trac-eggs'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

En este código resaltamos dos aspectos:

USUARIO: es el usuario que usas tanto para acceder a tu cuenta FTP, cPanel, etc.
DIRECTORIO_PROYECTO_DJANGO: es el hombre del directorio donde se hospeda el proyecto django, normalmente el creado por
Código: [Seleccionar]
django-admin.py.

Una vez hecho eso, procedemos a crear un archivo llamado .htaccess con el siguiente contenido:

Código: [Seleccionar]
SetHandler wsgi-script
PythonHandler wsgi_handler

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !(django.wsgi)
RewriteRule ^(.*)$ django.wsgi/$1 [L]

Este archivo activa el manejador Apache/mod_wsgi para empezar a trabajar (con las dos primeras líneas), luego activa el motor de manejo de URLs (mod_rewrite) de Apache para entre otras cosas proteger el archivo django.wsgi, esto es una medida de seguridad, pues acceder directamente mediante una URL al archivo django.wsgi puede dejar al descubierto nuestra aplicación Django, de esta manera se resuelve el problema.

Con esto debemos tener una estructura dentro del directorio
Código: [Seleccionar]
public_html parecida a la siguiente:

Código: [Seleccionar]
public_html
    cgi-bin
    DIRECTORIO_PROYECTO_DJANGO
    .htaccess
    django.wsgi
    error_log

Recordando siempre que DIRECTORIO_PROYECTO_DJANGO es el nombre del directorio creado por
Código: [Seleccionar]
django-admin.py, como ejemplo concreto yo lo tengo así:

Código: [Seleccionar]
public_html
    cgi-bin
    mysite
    .htaccess
    django.wsgi
    error_log

Luego es cuestión de acceder a vuestro sitio desde el navegador y ver que todo funciona correctamente.

Pythoner (pythonero at gmail.com) ;)
Espero que os halla sido de ayuda.

Un saludo

 ;)
Título: Re:Ejemplo de prueba index.py para Django y MySQL con mod_wgsi
Publicado por: ernestmego en Abril 06, 2011, 14:16:01 pm
Muchas gracias pythoner, contribuciones y tutoriales como este hacen el despliegue de aplicaciones django mucho más sencillas.