Erreur d'importation d'application Python dans Django avec WSGI gunicorn

j'essaie de déployer une application Django avec gunicorn sur Heroku et j'ai rencontré quelques accrocs.

quand j'ai commencé mon projet ma version Django était 1.3 et ne contenait pas la norme wsgi.py module, donc j'ai ajouté le module standard wsgi comme top/wsgi.py (top étant mon nom de projet, turk étant mon nom d'application, topturk étant le répertoire contenant préservé de sorte que les journaux d'erreurs ont un sens ci - dessous).

Maintenant, quand je lance

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

le serveur démarre avec succès,

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

mais quand je navigue vers 0.0.0.0: 5000, Je reçois une erreur de serveur interne:

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"

je suppose qu'il s'agit d'une erreur de chemin python, où le serveur ne sait pas comment importer à partir de mon répertoire app

le code d'importation pertinent est ici dans les paramètres:

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

j'ai essayé de corriger ce problème en insérant mon répertoire app dans sys.chemin comme si du haut de mon settings.py fichier comme ceci:

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

que j'ai vérifié ajoute le répertoire app au chemin, mais toujours pas de dés. Des idées? Aussi

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

semble hackish et ajoute au moins deux copies du répertoire au chemin, Quelle est la bonne façon d'ajouter à Python_path dans Django? Merci!

5
demandé sur Intenex 2012-07-26 04:20:54

3 réponses

a résolu mon problème. Nécessaire pour ajouter le répertoire de projet à Python path, pas le répertoire app - c'est-à-dire topturk/top au lieu de topturk/top/turk afin d'importer des modules de répertoire turk.

python top/manage.py run_gunicorn

et

python top/manage.py runserver

fonctionnaient très bien car selon la documentation Python path, le répertoire du module appelant est toujours ajouté en tant qu'élément 0 dans le tuple Python path - et donc quand top/manage.py était utilisé, topturk / top était toujours sur le chemin Python.

avec heroku cependant, le fichier Procfile est dans le répertoire parent du projet, topturk et pas topturk/top, donc quand les commandes Procfile sont exécutées, topturk est ajouté au chemin Python mais pas topturk/top, et donc les erreurs.

avec le recul, a compris ce à quoi la documentation de Django faisait référence dans la dernière phrase de cette section: https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/gunicorn/#running-django-in-gunicorn-as-a-generic-wsgi-application , où ils disent que pour exécuter cette commande le projet doit être sur le chemin Python.

Problème résolu en ajoutant

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

à l'un des settings.py ou wsgi.py -ajouté à settings.py comme cela semble comme ce que d'autres personnes ont recommandé (http://codespatter.com/2009/04/10/how-to-add-locations-to-python-path-for-reusable-django-apps/), mais pas sûr de ce que le meilleur place pour mettre l'insert est. Tout le monde sait?

10
répondu Intenex 2012-07-26 01:02:27

bien au-dessus de la méthode a été déprécié par gunicorn maintenant. Quand j'ai essayé la même chose si échoué avec le message d'avertissement!

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

!!!

!!! AVERTISSEMENT: Cette commande est obsolète.

!!!

!!! Vous devez maintenant exécuter votre application avec l'interface WSGI

!!! installé avec votre projet. Ex.:

!!!

!!! gunicorn myproject.wsgi: application

!!!

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

!!! pour plus d'info.

!!!

donc, j'ai essayé sous commandement et ça a marché pour moi.

gunicorn myproject.wsgi:application
1
répondu Jadav Bheda 2015-10-23 12:14:20

ajouter "gunicorn" dans les paramètres.py / INSTALLED_APPS and use

python manage.py run_gunicorn 127.0.0.0:8001

(quel que soit le port que vous aimez) Pour plus d'informations visitez: https://pypi.python.org/pypi/gunicorn /

0
répondu The Hun 2013-10-08 14:12:42