ModuleNotFoundError - No module named 'main' when attempting to start service
Solution 1
By default, App Engine looks for an app
variable in a file called main.py
. You have two options: put your WSGI app where App Engine expects it to be, or define a custom entrypoint:
Put your WSGI app where App Engine expects it to be:
You can create a file called main.py
that has an app
variable which is simply imported and aliased from the correct location:
from demosite.wsgi import main as app
Adding a custom entrypoint:
From https://cloud.google.com/appengine/docs/standard/python3/config/appref:
entrypoint
: Optional. The command that is executed when your app starts. For your app to receive HTTP requests,entrypoint
should contain a command which starts a web server that listens on the port specified by the PORT environment variable. If you do not specify anentrypoint
, App Engine will configure and start the Gunicorn webserver.
By default it's this:
entrypoint: gunicorn -b :$PORT main:app
You would need something like:
entrypoint: gunicorn -b :$PORT demosite.wsgi:main
See here for more details about application startup: https://cloud.google.com/appengine/docs/standard/python3/runtime#application_startup
Solution 2
Adding:
The main.py have to be in root of your application, where app.yaml is.
And the content, can to be, as well:
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
Solution 3
Simply rename your main python app (for me it was app.py) to main.py. Google Cloud requires main.py to begin the process.
Related videos on Youtube
Marley
Updated on July 09, 2022Comments
-
Marley almost 2 years
Context:
- I created a Django application using Python 3.7.
- I am (attempting) to use the 2nd generation Google App Engine standard environment.
My application performs flawlessly when I run it via
python manage.py runserver
. Yet it comes to a sudden halt when I attempt to deploy it to 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'
I've gone through numerous threads and I cannot find the problem. (For reference the
dev_appserver.py
emulator produces the same problem, which is a good thing).Following is my
app.yaml
runtime: python37 env: standard handlers: - url: /static static_dir: static/ - url: .* script: demosite.wsgi.main
My
wsgi.py
file is located in the following path:demosite/wsgi.py
and it's contents look like this:import os from django.core.wsgi import get_wsgi_application os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'demosite.settings') main = get_wsgi_application()
My
settings.py
file: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
What am I missing, what am I doing wrong? I've spent close on 4 hours trying to figure this problem out to no avail.
-
Marley over 5 yearsDustin - thank you for your help. This was exactly what I needed (apart from having to juggle around
STATIC_URL
definitions after the fact). -
Rohit Singh almost 4 yearsThis is exactly the problem in my case. I was trying to deploy Flask application o Google App Engine. I changed app.py --> main.py. Works like charm