-------------------------------------------------------------------------------------
"""
Con-way XML Interface Sample Code for Python - Shipment Status Tracking
Requires:
ElementTree 1.X - http://effbot.org/downloads
expat (get PyXML from http://pyxml.sourceforge.net)
-----------------
TODO:
* replace the USERNAME and PASSWORD String values in the ConwayXml class
with your Con-way username and password
* If you are not passing in the PRO Number, enter the string value
-----------------
Send questions to Andrew vonderLuft at vonderluft.andrew@Con-way.com
"""
import string, httplib, urllib, base64, sys, pprint
from elementtree.ElementTree import ElementTree
class HTTPRequest:
"""Helper class that abstracts HTTP request process"""
def __init__(self,host,path,username,password):
self.host = host
self.path = path
self.username = username
self.password = password
def getBasicAuth(self):
"""Return basic authentication userid password"""
s = self.username +':' + self.password
z = base64.encodestring(s)[:-1] # strip trailing \12
return 'Basic '+z
def encodeParams(self,d={}):
"""Given a dict of key values, return encoded params"""
return urllib.urlencode(d)
def getPostBody(self):
"""return the body of the post, implement in subclass"""
raise NotImplementedError
def Process(self):
"""Submit the HTTP POST XML request"""
body = self.getPostBody()
h = httplib.HTTP(self.host)
h.putrequest('POST',self.path)
h.putheader("Content-type","application/x-www-form-urlencoded")
h.putheader('Content-length',"%d" % len(body))
h.putheader('Authorization',self.getBasicAuth())
h.putheader('Accept','*/*')
h.putheader('Host',self.host)
h.endheaders()
h.send(body)
reply, msg, hdrs = h.getreply()
if reply != 200:
raise RuntimeError('HTTP request error',(reply,msg,hdrs))
return self.DecodeResponseFile(h.getfile())
def DecodeResponse(self,f):
"""Decode response data from file object f"""
raise NotImplementedError
class I:
"""A helper class containing various attributes"""
def __init__(self,**kw):
self.__dict__.update(kw)
def valueOf(self):
"""make printing prettier"""
prettyDict = {}
for k,v in self.__dict__.items():
if isinstance(v,I):
v = v.valueOf()
prettyDict[k] = v
return prettyDict
def __str__(self):
import pprint
return pprint.pformat(self.valueOf())
class ConwayXml(HTTPRequest):
"""Submit the XML request and return its detailed information"""
# replace the USERNAME and PASSWORD String values with your Con-way username and password:
USERNAME='USERNAME'
PASSWORD='PASSWORD'
HOST='www.Con-way.com'
PATH='/XMLj/X-ShipmentStatus'
def __init__(self,arg):
# initialize base class
HTTPRequest.__init__(self,self.HOST,self.PATH,self.USERNAME,self.PASSWORD)
self.myarg = arg
def getIt(self):
"""Process the request"""
return self.Process()
def getPostBody(self):
# return the body of the post
# construct the request XML, send URL-Form-encoded instead of plain XML
res = []
# Build the XML input stream here
res.append('')
res.append('%s' % self.myarg)
res.append('')
return self.encodeParams({'ShipmentStatusRequest':"\n".join(res)})
def DecodeResponseFile(self,f):
"""Decode response data from file object f"""
tree = ElementTree(file=f) # decode xml return in file object 'f'
##tree.write(sys.stdout) # dump it to stdout for diagnostics
root = tree.getroot()
error = root.find('Error')
if error is not None:
raise RuntimeError((error.text,error.get('returncode'),error.get('responsecode')))
result = I()
# we iterate over the top level children to populate the result object
# we'll descend at most one level to get subelements of top level children
# Tracking results aren't nested more than this
for child in root.getchildren():
children = child.getchildren()
if children: # has children
placeholder = I()
for item in children:
setattr(placeholder,item.tag,item.text)
else:
placeholder = child.text
setattr(result,child.tag,placeholder)
return result
if __name__ == "__main__":
# You can hardcode your input String argument here
# in this case, a PRO Number
arg = "PRONUMBER"
# or pass it in as the argument
if len(sys.argv) > 1:
arg = sys.argv[1]
t = ConwayXml(arg)
res = t.getIt()
pprint.pprint(res.valueOf())
-------------------------------------------------------------------------------------