Although we'll be using Ruby and Sinatra in this example application, this functionality could be integrated into any app written with Python, PHP, Java, and other languages with EasyPost's official client libraries and PrintNode’s client libraries.
The PrintNode documentation has an in-depth guide, but given that we were using OSX, we found the below steps easier.
lpinfo -vto find your connected printers, and look for a line that begins with
direct usb://<printer connection>
usb://<printer connection>string and run
lpadmin -p raw_label_printer -E -v usb://<printer connection>. Feel free to change the printer’s name (in our example
raw_label_printer) to another name if you prefer.
raw_label_printeravailable on the printers tab. Take note of the Id column, as we will be needing this in the next step.
Our application will have a few details specific to our accounts which we will need to provide.
The first thing we need is an API key from EasyPost. This is an example application, so we're going to use the test API key, but be aware that non-test data will still be visible! You can find your test key on the API Keys page.
In order to print from our application, we'll use the PrintNode API. Go to printnode.com, sign up and download and install the PrintNode client if you haven’t yet. Once you're in, go to the API tab and make a new API Key.
Next, make a new directory for you project, and open your favorite code editor and create a new file called
.env in your new folder. Fill in the test EasyPost API key, PrintNode API key, and your printer’s PrintNode Id, so it looks something like this:
We'll start out by creating a Gemfile with the dependencies we will need. This will be a new file titled
Gemfile in the project root directory. We can get away with a pretty minimal list, so let’s add in the
printnode gems to communicate with the respective APIs, the
sinatra gem for our web application, and the dotenv gem to load our configuration values in. Your Gemfile should look like this:
At this point, we can go ahead and install our dependencies by running
bundle install, so let’s do that.
Next, we can start writing our web application. Create a file called
app.rb and save it in the project root directory. Here are the first few lines:
In these first couple of lines, we import the dependencies we installed, the app is defined (we’re using Sinatra’s modular style) and the config variables are loaded. We then instantiate the EasyPost and PrintNode clients with the keys from our
If you want to give it a shot to check that it’s all working, just type
ruby app.rb from your project root, and you should see a few lines saying:
Go ahead and visit http://localhost:4567/ and you should see a message with the PrintNode printer id from our configuration.
When you’ve had your fill, stop the application with Ctl-C, and give yourself a pat on the back before moving on to adding a route for viewing our shipment labels, right below our root route in
These lines are getting a paged list of Shipments belonging to the current EasyPost API key, and then passing them to an erb view. We’re doing the bare minimum here, so the default parameters of our client will be used. It should limit how many results we get and we won’t bother paging any results, so don’t worry if you don’t see all your shipments. Be aware the default view will only show items for the past 30 days.
Let’s create a simple view next. In your project folder, make a new directory called
views and create a file named
shipments.erb in it. In this file, we can create a simple html document that displays our items:
You can feel free to make this look prettier, or lay it out as you like, but really we are just looping through our Shipments and printing out information. The important part here is the links we create for each Shipment. You’ll notice that if a Postage Label has a label_zpl_url, we filled in links to print and download the file, and if it doesn’t we provided a link to generate the ZPL. We will need to define one method to generate the ZPL, and one for the printing.
Let’s quickly define a route to generate a ZPL formatted shipping label if one doesn’t exist.
The code in this route finds our specific shipment, and makes a request to the EasyPost API to generate one unless a url for a ZPL formatted label already exists on the Postage Label object. Once this request finishes, it redirects us back to the page we were on.
As a side note, if you were interested in generating a PDF format file instead, you could change the check to verify a label_pdf_url doesn’t exist, and then change the file_format to ‘PDF’ in the EasyPost request.
Now that we can generate ZPL format labels for any Shipment that is missing one, lets move on to printing!
Our final route that handles the printing looks fairly similar to our generate route, however instead of issuing a request to generate the ZPL file, it creates a printjob using PrintNode’s API. We first look up our shipment using the id, then create a new PrintNode::PrintJob object, passing in our PrintNode designated printer_id that we configured earlier, our shipment’s id as a job name, the ‘raw_uri’ printing format, our postage label ZPL url, and the app name ‘PrintLabel’ as our job source. We then take our PrintJob object, and pass it to the create_printjob method on our application’s PrintNode client instance. When this is successfully sent, we redirect back to our listing page.
If you are interested in printing PDFs instead, note that similar to our generation, you can change the ‘raw_uri’ to ‘pdf_uri’, and pass in the label_pdf_url instead.
Yep, that’s it! If you have the PrintNode client running and configured, that’s all the code you need to both generate ZPL format labels and get them printed!
So now that it seems we have most of the functionality to demonstrate this, let’s take our application for a spin!
As before run
ruby app.rb from the project folder, and you should see your application start up.
Then just visit http://localhost:4567/shipments to see it in action!
We simplified things for the purpose of the tutorial, but you can view a more complete example in the repository we set up alongside this which is available on GitHub. The sample repo also demonstates paging through all your Shipments, and would serve as a great starting point to keep building off of!
Note that these printers can sometimes be a bit finicky, so if nothing is printing even though the PrintNode Desktop client is receiving the print requests (which is also viewable on the PrintNode dashboard), we recommend power cycling your printer.