Thursday, July 05, 2007

Printing Postage with Python and Endicia.com

As my self-help business has grown, I've been needing to ship dozens of newsletters and CDs to my members each month, not counting incidental orders for other products.  Last year, I did all my shipping manually through the USPS website, but as soon as I started offering subscriptions, I switched to using Endicia.com, as previously recommended by Joel on Software.

Endicia offers a Windows client that lets you copy and paste a slew of addresses from the clipboard, and print shipping labels to a Zebra label printer (or pretty much any other kind of printer).  And since the May 2007 rate changes, I can now print customs forms right on the shipping label for shipping to every one of the countries my subscribers are in.  I don't even have to hand-sign and date the customs forms any more!

However, one of the most annoying things about using the client manually is that it has to be carefully configured before printing each kind of label, and it cannot print more than one non-US label at a time.  Almost exactly half of my subscribers are outside the US, so it literally takes me hours to copy-and-paste their addresses one at a time, double-check all rate options, and print the labels.

So this month I got fed up with that process and wrote a Python library to interface with Endicia via XML: PyDicia.

PyDicia is an industrial-strength (well, light industrial, anyway!) interface to Endicia's DAZzle client for Windows.  It can not only send arbitrary packages to anywhere in the world with any shipping option or label type supported by Endicia and the USPS, it can retrieve address corrections, delivery confirmation numbers, customs IDs, etc.  If you have application objects like a "Customer" or "Invoice", you can register callbacks to turn them into address data that PyDicia understands, and to receive the address corrections, delivery confirmation numbers, etc.  (e.g. So you can mark an order "shipped" in your database.)

In my current actual use so far, I've only printed out labels from a script, and haven't done any application integration yet.  That's because my "customer database" currently consists of an Excel spreadsheet and a plain text file of addresses.  I'll probably replace all that with an Access database soon and implement business rules to figure out what should go into each person's package(s).  (Eventually, the Access database wouldl probably move to some sort of server-side database, but it's a YAGNI for now.)

However, I've already saved a couple of hours of data entry...  at the cost of two or three days programming time.  :-(  Oh well, so it'll take a few more mailings (or a handful more members!) before the time savings really starts showing.  But on the flip side, I had fun writing it, and now I don't dread the process of doing the international shipments as much.  Even more important, I no longer dread the idea of getting a lot of new members, which has been causing me to avoid promoting the group as effectively as I should!

A few tips for using PyDicia, by the way: be sure to set up your DAZzle layouts first, including saving the printer setup with each layout and enabling "stealth" postage.  This will prevent constant prompting to enable stealth postage for international shipments, and avoid device errors or badly printed labels due to incorrect printer information.  That way, you can disable the prompts and just spew labels out at lightning speed.  Yay!