[python-win32] Python in classic ASP

Erik Oosterwaal erik at softwaresociety.nl
Tue Dec 7 10:00:14 CET 2010


Hi Everybody,

In reply to my own mail, because others might run into the same problem; I received some help from Mark Hammond regarding the use of Python in WSC's.
Here's the deal:

1. It is possible to use a Python WSC from vbscript ASP, as long as your returnvalues are simple types (strings, integers..) or COM types (so having a Python WSC that passes an ADO recordset object from a vbscript WSC to a vbscript ASP page will work).

2. Even when using Python WSC's and calling them from a Python code block, it is not possible to pass Python objects to and from the WSC.
The WSC is still a "com-layer" between the ASP page and the Python code in the WSC, and it wants all passed objects to be com variants. You will get an error like:

Unexpected Python Error: TypeError: Objects of type 'module' can not be
converted to a COM VARIANT

3. The <implements type="ASP" id="ASP"/> tag you can normally use in a WSC doesn't work, so you don't have IIS' objects available. A workaround for this is to pass these objects from ASP to the WSC yourself:

class IISobjectsClass
    public request, response, session, application, server
end class

dim IISobjects
set IISobjects = new IISobjectsClass
    set IISobjects.request   = request
    set IISobjects.response   = response
    set IISobjects.session   = session
    set IISobjects.application  = application
    set IISobjects.server    = server

' suppose we have a translation WSC in the current directory, that has open(), close() and Label() functions defined.
' the open() function could have a parameter to accept the IISobjects, so you pass them to, and have them available inside the WSC :
Dim translate
Set translate = GetObject("script:" & Server.MapPath("./translate.wsc") )
    translate.open(IISobjects)
    Response.Write(translate.label("firstname"))
    translate.close()
Set translate = Nothing

4. When an error occurs in the Python code of the WSC, there will be a very vague ASP error, i.e.:

error '80020009'
Exception occurred.

Mark has concluded that the Python engine -is- reporting the error, but the script container doesn't pass it to asp. Python doesn't print the error, assuming asp will show it. A workaround for this is to decorate the functions in the WSC you want to debug:

Add this function to the top of the Python WSC:

def debug(func):
 def callit(*args, **kw):
  try:
   return func(*args, **kw)
  except:
   import traceback
   traceback.print_exc()
   raise
 return callit

Then add the decorator to the function you want to debug, any other functions that get called by the function you decorated will also be debugged:

@debug
def Label(lblName):
 """ Returns a specific label from a Python dictionary """
 global d, new_labels_added
 if str(lblName) in d:
  return d[str(lblName)]
 else:
  d[lblName] = unicode(str(lcid) + "|" + lblName)
  new_labels_added = True
  return str(lcid) + "|" + lblName

Any errors will now show up in a Python trace collector. I have tested this under IIS6 on XP and IIS7 on Windows 7 x64 (setting the application pool to support 32-bit). Under IIS6 this works out of the box (when enabling server-side debugging). Under IIS7 I had to adjust some settings in the IIS configuration to get it to work. Unfortunately I don't know exactly what settings I changed on IIS7 to get the errors to be passed from the WSC to ASP and the trace collector, but at first the "exception occurred" error that IIS6 gave me was not showing up in IIS7, just a blank screen. Messing with some of the debugging settings in IIS7 made them show up eventually and at that point the trace collector was also showing me the underlying Python errors.

Problem nr. 2 mentioned above (not being able to pass Python objects from a WSC to an ASP page and vice versa), limits the usability of Python in WSC's severely. There is another option Mark suggested; using plain Python in ASP (in a <script runat=server> block) and using Python imports to divide code up into re-usable parts like this:

<script language="Python" runat="server">
import os
mod_path = Server.MapPath("./pythonwsc.py")
print "MOD", mod_path
import sys; sys.path.append(os.path.dirname(mod_path))
from pythonwsc import list_builtins
</script>


<script language="vbscript" runat="server">
 Response.write("<hr/>")
 Response.write(list_builtins())
 Response.write("<hr/>")
</script>

If you include Python blocks in your page, it is possible to access Python functions from other languages (i.e. vbscript) if there are multiple of these script blocks on the page. Please note however that there are some things to consider regarding the order in which these blocks are processed by IIS: http://phrogz.net/tmp/serversidejsandvb.html
Using this method Python can access all of IIS' special objects as well.

I'm still struggling now to get the Python imports to work like my WSC's work, so I don't have to change the syntax throughout my pages; i.e.; I have a "translate" wsc, and currently I can translate parts of a webpage by saying for example:

Translate.Label("pagetitle")

In the Python example above I would import "translate.py" and then call the Label() function directly, so without the leading "Translate.". In order to maintain the same syntax I guess I need to write a class inside the .py file and import that, but being new to Python I haven't yet figured out how that works exactly.

Hopefully this helps some other people struggling with Python/classic asp/WSC's, if there still are any :)
Thanks to Mark for all of his help.

Erik
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-win32/attachments/20101207/c43476e8/attachment-0001.html>


More information about the python-win32 mailing list