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
_______________________________________________
python-win32 mailing list
python-win32@python.org
http://mail.python.org/mailman/listinfo/python-win32

Reply via email to