Weeknote: bookshelf takes shape

July 25, 2025 · Weeknotes

Missed the last update as I was on summer vacation; I should have planned to start this week instead.

This week my focus has largely been on the bookshelf project. It has been tough but also rewarding to get to where I am, and I feel like I’m learning at the edge of my abilities. I far overestimated that I would be done by now, but it’s been good progress just putting in the time to learn.

I started by learning a lot about Typer and how it works as the CLI tool of choice.

I implemented a skeleton cli.py with all the commands I plan on adding so that I can see with bookshelf --help what the interface looks like. Most of the work has been creating data models for the Book and Review classes, and setting up a database.

Below is the demo of the app with the bookshelf add command in action. Inspired by libro - a command-line book tracking tool

Not sure what I’ll show in next weeks demo, but I hope to have a few more commands implemented. I’d be very happy if I can get to importing some data directly from Goodreads, which will involve working on a custom parser.

Some things I learned this week

Learning Typer at first by going through the tutorial, but found it more helpful to sketch out what I wanted and then ask an LLM for specific things as I needed them.

A review of classes in Python and using dataclasses to build the Book and Review data models. A good refresher on class methods, static methods, and using the typing module to enforce type hints. It was really nice to finally use dataclasses for a non-trivial project.

Working with SQLite, which was a highlight. One of my joys has been exploring information stored in SQLite databases e.g. book info from my ereader; bookmarks, history from web browser, messages from iMessage… This was my first time creating one myself, and it was delightful. Already thinking of mother projects to take on after. Some notes to self for the future:

with get_db_connection() as conn:
    book_dict = self.to_dict()

    # convert tags to a json string
    book_dict["tags"] = json.dumps(book_dict["tags"])

    cursor = conn.execute(
    """
    INSERT INTO books (title, author, tags)
    VALUES (?, ?, ?)""",
    tuple(book_dict.values()),
    )
    
    book_id = cursor.lastrowid
    
    conn.commit()

Other updates this week