3

In my Google App Engine app, I'm getting the error

ImportError: No module named main

when going to the URL /foo. All the files in my app are in the parent directory.

Here is my app.yaml:

application: foobar
version: 1
runtime: python27
api_version: 1
threadsafe: no

handlers:

- url: /foo.*
  script: main.application

- url: /
  static_files: index.html

- url: /(.*\.(html|css|js|gif|jpg|png|ico))
  static_files: \1
  upload: .*
  expiration: "1d"

Here is my main.py:

from google.appengine.ext import webapp
from google.appengine.ext.webapp import util

class Handler(webapp.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'text/plain'
        self.response.write('Hello world!') 

def main():
    application = webapp.WSGIApplication([('/foo', Handler)],
                                         debug=False)
    util.run_wsgi_app(application)

if __name__ == '__main__':
    main()

I get the same error when I change main.application to main.py or just main. Why is this error occurring?

1''
  • 26,823
  • 32
  • 143
  • 200

3 Answers3

4

Your configuration is OK - only for a small misstep in the main.py: you need an access of the application name from the main module, thus the config is: main.application. This change should do the trick:

application = webapp.WSGIApplication([('/foo', Handler)],
                                     debug=False)
def main():
    util.run_wsgi_app(application)

Don't worry - the application object will not run on creation, nor on import from this module, it will run only on explicit all such as .run_wsgi_app or in google's internal architecture.

vonPetrushev
  • 5,457
  • 6
  • 39
  • 51
2

Have a look at getting started with python27. You mixing CGI and WSGI. You have to use webapp2 here.

Your WSGI main.py :

import webapp2

class Handler(webapp2.RequestHandler):

    def get(self):
        self.response.headers['Content-Type'] = 'text/plain'
        self.response.write('Hello World!')


application = webapp2.WSGIApplication([
    ('/foo', Handler),
], debug=True)

See also this blog post about CGI and WSGI : http://blog.notdot.net/2011/10/Migrating-to-Python-2-7-part-1-Threadsafe

voscausa
  • 11,253
  • 2
  • 39
  • 67
  • Thanks, I should be using webapp2. However, it still doesn't work. The [hello world example](https://developers.google.com/appengine/docs/python/gettingstartedpython27/helloworld) works fine; the problem seems to happen when the python script is not the main request handler (i.e. only for `/foo.*`) – 1'' Jun 24 '13 at 01:00
  • Please explain. What do you mean with : "when the python script is not the main request handler" – voscausa Jun 24 '13 at 01:12
  • As in, it only handles URLs starting with `/foo`, not the base URL `/`. – 1'' Jun 24 '13 at 02:01
  • But you did not create a handler for '/', and what about : ImportError: No module named main? Is this problem solved. – voscausa Jun 24 '13 at 09:51
  • index.html is the handler for `/`. The problem is not solved. – 1'' Jun 24 '13 at 13:53
  • The index.html yaml config for / will not work : have a look at : http://stackoverflow.com/questions/5609000/serve-static-file-using-app-engine – voscausa Jun 24 '13 at 14:01
  • That question seems to apply only when files are in sub-directories. All my files are in the same directory. – 1'' Jun 24 '13 at 14:13
  • Compare your site root / config to the one in the answer. – voscausa Jun 24 '13 at 14:24
  • Mine looks the same, except there's no sub-directory for static files. What are you getting at? – 1'' Jun 24 '13 at 14:35
  • # site root - url: / static_files: index.html upload: index.html # THIS ONE IS MISSING – voscausa Jun 24 '13 at 14:37
  • Right, sorry, I already put that back in at some point, and it doesn't seem to affect anything. I think the problem is actually related to ["Static files cannot be the same as application code files. If a static file path matches a path to a script used in a dynamic handler, the script will not be available to the dynamic handler."](https://developers.google.com/appengine/docs/python/config/appconfig) However, I can't see how `main.py` matches the static request handlers. – 1'' Jun 24 '13 at 14:51
2

As the documentation says,

Static files cannot be the same as application code files. If a static file path matches a path to a script used in a dynamic handler, the script will not be available to the dynamic handler.

In my case, the problem was that the line

upload: .*

matched all files in my parent directory, including main.py. This meant that main.py was not available to the dynamic handler. The fix was to change this line to only recognize the same files that this rule's URL line recognized:

upload: .*\.(html|css|js|gif|jpg|png|ico)
1''
  • 26,823
  • 32
  • 143
  • 200