Error de importación de la aplicación Python en Django con WSGI gunicorn

Estoy tratando de implementar una aplicación Django con gunicorn en Heroku y me he topado con algunos problemas.

Cuando comencé mi proyecto, mi versión de Django era 1.3 y no contenía el módulo wsgi.py estándar, así que agregué el módulo wsgi estándar como top / wsgi.py (el nombre de mi proyecto es el principal, turk es el nombre de mi aplicación, el de topturk el directorio que contiene – preservado para que los registros de errores tengan sentido a continuación).

Ahora cuando corro

gunicorn top.wsgi:application -b 0.0.0.0:$PORT 

El servidor se inicia con éxito,

 19:00:42 web.1 | started with pid 7869 19:00:42 web.1 | 2012-07-25 19:00:42 [7869] [INFO] Starting gunicorn 0.14.5 19:00:42 web.1 | 2012-07-25 19:00:42 [7869] [INFO] Listening at: http://0.0.0.0:5000 (7869) 19:00:42 web.1 | 2012-07-25 19:00:42 [7869] [INFO] Using worker: sync 19:00:42 web.1 | 2012-07-25 19:00:42 [7870] [INFO] Booting worker with pid: 7870 

pero luego cuando navego a 0.0.0.0:5000 me devuelven un error interno del servidor:

 19:00:45 web.1 | 2012-07-25 17:00:45 [7870] [ERROR] Error handling request 19:00:45 web.1 | Traceback (most recent call last): 19:00:45 web.1 | File "/Users/intenex/Dropbox/code/django/topturk/venv/lib/python2.7/site-packages/gunicorn/workers/sync.py", line 102, in handle_request 19:00:45 web.1 | respiter = self.wsgi(environ, resp.start_response) 19:00:45 web.1 | File "/Users/intenex/Dropbox/code/django/topturk/venv/lib/python2.7/site-packages/django/core/handlers/wsgi.py", line 219, in __call__ 19:00:45 web.1 | self.load_middleware() 19:00:45 web.1 | File "/Users/intenex/Dropbox/code/django/topturk/venv/lib/python2.7/site-packages/django/core/handlers/base.py", line 47, in load_middleware 19:00:45 web.1 | raise exceptions.ImproperlyConfigured('Error importing middleware %s: "%s"' % (mw_module, e)) 19:00:45 web.1 | ImproperlyConfigured: Error importing middleware turk.middleware.subdomain: "No module named turk.middleware.subdomain" 19:00:47 web.1 | 2012-07-25 17:00:47 [7870] [ERROR] Error handling request 19:00:47 web.1 | Traceback (most recent call last): 19:00:47 web.1 | File "/Users/intenex/Dropbox/code/django/topturk/venv/lib/python2.7/site-packages/gunicorn/workers/sync.py", line 102, in handle_request 19:00:47 web.1 | respiter = self.wsgi(environ, resp.start_response) 19:00:47 web.1 | File "/Users/intenex/Dropbox/code/django/topturk/venv/lib/python2.7/site-packages/django/core/handlers/wsgi.py", line 219, in __call__ 19:00:47 web.1 | self.load_middleware() 19:00:47 web.1 | File "/Users/intenex/Dropbox/code/django/topturk/venv/lib/python2.7/site-packages/django/core/handlers/base.py", line 47, in load_middleware 19:00:47 web.1 | raise exceptions.ImproperlyConfigured('Error importing middleware %s: "%s"' % (mw_module, e)) 19:00:47 web.1 | ImproperlyConfigured: Error importing middleware turk.middleware.subdomain: "No module named turk.middleware.subdomain" 

Supongo que este es un error de ruta de acceso de Python, donde el servidor no sabe cómo importar desde el directorio de mi aplicación

El código de importación relevante está aquí en la configuración:

 MIDDLEWARE_CLASSES = ( 'turk.middleware.subdomain.SubdomainMiddleware', 'turk.middleware.removewww.RemoveWWWMiddleware', ) 

Intenté solucionar este problema insertando el directorio de mi aplicación en sys.path como en la parte superior de mi archivo settings.py, así:

 PROJECT_ROOT = os.path.dirname(os.path.realpath(__file__)) sys.path.insert(1, PROJECT_ROOT+'/turk/') 

Lo que he verificado agrega el directorio de la aplicación a la ruta, pero aún no hay dados. ¿Algunas ideas? también

 sys.path.insert(1, PROJECT_ROOT+'/turk/') 

parece truculento y agrega al menos dos copias del directorio a la ruta, ¿cuál es la forma correcta de agregar a PYTHON_PATH en Django? ¡Gracias!

Descubrí mi problema Se necesita agregar el directorio del proyecto a la ruta de Python, no el directorio de la aplicación, es decir, topturk / top en lugar de topturk / top / turk para importar módulos de directorio turk.

 python top/manage.py run_gunicorn 

y

 python top/manage.py runserver 

funcionaban bien porque, según la documentación de la ruta de Python, el directorio del módulo de llamada siempre se agrega como elemento 0 en la tupla de la ruta de Python, por lo que cuando se usaba top / manage.py, topturk / top siempre estaba en la ruta de Python.

Sin embargo, con heroku, el Procfile está en el directorio principal del proyecto, topturk y no topturk / top, por lo que cuando se ejecutan los comandos Procfile topturk se agrega a la ruta de Python pero no topturk / top, y por lo tanto, los errores.

En retrospectiva, descubrí que esto es a lo que se refería la documentación de Django en la última oración de esta sección: https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/gunicorn/#running-django-in -gunicorn-as-a-generic-wsgi-application , donde dicen que para ejecutar este comando, el proyecto debe estar en la ruta de Python.

Problema resuelto añadiendo

 sys.path.insert(1, os.path.dirname(os.path.realpath(__file__))) 

a settings.py o wsgi.py – agregado a settings.py ya que parece ser lo que otras personas han recomendado (http://codespatter.com/2009/04/10/how-to-add-locations-to- python-path-for-reutilizable-django-apps /), pero no está seguro de cuál es el mejor lugar para colocar el inserto. ¿Nadie sabe?

Muy por encima del método ha sido desaprobado por Gunicorn ahora. Cuando intenté lo mismo si fallaba con un mensaje de advertencia!

(venv) root @ ip-172-31-23-172: ~ / myproj # python manage.py run_gunicorn 0.0.0.0:8001

!!!

!!! ADVERTENCIA: Este comando está en desuso.

!!!

!!! Ahora debería ejecutar su aplicación con la interfaz WSGI

!!! instalado con su proyecto. Ex.:

!!!

!!! gunicorn myproject.wsgi: aplicación

!!!

!!! Consulte https://docs.djangoproject.com/en/1.5/howto/deployment/wsgi/gunicorn/

!!! para más información.

!!!

Por lo tanto, intenté debajo del comando y funcionó para mí.

 gunicorn myproject.wsgi:application 

Agregue “gunicorn” en settings.py/INSTALLED_APPS y use

 python manage.py run_gunicorn 127.0.0.0:8001 

(cualquiera que sea el puerto que desee) Para obtener más información, visite: https://pypi.python.org/pypi/gunicorn/