December 2009
November 2009
October 2009
September 2009
June 2009
April 2009
March 2009
February 2009
January 2009
December 2008
November 2008
October 2008
July 2008
June 2008
October 2007
September 2007
I am releasing my package for accessing Authorize.net's CIM API under the LGPL license.
It requires lxml to function.
You can download pyauthdotnet here or you can clone the repository with this command, assuming you have mercurial installed:
hg clone http://code.tylerlesmann.com/pyauthdotnet
You will install it like many other packages:
python setup.py install
This package is not well documented as of yet, though it is written to coincide with Authorize.net's documentation. Here is a quick example of its use:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | #!/usr/bin/env python from pyauthdotnet import cim from copy import deepcopy from lxml import etree login = 'Your_API_login' key = 'Your_API_key' def printxml(xml): print(etree.tostring(xml, pretty_print=True, encoding='UTF-8', xml_declaration=True)) billTo = cim.constructAddress('billTo', firstName='John', lastName='Doe', company='Superhappy testing', address='123 Fake Street', city='Aurora', state='CO', zip='80014', country='USA', phoneNumber='(303)555-5555', faxNumber='(303)666-6666') printxml(billTo) ba = cim.constructBankAccount('011000015', '123123123', 'John Doe', 'checking', 'CCD', 'Some Bank') printxml(ba) cc = cim.constructCreditCard('4007000000027', '2010-03', '123') printxml(cc) pp1 = cim.constructPaymentProfiles(customerType='individual', billTo=deepcopy(billTo), bankAccount=ba) printxml(pp1) pp2 = cim.constructPaymentProfiles(customerType='business', billTo=deepcopy(billTo), creditCard=cc) printxml(pp2) stl = deepcopy(billTo) stl.tag = 'shipToList' stl2 = deepcopy(stl) newprof = cim.createCustomerProfileRequest(login, key, merchantCustomerId='1235', description='test1235', email='not2@valid.email', paymentProfiles=[pp2], shipToList=[stl, stl2], validationMode='liveMode') printxml(newprof) custid = newprof.customerProfileId prof = cim.getCustomerProfileRequest(login, key, custid) printxml(prof) ppid = prof.profile.paymentProfiles.customerPaymentProfileId.text said = prof.profile.shipToList.customerAddressId.text tax = cim.constructAmount('tax', amount='1.00', name='tax', description='mininature american flags tax') shipping = cim.constructAmount('shipping', amount='3.00', name='Fedex Express Saver') duty = cim.constructAmount('duty', amount='5.00') li1 = cim.constructLineItem('123F12', name='widget', description='Used with whatsits', quantity='5', unitPrice='5.00', taxable='true') li2 = cim.constructLineItem('123F13', name='whatsit', description='Used with widgets', quantity='5', unitPrice='5.00', taxable='false') trans = cim.createCustomerProfileTransactionRequest(login, key, '59.00', custid, ppid, refId='123', tax=tax, shipping=shipping, duty=duty, lineItems=[li1, li2], customerShippingAddressId=said, invoiceNumber='20090211', description='widget/whatsit purchase', purchaseOrderNumber='20090211123', taxExempt='false', recurringBilling='false', cardCode='123', extraOptions='x_customer_ip=100.0.0.1') printxml(trans) cc2 = cim.constructCreditCard('XXXX0002', '2013-12', '789') pp3 = cim.constructPaymentProfile( customerType='individual', billTo=deepcopy(billTo), creditCard=cc2, customerPaymentProfileId=ppid) ppr = cim.updateCustomerPaymentProfileRequest(login, key, custid, pp3, refId='123', validationMode='liveMode') printxml(ppr) address = cim.constructAddress('address', firstName='John', lastName='Doe', company='Superhappy testing', address='123 Fake Street', city='Aurora', state='CO', zip='80014', country='USA', phoneNumber='(303)555-5555', faxNumber='(303)666-6666', customerAddressId=said) csa = cim.updateCustomerShippingAddressRequest(login, key, custid, address, refId='6') printxml(csa) profids = cim.getCustomerProfileIdsRequest(login, key) printxml(profids) valid = cim.validateCustomerPaymentProfileRequest(login, key, custid, ppid, customerShippingAddressId=said, cardCode='123', validationMode='liveMode') printxml(valid) up = cim.updateCustomerProfileRequest(login, key, custid, merchantCustomerId='whoa', description='man', email='no@no.no') printxml(up) |
If you do not know about ZoomInfo yet, it is a business intelligence search service. With it, you can find information about companies and people working in them. The great thing about ZoomInfo is they offer an API for accessing their service. I have written up a little convenience module for this API. The only requirement is lxml.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | import urllib2 from lxml import objectify from urllib import urlencode apiurl = 'http://api.zoominfo.com/PartnerAPI/XmlOutput.aspx?' class ZoomInfoException(Exception): pass def zoom_query(qtype, key, **kwargs): args = { 'query_type': qtype, 'pc': key, } args.update(kwargs) resp = urllib2.urlopen(''.join([apiurl, urlencode(args)])) resptree = objectify.parse(resp).getroot() if hasattr(resptree, 'ErrorMessage'): raise ZoomInfoException, resptree.ErrorMessage return resptree def company_competitors(key, **kwargs): return zoom_query('company_competitors', key, **kwargs) def company_detail(key, **kwargs): return zoom_query('company_detail', key, **kwargs) def company_search_query(key, **kwargs): return zoom_query('company_search_query', key, **kwargs) def people_search_query(key, **kwargs): return zoom_query('people_search_query', key, **kwargs) |
This module is only 32 lines, but provides full functionality to the current ZoomInfo API. It is lacking in documentation, but it follows the API documentation to the letter. Here's some example of its use.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #!/usr/bin/env python from lxml import etree from time import sleep import zoominfo key = 'Your_API_key_here' xml = zoominfo.company_search_query(key, companyName="red hat") for rec in xml.CompanySearchResults.CompanyRecord: print rec.CompanyID, rec.CompanyName, rec.Website sleep(2) xml = zoominfo.company_detail(key, CompanyDomain='www.redhat.com') for person in xml.KeyPerson: print person.JobTitle, '-', person.FirstName, person.LastName redhatid = xml.CompanyID sleep(2) try: xml = zoominfo.company_competitors(key, CompanyID=redhatid) except zoominfo.ZoomInfoException, e: print 'Caught Error from ZoomInfo:', e print 'You need to upgrade your ZoomInfo to use this function' sleep(2) xml = zoominfo.people_search_query(key, firstName='Paul', lastName='Cormier') rec = xml.PeopleSearchResults.PersonRecord[0] print rec.CurrentEmployment.JobTitle, '@', rec.CurrentEmployment.Company.CompanyName |
If you use this module, you are still subject to ZoomInfo's use restrictions and branding requirements. This is why my example includes a few time.sleeps in between queries.
If you have any suggestions, please leave a comment.
I have been using lxml to generate XML to interface with Authorize.net's CIM API and I noticed something. Element does not behave as expected, which is supposed to be as a list. The key difference is with references to the same Element.
1 2 3 4 5 6 7 8 | #!/usr/bin/env python from lxml import etree root = etree.Element('root') child = etree.Element('child') root.append(child) root.append(child) print etree.tostring(root, pretty_print=True) |
If you run this, you will get the following output:
<root> <child/> </root>
One child when we are expecting two. This is a bug. The workaround is to use deepcopy.
1 2 3 4 5 6 7 8 9 | #!/usr/bin/env python from copy import deepcopy from lxml import etree root = etree.Element('root') child = etree.Element('child') root.append(child) root.append(deepcopy(child)) print etree.tostring(root, pretty_print=True) |
This results with the expected output:
<root> <child/> <child/> </root>
