Tuesday, April 26, 2005

build-pk.py now part of Python Paste

Ian has given me check-in access to the PythonPaste SVN, so I have checked in my cross-platform build-pkg.py script. Also looking at making a distribution of the 3rd party packages using Python Eggs.

Saturday, April 23, 2005

Installing WSGIKit, opps I mean Python Paste under Win32

Ian has been unhappy with the name WSGIKit, so it has been renamed Python Paste I think the name better matches what the package does, the WSGI glue that sticks all the python components together. Anyway have made some minor changes to my cross-platform build-pkg.py script so that it works more like Ian's shell script. Have sent a copy to him, so who knows, maybe it will be part of Python Paste.
                                                                               
#!/usr/bin/env python
"""
Install required third party packages for Python Paste.

Known limitations

- Running under Windows, it must be run with Python 2.3+
as it requires the tarfile module. On Unix/Linix platform
will fallback to tar program.
"""
import os
import sys
import errno
import urllib
import shutil

TMP="/tmp"
for tmp in ['TEMP','TMPDIR','TMP']:
if os.environ.has_key(tmp):
TMP = os.environ[tmp]
break
TMP = TMP + os.sep + "tmp-build"

BASE=os.path.dirname(sys.argv[0])
if BASE == '' or BASE == ".":
BASE = os.getcwd()

THIRD = BASE + "/paste/3rd-party"

def basename(filename, ext):
try:
i = filename.index(ext)
base = filename[0:i]
except ValueError:
base = filename
pass

return base

def mkdirs(dirname, mode=0777):
# Python Cookbook Edition 1 Recipe 4.17
try:
os.makedirs(dirname)
except OSError, err:
if err.errno != errno.EEXIST or not os.path.isdir(TMP):
raise

def delete_pyc(arg, dirname, files):
"""
Called by os.path.walk to delete .pyc and .pyo files
"""
for name in files:
if name.endswith(".pyc") or name.endswith(".pyo"):
os.remove(os.path.join(dirname, name))

def get_file(zip_type, filename, url):
"""
If required, download requested third party package and extract.
On exit, the script is in the extracted package directory.
"""
mkdirs(TMP)
os.chdir(TMP)
if not os.path.exists(filename):
print "Download %s ..." % filename
urllib.urlretrieve(url, filename)
DIR=basename(filename, ".tar.gz")
DIR=basename(DIR, ".tar.bz2")
DIR=basename(DIR, ".tgz")
if not os.path.exists(DIR):
try:
import tarfile
tar = tarfile.open(filename, "r:" + zip_type)
for file in tar.getnames():
tar.extract(file)
except ImportError:
# No tarfile module, so use actual tar program
if zip_type == "gz":
zip_type = "z"
else:
zip_type = "j"
os.system('tar fx%s "%s"' % (zip_type, filename))

try:
os.chdir(DIR)
except OSError:
pass

def installer(name):
mkdirs(THIRD + "/" + name +"-files")
cmd = '%s setup.py install -f --install-lib="%s/%s-files" --install-scripts="%s/%s-files/scripts" --no-compile' % (sys.executable, THIRD, name, THIRD, name)
print cmd
os.system(cmd)

get_file("gz","WSGI Utils-0.5.tar.gz",
"http://www.owlfish.com/software/wsgiutils/downloads/WSGI%20Utils-0.5.tar.gz")
installer("wsgiutils")

get_file("gz", "Component-0.1.tar.gz",
"http://webwareforpython.org/downloads/Component-0.1.tar.gz")
DEST = THIRD + "/Component-files/Component"
mkdirs(DEST)
shutil.rmtree(DEST,ignore_errors=1)
os.chdir(THIRD)
shutil.copytree(TMP + os.sep +"Component-0.1", DEST)

zptkit_tmpdir = TMP + "/" + "ZPTKit"
if os.path.exists(zptkit_tmpdir):
os.chdir(zptkit_tmpdir)
cmd ="svn up"
else:
cmd ="svn co http://svn.w4py.org/ZPTKit/trunk %s/ZPTKit" % TMP
os.system(cmd)
DEST = THIRD + "/ZPTKit-files/ZPTKit"
mkdirs(DEST)
shutil.rmtree(DEST,ignore_errors=1)
os.chdir(THIRD)
shutil.copytree(TMP + "/ZPTKit", DEST)

get_file("gz", "ZopePageTemplates-1.4.0.tar.gz",
"http://belnet.dl.sourceforge.net/sourceforge/zpt/ZopePageTemplates-1.4.0.tgz")
os.chdir("ZopePageTemplates")
installer("ZopePageTemplates")

get_file("gz", "scgi-1.2.tar.gz",
"http://www.mems-exchange.org/software/files/scgi/scgi-1.2.tar.gz")
installer("scgi")

# Do not clean up compiled python files for now
#os.path.walk(THIRD,delete_pyc,None)

sqlobject_tmpdir = TMP + "/" + "SQLObject"
if os.path.exists(sqlobject_tmpdir):
os.chdir(sqlobject_tmpdir)
cmd ="svn up"
else:
cmd ="svn co http://svn.colorstudy.com/trunk/SQLObject %s/SQLObject" % TMP
os.system(cmd)
os.chdir(sqlobject_tmpdir)
installer("sqlobject")
mkdirs(THIRD + "/sqlobject-files/scripts")
shutil.copy(TMP + "/SQLObject/scripts/sqlobject-admin",
THIRD + "/sqlobject-files/scripts")


if not os.path.exists(TMP + "/PySourceColor.py"):
urllib.urlretrieve("http://bellsouthpwp.net/m/e/mefjr75/python/PySourceColor.py",
TMP + "/PySourceColor.py")
mkdirs(THIRD + "/PySourceColor-files")
shutil.copy(TMP + "/PySourceColor.py", THIRD + "/PySourceColor-files")

Sunday, April 17, 2005

Installing WSGIKit on a Win32 platform

So I could have a play with WSGIKit and look at how I could make ISAPI_WSGI work with it, I decided to install it on my home Windows XP box. As part of the svn checkout, there is a shell script called build-pkg which will download the required third party packages and install them under WSGIKit for you. Tried to run the script with a standard install of Cygwin but it failed due to various errors. I could have debugged my way thru the errors but thought why not create a truly cross-platform version of buld-pkg in python. So an hour later, the following script did the job for me. It currently lacks the checks to see if the package has already been downloaded, but it did the job for me.


import os
import sys
import errno
import tarfile
import urllib
import shutil

TMP="/tmp/tmp-build"
BASE=os.path.dirname(sys.argv[0])

if BASE == "" or BASE == ".":
BASE = os.getcwd()

THIRD = BASE + "/wsgikit/3rd-party"

def basename(filename, ext):
try:
i = filename.index(ext)
base = filename[0:i]
except ValueError:
base = filename
pass

return base

def mkdirs(dirname, mode=0777):
# Python Cookbook Recipe edition 1 4.17
try:
os.makedirs(dirname)
except OSError, err:
if err.errno != errno.EEXIST or not os.path.isdir(TMP):
raise

def get_file(zip_type, filename, url):
print "Getting %s ..." % filename
mkdirs(TMP)
os.chdir(TMP)
# TODO: check for existing package, download if not there
urllib.urlretrieve(url, filename)
DIR=basename(filename, ".tar.gz")
DIR=basename(DIR, ".tar.bz2")
DIR=basename(DIR, ".tgz")
tar = tarfile.open(filename, "r:" + zip_type)
for file in tar.getnames():
tar.extract(file)
try:
os.chdir(DIR)
except OSError:
pass

def installer(name):
mkdirs(THIRD + "/" + name +"-files")
cmd = 'python setup.py install -f --install-lib="%s/%s-files" --install-scripts="%s/%s-files/scripts" --no-compile' % (THIRD, name, THIRD, name)
os.system(cmd)

get_file("gz","WSGI Utils-0.5.tar.gz",
"http://www.owlfish.com/software/wsgiutils/downloads/WSGI%20Utils-0.5.tar.gz")
installer("wsgiutils")

get_file("gz", "Component-0.1.tar.gz",
"http://webwareforpython.org/downloads/Component-0.1.tar.gz")
mkdirs(THIRD + "/Component-files")
DEST = THIRD + "/Component-files/Component"
shutil.rmtree(DEST,ignore_errors=1)
try:
shutil.move(TMP + "/Component-0.1", DEST)
except OSError:
pass

get_file("gz", "ZPTKit-0.1.tar.gz",
"http://imagescape.com/software/ZPTKit/ZPTKit-0.1.tar.gz")
mkdirs(THIRD + "/ZPTKit-files")
DEST = THIRD + "/ZPTKit-files/ZPTKit"
shutil.rmtree(DEST,ignore_errors=1)
try:
shutil.move(TMP + "/ZPTKit-0.1", DEST)
except OSError:
# To handle permission errors under Windows
pass

get_file("gz", "ZopePageTemplates-1.4.0.tar.gz",
"http://belnet.dl.sourceforge.net/sourceforge/zpt/ZopePageTemplates-1.4.0.tgz")
os.chdir("ZopePageTemplates")
installer("ZopePageTemplates")

get_file("gz", "scgi-1.2.tar.gz",
"http://www.mems-exchange.org/software/files/scgi/scgi-1.2.tar.gz")
installer("scgi")

cmd ="svn co http://svn.colorstudy.com/trunk/SQLObject %s/SQLObject" % TMP
os.system(cmd)
os.chdir(TMP + "/SQLObject")
installer("sqlobject")
mkdirs(THIRD + "/sqlobject-files/scripts")
shutil.copy(TMP + "/SQLObject/scripts/sqlobject-admin",
THIRD + "/sqlobject-files/scripts")


urllib.urlretrieve("http://bellsouthpwp.net/m/e/mefjr75/python/PySourceColor.py",
TMP + "/PySourceColor.py")
mkdirs(THIRD + "/PySourceColor-files")
shutil.copy(TMP + "/PySourceColor.py", THIRD + "/PySourceColor-files")

Friday, April 15, 2005

Back to WSGI land

It's been over a month since my last entry as family and work have consumed most of my time. Some interesting developments for WSGI over the last month. Ian Bickings PyCon presentation provides a very good description of what WSGI is and what it is not. He used his WSGIKit for the usage examples. And just in case, we didn't appreciate what you can do with WSGIKit, a week later he provided an online tutorial on how to implement something like the famous Ruby on Rails ToDo List example with it. The WSGIKit tutorial can be found here.

Also came across some work that Allan Saddi has done. At last I can simply use FastCGI with my WSGI enabled web scripts. So using either isapi_wsgi or his fcgi.py I can run my scripts as long running processes on both IIS and Apache with no real extra effort.