Skip to content
Anirudh Rao
← All work

Streamlit trip organizer with a tested data layer

Travel Planner.

A Streamlit app that turns a trip's dates into a day-by-day itinerary and keeps activities, flights, hotels, and confirmation numbers in one place, backed by a unit-tested SQLite layer.

A trip planner built for CSC 470 at the University of Illinois Springfield. It keeps everything about a trip in one place: the dates, a day-by-day itinerary, flights, and hotels, with the confirmation numbers you always end up hunting for.

The problem

Trip details scatter across email confirmations, notes, and screenshots. The goal was a simple app where a traveler creates a trip once and every day of it, plus the bookings around it, lives on a single page.

How it works

The interface is a Streamlit app. Creating a trip generates an itinerary with a section for every day between the start and end dates. Each day takes activities with a time, cost, address, and confirmation number; flights record airline, flight number, seat, and cost; hotels record address, rooms, and cost. Adding anything happens in modal dialogs, and session state handles moving between the trip list and a trip's detail view.

Persistence is SQLite, in four tables that all reference the trip they belong to. All database access lives in its own module, separate from the UI, which kept the Streamlit code focused on layout and made the data layer testable on its own.

Tested data layer

A unittest suite covers the core operations: creating a trip, fetching it by id, attaching flights and hotels, adding and reading back activities, and deleting a trip.

python · 9 lines
def test_create_trip(self):
    title = "Test Trip"
    start_date = datetime.now().date()
    end_date = start_date + timedelta(days=7)
    create_trip(title, start_date, end_date)

    trips = get_all_trips()
    self.assertEqual(len(trips), 1)
    self.assertEqual(trips[0].title, title)

What I'd change next

  • Isolate the tests. They clean and reuse the real trips.db file; pointing them at an in-memory database would make them safe to run anywhere.
  • Reuse one database connection instead of opening a new one for every query.
  • Move from st.experimental_dialog to Streamlit's stable dialog API, and show a per-trip total cost from the costs already being recorded.
esc
↑↓ to move · ↵ to selectk=16