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
[email protected]
http://mail.python.org/mailman/listinfo/python-win32