10

I've tried adding the following line to my handler script (main.py), but it doesn't seem to work:

sys.path.append('subdir')

subdir lives in the my root directory (i.e. the one containing app.yaml).

This doesn't seem to work, because when I try to import modules that live in subdir, my app explodes.

allyourcode
  • 21,871
  • 18
  • 78
  • 106

2 Answers2

21

1) Ensure you have a blank __init__.py file in subdir.

2) Use a full path; something like this:

import os
import sys

sys.path.append(os.path.join(os.path.dirname(__file__), 'subdir'))

Edit: providing more info to answer questions asked in a comment.

As Nick Johnson demonstrates you can place those three lines of code in a file called fix_path.py. Then, in your main.py file, do this import fix_path before all other imports. Link to a tested application using this technique.

And, yes, the __init__.py file is required; per the documentation:

When importing the package, Python searches through the directories on sys.path looking for the package subdirectory.

The __init__.py files are required to make Python treat the directories as containing packages; this is done to prevent directories with a common name, such as string, from unintentionally hiding valid modules that occur later on the module search path. In the simplest case, __init__.py can just be an empty file, but it can also execute initialization code for the package or set the __all__ variable, described later.

mechanical_meat
  • 163,903
  • 24
  • 228
  • 223
  • I don't want to create a package named subdir. Isn't that what 1) will do? Also, where would I put the code you mentioned under 2)?? – allyourcode Mar 01 '10 at 20:01
  • 2) is the answer I'm looking for. 1) As your quote from the docs explains, this makes subdir a package, which is NOT what I want. – allyourcode Mar 13 '10 at 06:27
  • Actually, I'm not sure why my original method of adding sys.path.append('subdir') to main.py (the only non-static handler in my app.yaml) didn't work. I just tried it again, but this time, no explosion :/ – allyourcode Mar 13 '10 at 07:04
  • 4
    The `__init__.py` is **not** required when altering `sys.path`. The path you are adding isn't a module itself, rather its contents are. – Bob Aman May 10 '10 at 07:07
2

It worked for me inserting the new dirs as the first entries in sys.path.

path_changer.py:

import os
import sys

sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'libs'))
sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'apps'))

app.py:

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

from flask import Flask
import settings

app = Flask('myapp')
app.config.from_object('settings')

from website import views as website_views

run_wsgi_app(app)
gnrfan
  • 19,071
  • 1
  • 21
  • 12