11

Update: modules are called services these days.

I would like to organize my project's modules into various subfolders, where each subfolder contains code pertaining to each module. In particular, I would like the folder containing the default module to be on the same level as other modules (i.e. they are all siblings). I am following the diagram shown in the Modules documentation:

diagram
(source: google.com)

However, what confuses me is the statement "Important: The app.yaml file must be located in your application's root directory". Does this imply that the default module (and its app.yaml) must be in the project root directory, and therefore, be the parent of non-default modules?

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Kevin Lee
  • 2,307
  • 26
  • 31

1 Answers1

21

The modules can all be side by side. The <module>.yaml for each one can be inside the module dir.

The note about app.yaml file is misleading, it really applies just to single-module apps (many pieces of the documentation weren't updated for multi-module apps).

The default module's config file doesn't even have to be called app.yaml (or its dir called default). I'd keep the app-level config files (cron.yaml, dispatch.yaml, queue.yaml and index.yaml) at the top level, eventually symlinking them into the default (or other) module(s) as needed (some tools may complain otherwise).

Here's, for example, the structure I got to for one of my apps (the main dir contains the default module):

cron.yaml
dispatch.yaml
queue.yaml
index.yaml
main/cron.yaml -> ../cron.yaml
main/index.yaml -> ../index.yaml
main/main.yaml
main/queue.yaml -> ../queue.yaml
buildin/buildin.yaml
buildin/index.yaml -> ../index.yaml
buildin/queue.yaml-> ../queue.yaml

You just need to pay attention when invoking the related tools. This is my cheat-sheet for that app, executed from the app's dir, some of it is also reflected in the pycharm project config (I'm running the development server inside pycharm):

appcfg.py update main/main.yaml buildin/buildin.yaml
appcfg.py update_dispatch .
appcfg.py update_indexes -A <app-name> main
appcfg.py update_cron -A <app-name> .
appcfg.py update_queues -A <app-name> .

To run the devserver:

dev_appserver.py --host 0.0.0.0 --log_level=debug dispatch.yaml main/main.yaml buildin/buildin.yaml

Update: added some of my config files, as requested.

The dispatch.yaml file, taking care of the buildin module routing on both the appspot domain and my custom domain (everything else is automatically routed to the default module):

application: <my_app>
dispatch:
  - url: "buildin.my_domain.com/*"
    module: buildin
  - url: "buildin-dot-my_app.appspot.com/*"
    module: buildin
  - url: "*/buildin/*"
    module: buildin

The main.yaml file:

application: my_app
module: default
version: 1
runtime: python27
api_version: 1
threadsafe: true

handlers:

- url: /(.*\.min\.css)$
  static_files: stylesheets/\1
  upload: stylesheets/.*\.min\.css$
  secure: always

- url: /(.*\.(ico|gif|png|jpg|svg))$
  static_files: images/\1
  upload: images/.*\.(ico|gif|png|jpg|svg)$
  secure: always

- url: .*
  script: main.app
  secure: always

libraries:
- name: webapp2
  version: "2.5.2"
- name: jinja2
  version: "2.6"
- name: pycrypto
  version: "2.6"

The buildin.yaml file:

application: my_app
module: buildin
version: 1
runtime: python27
api_version: 1
threadsafe: true
instance_class: B2

handlers:

- url: /(.*\.min\.js)$
  static_files: scripts/\1
  upload: scripts/.*\.min\.js$
  secure: always

- url: /(.*\.min\.css)$
  static_files: stylesheets/\1
  upload: stylesheets/.*\.min\.css$
  secure: always

- url: /(.*\.(ico|gif|png|jpg|svg))$
  static_files: images/\1
  upload: images/.*\.(ico|gif|png|jpg|svg)$
  secure: always

- url: /buildin/cron*
  script: buildin.app
  login: admin

- url: .*
  script: buildin.app
  secure: always

libraries:
- name: webapp2
  version: "2.5.2"
- name: jinja2
  version: "2.6"
- name: pycrypto
  version: "2.6"
Dan Cornilescu
  • 39,470
  • 12
  • 57
  • 97
  • Thank you for the clarification and for providing the example along with the cheat sheet. It is very useful. – Kevin Lee Dec 07 '15 at 19:40
  • @dan , can you paste in your dispatch.yaml + main/main.yaml + buildin/buildin.yaml code ? – WebQube May 07 '16 at 06:50
  • @Kevin Lee, I'm still not able to figure it out getting this error. google.appengine.api.yaml_errors.EventError: Unexpected attribute 'dispatch' for object of type AppInfoExternal. in "./app.yaml", line 3, column 3 Please give me a working code, if possible. sirimala.sreenath@gmail.com – sreenath sirimala Jun 08 '17 at 11:44
  • @sreenathsirimala: Ask it as a separate question. Include the entire trace and the content of your yaml file. – Dan Cornilescu Jun 09 '17 at 12:51