------------------------------------------------------------------------------------- """ Con-way XML Interface Sample Code for Python - Bill of Lading 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 ----------------- Send questions to our Web Customer Support at web.support@Con-way.com """ import string, httplib, urllib, base64, sys, pprint from elementtree.ElementTree import ElementTree from datetime import date 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 username 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): """Make a rate quote 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-BOL' def __init__(self): # initialize base class HTTPRequest.__init__(self,self.HOST,self.PATH,self.USERNAME,self.PASSWORD) 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 now = date.today() formattedDate = now.strftime("%m/%d/%y") res = [] # Add the XML stream here res.append('<BOLrequest testmode="Y">') res.append('<RequesterUserId shipcode="S">' + self.USERNAME + '</RequesterUserId>') res.append('<ChargeCode>P</ChargeCode>') res.append('<PRONmbr></PRONmbr>') res.append('<CustRefNmbrs>') res.append(' <PurchaseOrderNmbr>3338889</PurchaseOrderNmbr>') res.append(' <PurchaseOrderNmbr>3338890</PurchaseOrderNmbr>') res.append(' <OtherRefNmbr refcode="SKU" refdesc="SKU Number">3213A</OtherRefNmbr>') res.append(' <OtherRefNmbr refcode="UPC" refdesc="UPC number">789283</OtherRefNmbr>') res.append('</CustRefNmbrs>') res.append('<Shipper>') res.append(' <ShipperName>Alan Shipley</ShipperName>') res.append(' <ShipperAddr>1234 NE Main</ShipperAddr>') res.append(' <ShipperCity>Portland</ShipperCity>') res.append(' <ShipperState>OR</ShipperState>') res.append(' <ShipperZip country="US">97202</ShipperZip>') res.append(' <ShipperPhone extension="6055">503.450.6055</ShipperPhone>') res.append(' <ShipperEmail>web.support@Con-way.com</ShipperEmail>') res.append('</Shipper>') res.append('<Consignee>') res.append(' <ConsigneeCustNmbr>883885</ConsigneeCustNmbr>') res.append(' <ConsigneePhone extension="6666">503.450.6436</ConsigneePhone>') res.append(' <ConsigneeEmail>web.support@Con-way.com</ConsigneeEmail>') res.append('</Consignee>') res.append('<Item>') res.append(' <Quantity pkgtype="PCS">11</Quantity> ') res.append(' <Weight unit="lbs">789</Weight>') res.append(' <Description>widget-arms</Description>') res.append(' <CmdtyClass>775</CmdtyClass>') res.append(' <NMFClass></NMFClass>') res.append(' <HazMat>N</HazMat>') res.append('</Item>') res.append('<Accessorial chargecode=\"C\">DID</Accessorial>') res.append('<ShippingRemarks>TEST TEST TEST</ShippingRemarks>') res.append('<EmergencyContact></EmergencyContact>') res.append('<PickupRequest>') res.append(' <PickupDate>' + formattedDate + '</PickupDate>') res.append(' <PickupReadyTime>4:00 pm</PickupReadyTime>') res.append(' <DockCloseTime>7:00 pm</DockCloseTime>') res.append(' <ContactName>Frank</ContactName>') res.append(' <ContactCompany>Franklin Arms</ContactCompany>') res.append(' <ContactPhone>(333)444-4321</ContactPhone>') res.append('</PickupRequest>') res.append('<SendBOLemail/>') res.append('</BOLrequest>') return self.encodeParams({'BOLrequest':"\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__": t = ConwayXml() res = t.getIt() pprint.pprint(res.valueOf()) -------------------------------------------------------------------------------------