flowchart TD
A0["EmailFetcher
"]
A1["EmailSummarizer
"]
A2["EmailComposer
"]
A3["DigestReport
"]
A4["Config
"]
A5["EmailDigestApp
"]
A6["Scheduling Mechanism
"]
A0 -- "Provides emails" --> A1
A1 -- "Generates summaries" --> A2
A2 -- "Creates reports" --> A3
A3 -- "Uses config data" --> A4
A5 -- "Schedules tasks" --> A6
A6 -- "Triggers fetching" --> A0
A5 -- "Initiates process" --> A0
A5 -- "Manages email sending" --> A2
Welcome to the first chapter of our journey into the world of bored-email! In this chapter, we will introduce the EmailDigestApp, a vital component of our project that simplifies the way we process and manage email digests.
Think of the EmailDigestApp as the conductor of an orchestra. Just as a conductor brings together different instruments to create beautiful music, the EmailDigestApp brings together various components—fetching, summarizing, and composing emails—into a harmonious email digest process. Its main job is to manage everything smoothly, ensuring that the email digests are generated and sent out in a timely manner.
Imagine you receive hundreds of emails every day, and keeping track of important messages becomes overwhelming. Instead of sifting through each email, what if you could receive a concise summary of the most important ones every morning and evening?
That's where EmailDigestApp comes in! It collects your emails, summarizes their contents, and sends you a digest, saving you from mental clutter.
To understand how EmailDigestApp works, let's break down its key components:
- Configuration Loading: It loads important settings from a
.envfile, like your email credentials and schedule for sending digests. - Fetching Emails: It retrieves emails based on predefined time windows.
- Summarizing Emails: It condenses the fetched emails into short summaries.
- Composing and Sending Digests: It formats the summaries into a digest email and sends them out.
- Scheduling: It ensures that the digests are processed at the correct times automatically.
When you run the EmailDigestApp, it might look something like this:
-
Input:
- Emails received: 10 emails
- Digests sent on: Morning at 7 AM, Evening at 9 PM.
-
Output:
- Morning Digest: "Summary of Email 1, Summary of Email 2... (5 summaries)"
- Evening Digest: "Summary of Email 6, Summary of Email 7... (5 summaries)"
Here's a step-by-step breakdown of what happens when you run the EmailDigestApp:
sequenceDiagram
participant FE as EmailFetcher
participant SU as EmailSummarizer
participant CO as EmailComposer
participant EDA as EmailDigestApp
participant REC as Email Recipients
EDA->>FE: Fetch Emails
FE-->>EDA: Return Emails
EDA->>SU: Summarize Emails
SU-->>EDA: Return Summaries
EDA->>CO: Create Digest
CO-->>EDA: Return Digest
EDA->>REC: Send Digest
In this diagram, the EmailDigestApp first fetches the emails using the EmailFetcher, summarizes them with the EmailSummarizer, creates the digest through the EmailComposer, and finally sends the digest to the recipients.
Now let’s explore the code that makes this happen. Below is the class definition for EmailDigestApp.
class EmailDigestApp:
def __init__(self, env_path: str = ".env"):
# Load configuration and set up components
self.config = self._load_config(env_path)
self.fetcher = EmailFetcher(self.config)
self.summarizer = EmailSummarizer(self.config)
self.composer = EmailComposer(self.config)Here, the constructor initializes the application. It loads the configuration and sets up the necessary components like EmailFetcher, EmailSummarizer, and EmailComposer. This setup is vital because it prepares the app to start fetching, summarizing, and sending emails.
Next, let's see how we process the morning digest:
def process_morning_digest(self):
logger.info("Starting morning email digest process")
emails = self.fetcher.fetch_emails(self.config.morning_cutoff_hours)
summaries = self.summarizer.summarize_emails(emails)
digest = self.composer.create_digest_report(summaries, "morning")
self.composer.send_email(digest)In this method, we:
- Start the morning digest process.
- Fetch emails based on the morning cutoff hours.
- Summarize those emails.
- Create a digest report from the summaries.
- Finally, send the digest email.
This simple flow makes it easy for the EmailDigestApp to handle the daily email digests efficiently.
We learned about the EmailDigestApp, which acts as the central hub for processing our email digests. We explored its key components and how they work together to simplify our email management.
With this understanding, you’re now ready to dive into the next chapter, where we will explore the scheduling mechanism that automates the timing for our email digests: Scheduling Mechanism
Welcome back! In the previous chapter, we introduced the EmailDigestApp, which organizes our email digests. Now, we’ll dive into an essential component of our application: the Scheduling Mechanism. This will help us automate tasks so our application can send email digests at specific times without any manual effort.
Imagine you have an alarm clock that wakes you up every morning at the same time. The Scheduling Mechanism functions similarly. It acts like an alarm for our application, ensuring that it wakes up and performs specific tasks at designated times—such as sending out email digests in the morning and evening.
Picture this: You want to receive a summary of your emails every morning at 7 AM and every evening at 9 PM, so you can stay updated without having to check your email every time. The scheduling mechanism takes care of this for us!
To understand the scheduling mechanism better, let’s break down the key concepts:
-
Cron Jobs: These are scheduled tasks that run at specific intervals or times. Our scheduling mechanism utilizes cron jobs to determine when to trigger email digests.
-
Triggers: These define the conditions for when to execute certain actions. In our case, we specify conditions for morning and evening digests.
-
BlockingScheduler: This is a tool that holds the application in a loop, allowing it to keep running and checking for scheduled tasks.
Let’s see how we implement this scheduling mechanism in our application. We will look at some code examples and explain what they do.
Here’s a snippet of code that sets up the scheduling for both morning and evening digests:
def schedule_jobs(self):
"""Schedule the morning and evening digest jobs"""
# Schedule morning digest (7 AM)
self.scheduler.add_job(
self.process_morning_digest,
CronTrigger.from_crontab(self.config.morning_schedule),
id='morning_digest'
)
# Schedule evening digest (9 PM)
self.scheduler.add_job(
self.process_evening_digest,
CronTrigger.from_crontab(self.config.evening_schedule),
id='evening_digest'
)In this part of the code:
- We define a function called
schedule_jobsto add our morning and evening jobs to the scheduler. - The
CronTrigger.from_crontabmethod reads the schedule we set in our configuration, like "0 7 * * *" for 7 AM and "0 21 * * *" for 9 PM.
When the scheduling mechanism runs, it will call the corresponding functions to process the email digests. Here's a simplified visual representation:
sequenceDiagram
participant SC as Scheduler
participant PM as Process Morning Digest
participant PE as Process Evening Digest
participant EDA as EmailDigestApp
participant REC as Recipients
SC->>EDA: Start Scheduler
SC->>PM: Trigger Morning Digest
PM-->>REC: Send Morning Digest
SC->>PE: Trigger Evening Digest
PE-->>REC: Send Evening Digest
In this diagram:
- The Scheduler starts and triggers tasks at specified times.
- It calls the respective functions to process and send the morning and evening digests to the recipients.
Now, let’s look at how the EmailDigestApp integrates the scheduling behind the scenes. Here is a simple approach to initialize our scheduler inside the app:
def __init__(self, env_path: str = ".env"):
"""Initialize the application with configuration from .env file"""
self.config = self._load_config(env_path)
self.fetcher = EmailFetcher(self.config)
self.summarizer = EmailSummarizer(self.config)
self.composer = EmailComposer(self.config)
self.scheduler = BlockingScheduler() # Initialize the schedulerIn the above code:
- The
__init__method ofEmailDigestAppinitializes theBlockingScheduler, which manages our scheduled jobs. - It sets up other components like the
EmailFetcher,EmailSummarizer, andEmailComposerfor later use.
In this chapter, we explored the Scheduling Mechanism and understood how it automates the email digest process. From using cron jobs to setting up triggers in our application, we’ve seen how our EmailDigestApp maintains an efficient scheduling system that saves us time and effort.
Now that you have a solid grasp of the scheduling mechanism, you’re prepared to learn about fetching emails in the next chapter: EmailFetcher.
Welcome back! In the previous chapter, we learned about the Scheduling Mechanism, which automates when our email digests are generated and sent. Now, let’s dive into a crucial part of our application: the EmailFetcher.
Imagine having a friendly mailman who delivers letters to your mailbox every day. The EmailFetcher serves a similar purpose but in the digital world. It’s responsible for collecting emails from your Gmail account for further processing. Depending on your setup, it can use the modern Gmail API or the traditional IMAP method to fetch your emails.
Let’s start with a simple use case. Imagine you want to collect all the emails you received in the last 24 hours so you can summarize them. Instead of going through your inbox manually, the EmailFetcher does that job for you, allowing you to focus on what’s important.
To understand how the EmailFetcher works, let’s break down its key concepts:
-
Configuration: It uses a configuration file to know your email settings and preferences. This includes API keys or IMAP credentials.
-
Fetching Methods: The EmailFetcher can fetch emails using:
- Gmail API: This is the modern approach that utilizes Google’s official API.
- IMAP: A traditional method that works with many email clients and services.
-
Email Collection: It gathers the emails from your mailbox based on a specified time frame.
The EmailFetcher allows us to gather emails seamlessly. Here’s how you can use it:
Suppose you want to fetch emails from the last 24 hours.
-
Input:
- Time Frame: Last 24 hours
- Method: Using Gmail API (or IMAP)
-
Output:
- A list of email summaries you can use for further processing.
Here’s a simple code snippet to illustrate how to use the EmailFetcher:
# Import the EmailFetcher from your project
from email_fetcher import EmailFetcher
# Initialize the EmailFetcher
fetcher = EmailFetcher(config, use_api=True) # Set use_api to True for Gmail API
# Fetch emails received in the last 24 hours
emails = fetcher.fetch_emails(hours_back=24)
# Output the fetched emails
for email in emails:
print(f"From: {email.sender}, Subject: {email.subject}")In the code above:
- We import the
EmailFetcherclass from our project. - We create an instance of
EmailFetcher, providing it with the necessary configuration and specifying to use the Gmail API. - We call
fetch_emailsto retrieve emails from the last 24 hours and then print the sender and subject of each fetched email.
Let’s explore what happens step-by-step when you call the fetch_emails function:
sequenceDiagram
participant U as User
participant EF as EmailFetcher
participant API as Gmail API
participant IMAP as IMAP Server
participant DB as Email Database
U->>EF: Request to Fetch Emails
EF->>API: Fetch Emails with API (if use_api=True)
API-->>EF: Return Fetched Emails
EF->>DB: Store Fetched Emails
U-->>EF: Provide Processed Emails
In this diagram:
- The user requests to fetch emails.
- The
EmailFetcherchecks if it should use the Gmail API or IMAP. - It fetches the emails using the selected method.
- The emails are stored for further processing.
- Finally, the user receives the processed emails.
Now let's explore the code implementation behind the EmailFetcher. Here's a simplified version of how it works:
class EmailFetcher:
def __init__(self, config: Config, use_api: bool = False):
self.config = config
self.use_api = use_api
if use_api:
self._setup_gmail_api() # Initialize Gmail API
def fetch_emails(self, hours_back: int):
if self.use_api:
return self.fetch_recent_emails_api(hours_back) # Must implement this method
else:
return self.fetch_recent_emails_imap(hours_back) # Must implement this methodIn the constructor:
- We initialize the
EmailFetcherwith a configuration object. - We determine whether to use Gmail API based on the
use_apiflag. If it'sTrue, we set up the API.
Here’s an example code snippet that shows how the fetch_recent_emails_api method might look:
def fetch_recent_emails_api(self, hours_back: int):
# Calculate the time frame for fetching emails
time_back = datetime.now() - timedelta(hours=hours_back)
query = f"after:{int(time_back.timestamp())}" # Create query for Gmail
results = self.service.users().messages().list(userId='me', q=query).execute()
# Process the messages and return them
...In this part:
- We calculate the time frame to search the emails by subtracting from the current time.
- We create a query to find emails received after this calculated time.
In this chapter, we introduced the EmailFetcher, an essential component that gathers emails from your Gmail account. We learned how to use it, the essential concepts behind its operation, and a glimpse of its internal workings.
Now that you understand how the EmailFetcher collects emails, you’re ready to move on to the next chapter where we will explore the EmailSummarizer—the part of our application that condenses those emails into easy-to-read summaries. Let’s continue on this exciting journey: EmailSummarizer
Welcome back! In the previous chapter, we explored the EmailFetcher, which collects your emails for further processing. Now, let’s delve into an essential component of our application: the EmailSummarizer. This handy tool acts like a smart assistant, helping you make sense of your emails quickly.
Imagine you receive a barrage of emails every day, filled with important information, requests, and updates. It can be overwhelming to sift through all of it. The EmailSummarizer solves this problem by distilling each email into key points, action items, and prioritizing them. Instead of reading every email in detail, you get a concise summary that helps you quickly identify what's important.
Consider this scenario: You received five emails about different project updates, meeting requests, and follow-ups. Instead of reading through each lengthy email, you just want to know:
- What are the key points?
- Are there any action items you need to address?
- How urgent are these emails?
The EmailSummarizer achieves all this efficiently!
To understand how the EmailSummarizer works, let’s break down its key concepts:
-
Email Structure: Each email has specific parts, like the sender, subject, date, and body, which need to be analyzed to extract relevant information.
-
Summarization Process: This involves using an AI model to analyze the email body and create a summary. It distills the essential information, such as key points and action items.
-
Priority Classification: Based on urgency and importance, each email is assigned a priority level (High, Medium, or Low).
Now, let’s see how you can use the EmailSummarizer to tackle the email summary use case we just described.
Here’s a friendly guide to using the EmailSummarizer to summarize your emails!
Suppose you want to summarize an email you just fetched.
-
Input: An email with:
- Sender:
alice@example.com - Subject:
Project Update - Date:
2023-10-01 - Body:
The project is on track. Please update the document by Friday.
- Sender:
-
Output: A summary that includes:
- Key Points:
["Project is on track", "Update the document by Friday"] - Action Items:
["Update the document"] - Priority:
Medium
- Key Points:
Here’s how you can summarize an email using the EmailSummarizer:
# Import the EmailSummarizer class from your project
from email_summarizer import EmailSummarizer
from models import EmailMessage
# Create an instance of EmailSummarizer with configuration
summarizer = EmailSummarizer(config)
# Create a sample email message
email = EmailMessage(
message_id="123",
sender="alice@example.com",
subject="Project Update",
date="2023-10-01",
body="The project is on track. Please update the document by Friday."
)
# Summarize the email
summary = summarizer.summarize_email(email)
# Print the summary details
print("Key Points:", summary.key_points)
print("Action Items:", summary.action_items)
print("Priority:", summary.priority)In this example:
- We import the
EmailSummarizerand theEmailMessagemodel. - We create an instance of
EmailSummarizer. - We define a sample email message and summarize it.
- Finally, we print the key points, action items, and priority from the summary.
Let’s take a peek behind the scenes at how the EmailSummarizer works when you call it to summarize an email. Here’s a simple representation:
sequenceDiagram
participant U as User
participant ES as EmailSummarizer
participant API as OpenAI API
participant JSON as JSON Response
U->>ES: Request to Summarize Email
ES->>API: Send Email Content for Summarization
API-->>ES: Return Summary Data in JSON
ES-->>U: Provide Summarized Email
In this diagram:
- You (the user) request an email summary.
- The EmailSummarizer sends the email content to an AI service (like OpenAI).
- The AI service returns the summarized data in JSON format.
- Finally, the summarizer provides the summarized email back to you.
Now, let's examine how the EmailSummarizer is implemented in the codebase. Below is a simplified version of the code that summarizes a single email:
class EmailSummarizer:
def __init__(self, config):
self.config = config
openai.api_key = config.openai_api_key # Set up API key for OpenAI
def summarize_email(self, email: EmailMessage):
# Prepare the prompt with email details for summarization
prompt = f"FROM: {email.sender}\nSUBJECT: {email.subject}\nBODY:\n{email.body}\nSummarize this."
# Query the OpenAI API and receive the summary
response = openai.ChatCompletion.create(
model=self.config.openai_model,
messages=[{"role": "user", "content": prompt}]
)
# Extract summary from the response
summary_content = response.choices[0].message.content
return self.parse_summary(summary_content)
def parse_summary(self, summary_content):
# Code to parse summary_content and return a structured summary
...In the code above:
- We initialize the
EmailSummarizerwith configuration, including the OpenAI API key. - The
summarize_emailmethod prepares a prompt that includes the email details. - It sends the prompt to the AI model and retrieves a summary.
- Finally, the summary gets parsed into a structured format for easy use.
In this chapter, we learned about the EmailSummarizer, which significantly enhances our ability to manage emails. By summarizing the key points, of each email and assigning priorities, you can quickly understand what requires your attention.
With this knowledge, you’re well-equipped to explore the next component of our project: the EmailComposer, which allows us to create and send emails. Let’s continue our journey in the next chapter: EmailComposer.
Welcome back! In the previous chapter, we explored the EmailSummarizer, a helpful tool that distills your emails into concise summaries. Now, let’s dive into the next important component of our project: the EmailComposer.
Think of the EmailComposer as a digital newsletter editor. It takes all the summarized emails from the EmailSummarizer and formats them beautifully into an HTML email. Its primary purpose is to assemble a digest based on the key points from the emails and then send this digest to your team to keep everyone informed.
Imagine you’ve received a summary of important emails and now you want to share that information with your team. Instead of sending individual emails, you can create a beautifully formatted email digest containing all the key points and action items. This allows your team to quickly grasp what’s important without having to read through every single email.
To understand the EmailComposer better, let’s break it down into a few key concepts:
-
Creating Digest Reports: The EmailComposer gathers summaries and generates a report that provides insights like the total number of emails and action items.
-
Formatting HTML Emails: Beautifully formats the digest as an HTML email so that it looks nice and is easy to read.
-
Sending Emails: It uses SMTP (Simple Mail Transfer Protocol) to send the completed digest to your team members.
Now, let’s look at how to use the EmailComposer to create and send your email digest.
Suppose you want to send a morning digest after summarizing 5 emails collected from the previous day.
-
Input:
- Summarized Emails:
- Email 1: Action needed on Project A
- Email 2: Meeting scheduled for 3 PM
- Email 3: Update the documentation
- Email 4: Reminder to complete the form
- Email 5: Feedback required from the team
- Period: Morning
- Summarized Emails:
-
Output: A well-formatted HTML email that the recipients can open and read easily.
Here’s how to use the EmailComposer:
# Import the EmailComposer class from your project
from email_composer import EmailComposer
from models import DigestReport, EmailSummary
# Create an instance of EmailComposer with configuration
composer = EmailComposer(config)
# Sample summaries array (Here you can add real EmailSummary instances)
summaries = [
EmailSummary(sender="alice@example.com", subject="Project Update", body="Details...", priority="High"),
# Add other summaries...
]
# Create a digest report from the summaries
digest = composer.create_digest_report(summaries, period="morning")
# Send the email digest
success = composer.send_email(digest)
# Output result of email sending
print("Email sent successfully!" if success else "Failed to send email.")In this example:
- We import the
EmailComposerand the necessary models (DigestReport,EmailSummary). - We create an instance of EmailComposer, then generate a digest report using email summaries.
- Lastly, we send the digest email and check if it was sent successfully.
Let’s dive into what happens behind the scenes when you call the EmailComposer. Here’s a simple sequence diagram to illustrate the process:
sequenceDiagram
participant U as User
participant EC as EmailComposer
participant DR as Digest Report
participant SMTP as Email Server
U->>EC: Request to Create and Send Digest
EC->>DR: Compile Email Summaries
EC-->>U: Return Digest Report
EC->>SMTP: Send Digest Email
SMTP-->>U: Confirm Email Sent
In this diagram:
- You (the user) request the EmailComposer to create and send a digest.
- The EmailComposer compiles the email summaries into a digest report.
- After completing the report, it sends the email through an SMTP server.
- Finally, you receive a confirmation that the email was sent.
Let’s take a closer look at how the EmailComposer is implemented in our project. Below is a simplified version of a method that creates the digest report:
class EmailComposer:
def create_digest_report(self, summaries: List[EmailSummary], period: str) -> DigestReport:
"""Creates a digest report based on email summaries"""
high_priority_count = sum(1 for summary in summaries if summary.priority == "High")
return DigestReport(
period=period,
email_count=len(summaries),
high_priority_count=high_priority_count,
summaries=summaries
)In the create_digest_report method:
- We count how many summaries are labeled as "High" priority.
- We then generate a
DigestReportthat contains the period of the report, the count of emails, the count of high-priority emails, and the summaries themselves.
Here’s how the method for sending emails looks:
def send_email(self, digest: DigestReport) -> bool:
"""Sends the digest email to recipients"""
# Additional code to create message and send it...
try:
server.sendmail(self.config.gmail_user, self.config.team_recipients, msg.as_string())
return True
except Exception as e:
print(f"Error sending email: {str(e)}")
return FalseIn the send_email method:
- It utilizes the SMTP server to send out the formatted email.
- If the sending is successful, it returns
True; otherwise, it prints an error message and returnsFalse.
In this chapter, we learned about the EmailComposer, a crucial tool for creating and sending email digests. We explored how it compiles email summaries, formats them beautifully for readability, and sends them to your team. Now you have the knowledge to share key information effectively with others!
With this understanding, you’re ready to continue to the next exciting component of our project, the DigestReport: DigestReport.
Welcome back! In the previous chapter, we explored the EmailComposer, which beautifully assembles and sends your email digests. Now, we’re going to introduce you to the DigestReport, a crucial abstraction that helps organize and present the information from your emails clearly.
Think of the DigestReport as a report card for your emails. Imagine you have collected numerous email summaries and need a way to present this information in a digestible format. The DigestReport compiles statistics on total emails, counts of high-priority messages, and provides a structured summary of the emails received. It ensures that the recipients of the digest are well-informed without feeling overwhelmed.
Let’s consider a scenario where you receive many emails throughout the day. Every evening, you want a quick overview of what you received, focusing on the important points and urgent tasks. Using the DigestReport, you can send a well-structured report that highlights:
- The total number of emails received.
- How many of those were marked as high-priority.
- Summaries of each email for easy reference.
This allows your team to quickly catch up on what’s important without digging through every single email.
To understand how the DigestReport works, let's break down its key concepts:
-
Email Count: This refers to the total number of emails received within the specified time frame.
-
High-Priority Count: This tracks how many of those emails were marked as high priority, helping recipients focus on what requires urgent attention.
-
Summaries: These are the brief details of each email, providing a snapshot of important contents directly in the report.
Now, let’s see how the DigestReport can be used.
You have received 10 emails, out of which 3 are marked as high priority. The summaries of these emails are ready for reporting.
The generated DigestReport will contain:
- Total Emails Received: 10
- High-Priority Emails: 3
- Summarized Content of Each Email: A neat list of key points from each email.
Next, let’s look at how to create a DigestReport using it in code.
Here’s how you can create a DigestReport from the email summaries:
from models import DigestReport, EmailSummary
# Sample summaries from previous processing
summaries = [
EmailSummary(sender="alice@example.com", subject="Project Update", key_points=["Project is on track"], action_items=["Update document"], priority="High"),
EmailSummary(sender="bob@example.com", subject="Meeting Reminder", key_points=["Meeting at 3 PM"], action_items=[], priority="Medium"),
# Add more summaries...
]
# Create a DigestReport instance
digest_report = DigestReport(
period="evening",
email_count=len(summaries),
high_priority_count=len([s for s in summaries if s.priority == "High"]),
summaries=summaries
)In this code:
- We first import
DigestReportandEmailSummary. - We create a list of sample
EmailSummaryinstances that represent the processed email summaries. - We then create a
DigestReportinstance by providing the period, total email count, high-priority count, and the summaries.
Now let’s walk through the internal workings when you create a DigestReport. Here’s a simple sequence diagram to illustrate the process:
sequenceDiagram
participant U as User
participant DR as DigestReport
participant ES as EmailSummary
U->>DR: Request Digest Report
DR->>ES: Retrieve Summaries
DR-->>U: Provide Digest Report
In this diagram:
- You, the user, request to create a DigestReport.
- The DigestReport retrieves the email summaries associated with that request.
- Finally, the DigestReport is provided back to you, containing the compiled information.
Let’s look at how the DigestReport is implemented in the codebase. Here’s a simplified version of how the DigestReport model is structured:
from pydantic import BaseModel
from typing import List
from datetime import datetime
class DigestReport(BaseModel):
period: str
date: datetime = Field(default_factory=datetime.now)
email_count: int
high_priority_count: int
summaries: List[EmailSummary]In this code:
- We define
DigestReportwith attributes for the report period, count of emails, count of high-priority emails, and the list ofEmailSummaryinstances. Field(default_factory=datetime.now)automatically sets the report generation time.
In this chapter, we learned about the DigestReport, which compiles and presents email information in a clear format. By creating a digest of the total number of emails and their priority levels, your team can efficiently stay informed about important communications.
Now that you understand how to create a DigestReport, you’re ready to move on to the following chapter where we will discuss configuration settings in our application: [Config].
Welcome back! In the previous chapter, we explored the DigestReport, which helps compile and present the summaries of your emails in an organized way. Now, let's delve into a crucial aspect of our application: the Config. This is where all the magic begins!
Think of Config as the control panel for your email digest system. It holds all the critical settings that allow the application to adapt to different users and setups without changing the core code. Just like a pilot needs controls for operating an airplane, Config provides the necessary configurations to tailor the behavior of your email digest application.
Imagine you’re using the bored-email application for the first time. You want to receive email digests every morning at 7 AM and evening at 9 PM, but your email account is different from your friend’s. Instead of digging into code to change those times manually, you can adjust settings in the Config file.
Let’s break down the key concepts of the Config section to understand its structure better:
-
Email Credentials: These are your Gmail username and application-specific password. The application uses them to access your email account securely.
-
Schedule Settings: You can specify the times for fetching emails and sending digests. By default, the application might be set to check emails at specific times, but you can change this.
-
API Keys: If your app integrates with external services, like OpenAI for summarization, you’ll need API keys. The Config provides a place to keep these keys safe.
-
Limits: Sometimes, you may want to limit how many emails are included in your digest. This is especially useful if you receive a high volume of emails.
Let’s see how you can set up the Config to tailor your email digests!
Suppose you want to set your configuration for the bored-email application.
-
Input: A
.envfile with the following contents:GMAIL_USER=your_email@gmail.com GMAIL_APP_PASSWORD=your_app_password OPENAI_API_KEY=your_openai_api_key TEAM_RECIPIENTS=recipient1@example.com,recipient2@example.com MORNING_SCHEDULE=0 7 * * * EVENING_SCHEDULE=0 21 * * * MAX_EMAILS_PER_DIGEST=50 -
Output: The application now knows when to fetch emails, who to send digests to, and how to access your email account successfully!
Now let's walk through what happens when the Config is loaded. Here’s a simple representation of that process:
sequenceDiagram
participant U as User
participant C as Config
participant E as Email App
U->>C: Provide Config File
C->>E: Load Credentials and Settings
E-->>U: Application Ready with Config
In this diagram:
- You (the user) provide a config file with all the necessary settings.
- The Config class loads those settings.
- The email application is now configured and ready to go!
Let’s take a peek into how the Config is structured in the codebase. Here’s a simplified version of the Config model:
from pydantic import BaseModel
from typing import List
class Config(BaseModel):
gmail_user: str
gmail_app_password: str
openai_api_key: str
team_recipients: List[str]
morning_schedule: str = "0 7 * * *" # Default Schedule
evening_schedule: str = "0 21 * * *" # Default Schedule
max_emails_per_digest: int = 50 # Default limitIn this code:
- We define the
Configclass using Pydantic, which helps validate input and ensure everything is structured. - Each attribute corresponds to a setting we discussed earlier, with default values for ease of use.
In this chapter, we learned about the Config and how it serves as the configuration hub for the email digest application. By setting up the Config properly, you can customize your experience without diving deep into the code. This flexibility is essential for any user-friendly application!