web-dev-qa-db-fra.com

ModuleNotFoundError - Aucun module nommé «principal» lors de la tentative de démarrage du service

Le contexte:

  • J'ai créé une application Django en utilisant Python 3.7.
  • J'essaie (j'essaie) d'utiliser l'environnement standard Google App Engine de 2e génération.

Mon application fonctionne parfaitement lorsque je l'exécute via python manage.py runserver. Pourtant, il s'arrête soudainement lorsque j'essaie de le déployer sur Google App Engine.

Traceback (most recent call last):
  File "/tmp/tmphgUsp3/lib/python3.7/site-packages/gunicorn/arbiter.py", line 583, in spawn_worker
    worker.init_process()
  File "/tmp/tmphgUsp3/lib/python3.7/site-packages/gunicorn/workers/base.py", line 129, in init_process
    self.load_wsgi()
  File "/tmp/tmphgUsp3/lib/python3.7/site-packages/gunicorn/workers/base.py", line 138, in load_wsgi
    self.wsgi = self.app.wsgi()
  File "/tmp/tmphgUsp3/lib/python3.7/site-packages/gunicorn/app/base.py", line 67, in wsgi
    self.callable = self.load()
  File "/tmp/tmphgUsp3/lib/python3.7/site-packages/gunicorn/app/wsgiapp.py", line 52, in load
    return self.load_wsgiapp()
  File "/tmp/tmphgUsp3/lib/python3.7/site-packages/gunicorn/app/wsgiapp.py", line 41, in load_wsgiapp
    return util.import_app(self.app_uri)
  File "/tmp/tmphgUsp3/lib/python3.7/site-packages/gunicorn/util.py", line 350, in import_app
    __import__(module)
ModuleNotFoundError: No module named 'main'

J'ai parcouru de nombreux threads et je ne trouve pas le problème. (Pour référence, le dev_appserver.py l'émulateur produit le même problème, ce qui est une bonne chose).

Voici mon app.yaml

runtime: python37
env: standard

handlers:
- url: /static
  static_dir: static/
- url: .*
  script: demosite.wsgi.main

Ma wsgi.py le fichier se trouve dans le chemin suivant: demosite/wsgi.py et son contenu ressemble à ceci:

import os

from Django.core.wsgi import get_wsgi_application

os.environ.setdefault('Django_SETTINGS_MODULE', 'demosite.settings')

main = get_wsgi_application()

Ma settings.py fichier:

import os

class AppSettings(object):
    GoogleCloudProject = os.getenv('GOOGLE_CLOUD_PROJECT')

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

SECRET_KEY = 'say what?'

DEBUG = True

ALLOWED_HOSTS = [
    '*'
]


INSTALLED_APPS = [
    'anchor.apps.AnchorConfig',
    'crispy_forms',
    'Django.contrib.admin',
    'Django.contrib.auth',
    'Django.contrib.contenttypes',
    'Django.contrib.sessions',
    'Django.contrib.messages',
    'Django.contrib.staticfiles',
]

MIDDLEWARE = [
    'Django.middleware.security.SecurityMiddleware',
    'Django.contrib.sessions.middleware.SessionMiddleware',
    'Django.middleware.common.CommonMiddleware',
    'Django.middleware.csrf.CsrfViewMiddleware',
    'Django.contrib.auth.middleware.AuthenticationMiddleware',
    'Django.contrib.messages.middleware.MessageMiddleware',
    'Django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'demosite.urls'

TEMPLATES = [
    {
        'BACKEND': 'Django.template.backends.Django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'Django.template.context_processors.debug',
                'Django.template.context_processors.request',
                'Django.contrib.auth.context_processors.auth',
                'Django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'demosite.wsgi.main'

try:
    import MySQLdb
except ImportError:
    import pymysql
    pymysql.install_as_MySQLdb()


if os.getenv('SERVER_SOFTWARE', '').startswith('Google App Engine'):
    DATABASES = {
        'default': {
            'ENGINE': 'Django.db.backends.mysql',
            'NAME': 'webapp',
            'USER': 'aasdeytst',
            'PASSWORD': 'asdasygetasfasdfasd.',
            'Host': 'asdgiuasfivaasd',
            'PORT': '3306'
        }
    }
else:
    DATABASES = {
        'default': {
            'ENGINE': 'Django.db.backends.mysql',
            'NAME': 'webapp',
            'USER': 'awthdsfhfdhdf',
            'PASSWORD': 'asdasdasdagwdatwt',
            'Host': 'localhost',
            'PORT': '3306'
        }
    }

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'Django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'Django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'Django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'Django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

ANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

STATIC_ROOT = 'static'
STATIC_URL = '/static/'

CRISPY_TEMPLATE_PACK = 'bootstrap4'

LOGIN_REDIRECT_URL = 'index'
LOGIN_URL = 'login'

SESSION_EXPIRE_AT_BROWSER_CLOSE = False
SESSION_COOKIE_AGE = 1800

Qu'est-ce que je manque, que fais-je de mal? J'ai passé près de 4 heures à essayer de résoudre ce problème en vain.

11
Marley

Par défaut, App Engine recherche une variable app dans un fichier appelé main.py. Vous avez deux options: placez votre application WSGI là où App Engine l'attend, ou définissez un point d'entrée personnalisé:

Placez votre application WSGI là où App Engine s'attend à ce qu'elle soit:

Vous pouvez créer un fichier appelé main.py qui a une variable app qui est simplement importée et aliasée de l'emplacement correct:

from demosite.wsgi import main as app

Ajout d'un point d'entrée personnalisé:

De https://cloud.google.com/appengine/docs/standard/python3/config/appref :

entrypoint: facultatif. La commande qui est exécutée au démarrage de votre application. Pour que votre application reçoive des requêtes HTTP, entrypoint doit contenir une commande qui démarre un serveur Web qui écoute sur le port spécifié par la variable d'environnement PORT. Si vous ne spécifiez pas de entrypoint, App Engine configurera et démarrera le serveur Web Gunicorn.

Par défaut, c'est ceci:

entrypoint: gunicorn -b :$PORT main:app

Vous auriez besoin de quelque chose comme:

entrypoint: gunicorn -b :$PORT demosite.wsgi:main

Voir ici pour plus de détails sur le démarrage de l'application: https://cloud.google.com/appengine/docs/standard/python3/runtime#application_startup

4
Dustin Ingram

Ajouter:

Le fichier main.py doit se trouver à la racine de votre application, où se trouve app.yaml.

Et le contenu peut aussi être:

   from mysite.wsgi import application

   # App Engine by default looks for a main.py file at the root of the app
   # directory with a WSGI-compatible object called app.
   # This file imports the WSGI-compatible object of your Django app,
   # application from mysite/wsgi.py and renames it app so it is discoverable by
   # App Engine without additional configuration.
   # Alternatively, you can add a custom entrypoint field in your app.yaml:
   # entrypoint: gunicorn -b :$PORT mysite.wsgi
   app = application
0