0

I'm writing a Google App Engine project in Python with Flask. Here's my directory structure for a Hello, World! app (contents of third party libraries ommitted for brevity's sake):

project_root/
    flask/
    jinja2/
    markupsafe/
    myapp/
        __init__.py
    simplejson/
    werkzeug/
    app.yaml
    itsdangerous.py
    main.py

Here's main.py:

from google.appengine.ext.webapp.util import run_wsigi_app
from myapp import app

run_wsgi_app(app)

And myapp/__init__.py:

from flask import Flask

app = Flask("myapp")

@app.route("/")
def hello():
    return "Hello, World!"

Since Flask has so many dependencies and sub dependencies, I thought it would be nice to tidy up the directory structure by putting all the third party code in a subdirectory (say project_root/lib). Of course, then sys.path doesn't know where to find the libraries.

I've tried the solutions in How do you modify sys.path in Google App Engine (Python)?, but that doesn't seem to work. I've also tried changing from flask import Flask to from lib/flask import Flask, to no avail. Is there a good way to do this?

Community
  • 1
  • 1
user2752467
  • 864
  • 5
  • 16

4 Answers4

3

Add a python file called appengine_config.py with the following content.

import sys
import os.path

sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'lib'))

As Tim Hoffman has mentioned the appengine_config.py is called once when a new instance is started.

Now you can do what you intended. adding all the third-party libraries to the lib folder.

neotrinity
  • 230
  • 1
  • 5
  • Good answer. I gave the accepted answer to @TimHoffman just because he answered first and his code is more concise. – user2752467 Nov 03 '14 at 20:39
1

Look at defining your path manipulation in appengine_config.py This means any path manipulation only has to be performed once.

Then move your third party files in to a lib as per your suggestion. Use a relative path 'lib' either by specifying sys.path

sys.path.insert(0,'./lib')

or use

import site
site.addsitedir("./lib")

Do not use absolute paths, as they won't be the same when you deploy your code.

Putting your lib first sometimes can be useful, especially if you don't want the google supplied version of webob.

Tim Hoffman
  • 12,976
  • 1
  • 17
  • 29
0

try to add the full path to your lib, like here sys.path[0:0] = ['/home/user/project_root/lib']

Igor Komar
  • 381
  • 1
  • 8
  • 16
  • Absolute paths don't work because then I wouldn't be able to run the code in both my local test environment and the App Engine runtime. – user2752467 Nov 03 '14 at 20:40
-2

I've actually run into this problem a number of time when writing my own Google App Engine® products before. My solution was to cat the files together to form one large python file. The command to do this is:

cat *.py

Of course, you may need to fix up the import statements inside the individual files. This can be done with a simple sed command to search for import statements in the files that match file names used in the cat command. But this is a relatively simple command compared to actually creating the huge python file (HPF, for short).

Another advantage of combining them all is increased speed: Because python doesn't need to go loading a whole bunch of useless tiny files all the time, it will run much faster. This means that the users of your Google App Engine® product will not need to wait for crazy long file load latency.

Of course, updating the libraries can be tricky. I recommend keeping the directory tree you used to cat the files together in order to easily update things in the future. All you need to do is copy the new files in and re-run the cat and sed commands. Think of it like pre-compiling your python library.

All the best!

-Milo