registration
Python

Python

This course contains the basics of Python

Course introduction
Test Your Caliber
Interview Questions
Pragnya Meter Exam

Python

Objects Interfacing and Distribution
Object Interfacing and Distribution

Python has very comprehensive support for object interfacing and distributing technologies. It is particularly well integrated with the Windows platform; its programs can interact with COM and DCOM services.

The win32com Python extensions developed by Mark Hammond can be used to interface Python to Microsoft's COM and ActiveX architectures. This package, which is part of the Python Win distribution, enables Python to be used in Active Server Pages, or as a COM controller that can exchange information with other COM-aware applications, such as Microsoft Word and Visual Basic.

Object- oriented design and programming is specifically beneficial in distributed environments where the encapsulation and subsequent independence of objects enable distribution of an application over a network.

The possibilities of heterogeneous machine architectures, physically distant locations, and independent component failures make it difficult to program distributed object systems.

A number of distributed- processing environments, such as OMG's CORBA and Microsoft's DCOM, have been developed to attempt to hide these problems from programmers, reducing the complexity of their task. Besides the most famous object models, an international standard known as the Reference Model for Open Distributed Processing (RM-ODP) is currently being developed.

Python is one of the languages supported by Xerox PARC's ILU (Inter -Language Unification), which is a free CORBA -compatible distributed object system. To this date, many distributed applications systems have been developed in Python using this technology.

The Hector project at the University of Queensland, Australia, also uses Python.

Interfacing Objects

Currently, one of the biggest problems with both COM and DCOM architectures is that they are supported only by Windows systems. However, most operating systems have their own native way of connecting systems together at a remote procedure call level. At the time of this writing, there are some unconfirmed rumors that Microsoft is planning to create an interface to the Windows operating system using the XML-RPC protocol. This development would bring a whole new world to the Windows applications by increasing their connectivity with all the other platforms. Note that Microsoft has already produced a similar protocol called SOAP.

The COM-based technologies are the focus of Microsoft's development plans for Windows, ranging from operating systems and languages to messaging and databases. Nowadays, new COM-based technologies are found in a lot of places inside your Windows system, such as the ActiveX controls and VBScript processing. OLEDB, for example, is the successor to ODBC. ODBC gives access to relational databases, whereas OLEDB provides a more versatile level of access, so that the same API can be used to retrieve data from all kinds of sources, ranging from flat text files, through Excel spreadsheets, up to ODBC databases.

Introduction to COM Objects

Let's learn a little about what is behind the Microsoft Common Object Model (COM) technology before seeing how you can use it along with Python.

COM is the most widely used component software model in the world. It provides a rich set of integrated services, a wide choice of easy-to-use tools, and a large set of available applications. COM underlies a large majority of the new code developed for Windows and Windows NT operating systems, whether created by Microsoft or by others.

COM consists of a well-defined, mature, stable, and freely available specification, as well as a reference implementation, which has been widely tested and adopted worldwide. It provides the richest set of existing services for applications today, as well as the largest set of development tools available for any component or object model on the market. Of course, Windows is the only Operating System in which you can be assured of finding COM, which makes us think that COM doesn't appear to be a standard because it doesn't provide cross-platform solutions.

The COM Specification

COM is a specification and a set of services that enables you to create modular, object-oriented, customizable and upgradable, distributed applications using a number of languages. You can even use components that you already have written in other languages.

The COM specification describes the standards that you need to follow in order to create interoperable COM components. This standard describes what COM objects should look like and how they should behave. The specification is backed up by a set of services, or APIs. The COM library provides these services, which are part of the operating system for Win32 platforms, and available as a separate package for other operating systems.

COM components can be packaged as EXE or DLL files—COM provides the communication mechanism to enable components in different modules to talk to each other. They are true objects in the usual sense—they have identity, state, and behavior. COM components that implement a common interface can be treated polymorphically, enabling easy customization and upgrades of your applications.

COM components link with each other dynamically, and COM defines standard ways of locating components and identifying their functionality, so individual components are swappable without having to recompile the entire application. COM provides a communication mechanism that enables components to interact across a network.

More importantly, COM provides location transparency to applications (if desired) that enables them to be written without regard to the location of their components. The components can be moved without requiring any changes to the application.

COM is a binary standard. Any language that can cope with the binary standard can create or use COM objects. The number of languages and tools that support COM increases every day. C, C++, Java, JScript, Visual Basic, VBScript, Delphi, and PowerBuilder form just part of that growing list, which means that any one of these languages can easily interoperate with Python. Keep in mind that COM is a standard for interaction between programs—an Object Request Broker service.

COM is the object model that underlies most of the Microsoft technologies; here are a few of those COM applications:

  • ActiveX uses COM to provide controls.
  • OLE uses COM to combine documents.
  • OLEDB and ADO use COM for data access.
  • DirectX uses COM for graphics.

Any COM-aware program is able to interact with other COM-aware programs. One program can even execute commands of the other. The program that executes the method call is called the COM server, and the program that calls the object method is called the COM client. Because COM is a Microsoft product, most applications for Windows can act as COM servers or clients.

Python's support for the COM technology is included in the Python for Windows (PythonWin) extensions.

COM Interfaces

The COM technology is very broad and complex. Basically, it enables objects to be shared among many applications, without applications knowing the implementation details of the objects. Objects that implement the COM technology can communicate with each other without the need for knowing the others'details.

COM components do business with interfaces. An interface defines functionality, but not implementation. Objects must handle the implementation. COM objects are small pieces of selfcontained software that interact with other applications by exposing well-defined, languageindependent interfaces.

COM is an object model that relies heavily on interfaces. These interfaces are entirely separate from their implementations. Although COM defines the interfaces, its model doesn't provide the interface's implementation. Each object's class has the task of defining the implementations. The interfaces can be standard ones that other objects also expose, or they can be special ones that are particular to that object. A unique ID, called an IID (Interface ID), identifies each interface. IIDs use Universally Unique Identifiers (UUID). UUID is a format used for many COM IDs to allocate a unique identification string for objects. Many tools can generate unique UUIDs. Python's pythoncom module has a function called CreateGuid() that generates UUID strings.

In order to create an object, COM locates the required class and creates an instance of it. The concept of COM classes is identical to the other Python classes. Additionally, each COM class needs to implement two identifiers: Class ID (_reg_clsid_), which is another UUID, and Program ID (_reg_progid_), which is a identification string that must be easier to remember than the Class ID. This string is not guaranteed to be unique. In order to create an object, the programmer must specify either the progid, or the clsid.

All interfaces are derived from the IUnknowninterface. Therefore, they support its methods. The IUnknowninterface is the base of all COM interfaces. This interface contains only three methods:

  • AddRef() and Release() are used for managing COM lifetimes, which are based on reference counts.
  • QueryInterface() is used for obtaining a reference to one of the other interfaces that the object exposes. In other words, interfaces are obtained by using the IUnknown::QueryInterface() method.
  • Stream, IStorage, and IPropertyPageare examples of standard interfaces defined by COM. They define file-like operations, file system-like semantics, and how a control exposes a property page, respectively. Besides the standard interfaces, COM also enables you to define your own custom interfaces by using an Interface Definition Language (IDL).

The IDispatchinterface enables any COM objects to be used from a scripting environment. This interface was designed explicitly for languages that cannot use normal COM interfaces. The objects that implement this interface are known as automation objects because they expose a programmable interface that can be manipulated by another program. This interface exposes dynamic object models whose methods and properties can be determined at runtime. Basically, this interface is used whenever you are handling an object whose interface is not known at compile time, or if there is no compile time at all.

To access a method or a property of an object, you can use either late or early binding. All the examples that you see in this book use late bindings because the Python interpreter doesn't know what the object interfaces look like. It doesn't know which are the methods and properties that compound the object. It just makes the calls dynamically, according to the function names that you provide.

Late bindings use the IDispatchinterface to determine the object model at runtime. Python function win32com.client.Dispatch() provides this runtime facility. Most examples in this use the IDispatch interface. However, the win 32com .client .Dispatch() function hides many implementation details from us. Internally, Python converts the names into IDs using the internal function Get IDs Of Names(). Then, this ID is passed as an argument to the Invoke() function.

You can try to improve the performance of your program by calling the Invoke() function directly. Usually, the performance gets better when names are not resolved at runtime. Just be careful to provide the right ID. If you implement this way, an early binding operation is executed.

For the early bindings, we have the concept of Type Libraries, wherein the object model is exposed at compile time. In this kind of implementation, you don't call the methods and properties directly. The GetIDsOfNames() method gets an ID for the method or property that you want to use, and the Invoke() method makes the call.

For example, a function call would be invoked as

  id = GetIDsOfNames("YourMethodCall")
Invoke(id, DISPATCH_METHOD)

And a property would be collected as

  id = GetIDsOfNames("ObjectProperty")
Invoke(id, DISPATCH_PROP_GET)

Usually, you don't have to worry about this kind of implementation. You just say

  YourObject.YourMethodCall()
and
YourObject.ObjectProperty

In order to implicitly call the Invoke() method without causing data type problems, the IDispatchinterface assumes the data type VARIANT for all variables. That's because late bindings do not know the specific types of the parameters, whereas early bindings do.

Late bindings do not know about parameters passed by reference, so no parameters are passed by reference. However, early bindings accept parameters passed by reference, and return them as tuples.

COM objects can be implemented as InProcobjects, which are implemented as DLLs. These objects are loaded into the calling process providing that best performance because no marshalling is required.

Of course, for most objects, some marshaling will be needed to marshal Python parameters into a form that can be passed to the COM object.

The other option is to implement COM objects as LocalServer/ RemoteServer objects. This kind of object is implemented as a standalone EXE, which is safer than the first option because of process isolation.

COM can also be used to decide which implementation should be used. If both types of implementation are available, the caller interface is able to decide which option is the best one to choose.

The Windows Registry

All the information concerning a COM object, such as the mapping between its progid and clsid, is stored in the Windows Registry. The Windows Registry also stores the name of the DLL file of an InProcobject, and the name of the EXE LocalServerobject. Object security, threading models, and many other details are also stored there.

ADO

ActiveX Data Objects (ADO) is an automation-based interface for accessing data. This technology uses the OLE DB interface to access an extensive range of data sources, including but not limited to data provided by the ODBC.

Microsoft Remote Data Service (RDS) is a component of ADO that provides fast and efficient data frameworks for applications hosted in Microsoft Internet Explorer. RDS uses data-aware ActiveX controls to provide data access programming to Web developers, who need to build distributed, dataintensive applications for use over networks. RDS is based on a client/server, distributed technology that works over HTTP, HTTPS (HTTP over Secure Sockets layer), and DCOM application protocols.

ActiveX

An ActiveX control is an OLE control that can live inside an HTML page; it can be simple Window objects, such as buttons, text boxes, or scrollbars. It also can be quite complicated, for example, a bar chart graph display can be an ActiveX control. An entire spreadsheet can also be a single control. Each ActiveX control has properties and reacts to external events. Its properties can be modified to change its appearance. For example, its containing program can set color and fonts. External events such as a mouse click or keyboard input can cause a control's event handler to execute. Note that the ActiveX technology is another Windows only thing, and not really any use in a cross platform environment.

Microsoft's Web browser, Internet Explorer, is ActiveX-aware, meaning that Web application developers can package ActiveX components to create more dynamic content in their Web pages. ActiveX controls use COM technologies to provide interoperability with other types of COM components and services. ActiveX controls provide a number of enhancements specifically designed to facilitate distribution of components over high-latency networks and to integrate controls into Web browsers. These enhancements include features such as incremental rendering and code signing, which enables users to identify the authors of controls before allowing them to execute.

Implementing COM Objects in Python

In order to implement COM objects in the Python version of Windows, you need a set of extensions developed by Mark Hammond and Greg Stein. Part of the win32com package, these extensions enable you to do everything that is COM-related, including writing COM clients and COM servers.

All the Win32 extensions (including the COM extensions) are part of the win32all installation package. This package also installs the PythonWinIDE in your machine.

After installing the package in your machine, take a look at the readme.htm file, which is stored at the win32comdirectory.

COM support for Python is compounded of the core PythonCOM module, which supports the C++ code, and the other modules that implement helper code in Python. The whole package is known as win32com.

The win32com Package

The win32com support is standalone, as it does not require PythonWin. The win32com package itself does not provide any functionality. Some of the modules contained in this package are win32com.pythoncom— Provides core C++ support for COM objects and exposes COM object methods, such as QueryInterface() and Invoke(), just as the C++ API does. Note that all the reference counting is automatically done for you. Programmers rarely access this module directly. Instead, they usually use the win32com wrapper classes and functions written in Python to provide a nice, programmable interface.

win32com.client— Provides support for COM clients (for example, using Python to start Microsoft Excel and create a spreadsheet). The COM client support enables Python to manipulate other COM objects via their exposed interfaces. All client-side IUnknown-derived objects, includingIDispatch, are supported.

win32com.server— Provides support for COM servers (for example, creating and registering a COM server object in Python and using a language such as Visual Basic or Delphi to access the Python objects). The COM server support enables Python to create COM servers, which can be manipulated by another COM client. All server-side IUnknown-derived objects are supported.

  • win32com.axscript— This is the ActiveX Scripting implementation for Python.
  • win32com.axdebug— This is the Active Debugging implementation for Python.
  • win32com.mapi— Provides utilities for working with MAPI and the Microsoft Exchange Server.

Talking to Windows Applications

The COM technology has been part of the Windows world for a long time. The COM genealogy can be traced back to DDE (Dynamic Data Exchange). DDE was the first device for transferring data between various applications in a multi-tasking computer. After some time, DDE was expanded to Object Linking and Embedding (OLE)—note that COM was invented as part of OLE. The creation of the Visual Basic Extensions (VBXs) enhanced the OLE technology for visual components, originating a new standard called OLE2, which was based on top of COM. Soon, the OLE2 technology became more integrated with COM, which is a generalpurpose mechanism. Nowadays, COM is mostly known, in part, because of the ActiveX technology.

Professional applications such as Microsoft Office and the Netscape browser enable you to control their objects using COM. Therefore, programs written in Python can be easily used to control those applications.

COM passes string objects as Unicode characters. Before using these objects in Python, it's necessary to convert them to strings. The Python-2.0 Unicode string type is not the same as the string type, but it is easy to convert between the two.

PythonWin comes with a basic COM browser (Python Object browser). This program helps you to identify the current objects in your system that implement COM interfaces.
To run the browser, select it from the PythonWin Tools menu, or double-click on the file win32comclientcombrowse.py.

Note that there are other COM browsers available, such as the one that comes with the Microsoft Visual C++. If you study the file pythonwin32comserversinterp.py, which is installed as part of your PythonWin distribution, you will learn how to implement a very simple COM server. This server exposes the Python interpreter by providing a COM object that handles both the exec and evalmethods. Before using this object, register it by running the module from Python.exe. Then, from Visual Basic, use CreateObject('Python.Interpreter') to initialize the object, and you can start calling the methods.

Word and Excel

Let's quit talking and get to some practicing. Our objective here is to open and manipulate Microsoft applications from Python.

The first thing that you need to do is to import the COM client and dispatch the right object. In the next example, a variable is assigned a reference to an Excel application:

>>> import win32com.client
>>>xl = win32com.client.Dispatch("Excel.Application")

The following does the same thing, but this time the reference is to a Word application.

>>>wd =  win32com.client.Dispatch("Word.Application")

Excel.Applicationand Word.Applicationare the Program IDs (progid), which are the names of the objects for which you want to create an instance. Internally, these objects have a Class ID (clsid) that uniquely registers them in the Windows Registry. The matching table between progids and clsids is stored in the Windows Registry and the matching is performed by the COM mechanism.

It is not an easy job to identify an application progid, or to find out object methods and attributes. You can use COM browsers to see what applications have COM interfaces in your system. For the Microsoft Products, you can take a look at the documentation; it is a good source of information. Not necessarily every COM object implements the same interface. However, there are similarities.

For example, if the previous assignments have just created the objects and you want to make them visible, you have to type

>>>xl.Visible = 1 # Sets the visible property for
  the Excel  application
>>>wd.Visible = 1 # Sets the visible property for the Word application

To close both programs and release the memory, you need to say

>>>xl = None
>>>wd = None
or, you could use
>>>del xl, wd

These were simple examples of implementing COM clients in Python. Next, we will see how to implement a Python COM server by creating a Python interface that exposes an object. The next block of code registers the interface in the Windows Registry. Note that every new COM object that you create must have a unique clsid, but you don't have to worry about it.

The complex algorithm that works behind the scenes is ready to generate a unique identification, as shown here:

>>> import pythoncom
>>> print pythoncom.CreateGuid()

Your COM server is defined next. You have to execute the program in order to make the COM object available in the system. Store it on a file, and double-click on it.

   class TaxApplication:
_public_methods_ = ['PAtax']
_reg_progid_ = "Tax.Application"
_reg_clsid_ = "{D2DEB6E1-3C6D-11D4-804E-0050041A5111}"

defPAtax(self, amount, tax=0.07):
return amount + (amount * tax)
if __name__=='__main__':
print "Registering COM server"
import win32com.server.register
win32com.server.register.UseCommandLine(TaxApplication)
  • Line 2: Exposes the method to be exported.
  • Line 3: Defines the name that the COM client application must use to connect to the object.
  • Line 4: Defines the unique Class ID (clsid) used by the object.
  • Line 12: Registers the TaxApplicationclass.

In order to test the program, we need to have an external COM client. Let's use the Visual Basic for Applications Editor, which is present in both Excel and Word.

Open your Microsoft application, type ALT+F8 in the Macro dialog box, and select the option that creates a macro. Now, you need to type the following block of code:

  Sub Tax()
Set TaxApplication = CreateObject("Tax.Application")
newamount = TaxApplication.PAtax(100)
MsgBoxnewamount
Set TaxApplication = Nothing
End Sub

Now, if you press F5, Visual Basic should display a message box showing the result of our simple tax operation, which, in our case, is 107. To unregister your COM object you can either pass the argument --unregister when calling your script, or you can use the following line of code inside your Python program:

>>>win32com.server.register.UnregisterClasses(TaxApplication)

A very comprehensive example of using Microsoft Word and Excel is stored in the testMSOffice.py file, which is part of your PythonWin distribution. It's worth checking out!!!

Word

The following code implements a simple wrapper for the Microsoft Word Application. To test it you need to create a Word document and replace its path in the code. The program will open this file, replace the first occurrence of the string "#name#" within the file, add a small bit of text to the end of the line, and print the file.

  import win32com.client
False = 0
True = -1
wdLine = 5
classWordApp:
def __init__(self):
self.app = win32com.client.Dispatch("Word.Application")
def open(self, document_file):
self.app.Documents.Open(document_file)
def replace(self, source_selection, new_text):
self.app.Selection.HomeKey(Unit=wdLine)
self.app.Selection.Find.Text = source_selection
self.app.Selection.Find.Execute()
self.app.Selection.TypeText(Text=new_text)
defaddtext(self, new_text):
self.app.Selection.EndKey(Unit=wdLine)
self.app.Selection.TypeText(Text=new_text)
defprintdoc(self):
self.app.Application.PrintOut()
def close(self):
self.app.ActiveDocument.Close(SaveChanges =False)
worddoc = WordApp()
worddoc.open(r"s: template.doc")
worddoc.replace("#name#", "Andre Lessa")
worddoc.addtext(" What do you want to learn ?")
worddoc.printdoc()
worddoc.close

If you type in the name of the object's attribute that accesses the Dispatch method, you get as a result, the COM object name:

>>>worddoc.app
<COMObjectWord.Application.>

This object is an example of a dynamic dispatch object. The provided name indicates that the object is a generic COM object, and affirms that Python doesn't know anything about it, except the name that you used to create it.

All the information about this object is built dynamically. Besides dynamic dispatches, you can also use static dispatches, which involve the generation of a .pyfile that contains support for the specific COM object. In CORBA speak, this is called stub generation, or IDL compilation.

In order to generate the Python files that support a specific COM object, you need to execute win32comclientmakepy.py. A list of Type Libraries will be displayed. Select one (for example, 'Microsoft Word 8.0 Object Library') and click OK. You can also call the makepy.py program directly from the command prompt by typing makepy .py "Microsoft Word 8.0 Object Library".

Now, Python knows exactly how to handle the interfaces before invoking the COM object. Although, you can't see any differences, you can check that Python really knows something else now by querying the COM object:

>>> import win32com.client
>>>wd=win32com.client.Dispatch("Word.Application")
>>>wd
<win32com.gen_py.Microsoft Word 8.0 Object Library._Application>
Note that Python knows the explicit type of the object now.

All the compiled information is stored in a file in the win32com/gen_pydirectory. You probably won't understand the filename because it is encoded. Actually, you don't need to use this file at all. All the interface information is made available via win32com.client.Dispatch and win32com.client.constants.

If you really need to identify the name of the module that was generated, you can use the win32com.client.gencachemodule. This module has two functions: Get Module For CLSID and GetModuleForProgIDthat return Python module objects you can use in your code. makepy.pyalso automatically installs all generated constants from a library of types in an object called win32com.clients.constants. After creating the object, all the constants become available to you. In the previous example, we had to initialize the constant wdLine, because the constants were not available.

Now, after running makepy.py, you can replace the line

  self.app.Selection.EndKey(Unit=wdLine)
with
self.app.Selection.EndKey(Unit=win32com.clients.constants.wdLine)
and remove the initialization line
wdLine = 5

The next example uses the wdWindowStateMaximizeconstant to maximize Microsoft Word:

>>>w.WindowState =  win32com.client.constants
  .wdWindowStateMaximize

Excel

Next, we'll see how to create COM clients using Microsoft Excel. The principle is very simple. Actually, it is the same one used previously for wrapping Microsoft Word, as it is demonstrated in the following example.

>>> import win32com.client
>>>excelapp = win32com.client.Dispatch("Excel.Application")
>>>excelapp.Visible = 1

Note that we have to change the Visibleproperty in order to see the Excel application. The default behavior is to hide the application window because it saves processor cycles. However, the object is available to any COM client that asks for it.

As you can see in the example, Excel's progid is Excel.Application. After you create the Excel object, you are able to call its methods and set its properties. Keep in mind that the
Excel Object Model has the following hierarchy: Application, WorkBook, Sheet, Range, and Cell.

Let's play a little with Excel. The following statements write to the workbook:

>>>excelapp.Range("A1:C1").Value =  "Hello", "Python", "World"
>>>excelapp.Range("A2:A2").Value = 'SPAM! SPAM! SPAM!'
Note that you can also use tuples to transport values:
>>>excelapp.Range("A1:C1").Value = ('Hello', 'Python', 'World')
To print a selected area, you need to use the PrintOut() method:
>>>excelapp.Range("A1:C1").PrintOut()

What about entering date and time information? The following examples will show you how to set the Date/Time format for Excel cells.

First, call Excel's time function:

>>>excelapp.Cells(4,3).Value = "=Now()"
>>>excelapp.Columns("C").EntireColumn.AutoFit()

The AutoFit() function is required in order to display the information, instead of showing "#######".

Now, use Python to set the time you want:

>>> import time, pythoncom
>>>excelapp.Cells(4,1).Value = pythoncom.MakeTime(time.time())
>>>excelapp.Range("A4:A4").NumberFormat = "d/mm/yy h:mm"
>>>excelapp.Columns("A:C").EntireColumn.AutoFit()

Note that the Cells() structure works like a numeric array. That means that instead of using Excel's notation of letters and numbers, you need to think of the spreadsheet as a numeric matrix.

Visual Basic

In order to implement a COM object using Python you need to implement a Python class that exposes the functionality to be exported. It is also necessary to assign two special attributes to this class, as required by the Python COM implementation.

The first attribute is the Class ID (_reg_clsid_). This attribute must contain a UUID, which can be generated by calling the pythoncom.CreateGuid() function. The other attribute is a friendly string that you will use to call the COM object (_reg_progid_), as follows:

  classCOMCalcServer:
_reg_clsid_ = '{ C76BEA61-3B39-11D4-8A7C-444553546170} '
_reg_progid_ = 'COMCALCSERVER.VERSION1'
_public_methods_ = ['mul','div','add','sub']

Other interesting attributes are
  • _public_methods—A list of all method names that you want to publicly expose to remote COM clients.
  • _public_attrs—A list of all attribute names to be exposed to remote COM clients. l_readonly_attrs—A list of all attributes that can be accessed, but not set. This list should be a subset of the list exposed by _public_attrs.

After creating the class, you need to register your COM object. The general technique is to run the module that implements the COM object as a script, in order to register the object:
if __name__ == '__main__':

  import win32com.server.register
win32com.server.register.UseCommandLine(COMCalcServer)

Notice that you need to inform the class object, and not a class instance. After the UseCommandLine() function has been successfully executed, the following message is returned by the Python interpreter:

Registered: COMCALCSERVER.VERSION1

When you have your COM object up and running, any automation-capable language, such as Python, Visual Basic, Delphi, or Perl, can use it. The following example is a complete program that implements a calculator. First, you need to collect the unique IDs for your class:

  Python 1.5.2 (#0, Apr 13 1999, 10:51:12)
  [MSC 32 bit (Intel)] on  win32
Copyright 1991-1995 StichtingMathematisch Centrum, Amsterdam
>>> import pythoncom
>>> print pythoncom.CreateGuid()
<iid:{C76BEA60-3B39-11D4-8A7C-444553546170}>

After informing the new clsidvalue to the _reg_clsid_ attribute, we have the following program:

  # File: comcalcserver.py
classCOMCalcServer:
_reg_clsid_ = '{C76BEA61-3B39-11D4-8A7C-444553546170}'
_reg_progid_ = 'COMCALCSERVER.VERSION1'
_public_methods_ = ['mul','div','add','sub']
defmul(self, arg1, arg2):
return arg1 * arg2
def div(self, arg1, arg2):
return arg1 / arg2
def add(self, arg1, arg2):
return arg1 + arg2
def sub(self, arg1, arg2):
return arg1 - arg2
if __name__ == '__main__':
import win32com.server.register
win32com.server.register.UseCommandLine(COMCalcServer)

Make sure that all methods are included in the _public_methods_. Otherwise, the program will fail. Now, go to the DOS prompt and execute the program to register the COM object:
C: python >c: progra~1 python python com calc server. py Registered: COMCALC SERVER .VERSION1 To create the Visual Basic COM client, you need to create a Visual Basic Form that contains all the implementation details.

A design for creating the Visual Basic Form.

Most of the time, the initialization steps are stored in the Form_Load section in order to be executed when the application starts:

  Dim COMCalcServer as Object
Set COMCalcServer = CreateObject ("COMCALCSERVER.VERSION1")

Remember to always deallocate the objects before exiting the application. It's good practice to do it in the Form_Unload section:

  Set COMCalcServer = Nothing
Public COMCalcServerAs Object
Private Sub Form_Unload(Cancel As Integer)
Set COMCalcServer = Nothing
End Sub
Sub InitCOMCalcServer()
Set COMCalcServer = CreateObject ("COMCALCSERVER.VERSION1")
Exit Sub
End Sub
Private Sub Command1_Click()
Dim result As Double
result = COMCalcServer.Mul(Val(Text1), Val(Text2))
MsgBox Text1 & "*" & Text2 & "=" &Str(result)
End Sub
Private Sub Command2_Click()
Dim result As Double
result = COMCalcServer.Div(Val(Text1), Val(Text2))
MsgBox Text1 & "/" & Text2 & "="&Str(result)
End Sub
Private Sub Command3_Click()
Dim result As Double
result = COMCalcServer.Add(Val(Text1), Val(Text2))
MsgBox Text1 & "+" & Text2 & "="&Str(result)
End Sub
Private Sub Command4_Click()
Dim result As Double
result = COMCalcServer.Sub(Val(Text1), Val(Text2))
MsgBox Text1 & "-" & Text2 & "="&Str(result)
End Sub
Private Sub Form_Load()
Text1 = 0
Text2 = 0
Command1.Caption = "Mul"
Command2.Caption = "Div"
Command3.Caption = "Add"
Command4.Caption = "Sub"
InitCOMCalcServer
End Sub

While executing the application (see Figure below), your Visual Basic application will be talking to the Python COM object behind the scenes.

A Visual Basic executable running.

The next example is based on the previous one. This one implements a callback function. The VB program calls a Python function that clearly manipulates the Visual Basic Form object.

You need to add or replace the following functions in the Visual Basic code:

  Sub InitCOMCalcServer()
Set COMCalcServer = CreateObject ("COMCALCSERVER.VERSION2")
Exit Sub
End Sub
Private Sub Form_Load()
Text1 = 0
Text2 = 0
Command1.Caption = "Mul"
Command2.Caption = "Div"
Command3.Caption = "Add"
Command4.Caption = "Sub"
InitCOMCalcServer
COMCalcServer.updatecaption Me
End Sub

The following new function must be created in the Python code, too. The VB function call uses the keyword Me to send a reference of the Form object to Python's updatecaption() method:

defupdatecaption(self, object):

  Form = win32com.client.Dispatch(object)
Form.Caption = "Python COM Routine is Active"

The following code is a full replacement to be used with this example. Remember to create a new _reg_clsid_ for this new example.

  # File: comcalcserver2.py
classCOMCalcServer:
_reg_clsid_ = '{ C76BEA64-3B39-11D4-8A7C-444553546170} '
_reg_progid_ = 'COMCALCSERVER.VERSION2'
_public_methods_ = ['mul','div','add','sub', 'updatecaption']
defmul(self, arg1, arg2):
return arg1 * arg2
def div(self, arg1, arg2):
return arg1 / arg2
def add(self, arg1, arg2):
return arg1 + arg2
def sub(self, arg1, arg2):
return arg1 - arg2
defupdatecaption(self, object):
import win32com.client
Form = win32com.client.Dispatch(object)
Form.Caption = "Python COM Routine is Active"
if __name__ == '__main__':
import win32com.server.register
win32com.server.register.UseCommandLine(COMCalcServer)

Python/Visual Basic callback implementation.

Every script that defines a COM class can be used to unregister the class, too. Python automatically knows that, when you pass the argument --unregister to the script, you want to remove all the references to this class from the Windows Registry.

  C:python>python comcalcserver2.py --unregister
Unregistered: COMCALCSERVER.VERSION2

Handling Numbers and Strings

Whenever you have a Python method as part of a COM server interface that returns a number or a string, as shown in the next few lines of code:
defGetNumber(self):

  return 25
defGetString(self, name):
return 'Your name is %s'% name

The COM client written in Visual Basic must handle the methods as follows

  Dim num as Variant
num = Server.GetNumber
Dim str as Variant
str = Server.GetString("Andre")
MsgBoxstr

Python and Unicode do not really work well together in the current version of Python. All strings that come from COM will actually be Unicode objects rather than string objects. In order to make the previous code work in a COM environment, the last line of the GetString() method must become return 'Your name is %s'% str(name) The conversion of the "name" to "str(name)" forces the Unicode object into a native Python string object.

In Python-2.0, if the win32com stuff starts using native Python Unicode strings, the str() call will cause the Unicode string to be reencoded in UTF8.

Handling Lists and Tuples

When you have a Python method as part of a COM server interface that returns a list or a tuple, as illustrated in the next example:
defGetList(self):

  return [1,2,3,4]

The COM client written in Visual Basic must handle the method as follows:

  Dim arry as Variant
arry = Server.GetList
Debug.PrintUBound(arry)
For Each item in arry
Debug.Print item
Next

Delphi

Using Delphi to implement a COM client is very similar to using Visual Basic. First, you need to register the COM class. The following code is similar to the one used for the Visual Basic example.

  # File: comcalcserver.py
classCOMCalcServer:
_reg_clsid_ = '{ C76BEA61-3B39-11D4-8A7C-444553546170} '
_reg_progid_ = 'COMCALCSERVER.VERSION1'
_public_methods_ = ['mul','div','add','sub']
defmul(self, arg1, arg2):
return arg1 * arg2
def div(self, arg1, arg2):
return arg1 / arg2
def add(self, arg1, arg2):
return arg1 + arg2
def sub(self, arg1, arg2):
return arg1 - arg2
if __name__ == '__main__':
import win32com.server.register
win32com.server.register.UseCommandLine(COMCalcServer)

Now, you need to create a Delphi form to support all the COM client activities.

Delphi design: A form with three Edit boxes and four buttons.

  unitCalcform;
interface
uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, OLEAuto;

  type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Button2: TButton;
Button3: TButton;
Button4: TButton;
procedureFormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
COMCalcServer: Variant;
implementation
{ $R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
try
COMCalcServer :=CreateOleObject('COMCALCSERVER.VERSION1');
Form1.Caption := 'Python COM Routine is Active';
Edit1.text := '';
Edit2.text := '';
Edit3.text := '';
Button1.Name := 'mul';
Button2.Name := 'div';
Button3.Name := 'add';
Button4.Name := 'sub';
except
MessageDlg('An error has happened!', mtError, [mbOk],0);
Application.Terminate;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var tmp1float, tmp2float : Real;
tmp3string : String;
begin
tmp1float := StrToFloat(Edit1.text);
tmp2float := StrToFloat(Edit2.text);
tmp3string := FloatToStr(COMCalcServer.mul(tmp1float, tmp2float));
Edit3.text := tmp3string;
end;
procedure TForm1.Button2Click(Sender: TObject);
var tmp1float, tmp2float : Real;
tmp3string : String;
begin
tmp1float := StrToFloat(Edit1.text);
tmp2float := StrToFloat(Edit2.text);
tmp3string := FloatToStr(COMCalcServer.div(tmp1float, tmp2float));
Edit3.text := tmp3string;
end;
procedure TForm1.Button3Click(Sender: TObject);
var tmp1float, tmp2float : Real;
tmp3string : String;
begin
tmp1float := StrToFloat(Edit1.text);
tmp2float := StrToFloat(Edit2.text);
tmp3string := FloatToStr(COMCalcServer.add(tmp1float, tmp2float));
Edit3.text := tmp3string;
end;
procedure TForm1.Button4Click(Sender: TObject);
var tmp1float, tmp2float : Real;
tmp3string : String;
begin
tmp1float := StrToFloat(Edit1.text);
tmp2float := StrToFloat(Edit2.text);
tmp3string := FloatToStr(COMCalcServer.sub(tmp1float, tmp2float));
Edit3.text := tmp3string;
end;
end.

After compiling and running the application, you should see the interface.

Delphi Calculator Application.

Distributing Objects with Python

There are some other packages that enable you to talk to other programs on platforms without COM support. As for the object distribution models, Python has many projects currently being developed.

The Inter-Language Unification system (ILU) is a free and stable multi-language object interface system.

The Object Request Broker is the mechanism that lets objects transparently make requests to—and receive from—other objects located locally or remotely. The ORB component is also commonly referred to as CORBA, which stands for Common Object Request Broker Architecture. omniORBpy is an almost complete implementation of the current Python CORBA mapping.

Fnorb is an Object Request Broker (ORB) that is compliant with the CORBA 2.0 specification from the Object Management Group (OMG). Fnorb implements a single language mapping from OMG IDL to Python. This implementation is excellent for those who want to learn CORBA. Another project worth mentioning is the ORBit-python project, which a binding for ORBit, the CORBA orb used by GNOME and some other projects.

DCOM is the COM technology that distributes objects between different machines on the network. It defines a protocol that enables software components to communicate directly over a network in a reliable, secure, and efficient manner.

The Object Management Facility (OMF) is an object-oriented middleware environment for the process automation area. Even though it doesn't contain any Python code, it is heavily tested using Python scripts. The object model used by OMF is similar to other distributed object systems, such as OMG's CORBA and Xerox's ILU. OMF is implemented in C++, with APIs for other languages, including Python. It is said that the Python API was primarily created for writing test programs, but it has since been used to write various tools for application development and runtime management.

Hector is a distributed object system developed at the University of Queensland, Australia. It is written almost entirely in Python. Hector attempts to provide application objects with a consistent environment, regardless of their physical location, through a series of transparencies.

Inter-Language Unification (ILU)

The Inter-Language Unification system (ILU) is a free and stable multi-language object interface system, whose interfaces hide implementation distinctions between different languages, address spaces, and operating system types. ILU can be used to build multilingual, object-oriented class libraries with well-specified, language-independent interfaces. It can also be used to implement distributed systems and to define and document interfaces between the modules of nondistributed programs. ILU interfaces can be specified in either the OMG's CORBA Interface Definition Language (OMG IDL) or ILU's Interface Specification Language (ISL).

ILU is primarily about interfaces between modules of program structure. Each module encapsulates the part of a program that has high adhesion internally and low connection to other parts of the program.

The main goal of ILU is to create object-oriented interfaces that can communicate with those modules.

ILU does all the translating and communicating necessary to use all kinds of modules in a single program. Its mechanism optimizes calls across module interfaces to involve only what it is necessary for the calling and called modules to interact. The notion of a module should not be confused with the independent concept of a program instance, which is translated as a combination of code and data running in one memory image, such as the UNIX processes.

ILU standardizes many of the issues involved in providing proper inter-module independence, such as memory management and error detection and recovery strategies. ILU also includes an implementation of the Object Management Group's CORBA Internet Inter-Orb Protocol (IIOP), and can be used to write CORBA services or clients, as well. ILU provides a standard notation to write its interfaces—ISL, which stands for Interface Specification Language. ISL is a declarative language, which can be processed by computer programs that enables you to define exceptions, constants, object and non-object types. Next, you have a sample of what ISL looks like:

  INTERFACE CalcMachine;
EXCEPTION DivideByZero;
TYPE Calculator = OBJECT
METHODS
SetValue (v : REAL),
GetValue () : REAL,
Divide (v : REAL) RAISES DivideByZero END
END;

ILU provides a program, islscan, which can be used to check the syntax of an ISL specification, parse the specification, and summarize it to standard output. After you've defined an interface, you then need to supply an implementation of your module, which can be done in any language supported by ILU.

The program python-stubberis used to read an ISL file, and generate all the Python code that is required to support the ISL interface. One of the files generated is 'Interface.py', which contains the definitions of all the Python types for that interface:

  % python-stubberCalcMachine.isl
client stubs for interface "CalcMachine" to CalcMachine.py …
server stubs for interface " CalcMachine " to CalcMachine__skel.py …
%

To provide an implementation of your interface, subclass the generated Python class for the Calculator class:

  # CalculatorImpl.py
importCalcMachine, CalcMachine__skel
class Calculator (CalcMachine__skel.Calculator):
def __init__ (self):
self.value = 0.0
defSetValue (self, value):
self.value = value
defGetValue (self):
returnself.value
def Divide (self, value):
try:
self.value = self.value / value
exceptZeroDivisionError:
raiseCalcMachine.DivideByZero

Each instance of a CalculatorImpl.Calculatorobject inherits from Calc Machine __skel. Calculator, which in turn inherits from Calc Machine. Calculator. Each has an instance variable called value, which maintains a running total of the accumulator for that instance. We can create an instance of a

  CalcMachine.Calculatorobject by simply calling 
  CalculatorImpl.Calculator().

A very simple program to demonstrate the use of the CalcMachinemodule is listed next. To run this program, you have to type the command python divide.py < NUMBER _TO _DIVIDE >.

  # File: divide.py
importCalcMachine, CalculatorImpl, sys, string
def main (argv):
calc = CalculatorImpl.Calculator()
if not calc:
error("Error creating the calculator")
calc.SetValue (10.0)
divisor = string.atof(argv[1])
calc.Divide(divisor)
print "the division result is", calc.GetValue()
sys.exit(0)
main(sys.argv)
This program would be compiled and run as follows:
% python divide.py 5.0
the division result is 2.0
%

ILU also supports the use of the interface definition language OMG IDL, defined by the Object Management Group (OMG) for its Common Object Request Broker Architecture (CORBA). That kind of support allows more programmers to easily use ILU because OMG's IDL uses a syntax similar to C++. However, because CORBA doesn't implement some of the concepts found in ILU, programmers can't implement all types of ILU interface using OMG IDL.

CORBA Binding and Implementation

The Object Request Broker (ORB) is the mechanism that lets objects transparently make requests to—and receive from—other objects located locally or remotely. The ORB is the middleware that establishes the client/server relationship between objects.

Using an ORB, a client object can transparently invoke a method on a server object, which can be on the same machine or across a network. The ORB intercepts the call and is responsible for finding an object that can implement the request, pass it the parameters, invoke its method, and return the results.

The client does not have to be aware of where the object is located, its programming language, its operating system, or any other system aspects that are not part of an object's interface. The client is not aware of the mechanisms used to communicate with, activate, or store the server objects. The ORB serves as the foundation for building distributed object applications. Note that CORBA can short circuit requests to objects in the same address space, as ILU and COM can, if the implementation supports this.

The ORB component, or CORBA, is a set of specifications defining the ways software objects should work together in a distributed environment. The organization that drives the specifications, the Object Management Group (OMG), has hundreds of members representing a major portion of the software industry. The members work together to propose, review, and finally adopt a set of specifications to enable software objects to be developed independently and yet work together in a harmonic fashion.

The fundamental piece of CORBA is the ORB, or Object Request Broker. The ORB can be viewed like a channel carrying objects between the clients (those that consume the objects) and the servers (those that produce the objects). The consumers are provided with object interfaces, which are defined using a language called the Interface Definition Language. The detailed implementation of the objects by the producers is totally shielded from the consumers. The ORB is usually just a library that the program links to that marshals object requests. The promised benefits of making the software objects from different vendors publicly known made those vendors highly endorse OMG's specifications.

At the most basic level, CORBA is a standard for distributed objects. CORBA enables an application to request that an operation be performed by a distributed object and that the results of the operation be returned to the application making the request. The application communicates with the distributed object performing the operation. This is basic client/server functionality, in which a client issues a request to a server, and the server responds to the client. Data can pass from the client to the server and is associated with a particular operation on a particular object. Data is then returned to the client in the form of a response. Note that just like COM/DCOM, CORBA can be used to access objects that are local to the process, machine, or non-local.

DCOM is a Microsoft-specific distribution solution, whereas CORBA products are available from more than 20 different vendors, and they support Microsoft and non-Microsoft operating systems. CORBA is an excellent mechanism to bridge between Microsoft desktops and UNIX servers.

There is no explicit need to choose between DCOM and CORBA. Distributed applications can be developed using both CORBA and DCOM. For example, a client application might be developed to access a set of OLE automation objects, and OLE automation objects might in turn access CORBA Objects running on a non-Microsoft platform such a UNIX. The OMG has defined a COM/CORBA interworking specification that standardizes this sort of bridging.

CORBA is more mature than DCOM; it has existed since 1990, and commercial implementations have been available since 1992. DCOM wasn't available in beta form until 1996. Also, a large number of different companies have developed CORBA ORBs. This level of competition increases the robustness of CORBA solutions on the whole. It also ensures compatibility—a vendor's CORBA ORB is of much greater value if it can talk to a competitor's ORBs.

One of the advantages of DCOM over CORBA is the fact that DCOM is well suited to front-end application development. If entire distributed application runs under Microsoft platforms, DCOM might be a good choice. DCOM can also be used with CORBA. Of course, using DCOM will lock you into Win32 in the future, which might not be a good thing even if you are using Win32 at the moment.

The CORBA distributed object system is becoming an important standard in developing industrial strength client/server and Web applications. It is also used as an IPC layer between a number of components in both the Gnome and KDE desktop environments for UNIX.

In the current development phase of the CORBA binding for Python, the OMG board of directors has adopted the specification, and the finalization task force has completed its report. After approval, this report will become an available specification. omniORBpyis an almost complete implementation of the current Python/CORBA mapping. It is currently in beta, but is very stable.

This parser uses Aaron Watters' kwParsingparser-generator package to construct a CORBA IDL parser in Python. Object Management Group Common Object Request Broker Architecture 2.0

Fnorb

Fnorb is written in Python and its framework supports only Python. The implementation provided by this object-model helps you to learn more about CORBA systems.

Fnorb is an object request broker (ORB) compliant with the CORBA 2.0 specification from the Object Management Group (OMG). Fnorb implements a single language mapping from OMG IDL to Python.

Because of the interpreted and interactive nature of Python, and the simplicity of the mapping (as compared to mappings with C++ and Java), Fnorb is ideally suited as a tool for the rapid prototyping, testing, and scripting of CORBA systems and architectures.

The pair Python/Fnorb is ideal for prototyping complex CORBA architectures, for using as a scripting tool, and for building test harnesses for all your CORBA development projects.

The combination of Python and Fnorb provides the existing CORBA community with a much needed tool for rapid prototyping and scripting, and gives those new to CORBA a great way to learn the fundamental concepts without being swamped by the intricacies of a "heavyweight" language mapping.

Like ILU from Xerox PARC, Fnorb gives the Python programmer access to the wonderful world of CORBA. It supports all CORBA 2.0 data types (including Any's) and provides a full implementation of IIOP. Unlike ILU, Fnorb is Python and CORBA/IDL-specific, which makes it simple, lightweight, and easy to install and use.

Using Fnorb, you no longer have to use other languages to write CORBA clients and servers—you can use Python now. This makes Fnorb ideal for prototyping complex CORBA architectures, for use as a scripting tool, and for building test harnesses for all your CORBA development projects.

The Python language mapping used by Fnorb is based on a specification document being prepared by members of the DO-SIG (Distributed Objects - Special Interest Group). One goal of Fnorb is to enable the Python community to experiment with the mapping before attempting to set it in stone via the OMG standardization process.

Fnorb is being developed at the CRC for Distributed Systems Technology based at the University of Queensland in Brisbane, Australia.Fnorb is released under a free for non-commercial use license. Another license must be acquired to use it commercially.

DCOM

DCOM is Microsoft's way of distributing objects between different machines on the network. DCOM, or Distributed Common Object Model, defines the specifications that an object must obey to interoperate with other objects using Microsoft distributing architecture.

The core of DCOM is the Common Object Model, defined and refined from the earlier Object Link and Embedding implementation. Started naively as a way to enable documents to be embedded or linked into another document, OLE has completely reinvented itself.

The Common Object Model (COM) lays the foundation for objects to gain knowledge about, and to make use of, each other; thus they can engage in so-called component-based computing. DCOM extends the capability to include the constituent objects on other machines connected through the network.

The Distributed Common Object Model (DCOM) is a protocol that enables software components to communicate directly over a network in a reliable, secure, and efficient manner. Previously called Network OLE, DCOM is designed for use across multiple network transports, including Internet protocols such as HTTP. DCOM is based on the Open Software Foundation's DCE-RPC spec and will work with both Java applets and ActiveX components through its use of the (COM).

DCOM enables objects to be remote from their caller, and it handles all marshalling across machines and necessary security. Configuration tools enable an administrator to configure objects so that neither the object nor the caller needs any changes.

OMF

Object Management Facility (OMF) is an object-oriented middleware environment for the process automation area. It is used as the middleware foundation for several ABB [the ABB Industrial Systems AB (Sweden)] control system applications. Although it doesn't contain any Python code, it is heavily tested using Python scripts.

OMF includes the all-important features of an object request broker. A type definition language defines the interface and provides mappings to multiple programming languages. Objects can be distributed transparently on heterogeneous platforms. Furthermore, services for naming, type management, messaging, and persistence are available. OMF contains features particularly for real-time distributed control, such as high-speed communication, asynchronous messaging, message prioritization, and support for different bus protocols.

OMF is a distributed object system specifically designed for the process control industry. The object model is similar to other distributed object systems, such as OMG's CORBA and Xerox's ILU. What makes OMF different from these is its interaction model. The OMF interaction model specifies that, after finding a set of objects, OMF has to select what methods to call (for each object) and what attributes to get or set. It also has to choose when to perform the operation (at request, at event, periodically). After all this is done, OMF sends a single request for all objects.

OMF is implemented in C++, with APIs for other languages, including Python. Created for writing test programs, Python API has since then been used to write various tools (testing tools, development tools, and maintenance tools) to aid in application development and runtime management.

The OMF API for Python is implemented in two layers: The lower layer is written using a slightly modified version of Jack Jensen's modulator tool, whereas the higher layer is completely written in Python. On top of this API there are a few utility classes, such as the OMF agent, in which the agent lets the user treat OMF objects as local Python objects with attributes and methods, as follows:
fromOMFagent import Agent

  # Connect to an object in the network
ai = Agent('AI1.1')
# Get the Analog Input's value
# This will actually result in an RPC
value = ai.VALUE

The Agent code is surprisingly small, but results in a drastically higher abstraction layer than the bare OMF API. This is a rather simple class because of Python's dynamic typing.

OMF

Object Management Facility (OMF) is an object-oriented middleware environment for the process automation area. It is used as the middleware foundation for several ABB [the ABB Industrial Systems AB (Sweden)] control system applications. Although it doesn't contain any Python code, it is heavily tested using Python scripts.

OMF includes the all-important features of an object request broker. A type definition language defines the interface and provides mappings to multiple programming languages. Objects can be distributed transparently on heterogeneous platforms. Furthermore, services for naming, type management, messaging, and persistence are available. OMF contains features particularly for real-time distributed control, such as high-speed communication, asynchronous messaging, message prioritization, and support for different bus protocols.

OMF is a distributed object system specifically designed for the process control industry. The object model is similar to other distributed object systems, such as OMG's CORBA and Xerox's ILU. What makes OMF different from these is its interaction model. The OMF interaction model specifies that, after finding a set of objects, OMF has to select what methods to call (for each object) and what attributes to get or set. It also has to choose when to perform the operation (at request, at event, periodically). After all this is done, OMF sends a single request for all objects.

OMF is implemented in C++, with APIs for other languages, including Python. Created for writing test programs, Python API has since then been used to write various tools (testing tools, development tools, and maintenance tools) to aid in application development and runtime management.

The OMF API for Python is implemented in two layers: The lower layer is written using a slightly modified version of Jack Jensen's modulator tool, whereas the higher layer is completely written in Python. On top of this API there are a few utility classes, such as the OMF agent, in which the agent lets the user treat OMF objects as local Python objects with attributes and methods, as follows:

fromOMFagent import Agent

  # Connect to an object in the network
ai = Agent('AI1.1')
# Get the Analog Input's value
# This will actually result in an RPC
value = ai.VALUE

The Agent code is surprisingly small, but results in a drastically higher abstraction layer than the bare OMF API. This is a rather simple class because of Python's dynamic typing.

Searches relevant to you
Top