Day 5 of the Anvil Advent Calendar

Build a web app every day until Christmas, with nothing but Python!

Make an API call. Send a card.

Let’s make a web app that sends physical Christmas cards - entirely in Python!

December is here already, and it’s time to start panicking thinking about your Christmas cards. You have two options:

  1. Give yourself a nasty case of RSI, writing all those names and addresses, or

  2. Get a robot to do it for you.

We’re going to choose option #2, with the help of Handwrytten, a service with actual robots that can write your Christmas cards – or indeed, any form of correspondence – for you.

Handwrytten has a comprehensive API, so we can build a web front end for it in Python, using Anvil.

Here’s how it will work:

Sending a card

First things first - let’s write a function to send a card. According to the API docs, you can do this with one call of the singleStepOrder endpoint. It will need your username and password, so we’ve used App Secrets to store our Handwrytten credentials:

import requests
import anvil.secrets

CARD_ID = 2887
# Hard-code the sender address:
SENDER_DATA = {"sender_name": "Anvil", "sender_address1": "28 Chesterton Road", ...}

@anvil.server.callable
def send_card(data):
    # "data" is a dictionary
    senddata = {
        "login": anvil.secrets.get_secret('username'),
        "password": anvil.secrets.get_secret('password'),
        "card_id": CARD_ID,
        "message": data["message"],
        "validate_address": True,
        "recipient_name": data["rcpt_name"],
        "recipient_address1": data["rcpt_addr1"],
        "recipient_address2": data["rcpt_addr2"],
        "recipient_city": data["rcpt_city"],
        "recipient_zip": data["rcpt_zip"],
        "recipient_country_id": data["rcpt_country_id"],
        "recipient_state": data["rcpt_state"],
        **SENDER_DATA,
    }
    r = requests.post("https://api.handwrytten.com/v1/orders/singleStepOrder", data=senddata).json()
    print(r)
    return "error" not in r, r.get("error")

Let’s test it. First, we’ll put our Handwrytten account into Test Mode, so it doesn’t send anything yet.

Now, we can call our function from a Server Console:

Well, it looks like it’s succeeded! And if we check our email, we’ll see a confirmation:

Building a UI

We can now build a user interface, so we don’t have to do that from a Python console.

Thanks to Anvil, building a user interface for this app is the easy part. Using Anvil’s drag and drop designer, we’ll create a form to enter the address, with TextBoxes for the recipient’s address and a TextArea to enter the message. Then we’ll use Data Bindings to write all the inputs into the self.item dictionary:

Now we just need to wire up the Send button, to call the function we defined above. We double-click on the button, and call our server function. Our data bindings have already populated the self.item dictionary, so it’s as simple as:

    def button_1_click(self, **event_args):
        """This method is called when the button is clicked"""
        success, err_text = anvil.server.call('send_card', self.item)
        if success:
            alert("Your card has been sent!")
            self.error_lbl.text = ""
        else:
            self.error_lbl.text = err_text

All done!

And there we have it – we’ve built a web application that sends a physical postcard using Handwrytten! You can see the source code here – although of course, if you want to use it, you’ll need to enter credentials for your own Handwrytten account.


Give the Gift of Python

Share this post: