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

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


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

6 comments:

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),

try:

http://timezonetimezone.appspot.com

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