How to Build a Customer Relationship Management System with FastAPI and SendGrid
Time to read: 9 minutes
Customer Relationship Management (CRM) systems play a pivotal role in helping businesses manage and nurture relationships with their customers. This article will explore the process of building a CRM application using FastAPI, SendGrid for email services, and marketing campaigns to enhance customer engagement and service.
Prerequisites
Before beginning the tutorial, you will need:
- A free Sendgrid account.
- The latest version of Python 3 installed to your operating system. Follow the instructions for your OS. This tutorial assumes you are developing on a Linux machine.
- Your IDE of choice.
- A database to store and manage data efficiently. This tutorial will walk you through installation of the PostgreSQL database. However, if you prefer another type of database, install it before beginning this tutorial.
Authentication has been removed from the following article to slim it down somewhat. Other models and schemas are also not shown. However, they can be found in the complete source code hosted on GitHub.
Set Up Your Project
For this tutorial, you will utilize FastAPI. FastAPI is a modern, fast web framework for building APIs with Python 3.7+, and will serve as the backbone of your CRM application. Its simplicity, speed, and automatic OpenAPI and JSON Schema generation make it an excellent choice.
Create a project folder and navigate to it:
Create a virtual environment and immediately activate it:
Now you will install some tools necessary for your application. Pydantic will be used to define models for the application. These models will serve as a bridge between the database and the FastAPI application, providing data validation and serialization.
SQLAlchemy, an SQL toolkit and Object-Relational Mapping (ORM) library, will be used to interact with the database. Alembic, a database migration tool, will help you manage database schema changes over time.
Install the necessary packages in the command line:
Create the folder structure needed for the app. Creating a folder structure is crucial for maintaining an organized, scalable, and maintainable codebase. It separates the different parts of the application, enhancing readability and manageability. You will start by creating the main app/ folder to hold all the code necessary for the project.
The project structure will follow a modular approach, with separate folders for models, schemas, CRUD operations, services, and API endpoints. It will be based on the following structure:
- Models ( app/models/) - Define SQLAlchemy models for the CRM entities - Leads, Customers, Users, Emails, Campaigns, and Deals.
- Schemas ( app/schemas/) - Pydantic models for data validation and serialization will be created for each entity.
- CRUD Operations ( app/crud/) - These files contain CRUD (Create, Read, Update, Delete) operations for each entity. They serve as the intermediary between the database and the API.
- Services ( app/services/) - The
EmailService
class, responsible for sending emails through SendGrid and tracking email opens, is placed in this folder.
- API Endpoints ( app/api/) - FastAPI routes for each entity, including endpoints for basic CRUD operations and email-related functionalities.
When it is complete, the model for the project database will look like the following:
Create the PostgreSQL Database and user
If you are choosing PostgreSQL for your database, install it now using the instructions for your appropriate operating system. Otherwise, you can use the database of your choice and move onto the next segment of the tutorial.
Install PostgreSQL on Windows
Step 1: Download PostgreSQL Installer
- Go to the official PostgreSQL download page.
- Click on the "Download the installer" link.
- Choose the version you want and download the installer for Windows.
Step 2: Run the Installer
1. Run the downloaded installer file.
2. Follow the setup wizard. Click "Next" to proceed with the default options or customize the installation directory if needed.
Step 3: Choose Installation Directory
Choose the directory where you want PostgreSQL to be installed. Click "Next".
Step 4: Select Components
Select the components you want to install. Typically, you'll want to install PostgreSQL Server, pgAdmin 4, and Command Line Tools. Click "Next".
Step 5: Set Password
Set a password for the PostgreSQL superuser (default user is postgres
). Make sure to remember this password. Click "Next".
Step 6: Set Port Number
Set the port number for PostgreSQL. The default port is 5432. Click "Next".
Step 7: Choose Locale
Choose the locale settings. By default, it is set to your system's locale. Click "Next".
Step 8: Start Installation
Click "Next" and then "Finish" to start the installation process. Wait for the installation to complete.
Step 9: Verify Installation
Open the pgAdmin 4 tool from the Start menu.
Connect to the PostgreSQL server using the password you set during installation.
Install PostgreSQL on macOS
Step 1: Install Homebrew
1. Open Terminal.
2. Install Homebrew if you haven't already:
Step 2: Install PostgreSQL
Use Homebrew to install PostgreSQL:
Step 3: Start PostgreSQL
Start the PostgreSQL service:
Step 4: Verify Installation
Verify the installation by checking the PostgreSQL version:
Step 5: Access PostgreSQL
Access the PostgreSQL prompt:
Step 2: Install PostgreSQL
Install PostgreSQL:
Step 3: Start PostgreSQL Service
Ensure the PostgreSQL service is running:
Step 4: Enable PostgreSQL Service
Enable PostgreSQL to start on boot:
Step 5: Switch to PostgreSQL User
Switch to the PostgreSQL user:
Step 6: Access PostgreSQL Prompt
Access the PostgreSQL prompt:
Step 7: Exit PostgreSQL Prompt
Exit the PostgreSQL prompt:
You will need to create a database for the application together with the user. After installing the database login into your database prompt:
Enter the following command to create a new database. For this project, the database can be named "sendgridapp":
Create a new user and grant that user all privileges to the newly created database:
Build Your Python Application
The main.py file will be your entry point to the application. The settings.py file is used to get environment variables from an .env file and store them in the Settings class.
Create an .env file and add the environment variables needed, which is the Sendgrid API Key and the Database URL. Use the database details above to fill in the dbname, dbuser, dbserver and dbpassword in the URL.
The "DBUSER" and "DBPASSWORD" correspond to the database login you use for your database. For instance the DBNAME will be the name of the database hosted on the DBSERVER. If you used the setup above, the default value for DBSERVER is localhost
.
After creating the file add the following to settings.py:
Currently, the directory structure of your application should look like the following, with the exception of the alembic/ folder which will be created with the command alembic:
Before creating the database models with SQLAlchemy, add the connection to the database by creating a new file in the /db folder called database.py. This is the contents of the new db/database.py file:
Create the Database Models
Now, create the database models.
The models in the lead.py file will look like the following:
Model file for Deals( deal.py):
The customer.py model file:
The campaign model file( campaign.py):
The email.py file that will store the emails locally. Each email will belong to a lead and each email will store a SendGrid email_id to link it. Here is the file:
And finally the user.py model file for the sales rep or users:
Use the Alembic Tool to Manage Database Migrations
After creating the models it is time to apply the schema to the database. Use alembic to manage the migrations.
Run the following to command from the /app directory to initialize an alembic managed project and specify the directory (usually also named alembic) for alembic migration files:
The command generates a file called alembic.ini in the current folder along with a directory to hold the migration changes using whatever name is given.
Edit the env.py file in the alembic/ folder to include your models and import the sqlalchemy metadata object by adding this code to the top:
Also edit the alembic.ini file generated by specifying the sqlalchemy url which is the same as your database URL.
Look for the line sqlalchemy.url = driver://user:pass@localhost/dbname
in your code, and replace it with correct and updated information for your database, replacing the placeholders as needed:
To create tables in the database, generate migrations from your created models and run the following alembic command, which will generate the SQL to commit to the database:
To complete the process and execute the SQL generated upgrade the migration in the command line:
Create the functions for CRUD operations
Change into the crud/ folder. The crud/ folder is like a controller for your app. It allows you to create functions that will make the necessary calls to the database or service. Create the necessary files:
Here is sample of the crud/crud_lead.py file:
Now create the CRUD operations for the users in the crud_users.py file:
Create the CRUD operations for the crud_campaigns.py file :
Create the CRUD operations for the crud_customers.py crud file:
The code for the crud_deals.py file is shown below:
And here's the code for crud_emails.py:
Create Pydantic Schemas for data validation
Now you will create some pydantic models which will be in the schemas/ directory. You will need to create new files for all the schemas. Pydantic schemas provide a powerful way to manage and validate data in Python applications. Each schema file will correspond to a model file with the same name for SQLAlchemy.
Here is the campaign.py schema:
The deal.py file schema:
The email.py schema which will be used by the email_service.py:
The schema for the customer.py will be light as only the name, email and phone are needed:
Most of the lead.py fields are optional with the only the name of the lead required:
And finally add the user.py schema file, none of its fields are optional:
Send emails with SendGrid
The integration of SendGrid adds a powerful email component to your CRM application. In the EmailService
class, you have methods for sending emails, tracking email opens, and retrieving the open status of an email.
The send_email
method utilizes SendGrid's Python library to send emails. It leverages the SendGrid API key and stores the email in the database.
Track Status of Open Emails
The track_email_open
method updates the is_opened
field in the database when an email is opened. This functionality provides insights into customer engagement. The get_email_open_status
method retrieves the open status of a specific email. This information can be valuable for follow-up actions.
Create the email_service.py file inside the services/ directory:
Here is the code for email_service.py:
While this CRM application lays the foundation for managing customer relationships, integrating marketing campaigns will further enhance customer engagement and conversion. In your application, you've introduced a Campaign
entity and corresponding CRUD operations.
Test the CRM API endpoints
The last folder in the app is the api/ folder which contains the routes of your application. It has routes for each module of your application. Create the endpoint files in the api/ directory:
For instance the api/lead.py will have 3 endpoints which can be tested:
The email.py file will retrieve the SENDGRID
key set from the .env file:
Here is the campaign.py file for campaigns:
The customer.py will handle the API calls for creating and listing customers:
You can now add deal.py to add API functions to handle deal creation and listing:
The remaining user.py file is about handling user related functionality, including checking if a user with certain email exists before proceeding:
The main.py file for the in the app/ folder will be nothing special and will look like most FastAPI applications:
In the project app/ folder, run the FastAPI application using the command line:
You will be greeted with the following confirmation on success:
Navigate to http://127.0.0.1:8081/docs to test the application. The URL points to a Swagger API documentation of the application. It lists all the endpoints for the application which you can test on the same page while it calls curl in the background:
Click on any endpoint you wish to test to reveal a drop down with a button on the right corner that says "Try it out". Click on the button which reveals an "Execute" button together with options and or requirements for your endpoint. The result of the request are displayed below in the response section:
What's next for SendGrid CRM Applications?
SendGrid, a cloud-based email delivery service, enables us to send and track emails seamlessly. It provides a reliable and scalable solution for managing email communication with customers.Building a CRM application shows just how sending emails and building marketing campaigns can help a business thrive with its customer engagement efforts. The modular project structure ensures maintainability, and the use of Pydantic models enhances data validation.
The source code for the complete api can be found here https://github.com/samaras/fastapi-conversation.
You can add generative AI to the application by exploring other Sendgrid APIs like event web hooks to further engage your customers by sending follow up emails on opened leads.
Samuel Komfi is a Freelance Software Developer based in Johannesburg. He has been programming since he was 16 and now shares his thoughts on various blogs. He loves coffee, sunny days and blazingly fast internet to crawl the web for all things not cat videos. He can be reached at skomfi [at] gmail.com.
His profile at X is @skomfi.
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.