Day 3 of Hanukkah at Anvil

Build a web app for each night of Hanukkah, with nothing but Python!

Send holiday wishes

It’s the third night of Hanukkah – probably time to write some cards! Even better, why not send personalised e-cards?

In today’s app, we show you how to create custom Hanukkah e-cards and send them out to all your friends and family.

Create your app

We’ll create a simple UI using TextBoxes and TextAreas for our user inputs.

To create our custom e-card, we’ll ask our users for:

  • the background image they’d like to use
  • the spelling of Hanukkah to use (Chanuka, חֲנֻכָּה, etc)
  • the recipient’s email address
  • the recipient’s name
  • a personal greeting
  • their name

Our basic UI looks like this:

Choose your background and spelling

We’ll use Anvil’s Data Tables to store background images for our users to choose from when creating their card.

We create a table called ‘backgrounds’ which has a text column for the name of the image and a media column to store the images. I have uploaded three images to my Data Table. It looks like this:

I’ve also added a second table names_for_the_holiday with the various spellings of the holiday! This is used to populate the second DropDown.

Preview backgrounds

Back in the UI, we’ll use a DropDown component to let our users choose the background image for their e-card. We’ll also show a preview of the selected image using an Image component.

We add this code to our Form’s __init__ method to:

  1. Populate the DropDown
  2. Show a preview of the image
    # get images from the data table
    cards = app_tables.backgrounds.search()
    # populate the DropDown
    self.card_dropdown.items = [(x['name'], x) for x in cards]
    # Show a preview of the image
    self.card_image.source = self.card_dropdown.selected_value['image']

We’ll also change the image preview when the user chooses a different image. We do this in our card_dropdown_change function which runs when the user selects a different value from the DropDown:

def card_dropdown_change(self, **event_args):
    card = self.card_dropdown.selected_value
    self.card_image.source = card['image']

Capture user inputs

All that’s left to do is capture user inputs and then send them to a Server Module which will handle sending the e-card.

We’ll send the inputs to the server when the ‘Send my e-card!’ button is clicked:

def button_1_click(self, **event_args):
    email_address = self.email_box.text
    recipient = self.recipient_box.text
    sender = self.sender_box.text
    greeting = self.greeting_box.text
    image = self.card_image.source
    spelling = self.spelling_chosen
    anvil.server.call('send_ecard', image, email_address, recipient, greeting, spelling, sender)

Send emails

We’ll need to enable the Anvil Email Service - just click the ‘+’ next to Services in the App Browser. We can now use anvil.email.send to send emails from our app.

Once that’s enabled, we add a Server Module and define our send_ecard() function to send our custom e-card. We use inline attachments to include the background image:

@anvil.server.callable
def send_ecard(image, email_address, recipient, greeting, spelling, sender):
  anvil.email.send(inline_attachments={'img':image},from_name="The folks at Anvil", 
               to=email_address, 
               subject="Chag sameach from {}".format(sender),
               text="Please open in a different email service to see your e-card in its true glory",
               html=f"""
               <div style="background: url(cid:img); background-color: #800; background-size: cover; width: 50%; height: 100%; ">
                 <div style="min-height:400px; padding: 30px;">
                  <p style="font-size: 54px; color: white; font-family: 'Snell Roundhand';">Happy {spelling}, {recipient}!</p>
                  <p style="font-size: 32px; color: white;">{greeting}</p>
                  <p style="font-size: 22px; color: white;">From {sender}</p>
                </div>
               </div>
               """
               )

Outgoing email is subject to a monthly quota, depending on your account plan.

Email sent through a custom SMTP server does not count towards your monthly quota.

Ta-da!

That’s it!

And that’s it! Go forth and send some cards!




Give the Gift of Python

Share this post:


Get tomorrow's app in your inbox

Don't miss a day! We'll mail you a new web app every night of Hanukkah: