henhen
henhen

Reputation: 1205

ImportError: no module named [directory] Google App Engine

I keep getting an error that says no module named backend, this is the directory where my webapp2 application is.

My folder structure:

/project
 /backend
   /env    #python virtual env libraries
   main.py #my main entry point where webapp2 app instance is
   requirements.txt
 app.yaml

My app.yaml:

service: default

handlers:
- url: /dist
  static_dir: dist

- url: /.*
  script: backend.main.app

libraries:
- name: webapp2
  version: latest
- name: jinja2
  version: latest

Before my app.yaml was in backend, but I decided to move to root. Now when I run dev_appserver.py in root, I keep getting ImportError: No module named backend

I created the virualenv and installed the requirements.txt packages inside the backend directory.

EDIT: I am unsure if this makes a difference, but I have already deployed my application when the app.yaml was inside the backend folder. I am guessing this should not matter since I am trying to test locally by moving the app.yaml in my project root and running dev_appserver.py app.yaml, but it seems to not work when I do this.

Upvotes: 1

Views: 396

Answers (1)

Dan Cornilescu
Dan Cornilescu

Reputation: 39814

The directory containing the app.yaml file for a GAE service is the service's top-level directory. The content of this directory is what will be uploaded to GAE when you deploy the service. All paths referenced in the service's code or configurations are relative to this top level dir. So moving the app.yaml file around without updating the related code and configurations accordingly will break the app's functionality.

You don't seem to grasp the meaning of the script: statement very well. From Handlers element:

A script: directive must be a python import path, for example, package.module.app that points to a WSGI application. The last component of a script: directive using a Python module path is the name of a global variable in the module: that variable must be a WSGI app, and is usually called app by convention.

Note: just like for a Python import statement, each subdirectory that is a package must contain a file named __init__.py

So, assuming your app.yaml file is located in your project dir, the

script: backend.pythonAttack.app

would mean:

  • having an __init__.py file inside the backend dir, to make backend a package
  • having a pythonAttack.py file in the backend dir, with an app variable pointing to your webapp2 application

According to your description you don't meet any of these conditions.

My recommendation:

  • keep the app.yaml inside the backend dir (which doesn't need to be a python package dir)
  • update its script line to match your code. Assuming the app variable for your webapp2 app is actually in the main.py file the line would be:

      script: main.app
    
  • run the app locally by explicitly passing the app.yaml file as argument (in general a good habit and also the only way to run apps with multiple services and/or a dispatch.yaml file):

    dev_appserver.py backend/app.yaml
    
  • store your service python dependencies inside a backend/lib directory (to follow the naming convention), separated from your virtualenv packages

  • store the env virtualenv package dir outside the backend directory to prevent unnecessarily uploading them to GAE when deploying the service (and potential interference with the app's operation). The goal of the virtualenv is to properly emulate the GAE sandbox locally so that you can run the development server correctly.

Potentially of interest for structuring a multi-service app: Can a default service/module in a Google App Engine app be a sibling of a non-default one in terms of folder structure?

Upvotes: 2

Related Questions