Using Python and XML with Microsoft .NET My Servicesby Christopher A. Jones, coauthor of Python & XML
Microsoft piqued developer interest when it announced a new project code-named “HailStorm” in the spring of 2000. The idea of a distributed, XML-based data store that would allow your information to follow you from device to device, and from Web site to Web site, sounded attractive. The idea of Microsoft securing this data on your behalf, however, raised a few concerns. Well, Microsoft has been busily working on .NET My Services (the new name for HailStorm), and they recently released a beta version of the services at this year’s Professional Developer’s Conference.
What many developers realized after viewing the beta code, presentations, and samples is that Microsoft has indeed been focusing on the nature of these XML-based Web services and their utility, and they've created a series of services with an infrastructure fabric underlying them. In this article, you’ll learn a bit about .NET My Services, specifically the .NET Contacts service, and how you can program for it using Python and XML.
Microsoft’s .NET My Services is focused squarely at end users. The services allow you to manage all sorts of things, ranging from documents and email to address book entries and your calendar. One simple goal is to allow you to view this information conveniently from any device or platform without worry of synchronization. With an online device talking to .NET My Services, the days of waiting to cradle your PDA to get your latest email would be over.
Perhaps a more interesting goal is the ability to allow others to access specific parts of your data. For example, while making an airline reservation online, you could allow the airline to update your calendar with the flight information. If that information changed due to a weather delay while you were in a taxi to the airport, your calendar could be automatically updated from the airline’s scheduling system without you lifting a finger or making a harried cell phone call. Business associates or friends could be automatically alerted to the change of plans, instead of sitting around waiting for you to arrive at baggage claim. The scope of the services that Microsoft is developing is robust and forward-looking, and it includes support for such things as specifying the particular device you would like to receive an email or alert on at a particular time, or even tying your geo-location information into your .NET Location service.
In this article, we’ll create a request for the simple .NET Contacts service. This service, in the simplest case, is a list of all your contacts, their phone numbers, email addresses, and any other information you would like to provide. This list is analogous to your address book in your desktop email program, PDA, or cell phone. In fact, the goal of the .NET Contacts service is to centralize your contacts list so that you can easily retrieve your contacts from your phone, PDA, or desktop email (or even a trusted Web site) without having to worry about synchronization or duplication.
But perhaps the best thing about .NET My Services is you can create this request using Python and XML on Linux.
XML Tools for Python
The number of tools available for working with Python and XML is growing all the time. Python’s popularity is steadily increasing, and developers are discovering its utility in working with XML. For the purposes of this article, I’ve chosen to work with Python 2.1 and the PyXML package. The PyXML package is the most comprehensive suite of XML tools for Python, and it's maintained on SourceForge.
The PyXML package gives you a wide variety of tools for working with Python, including the Document Object Model (DOM) interface that allows for the parsing and creation of XML documents programmatically. While SOAP support is still emerging for Python, SOAP is simply XML over HTTP and can be performed using many different tools. For this article, I relied on Python’s httplib to send and receive XML packets accordingly. If you are a SOAP die-hard, it's easy enough to use one of the emerging packages or one of Python’s many bridges into COM, Java, or C/C++, and utilize a package intended for another language.
Creating a .NET My Services Client
To create a client of .NET My Services with Python, you need to start with an operation or query in mind--after all, it’s a data store. Microsoft’s .NET My Services is a series of distributed services accessed via SOAP and XML. The data within .NET My Services is maintained as XML and the goal is to make this data readily available to any device or platform, mobile or otherwise. The focus of the data within .NET My Services, as noted earlier, is personal information, calendar and time management data, lists, contacts, and communications information, as well as information about the particular device you would like to receive information on at any particular time.
The client in this article was written in Python on Linux and communicated with an instance of .NET My Services beta software. The code featured in this article should also work with O’Reilly’s forthcoming .NET My Services book. Microsoft is planning significant security enhancements to .NET My Services, and the code here will likely need to be tweaked in future releases when .NET My Services begins to rely on .NET Passport for authentication.
The steps you’ll need to complete the request are straightforward:
- Build a SOAP packet with the appropriate .NET My Services query.
- Send the SOAP packet to .NET My Services.
- Retrieve the returned SOAP packet.
A .NET My Services SOAP Packet
As mentioned earlier, instead of using a SOAP tool to create and send the SOAP XML to .NET My Services, I chose to use the DOM to create the XML, and httplib for transport. The main reason is that the focus of this article is on using Python’s XML tools, and not necessarily a SOAP API.
Microsoft's .NET My Services uses XPath to target particular portions of the XML service document; various queries and inserts you perform against the services will always carry an XPath expression targeting a particular piece of the XML for focus.
The most interesting things about the SOAP packet created here are the payload and the headers. The headers contain a wealth of information (and will only contain more as .NET My Services evolves), while the payload contains a carefully constructed .NET My Services query. Microsoft's .NET My Services uses XPath to target particular portions of the XML service document; various queries and inserts you perform against the services will always carry an XPath expression targeting a particular piece of the XML for focus. In this article, we will simply extract all of the contacts within your .NET Contacts service, so the XPath is simple:
The ‘mc:’ is the prefix for the qName (qualified name, i.e., a namespace). The ‘contact’ is the actual contact element for each of the contacts within the service document. The ‘//’ implies that you wish to extract all occurrences of this particular element.
The XPath is wrapped within an xpQuery element, which in turn is placed within a queryRequest element:
<queryRequest xmlns='http://schemas.microsoft.com/hs/2001/10/core' xmlns:mc='http://schemas.microsoft.com/hs/2001/10/myContacts'> <xpQuery select='//mc:contact'/> </queryRequest>
In addition to queryRequest, .NET My Services has five basic commands represented as XML elements, including query (shown here), insert, replace, update, and delete.
Namespaces are used extensively within .NET My Services. Each service has an associated namespace, and the XML elements that make up the different services are sometimes reused in other services. Thus, it’s entirely possible that you use givenName and surname elements within the .NET Profile namespace within contact entries in the .NET Contacts namespace.
For a complete list of O'Reilly's .NET books, visit dotnet.oreilly.com.
The remainder of the SOAP request is standard SOAP fare, with the exception of the header. The SOAP header element is used by .NET My Services and contains routing information, user identity information, as well as application identity information. The entire SOAP packet generated by Python is shown below:
<?xml version='1.0' encoding='UTF-8'?> <Envelope xmlns='http://schemas.xmlsoap.org/soap/envelope/'> <Header> <path xmlns='http://schemas.xmlsoap.org/rp/'> <action> http://schemas.microsoft.com/hs/2001/10/core#request </action> <rev> <via/> </rev> <to>http://skweetis</to> <id>C6B9D29A-D4A9-11D5-AD8F-00B0D0E9071D</id> </path> <licenses xmlns='http://schemas.xmlsoap.org/soap/security/2000-12'> <identity xmlns='http://schemas.microsoft.com/hs/2001/10/core' mustUnderstand='1'> <kerberos>3066</kerberos> </identity> </licenses> <request xmlns='http://schemas.microsoft.com/hs/2001/10/core' document='content' service='myContacts' method='query' genResponse='always' mustUnderstand='1'> <key puid='3066' cluster='1' instance='1'/> </request> </Header> <Body> <queryRequest xmlns='http://schemas.microsoft.com/hs/2001/10/core' xmlns:mc='http://schemas.microsoft.com/hs/2001/10/myContacts'> <xpQuery select='//mc:contact'/> </queryRequest> </Body> </Envelope>
Pages: 1, 2