Dan Holman
Dan Holman

Reputation: 835

Including and referencing 3rd party libraries in a GAE project

For my gae python project, I'd like to import an external library named 'vobject'. What's the correct way to import it in my .py files?

The project's readme says that in order to install it, you need to run

  python setup.py install

Additionally, vobject requires the 'dateutil' package.

Since this is going to run on GAE, I thought I should copy both libs over into my project instead of running the install script to make use of it in my code.

But I'm getting a bunch of import errors and I'm not sure what the correct convention is for external gae/python libs.

utc = dateutil.tz.tzutc()
## error produced:
File "myGaeProject/external/vobject/icalendar.py", line 47, in <module>
NameError: name 'dateutil' is not defined

Because of the way I've structured my project, I changed icalendar.py's import structure from:

import dateutil.rrule
import dateutil.tz

to:

import external.dateutil.rrule
import external.dateutil.tz

I also tried:

from external.dateutil import *

What's the correct import mechanism for a project structured like so:

-myGaeProject

--external
----__init__.py    

----dateutil
------__init__.py
------tz.py
------rrule.py
------[more dateutil files]

----vobject
------__init__.py
------base.py    
------icalendar.py    

--handlers
------__init__.py
------mainHandler.py

Upvotes: 3

Views: 1167

Answers (3)

sahid
sahid

Reputation: 2610

The good way is to use zipimport, you can check the project jaikuengine they are a lot of good things about that.

http://code.google.com/p/jaikuengine/source/browse/trunk/build.py

In Jaiku, all external libs are stocked in the directory vendor but if you see the app.yaml, all files in vendor are skipped. Jaiku uses a script to build a zip of each libs in vendor and put it to the root of the project before the deployment or when the dev_server is launched.

With that, you don't need to fix the path of your libs.

EDIT an example to load all zipped archives Largely inspired from jaikuengine:

def load_zipped(path='.'):
  for x in os.listdir(path):
    if x.endswith('.zip'):
      if not any([y.endswith(x) for y in sys.path]):
        sys.path.append(os.path.abspath('%s/%s') % (path, x))

Upvotes: 0

Nick Johnson
Nick Johnson

Reputation: 101149

Don't modify the library. If you want to put all your libraries in external, you need to add external to your python path before you attempt to import libraries from there:

import os
import sys
sys.path.append(os.path.join(os.path.dirname(__file__), 'external'))
import some_external_library

Upvotes: 3

Torsten Engelbrecht
Torsten Engelbrecht

Reputation: 13496

You can't do from external import dateutil if external is missing an __init__.py file.

Upvotes: 1

Related Questions