How to build a daily planner using NiceGUI

6 min read

Waking up in the morning, we first check our phone or laptop to see what upcoming meetings we have and how many new emails we receive. Wouldn’t it be nice to have both in the same place? We can create a daily planner to do exactly that!

In order to build our daily planner, we will use NiceGUI, a Python-based Web-UI Framework.

Is your system ready?

Continue with the blog if you already have the Nylas Python SDK installed and your Python environment configured. Also, you can check the Nylas Quickstart Guides.

Otherwise, I recommend reading the post how to send emails with the Nylas Python SDK, where the basic setup is clearly explained.

What are we going to talk about?

  • What our NiceGUI daily planner will look like
  • Installing the required packages
  • Coding our daily planner
  • Running our NiceGUI daily planner

What our application will look like

When we run our daily planner, we will be presented with a calendar, all the events for the day, and the newest five unread emails, provided that we have new emails. We can also, of course, select any other day from the calendar.

Here is what the UI looks like:

Daily Planner with NiceGUI

Installing the required packages

Besides the Nylas and Dotenv packages, we need to install the NiceGUI package:

$ pip3 install nicegui

That’s it. Nothing too complex or complicated.

Coding our daily planner

And it’s coding time. We’re going to create a file called nicegui_planner.py:

Let’s break up the code:

Dependency Setup

# Import your dependencies
from dotenv import load_dotenv
import os
from nylas import APIClient  # type: ignore
from nicegui import ui
from datetime import date
from datetime import datetime
from dataclasses import dataclass
from typing import List

# Load your env variables
load_dotenv()

# Initialize an instance of the Nylas SDK using the client credentials
nylas = APIClient(
    os.environ.get("CLIENT_ID"),
    os.environ.get("CLIENT_SECRET"),
    os.environ.get("ACCESS_TOKEN"),
)

@dataclass # Class decorator
class EventItems:
    event_name: str

# To hold events
events: List[EventItems] = [

]

@dataclass # Class decorator
class EmailItems:
    email_name: str

# To hold emails
emails: List[EmailItems] = [

]

Nylas integration

# Get list of events
def get_events(current_date) -> None:
    # Get today's date as Year, month, day
    today_date = datetime.strptime(current_date, '%Y-%m-%d').date() 
    # Today’s date at 12:00:00 am
    AFTER = int(datetime(today_date.year, today_date.month, today_date.day, 0, 0, 0).strftime('%s'))
    # Today’s date at 11:59:59 pm 
    BEFORE = int(datetime(today_date.year, today_date.month,today_date.day, 23, 59, 59).strftime('%s'))
    # Get all events in the specified range
    events = nylas.events.where(calendar_id=os.environ.get("CALENDAR_ID"),  starts_after = AFTER, ends_before = BEFORE)
    # Auxiliary variables
    event_info = ""
    counter = 0
    # Loop events
    for event in events:
        counter += 1
        # Does the event have a start and end time?
        if "start_time" in event.when:
			# Grab from and end time, as well as the event title
            event_info = f"From:  {datetime.fromtimestamp(event.when['start_time']).strftime('%H:%M:%S')} \
                                 To: {datetime.fromtimestamp(event.when['end_time']).strftime('%H:%M:%S')} \
                                 | {event.title}"
            add(event_info, "event")
        # Does the event last all day?    
        else:
			# As an all day event, simply grab the title 
            add(f"All day event | {event.title}")
    # No events?
    if counter == 0:
        add("No events today", "event")		

# Get list of emails
def get_emails(current_date) -> None:
    # Get today's date as Year, month, day
    today_date = datetime.strptime(current_date, '%Y-%m-%d').date() 
    # Today’s date at 12:00:00 am
    AFTER = int(datetime(today_date.year, today_date.month, today_date.day, 0, 0, 0).strftime('%s'))
    # Today’s date at 11:59:59 pm 
    BEFORE = int(datetime(today_date.year, today_date.month,today_date.day, 23, 59, 59).strftime('%s'))	
    # Get all emails in the specified range
    messages = nylas.messages.where(in_ = "inbox", unread = "true", limit = 5, received_after = AFTER, received_before = BEFORE)
    # Auxiliary variables
    email_info = ""
    counter = 0
    # Loop emails    
    for message in messages:
        counter += 1
        # Grab the time, who's sending the email and the title of the email
        email_info = f"Time: {datetime.fromtimestamp(message.date).strftime('%H:%M:%S')} \
                             | From: {message.from_[0]['name']} | Title: {message.subject}"
        add(email_info, "email")
    # No emails?
    if counter == 0:
        add("No new emails today", "email")

# Function to add events and emails		
def add(name: str, type_ : str) -> None:
    # If it's an event, add it to the events list
    if type_ == "event":
        events.append(EventItems(name))
        render_events_list.refresh()
    # If it's an email, add it to the email list
    else:
        emails.append(EmailItems(name))
        render_emails_list.refresh()         

# Clear the list of events
def clear_events() -> None:
    events.clear()

# Clear the list of emails
def clear_emails() -> None:
    emails.clear()

# When we click on the calendar 
# to select a new date
def handle_input(e):
    # We pass the selected date
    current_date = e.value
    # If for some reason, there's no date
    # grab the current date
    if current_date is None:
        date.today()
        current_date = str(date.today())
    clear_events()
    # Get events for the selected date
    get_events(current_date)
    clear_emails()
    # Get emails for the selected date
    get_emails(current_date)

NiceGUI UI setup

# Decorator to refresh the events list
@ui.refreshable
def render_events_list():
    # Title using Tailwind CSS
    ui.label('Events').tailwind.font_weight('black').font_size('4xl').text_color('blue-700')
    # Loop events
    for event in events:
        # Put events one after the other
        with ui.row().classes('items-center'):
            # Detail of event
            ui.label(event.event_name).tailwind.font_weight('semibold').font_size('lg')

# Decorator to refresh the emails list            
@ui.refreshable
def render_emails_list():
    # Title using Tailwind CSS
    ui.label('Emails').tailwind.font_weight('black').font_size('4xl').text_color('blue-700')
    # Loop emails
    for email in emails:
       # Put events one after the other
        with ui.row().classes('items-center'):
            # Detail of event
            ui.label(email.email_name).tailwind.font_weight('semibold').font_size('lg')

# Main layout with everything centered
with ui.column().classes('w-full items-center'):
    # Get today's date
    today = date.today()
    current_date = str(date.today())
    # Clear all events and emails	
    clear_events()
    clear_emails()
    # Set application title
    ui.label('Daily Planner').tailwind.font_weight('black').font_size('6xl').text_color('blue-700')
    # Create the calendar widget
    ui.date(value=today, on_change=handle_input)
    # Show all events
    get_events(current_date)
    render_events_list()
    # Show all emails
    get_emails(current_date)
    render_emails_list()

# Run our application
ui.run(title = 'NiceGUI Planner')

Running our NiceGUI daily planner

In order to run our application, we just need to type the following on the terminal window:

$ python nicegui_planner.py

Our application will be running on port 8080 of localhost and on 10.0.0.161. We don’t even need to open our favourite browser, as it will be open automagically.

To learn more about our Email APIs, please go to our documentation Email API Overview.

You can sign up Nylas for free and start building!

Don’t miss the action. Join our LiveStream Coding with Nylas:

Related resources

How to build a CRM in 3 sprints with Nylas

What is a CRM? CRM stands for Customer Relationship Management, and it’s basically a way…

How to create an appointment scheduler in your React app

Learn how to create an appointment scheduler in your React app using Nylas Scheduler. Streamline bookings and UX with step-by-step guidance.

Beyond APIs: Designing elegant, smart Web Components

Dive into the world of smart Web Components for advanced API integration solutions. Design elegant, customizable elements to elevate user experiences.