Section 18.7. Windows Web Scripting Extensions


18.7. Windows Web Scripting Extensions

Although this book doesn't cover the Windows-specific extensions available for Python in detail, a quick look at Internet scripting tools available to Windows programmers is in order here. On Windows, Python can be used as a scripting language for both the Active Scripting and the Active Server Pages systems, which provide client- and server-side control of HTML-based applications. More generally, Python programs can also take the role of COM and DCOM clients and servers on Windows. The .NET framework provides additional options for Python programmers.

This section is largely Microsoft specificif you are interested in portability, other systems in this chapter may address your needs better (see Jython's client-side applets, PSP's server-side scripting support, and Zope's server-side object publishing model). On the other hand, if portability isn't a concern, the following techniques provide powerful ways to script both sides of a web conversation with Python.

18.7.1. Active Scripting: Client-Side Embedding

Active Scriptingsometimes known as ActiveX Scripting, or just ActiveXis a technology that allows scripting languages to communicate with hosting applications. The hosting application provides an application-specific object model API, which exposes objects and functions for use in the scripting language programs.

In one of its more common roles, Active Scripting provides support that allows scripting language code embedded in HTML pages to communicate with the local web browser through an automatically exposed object model API. Internet Explorer, for instance, utilizes Active Scripting to export things such as global functions and user-interface objects, for use in scripts embedded in HTML that are run on the client. With Active Scripting, Python code may be embedded in a web page's HTML between special tags; such code is executed on the client machine and serves the same roles as embedded JavaScript and VBScript.

Unfortunately, support for client-side Active Scripting with Python under Internet Explorer no longer works as I write this update using Python 2.4. It relied on the rexec module to implement security for embedded code. As mentioned earlier in this chapter, in the sidebar "The Missing rexec Section," that module was withdrawn due to vulnerabilities. Without it, the Windows extensions have no way to ensure that code embedded in web pages won't do damage on the clientthe code would have full access to the client machine, including all its files and data.

Instead of leaving this security hole open, Active Scripting on the client has been disabled, and Python code embedded in HTML will no longer run under Internet Explorer. I've kept a brief overview of its workings in this book, though, because this may be a temporary regression; it might be reenabled in the future if a rexec replacement arises. Moreover, its use in restricted intranets may still be reasonable (though you'll have to modify the Windows extensions code to turn it back on).


Despite the Internet Explorer regression, Python still works as a scripting engine inside trusted hosts, including the Windows Scripting Host, and ASP. In addition, JavaScript or VBScript coded embedded in web pages can still invoke Python-coded COM components on the client. At present, though, Python code embedded in web pages cannot be run on the client directly, and the section you are reading is included for historic or future interest. Check up-to-date resources to see whether Active Scripting under Internet Explorer on the client has been turned back on by the time you read these words.


18.7.1.1. Active Scripting basics

Embedding Python in client-side HTML works only on machines where Python is installed and Internet Explorer is configured to know about the Python language. Because of that, this technology doesn't apply to most of the browsers in cyberspace today. On the other hand, if you can configure the machines on which a system is to be delivered, this is a nonissue.

Before we get into a Python example, let's look at the way standard browser installations handle other languages embedded in HTML. By default, Internet Explorer knows about JavaScript (really, Microsoft's Jscript implementation of it) and VBScript (a Visual Basic derivative), so you can embed both of those languages in any delivery scenario. For instance, the HTML file in Example 18-12 embeds JavaScript code, the default Internet Explorer scripting language on my PC.

Example 18-12. PP3E\Internet\Other\Win\activescript-js.html

 <HTML> <BODY> <H1>Embedded code demo: JavaScript</H1> <SCRIPT> // pop up 3 alert boxes while this page is // being constructed on client side by IE; // JavaScript is the default script language, // and alert is an automatically exposed name function message(i) {     if (i == 2) {         alert("Finished!");     }     else {         alert("A JavaScript-generated alert => " + i);     } } for (count = 0; count < 3; count += 1) {     message(count); } </SCRIPT> </BODY></HTML> 

All the text between the <SCRIPT> and </SCRIPT> tags in this file is JavaScript code. Don't worry about its syntaxthis book isn't about JavaScript. The important thing to know is how this code is used by the browser.

When a browser detects a block of code like this while building up a new page, it strips out the code, locates the appropriate interpreter, tells the interpreter about global object names, and passes the code to the interpreter for execution. The global names become variables in the embedded code and provide links to browser context. For instance, the name alert in the code block refers to a global function that creates a message box. Other global names refer to objects that give access to the browser's user interface: window objects, document objects, and so on.

You can run this HTML file on the local machine by clicking on its name in a file explorer. It can also be stored on a remote server and accessed via its URL in a browser. Whichever way you start it, three pop-up alert boxes created by the embedded code appear during page construction. Figure 18-9 shows one under Internet Explorer.

Figure 18-9. Internet Explorer running embedded JavaScript code


18.7.1.2. Embedding Python in HTML

So how about putting Python code in that page, then? Alas, we need to do a bit more first. Although Internet Explorer is language neutral in principle, it does support some languages better than others, at least today. Moreover, other browsers may be more rigid and may not support the Active Scripting concept at all.

To make the Python version work, you must do more than simply installing Python on your PC. You must also install the PyWin32 package separately and run its tools to register Python to Internet Explorer. The PyWin32 package includes the win32com extensions for Python, plus the PythonWin IDE (a GUI for editing and running Python programs, written with the MFC interfaces in PyWin32) and many other Windows-specific tools not covered in this book.

In the past, registering Python for use in Internet Explorer was either an automatic side-effect of installing PyWin32 or was achieved by running a script located in the Windows extension's code in Lib\site-packages of the Python install tree, named win32comext\axscript\client\pyscript.py. Because this package changes over time, though, see its documentation for current registration details.

Once you've registered Python with Internet Explorer, Python code embedded in HTML works just like our JavaScript exampleInternet Explorer presets Python global names to expose its object model and passes the embedded code to your Python interpreter for execution. Example 18-13 shows our alerts example again, programmed with embedded Python code.

Example 18-13. PP3E\Internet\Other\Win\activescript-py.html

 <HTML> <BODY> <H1>Embedded code demo: Python</H1> <SCRIPT Language=Python> # do the same but with Python, if configured; # embedded Python code shows three alert boxes # as page is loaded; any Python code works here, # and uses auto-imported global funcs and objects def message(i):     if i == 2:         alert("Finished!")     else:         alert("A Python-generated alert => %d" % i) for count in range(3): message(count) </SCRIPT> </BODY></HTML> 

Figure 18-10 shows one of the three pop ups you should see when you open this file in Internet Explorer after installing PyWin32 and registering Python to Internet Explorer. Note that the first time you access this page, Internet Explorer may need to load Python, which could induce an apparent delay on slower machines; later accesses generally start up much faster because Python has already been loaded.

Figure 18-10. Internet Explorer running embedded Python code (currently disabled)


With a simple configuration step, Python code can be embedded in HTML and be made to run under Internet Explorer, just like JavaScript and VBScript. Although this works on only some browsers and platforms, for many applications, the portability constraint is acceptable. Active Scripting is a straightforward way to add client-side Python scripting for web browsers, especially when you can control the target delivery environment. For instance, machines running on an intranet within a company may have well-known configurations. In such scenarios, Active Scripting lets developers apply all the power of Python in their client-side scripts.

18.7.2. Active Server Pages: Server-Side Embedding

Active Server Pages (ASPs) use a similar model: Python code is embedded in the HTML that defines a web page. But ASP is a server-side technologyembedded Python code runs on the server machine and uses an object-based API to dynamically generate portions of the HTML that is ultimately sent back to the client-side browser. As we saw in the last two chapters, Python server-side CGI scripts embed and generate HTML, and they deal with raw inputs and output streams. By contrast, server-side ASP scripts are embedded in HTML and use a higher-level object model to get their work done.

Just like client-side Active Scripting, ASP requires you to install Python and the Python Windows PyWin32 extensions package. But because ASP runs embedded code on the server, you need to configure Python only on one machine. Like CGI scripts in general, this generally makes Python ASP scripting much more widely applicable, as you don't need Python support on every client. Moreover, because you control the content of the embedded code on your server, this is a secure configuration. Unlike CGI scripts, however, ASP requires you to run Microsoft's Internet Information Server (IIS) today.

18.7.2.1. A short ASP example

We can't discuss ASP in any real detail here, but here's an example of what an ASP file looks like when Python code is embedded:

 <HTML><BODY> <SCRIPT RunAt=Server Language=Python> # # code here is run at the server # </SCRIPT> </BODY></HTML> 

As before, code may be embedded inside SCRIPT tag pairs. This time, we tell ASP to run the code at the server with the RunAt option; if omitted, the code and its tags are passed through to the client and are run by Internet Explorer (if configured properly). ASP also recognizes code enclosed in <% and %> delimiters and allows a language to be specified for the entire page. This form is handier if there are multiple chunks of code in a page, as shown in Example 18-14.

Example 18-14. PP3E\Internet\Other\Win\asp-py.asp

 <HTML><BODY> <%@ Language=Python %> <% # # Python code here, using global names Request (input), Response (output), etc. # Response.Write("Hello ASP World from URL %s" %                           Request.ServerVariables("PATH_INFO")) %> </BODY></HTML> 

However the code is marked, ASP executes it on the server after passing in a handful of named objects that the code may use to access input, output, and server context. For instance, the automatically imported Request and Response objects give access to input and output context. The code here calls a Response.Write method to send text back to the browser on the client (much like a print statement in a simple Python CGI script), as well as Request.ServerVariables to access environment variable information.

To make this script run live, you'll need to place it in the proper directory on a server machine running IIS with ASP support, after installing and registering Python. Although this is a simple example, the full power of the Python language is at your disposal when it is embedded like this. By combining Python-generated content with HTML formatting, this yields a natural way to generate pages dynamically and separate logic from display. It's similar in spirit to the more platform-neutral Zope DTML idea we saw earlier, and the PSP pages we'll meet later.

18.7.3. The COM Connection

At their core, both Internet Explorer and IIS are based on the COM (Component Object Model) integration systemthey implement their object APIs with standard COM interfaces and look to the rest of the world like any other COM object. From a broader perspective, Python can be used as both a scripting and an implementation language for any COM object. Although the COM mechanism used to run Python code embedded within HTML is automated and hidden, it can also be employed explicitly to make Python programs take the role of both COM clients and COM servers. COM is a general integration technology and is not strictly tied to Internet scripting, but a brief introduction here might help demystify some of the Active Scripting magic behind HTML embedding.

18.7.3.1. A brief introduction to COM

COM is a Microsoft technology for language-neutral component integration. It is sometimes marketed as ActiveX, partially derived from a system called Object Linking and Embedding (OLE), and it is the technological heart of the Active Scripting system we met earlier.[*] COM also sports a distributed extension known as DCOM that allows communicating objects to be run on remote machines. Implementing DCOM often simply involves running through Windows registry configuration steps to associate servers with machines on which they run.

[*] Roughly, OLE was a precursor to COM, and Active Scripting is just a technology that defines COM interfaces for activities such as passing objects to arbitrary programming language interpreters by name. Active Scripting is not much more than COM itself with a few extensions, but acronym and buzzword overload seem to run rampant in the Windows development world. To further muddy the waters, .NET is essentially a successor to COM.

Operationally, COM defines a standard way for objects implemented in arbitrary languages to talk to each other, using a published object model. For example, COM components can be written in and used by programs written in Visual Basic, Visual C++, Delphi, PowerBuilder, and Python. Because the COM indirection layer hides the differences among all the languages involved, it's possible for Visual Basic to use an object implemented in Python, and vice versa.

Moreover, many software packages register COM interfaces to support end-user scripting. For instance, Microsoft Excel publishes an object model that allows any COM-aware scripting language to start Excel and programmatically access spreadsheet data. Similarly, Microsoft Word can be scripted through COM to automatically manipulate documents. COM's language neutrality means that programs written in any programming language with a COM interface, including Visual Basic and Python, can be used to automate Excel and Word processing.

Of most relevance to this chapter, Active Scripting also provides COM objects that allow scripts embedded in HTML to communicate with Microsoft's Internet Explorer (on the client) and IIS (on the server). Both systems register their object models with Windows such that they can be invoked from any COM-aware language. For example, when Internet Explorer extracts and executes Python code embedded in HTML, some Python variable names are automatically preset to COM object components that give access to Internet Explorer context and tools (e.g., alert in Example 18-13). Calls to such components from Python code are automatically routed through COM back to Internet Explorer.

18.7.3.2. Python COM clients

With the PyWin32 Python extension package installed, though, we can also write Python programs that serve as registered COM servers and clients, even if they have nothing to do with the Internet at all. For example, the Python program in Example 18-15 acts as a client to the Microsoft Word COM object.

Example 18-15. PP3E\Internet\Other\Win\comclient.py

 #################################################################### # a COM client coded in Python: talk to MS-Word via its COM object # model; uses either dynamic dispatch (runtime lookup/binding), # or the static and faster type-library dispatch if makepy.py has # been run; install the Windows PyWin32 extensions package to use # this interface; Word runs hidden unless Visible is set to 1 (and # Visible lets you watch, but impacts interactive Word sessions); #################################################################### from sys import argv docdir = 'C:\\temp\\' if len(argv) == 2: docdir = argv[1]              # ex: comclient.py a:\ from win32com.client import Dispatch             # early or late binding word  = Dispatch('Word.Application')             # connect/start Word word.Visible = 1                                 # else Word runs hidden # create and save new doc file newdoc = word.Documents.Add( )                       # call Word methods spot   = newdoc.Range(0,0) spot.InsertBefore('Hello COM client world!')     # insert some text newdoc.SaveAs(docdir + 'pycom.doc')              # save in doc file newdoc.SaveAs(docdir + 'copy.doc') newdoc.Close( ) # open and change a doc file olddoc = word.Documents.Open(docdir + 'copy.doc') finder = word.Selection.Find finder.text = 'COM' finder.Execute( ) word.Selection.TypeText('Automation') olddoc.Close( ) # and so on: see Word's COM interface specs 

This particular script starts Microsoft Wordknown as Word.Application to scripting clientsif needed, and converses with it through COM. That is, calls in this script are automatically routed from Python to Microsoft Word and back. This code relies heavily on calls exported by Word, which are not described in this book. Armed with documentation for Word's object API, though, we could use such calls to write Python scripts that automate document updates, insert and replace text, create and print documents, and so on.

For instance, Figure 18-11 shows the two Word .doc files generated when the previous script is run on Windows: both are new files, and one is a copy of the other with a text replacement applied. The interaction that occurs while the script runs is more interesting. Because Word's Visible attribute is set to 1, you can actually watch Word inserting and replacing text, saving files, and so on, in response to calls in the script. (Alas, I couldn't quite figure out how to paste a movie clip in this book.)

Figure 18-11. Word files generated by Python COM client


In general, Python COM client calls may be dispatched either dynamically by runtime look-ups in the Windows registry, or statically using type libraries created by a Python utility script. These dispatch modes are sometimes called late and early dispatch binding, respectively. See PyWin32 documentation for more details.

Luckily, we don't need to know which scheme will be used when we write client scripts. The Dispatch call used in Example 18-15 to connect to Word is smart enough to use static binding if server type libraries exist or to use dynamic binding if they do not. To force dynamic binding and ignore any generated type libraries, replace the first line with this:

 from win32com.client.dynamic import Dispatch     # always late binding 

However calls are dispatched, the Python COM interface performs all the work of locating the named server, looking up and calling the desired methods or attributes, and converting Python datatypes according to a standard type map as needed. In the context of Active Scripting, the underlying COM model works the same way, but the server is something like Internet Explorer or IIS (not Word), the set of available calls differs, and some Python variables are preassigned to COM server objects. The notions of "client" and "server" can become somewhat blurred in these scenarios, but the net result is similar.

18.7.3.3. Python COM servers

Python scripts can also be deployed as COM servers and can provide methods and attributes that are accessible to any COM-aware programming language or system. This topic is too complex to cover in depth here too, but exporting a Python object to COM is mostly just a matter of providing a set of class attributes to identify the server and utilizing the proper win32com registration utility calls. Example 18-16 is a simple COM server coded in Python as a class.

Example 18-16. PP3E\Internet\Other\Win\comserver.py

 ################################################################ # a COM server coded in Python; the _reg_ class attributes # give registry parameters, and others list methods and attrs; # for this to work, you must install Python and the PyWin32 # package, this module file must live on your Python path, # and the server must be registered to COM (see code at end); # run pythoncom.CreateGuid( ) to make your own _reg_clsid_ key; ################################################################ import sys from   win32com.server.exception import COMException         # what to raise import win32com.server.util                                  # server tools globhellos = 0 class MyServer:     # COM info settings     _reg_clsid_      = '{1BA63CC0-7CF8-11D4-98D8-BB74DD3DDE3C}'     _reg_desc_       = 'Example Python Server'     _reg_progid_     = 'PythonServers.MyServer'              # external name     _reg_class_spec_ = 'comserver.MyServer'                  # internal name     _public_methods_ = ['Hello', 'Square']     _public_attrs_   = ['version']     # Python methods     def _ _init_ _(self):         self.version = 1.0         self.hellos  = 0     def Square(self, arg):                                   # exported methods         return arg ** 2     def Hello(self):                                         # global variables         global globhellos                                    # retain state, but         globhellos  += 1                                     # self vars don't         self.hellos += 1         return 'Hello COM server world [%d, %d]' % (globhellos, self.hellos) # registration functions def Register(pyclass=MyServer):     from win32com.server.register import UseCommandLine     UseCommandLine(pyclass) def Unregister(classid=MyServer._reg_clsid_):     from win32com.server.register import UnregisterServer     UnregisterServer(classid) if _ _name_ _ == '_ _main_ _':       # register server if file run or clicked     Register( )                    # unregisters if --unregister cmd-line arg 

As usual, this Python file must be placed in a directory in Python's module search path before it can be used by a COM client. Besides the server class itself, the file includes code at the bottom to automatically register and unregister the server to COM when the file is run:

  • To register a server, simply call the UseCommandLine function in the win32com.server.register package and pass in the Python server class. This function uses all the special class attribute settings to make the server known to COM. The file is set to automatically call the registration tools if it is run by itself (e.g., when clicked in a file explorer).

  • To unregister a server, simply pass an unregister argument on the command line when running this file. When run this way, the script automatically calls UseCommandLine again to unregister the server; as its name implies, this function inspects command-line arguments and knows to do the right thing when unregister is passed. You can also unregister servers explicitly with the UnregisterServer call demonstrated near the end of this script, though this is less commonly used.

Perhaps the more interesting part of this code, though, is the special class attribute assignments at the start of the Python class. These class annotations can provide server registry settings (the _reg_ attributes), accessibility constraints (the _public_ names), and more. Such attributes are specific to the Python COM framework, and their purpose is to configure the server.

For example, the _reg_class_spec_ is simply the Python module and class names separated by a period. If it is set, the resident Python interpreter uses this attribute to import the module and create an instance of the Python class it defines, when accessed by a client.[*]

[*] But note that the _reg_class_spec_ attribute is no longer strictly needed and not specifying it avoids a number of PYTHONPATH issues. Because such settings are prone to change, you should always consult the latest Windows extensions package reference manuals for details on this and other class annotation attributes.

Other attributes may be used to identify the server in the Windows registry. The _reg_clsid_ attribute, for instance, gives a globally unique identifier (GUID) for the server and should vary in every COM server you write. In other words, don't use the value in this script. Instead, do what I did to make this ID, and paste the result returned on your machine into your script:

 C:\...>python >>> import pythoncom >>> pythoncom.CreateGuid( ) IID('{1BA63CC0-7CF8-11D4-98D8-BB74DD3DDE3C}') 

GUIDs are generated by running a tool shipped with the Windows extensions package; simply import and call the pythoncom.CreateGuid function and insert the returned text in the script. Windows uses the ID stamped into your network card to come up with a complex ID that is likely to be unique across servers and machines. The more symbolic program ID string, _reg_progid_, can be used by clients to name servers too, but it is not as likely to be unique.

The rest of the server class is simply pure-Python methods, which implement the exported behavior of the server; that is, things to be called or fetched from clients. Once this Python server is annotated, coded, and registered, it can be used in any COM-aware language. For instance, programs written in Visual Basic, C++, Delphi, and Python may access its public methods and attributes through COM; of course, other Python programs can also simply import this module, but the point of COM is to open up components for even wider reuse.

18.7.3.3.1. Using the Python server from a Python client

Let's put this Python COM server to work. The Python script in Example 18-17 tests the server in Example 18-16 in two ways: first by simply importing and calling it directly, and then by employing Python's client-side COM interfaces that were shown earlier to invoke it less directly. When going through COM, the PythonServers.MyServer symbolic program ID we gave the server (by setting the class attribute _reg_progid_) can be used to connect to this server from any languageincluding Python.

Example 18-17. PP3E\Internet\Other\Win\comserver-test.py

 ################################################################ # test the Python-coded COM server from Python two ways ################################################################ def testViaPython( ):                                 # test without COM     from comserver import MyServer                     # use Python class name     object = MyServer( )                              # works as for any class     print object.Hello( )     print object.Square(8)     print object.version def testViaCom( ):     from win32com.client import Dispatch             # test via client-side COM     server = Dispatch('PythonServers.MyServer')      # use Windows registry name     print server.Hello( )                                 # call public methods     print server.Square(12)     print server.version                             # access attributes if _ _name_ _ == '_ _main_ _':     testViaPython( )                                  # test module, server     testViaCom( )                                     # COM object retains state     testViaCom( ) 

If we've properly configured and registered the Python COM server, we can talk to it by running this Python test script. In the following, we run the server and client files from an MS-DOS console box (though they can usually be run by mouse clicks as well). The first command runs the server file by itself to register the server to COM; the second executes the test script to exercise the server both as an imported module (testViaPython) and as a server accessed through COM (testViaCom):

 C:\Python24>python d:\PP3E\Internet\Other\Win\comserver.py Registered: PythonServers.MyServer C:\Python24>python d:\PP3E\Internet\Other\Win\comserver-test.py Hello COM server world [1, 1] 64 1.0 Hello COM server world [2, 1] 144 1.0 Hello COM server world [3, 1] 144 1.0 C:\Python24>python d:\PP3E\Internet\Other\Win\comserver.py --unregister Unregistered: PythonServers.MyServer 

Notice the two numbers at the end of the Hello output lines: they reflect current values of a global variable and a server instance attribute. Global variables in the server's module retain state as long as the server module is loaded; by contrast, each COM Dispatch (and Python class) call makes a new instance of the server class, and hence new instance attributes. The third command unregisters the server in COM, as a cleanup step. Interestingly, once the server has been unregistered, it's no longer usable, at least not through COM (this output has been truncated to fit here):

 C:\Python24>python d:\PP3E\Internet\Other\Win\comserver-test.py Hello COM server world [1, 1] 64 1.0 Traceback (innermost last):   File "comserver-test.py", line 21, in ?     testViaCom( )                                     # COM object retains   File "comserver-test.py", line 14, in testViaCom     server = Dispatch('PythonServers.MyServer')        # use Windows register   ...more deleted... pywintypes.com_error: (-2147221005, 'Invalid class string', None, None) 

18.7.3.3.2. Using the Python server from a Visual Basic client

The comserver-test.py script just listed demonstrates how to use a Python COM server from a Python COM client. Once we've created and registered a Python COM server, though, it's available to any language that sports a COM interface. For instance, Visual Basic code can run the Python methods in Example 18-16 just as well. Example 18-18 shows the sort of code we write to access the Python server from Visual Basic. Clients coded in other languages (e.g., Delphi or Visual C++) are analogous, but syntax and instantiation calls vary.

Example 18-18. PP3E\Internet\Other\Win\comserver-test.bas

 Sub runpyserver( )     ' use python server from vb client     ' alt-f8 in word to start macro editor     Set server = CreateObject("PythonServers.MyServer")     hello1 = server.hello( )     square = server.square(32)     pyattr = server.Version     hello2 = server.hello( )     sep = Chr(10)     Result = hello1 & sep & square & sep & pyattr & sep & hello2     MsgBox Result End Sub 

The real trick, if you're not a Windows developer, is how to run this code. Because Visual Basic is embedded in Microsoft Office products such as Word, one approach is to test this code in the context of those systems. Try this: start Word, and then press Alt and F8 together, and you'll wind up in the Word macro dialog. There, enter a new macro name, and then press Create, and you'll find yourself in a development interface where you can paste and run the VB code just shown.

Running the Visual Basic code in this context produces the Word pop-up box in Figure 18-12, showing the results of Visual Basic calls to our Python COM server, initiated by Word. Global variable and instance attribute values at the end of both Hello reply messages are the same this time, because we make only one instance of the Python server class: in Visual Basic, by calling CreateObject, with the program ID of the desired server.

Figure 18-12. Visual Basic client running Python COM server in Word


If your client code runs but generates a COM error, make sure that the PyWin32 package has been installed, that the Python server module file is in a directory on Python's import search path, and that the server file has been run by itself to register the server with COM. If none of that helps, you're probably already beyond the scope of this text. Please see additional Windows programming resources for more details.

18.7.3.3.3. Using the Python server with client-side Active Scripting

Another way to kick off the Visual Basic client code is to embed it in a web page and rely on Internet Explorer to strip it out and launch it for us. In fact, even though Python cannot currently be embedded in a page's HTML directly (see the note in the earlier section "Active Scripting: Client-Side Embedding"), it is OK to embed code which runs a registered Python COM component indirectly. Example 18-19, for instance, embeds similar Visual Basic code in a web page; when this file is opened by Internet Explorer, it runs our Python COM server from Example 18-16 again, producing the page and pop up in Figure 18-13.

Figure 18-13. Internet Explorer running VBScript running Python COM server


Example 18-19. PP3E\Internet\Other\Win\comserver-test.bas

 <HTML><BODY> <P>Run Python COM server from VBScript embedded in HTML via IE</P> <SCRIPT Language=VBScript> Sub runpyserver( )     ' use python server from vb client     ' alt-f8 in word to start macro editor     Set server = CreateObject("PythonServers.MyServer")     hello1 = server.hello( )     square = server.square(9)     pyattr = server.Version     hello2 = server.hello( )     sep = Chr(10)     Result = hello1 & sep & square & sep & pyattr & sep & hello2     MsgBox Result End Sub runpyserver( ) </SCRIPT> </BODY></HTML> 

Trace through the calls on your own to see what is happening. An incredible amount of routing is going on herefrom Internet Explorer to Visual Basic to Python and back, and a control flow spanning three systems and HTML and Python filesbut with COM, it simply works. This structure opens the door to arbitrary client-side scripting from web pages with Python. Because Python COM components invoked from web pages must be manually and explicitly registered on the client, it is secure.

18.7.3.4. The bigger COM picture: DCOM

So what does writing Python COM servers have to do with the Internet motif of this chapter? After all, Python code embedded in HTML simply plays the role of COM client to Internet Explorer or IIS systems that usually run locally. Besides showing how such systems work their magic, I've presented this topic here because COM, at least in its grander world view, is also about communicating over networks.

Although we can't get into details in this text, COM's distributed extensions, DCOM, make it possible to implement Python-coded COM servers to run on machines that are arbitrarily remote from clients. Although largely transparent to clients, COM object calls like those in the preceding client scripts may imply network transfers of arguments and results. In such a configuration, COM may be used as a general client/server implementation model and an alternative to technologies such as Remote Procedure Calls (RPC).

For some applications, this distributed object approach may even be a viable alternative to Python's other client- and server-side scripting tools we've studied in this part of the book. Moreover, even when not distributed, COM is an alternative to the lower-level Python/C integration techniques we'll meet later in this book.

Once its learning curve is scaled, COM is a straightforward way to integrate arbitrary components and provides a standardized way to script and reuse systems. However, COM also implies a level of dispatch indirection overhead and is a Windows-only solution at this writing. Because of that, it is generally not as fast or as portable as some of the other client/server and C integration schemes discussed in this book. The relevance of such trade-offs varies per application.

As you can probably surmise, there is much more to the Windows scripting story than we cover here. If you are interested in more details, O'Reilly's Python Programming on Win32 (by Mark Hammond and Andy Robinson) provides an in-depth presentation of these and other Windows development topics. Much of the effort that goes into writing scripts embedded in HTML involves using the exposed object model APIs, which are deliberately skipped in this book; see Windows documentation sources for more details.

The IronPython C# Python Compiler

Late-breaking news: as this third edition was being developed, Microsoft hired Python developer Jim Huginin (who also created Jython) to work on his IronPython implementation. IronPython is a new, independent Python language implementation, like the Jython system described earlier in this chapter, but it compiles Python scripts for use in the Microsoft C# language environment and .NET Frameworka software component system based on XML that fosters cross-language interoperability. IronPython will also work on the Mono open source version of .NET. As such, it opens the door to other Python web-scripting roles and modes.

If successful, this new compiler system promises to be the third complete Python implementation (with Jython and the standard C implementation, and not counting projects such as PyPy) and an exciting development for Python in general. As in the Jython Java-based implementation, IronPython scripts are coded using the standard Python core language presented in this text and are translated to be executed by the underlying C# system. Moreover, .NET interfaces are automatically integrated for use in Python scripts: Python classes may freely use, subclass, and act as .NET components.

Also like Jython, this new alternative implementation of Python has a specific target audience and will likely prove to be of most interest to developers concerned with C# and .NET/Mono Framework integration. However, initial performance results suggest that IronPython may compete favorably with standard C Python, since it can leverage all the work done on .NET Just-in-Time (JIT) compilers. Search the Web for up-to-date details on IronPython.

An earlier version of .NET integration, Python.NET, has similar goals, but it uses the normal Python runtime engine to allow standard Python to use .NET classes. Be sure to watch Python web forums for more developments on this front.





Programming Python
Programming Python
ISBN: 0596009259
EAN: 2147483647
Year: 2004
Pages: 270
Authors: Mark Lutz

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net