July 12, 2008

Using zipped pytz on GAE

To handle timezone of all over the world crrectly, I think it is the most easy way to use pytz[1]. Besides that, there are many modules and programs which depends on pytz modes, so I believe that quite a few people would like to use pytz on GAE. However, pytz contains over 500 files in its zoneinfo directory, so it often bears on the 1000 files limit.

1. http://pytz.sourceforge.net/

This is an instruction about how to use zipped pytz on GAE environment. In this article, we use my_zipimport.py[2] provided by Guido van Rossum.

2. http://code.google.com/p/googleappengine/issues/detail?id=161#c19

First, make your own pytz.zip as following:

$ cd pytz-2006p
$ zip -q pytz.zip `find pytz -type f ! -name '*.pyc' -print`

Secondly, make sure to put my_zipimport.py and pytz.zip into your GAE app directory.
Lastly, put following code into your script.

import my_zipimport
import sys

sys.path.insert(0, 'pytz.zip')

That's all. Now you can use pytz module seamlessly.


Stefano said...

Unfortunately, zipping pytz does not work with recent versions of pytz, like version 2008c available from PyPI.

Pytz 2008c opens zoneinfo files using __file__, which breaks if the files are in a zip.

My solution at the moment is to zip only the zoneinfo directory inside pytz, and then replace the function open_resource inside pytz/__init__.py with the following:

import zipfile
from cStringIO import StringIO

def open_resource(name):
"""Open a resource from the zoneinfo subdir for reading.
name_parts = name.lstrip('/').split('/')
for part in name_parts:
if part == os.path.pardir or os.path.sep in part:
raise ValueError('Bad path segment: %r' % part)
zoneinfo = zipfile.ZipFile(os.path.join(os.path.dirname(__file__), 'zoneinfo.zip'))
return StringIO(zoneinfo.read(os.path.join('zoneinfo', *name_parts)))

tmatsuo said...

Shame on me!
I didn't know the existence of pytz newer version. Your suggestion really makes sense.

Thanks for your imformation Stefano!

Scott said...

When I set that up, it took about 10 seconds for pytz to import on my development server because it was loading the zip file repeatedly. Moving

zoneinfo = zipfile.ZipFile(os.path.join(os.path.dirname(__file__), 'zoneinfo.zip'))

outside the function fixed that though. Thanks for the info!

tmatsuo said...

This entry is obsolete. Please reffer to a newer one.

Junghwan Park said...
This comment has been removed by the author.
Junghwan Park said...

For a simpler uses (datetime conversion or timezone correctness check),



You can figure out how to use it in 5 mins.