1

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.

henhen
  • 1,038
  • 3
  • 18
  • 36

1 Answers1

2

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?

Dan Cornilescu
  • 39,470
  • 12
  • 57
  • 97
  • Thanks for the input. The `script` property of my app.yaml example was a type error. I have it as pythonAttack but changed it to main for SO post. As mentioned, when I have my app.yaml inside the `backend` directory, everything works fine, but the reason I wanted outside in the project root was so I can move my `dir` directory (static assets) to the root of the project as well and not in the `backend` dir. My app.yaml is in the same dir as the static dir `dir`, but if move my app.yaml back inside `backend` not sure how I can point my app.yaml static_dir path to one file up. – henhen Dec 25 '18 at 20:55
  • I basically want the app.yaml to be in the root because I am planning on splitting my application to a backend service and a frontend service. However, as suggested, after adding the __init__.py file inside the `backend` folder, I no longer get the Import error and everything seems to work. However, sometimes my server will just hang and never load. I am wondering if this has to do with my app.yaml being in project root, where my `libraries` settings/property doesnt point to the directory where I installed the virtualenv. – henhen Dec 25 '18 at 21:01
  • It's not impossible to have all the services smashed together in the `project` dir (that's what you'd do by moving the `.yaml` files one level up). But it's a lot more tedious to get it right. And you'd unnecessarily upload everything in each service. Still, posible. But I'd rather use symlinking to share the static assets (or any other stuff) across services. Much cleaner IMHO. – Dan Cornilescu Dec 26 '18 at 16:50
  • Not sure about the hangs. Decide on an approach and, if you still see the problem, ask it as a separate question, with a description updated for that problem. Personally I don't use a virtualenv. – Dan Cornilescu Dec 26 '18 at 16:55