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!
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?
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
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 /