How to Make Unique Holiday e-Cards with Python and SendGrid
Time to read: 7 minutes
Are the holidays quickly coming around the corner, and you can’t figure out anything to do? Why not harness the power of technology to create a personalized holiday card? And while you’re at it, you can grab a budding artist, programmer, or mathematician to help you program this project.
In this tutorial, you will use Python to create a drawing program that allows you to create holiday cards. With this program, you will also generate a snowflake. Afterwards, you will use SendGrid and Python to send the card out by email.
Prerequisites
To continue with this tutorial, you will need:
- Python 3.6 or higher installed on your machine.
- A SendGrid account. If you haven’t yet, sign up for a free SendGrid Account.
- Two or more email addresses to test this project.
After you complete the prerequisites, you are ready to proceed to the tutorial.
Set up your project environment
Before you can dive into the code, you will need to set up the project environment on your computer.
First, you’ll need to create a parent directory that holds the project. Open the terminal on your computer, navigate to a suitable directory for your project, type in the following command, and hit enter.
As a part of good practices for Python, you'll also want to create a virtual environment. If you are working on UNIX or macOS, run the following commands to create and activate a virtual environment. The first command creates the virtual environment, and the second command activates it.
However, if you are working on Windows, run these commands instead:
After activating your virtual environment, you’ll need to install the following Python packages:
- python-dotenv to manage your environmental variables.
- pygame to create simple graphics.
- sendgrid to interact with the Twilio SendGrid Web API.
To install these packages, run this command:
As a part of good programming practices, you’ll want to store sensitive information inside a secure location. To do this, you will store values in a .env file as environmental variables. In the snowflake-card-project directory, open a new file named .env (note the leading dot), and paste the following lines into the file:
Your project environment is now set up, but you must first configure your environmental variables in the .env file. "XXXXXXXXXXXXXXXX" are simply placeholder values for their corresponding variables. The next sections will cover how to get the actual values.
Obtain a SendGrid API Key
From the SendGrid dashboard, click Settings > API Keys to navigate to the SendGrid API Keys page. Then, click on Create API Key.
Next, enter the name (I named mine "Holiday Card") for the API Key. Then, under API Key Permissions, select Full Access. Finally, click Create & View to create the API Key.
Afterwards, your API Key should pop up on the screen. Copy the key, and in the .env file you created earlier, replace the "XXXXXXXXXXXXXXXX" placeholder for SENDGRID_API_KEY
with the value you copied.
Next, you need to create a verified sender to send emails from. On the left-hand side of the dashboard, navigate to Marketing > Senders to get to the Sender Management page. Click the Create New Sender button in the top right, fill out the necessary fields, and click Save. In the .env file you created earlier, replace the "XXXXXXXXXXXXXXXX" placeholder for VERIFIED_EMAIL_SENDER
with the email address you used for the sender. Then, verify the sender by checking for an email from SendGrid in the sender's email inbox.
After the sender is verified, you are now ready to begin coding the application!
Create the application
Here are the expected requirements of the application:
- The user will draw part of a snowflake.
- After the user clicks a button labeled CREATE, a snowflake is automatically generated.
- The user is then able to draw on the image as they want.
- When the user exits out, they are given an option to fill out a form to send the image via email.
Here is an example of a completed card:
There will be four files in the snowflake-card-project directory: settings.py, button.py, main.py, and sendMessage.py. Each section below will cover these files.
Define the settings module
The settings.py file is used as a module to store user preferences, constants, and common imports. In the snowflake-card-project directory, create a new file named settings.py and paste the following code into settings.py:
In the code shown above, values for several constants are defined. Feel free to change these values to match your preferences.
Define the button module
The button.py file is used as a module that defines the Button
class, so you can easily create buttons for your pygame window. In the snowflake-card-project directory, create a new file named button.py and paste the following code into button.py:
As depicted in the code above, the draw
function for the Button
class renders the button, and the clicked function checks whether the mouse position is within the area defined for the button. This module will be used to make the CREATE button to generate the snowflake in main.py.
Code main.py
The code in main.py creates and renders the graphic program. This section will cover the code step-by-step below. However, you can skip to the end of this section for the completed code.
In the snowflake-card-project directory, create a new file named main.py, and paste the following code into main.py:
The code above sets up the screen to draw on. Using a bit of math, you can use pygame to create the drawing area, i.e., the sector. This sector makes up 1/12th of a circle. Additionally, the user doesn’t actually draw on the screen. Instead, snowflakeSurface
is initialized for the user to draw on.
This is what the screen would look like.
Below are some helper functions to help you draw the snowflake. Copy and paste the following code below the lines you pasted earlier:
drawCircle
is used to draw white circles in the sector. However, the program should only allow you to draw inside the drawable area. In order to do this, the function isInsideSector
checks whether the mouse is inside the sector by checking its polar coordinates. Lastly, drawSnowflakeSymmetry
is where all the magic happens. Using the snowflakeSurface
, this function copies and rotates the surface every 60 degrees. It then flips the snowflakeSurface
horizontally and repeats the process to create the entire snowflake.
Lastly, all of the interactions need to be implemented. Copy and paste the following code below the lines you pasted earlier for the helper functions into main.py:
As depicted in the code snippet above, creating the card is split up into two phases: drawing the snowflake, and drawing elsewhere on the screen. These are split up into two functions: snowflake
and draw
.
The snowflake
function is called first. In the function, the screen is constantly updated using an infinite while-loop. Additionally, the loop checks for an event at each iteration. If the user holds the mouse button down, they are able to draw in the sector. Conditional statements check whether the user exits the window or whether the user clicks the CREATE button. Below is an example of part of a snowflake being drawn:
Once the create button is clicked, the drawSnowflakeSymmetry
function generates the snowflake, and the program then calls the draw
function to go into the drawing phase for finishing touches.
Below is an example after the CREATE button was clicked:
Afterwards, the user can draw anything they want onto the screen. For example, you can write some words or draw additional images. An example is depicted below:
After the user exits out of the window, the image that they created is saved, and they are given the option to send the email by running the sendEmailDialog
function from the sendMessage
module. This will be covered in the next section.
Here is the completed code for main.py:
Define the sendMessage module
The sendMessage.py file is used as a module to store user preferences, constants, and common imports.
In the snowflake-card-project directory, create a new file named sendMessage.py and paste the following code into sendMessage.py:
In the code above, the necessary modules are imported at the top. There are two functions in this module: sendEmail
and sendEmailDialog
.
The sendEmail
function uses SendGrid to create and send an email. First, a Mail
object is initialized with the arguments. Then, the API key is assigned to the variable sg
using the SendGridAPIClient()
method from the SendGrid helper library. To attach an image, the saved image is converted to base64 format and added as an attachment to the message. The message is then sent, and information about the response is printed out.
The sendEmailDialog
function displays all of the input prompts in the console. If an image is created, the user is prompted to answer whether they want to send the email. If they answer yes, they can fill out the recipient and subject lines. Then, the sendEmail
function is called. The user can also optionally send another email. An example of the console dialog is shown below:
Afterwards, the image should appear in the recipient’s inbox.
Run the application
To run the application, run this command in the snowflake-card-project directory where the virtual environment is activated.
After running the command, the screen should be opened and ready to draw on. Draw a snowflake and hit create. Afterwards, you can draw whatever you want on the screen. Once you’re ready to send out your masterpiece, exit out of the window, and the prompts to email the image should appear in the console.
Conclusion
Congratulations on building your application. First, you used Python to create a graphic program that allows you to generate snowflakes and draw on a digital holiday card. Then, using SendGrid and Python, you added additional functionality to the program by allowing the user to send the drawing as an email. Feel free to customize your application to your liking. For example, you could mess around with the layout, make the program more simple, or make it more complicated by allowing users to select colors.
Excited to learn more about what you could do with SendGrid, and Python? Check out this article on using Notion to template emails. Or perhaps you could learn how to send recurring emails with SendGrid. For more information on how to get started with SendGrid and Python, you can check out the SendGrid Email API Quickstart for Python. I can't wait to see what you build!
Johnny Nguyen is an intern developer turned freelancer on Twilio’s Developer Voices Team. He enjoys creating fun coding projects for others to learn and enjoy. When he’s not napping or watching TikTok, he can be reached by his LinkedIn.
Related Posts
Related Resources
Twilio Docs
From APIs to SDKs to sample apps
API reference documentation, SDKs, helper libraries, quickstarts, and tutorials for your language and platform.
Resource Center
The latest ebooks, industry reports, and webinars
Learn from customer engagement experts to improve your own communication.
Ahoy
Twilio's developer community hub
Best practices, code samples, and inspiration to build communications and digital engagement experiences.