Working with Sharepoint

This is an abbreviated version of a blog entry by Jon Udell.

Every SharePoint list offers an “export to Spreadsheet” link which produces an XML dump. Given that export URL, here’s a recipe for reading the data (from a Windows client that’s already authenticated to the server) and converting it to a list of Python dictionaries.

import clr clr.AddReferenceByPartialName('System.Xml') import System.Xml from System.Xml import * from System.Net import WebRequest from System.IO import StreamReader

def getDataAsListOfXmlNodes(URL): request = WebRequest.Create(URL) request.Method = "GET" request.UseDefaultCredentials = True response = request.GetResponse result = StreamReader(response.GetResponseStream).ReadToEnd doc = XmlDocument doc.LoadXml(result) nsmgr = XmlNamespaceManager(doc.NameTable) nsmgr.AddNamespace( 'z', '#RowsetSchema') nodes = doc.SelectNodes ("//z:row", nsmgr ) return nodes

def convertNodesToDicts(nodes): listOfDicts = [] for node in nodes: attrs = node.Attributes dict = {} for a in attrs: dict[a.Name] = a.Value listOfDicts.append(dict) return listOfDicts

nodes = getDataAsListOfXmlNodes('http://host/sites/mysite/_vti_bin/...') dicts = convertNodesToDicts(nodes)

To upload the merged data to the server, I used the IronPython “Dynamic Web Services Helpers” from the Web Services sample. These wrappers make it trivial to consume a WSDL-based web service.

Here, for example, is a snippet that uploads a photo using the Imaging web service:

import System, clr clr.AddReference("DynamicWebServiceHelpers.dll") from DynamicWebServiceHelpers import *

filename = 'jon.jpg' ws = WebService.Load('http://HOST/_vti_bin/Imaging.asmx') ws.UseDefaultCredentials = True bytes = open(filename,'rb').read bytes = map (ord, list(bytes)) bytes = System.Array.CreateArray(System.Byte,bytes) ws.Upload('Photos','',bytes,filename,True)

A generic service to upload any file to any document library was much harder. In the end I used a plain old HTTP PUT:

def upload(HOST,fname,rdir,rfile): wc = WebClient wc.UseDefaultCredentials = True bytes = open(fname,'rb').read bytes = map(ord,list(bytes)) bytes = System.Array.CreateArray(System.Byte,bytes) url = '%s/%s/%s' % (HOST, rdir, rfile) wc.UploadData(url,'PUT',bytes)

And presto. A local file called, say, myfile.html, lands someplace like http://host/sites/mysite/MyLibrary/myfile.html.

Back to Contents.