Building a Simple Birthday App with Flask-SQLAlchemy

Posted by Bob on Thu 11 May 2017 in Flask • 3 min read

One of my favorite Flask extensions is Flask-SQLAlchemy. It makes working with a database a breeze. For some time I wanted to detach my birthday management from Facebook. So I started a simple Flask app. Work so far here.

FB birthday data

I am almost sure you could use the FB API before to pull all your friends and birthdays. Not anymore :(

Luckily I found a way to export them and parse them into a useful format - see

Starting Flask-SQLAlchemy

Back to the article subject: how do we get this data into a DB? Flask-SQLAlchemy to the rescue:

  • First I defined a simple model in

    class Birthday(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        name = db.Column(db.String(120))
        bday = db.Column(db.DateTime)
        notify = db.Column(db.Boolean)
        def __init__(self, name, bday, notify=False):
   = name
            self.bday = bday
            self.notify = notify
        def __repr__(self):
            return '<Birthday %r %r %r>' % (, self.bday, self.notify)

    It's best to store dates as db.DateTime objects so we can easily query them (see further down).

  • If is run as standalone script (not imported) it recreates the DB:


    I use the ics parsing code to populate the table with all birthdays. You can even strip out the names (which was useful to share printscreens here). I store all birthdays with the same year (calendar ics ranges May '17 - May '18), otherwise the date querying fails (next step):

    # insert birthdays sorted
    for bd in sorted(get_birthdays('cal.ics'), key=lambda x: (x.bday.month,
        # no real names
        if TEST_MODE:
            name = get_random_name()
            name =
        # import all bdays with THIS_YEAR to make it easier to query later
        bday = bd.bday.replace(year=THIS_YEAR)
        bd_obj = Birthday(name, bday)
  • The app is still very bare-bones. It has an index/home route, to get the birthdays of the next 14 days, and a route to get birthdays for each month. See Here's why you want to work with datetime objects, it makes querying dates easier:

    • Upcoming n days:

      start =
      end = start + timedelta(days=UPCOMING_DAYS)
      bdays = Birthday.query.filter(Birthday.bday <= end).filter(Birthday.bday >= start)
    • How to get all birthdays of month n (see SO). The SQLAlchemy query is the same:

      _, num_days = calendar.monthrange(THIS_YEAR, month)
      start = date(THIS_YEAR, month, 1)
      end = date(THIS_YEAR, month, num_days)
      bdays = Birthday.query.filter(Birthday.bday <= end).filter(Birthday.bday >= start)

Resulting App

bday app upcoming

bday app for a particular month

You can use the calendar module to get the month name for a month int:

month_name = calendar.month_name[month]



This is it for starters. In part 2 I will make the app more functional:

  • Implement notifications: email me one day before a birthday.

  • Allow setting of notify == True for individual friends so I only get the notifications I want.

  • Full CRUD: add/update/delete friends and/or re-import new ics download.

  • Second (relational) model for tracking:

    • add the notifications sent to this table

    • have a "done" flag to update when I sent Happy Birthday wishes to a particular friend.

    This is a nice extension to use Flask-SQLAlchemy's db.ForeignKey.


Keep Calm and Code in Python!

-- Bob

>>> next(PyBites)

Get our 'Become a Better Python Developer' cheat sheet sent straight to your inbox by signing up for our Newsletter: