Flight booking system
Your hardcoded letters is easier to take from string (just in case the alphabet ever changes or to save you some typing in some future code you might write):

from string import ascii_uppercase as letters


I don't see the advantage of

class BookingClass:
    ECONOMY = 'Economy'
    BUSINESS = 'Business'
...
    self.seating_areas = {
            BookingClass.ECONOMY: economy_seats,
            BookingClass.BUSINESS: business_seats}


over

self.seating_areas = {
        "economy": economy_seats,
        "business: business_seats}


The __str__ of Seat could be slightly simplified:

def __str__(self):
    return '{0.row_number}{0.letter}'.format(self)


In the constructor of SeatingArea you don't need the intermediate variable:

    for row_number in range(start_row, row_count + start_row):
        for seat_number in range(seats_per_row):
            self.seats_remaining.append(Seat(row_number, letters[seat_number]))


Assigning the booking ID like this:

self.booking_id = random.Random().randrange(1000, 10000)


will mean a roughly a 1:9000 chance of a collision. I don't know how many customers this is supposed to deal with, but that does not seem too unrealistic for e.g. a year of running. Maybe give the Flight a name and date/time like this and use that together with the seat and hash it with md5 to get a more unique id:

from datetime import datetime
from hashlib import md5
...

class Flight:
    def __init__(self, 
                 path: str,
                 date: datetime,
                 economy_seats: SeatingArea,
                 business_seats: SeatingArea):
        ...
        self.path = path
        self.date = date

...

class Passenger:
    ...
    def book(self, flight: Flight, booking_class: str):
        ...
        id_str = "{0.path}{0.date}{1.seat}".format(flight, self)
        self.booking_id = md5(id_str.encode()).hexdigest()

...

    flight_time = datetime.strptime("2016-08-12 8:00:00 -0800" "%Y-%m-%d %H:%M:%S %z")
    flight = Flight("LAX-&gt;JFK", flight_time, economy, business)


This way every seat on every flight between two airports for every different starting time has a different id (at least the chance of collisions for md5 are a lot less than 1:9000).

In reality you would probably also have a Plane class, which has the SeatingArea's as parameters and just pass that on to Flight as the plane servicing that particular flight.