Creating Filterable FastAPI Endpoints for Civilizations and Events

Day 79 of 100 Days Coding Challenge: Python

For weeks now, I’ve been averaging two to three hours a day on this project—me, my laptop, and an endless parade of poetry commands. Today, however, I blinked, stretched, and realized my task was finished in just forty-five minutes. A miracle! Granted, I’m still fumbling with Poetry like it’s an unfamiliar dance partner, but at least I’ve learned that typing poetry run uvicorn app.main:api –reload is far superior to the old python something.py shuffle. Progress tastes sweet.

The mission of the day was to spin up read-only endpoints: /civs and /events, complete with filters for region, time period, and tags. My only real hiccup? Yesterday I had to reinstall Python 3.11, and AI didn’t quite catch that curveball. Starting a new session gave me déjà vu instructions—like being told twice to tie my shoes. So I stuck with yesterday’s session, which kept the advice on-track. Next, I’ll try this from a clean project folder to see if consistency still holds. Spoiler: consistency matters a lot more than I thought.

Today’s Motivation / Challenge

History is a mess of overlapping civilizations, wars, and inventions—but wouldn’t it be nice if you could filter it the way you filter Netflix shows? “Only East Asia, 200 BCE to 200 CE, with extra tags for technology, please.” That’s the vibe. Today’s endpoints turn a chaotic jumble into a menu you can actually navigate.

Purpose of the Code (Object)

The code opens up two doors into our database: one for civilizations, one for events. Instead of drowning you in everything at once, it politely asks, “Want to see just one region? Or only certain centuries? How about filtering by tags?” It’s a smarter way to explore history without scrolling through endless lists.

AI Prompt

Add the following functions:
Endpoints: /civs, /events, filters: region, year_range, tags.

Accept: Swagger lists routes; basic filters return sane counts.

Functions & Features

  • /civs: lists civilizations, filtered by region and year range.
  • /events: lists events, filtered by year, region, or tag.
  • Case-insensitive partial matches (so “Asia” catches “East Asia” and “South Asia”).
  • Bonus: endpoints /meta/tags and /meta/regions to preview valid options.

Requirements / Setup

You’ll need:

  • Python 3.11

A few installs:

pip install fastapi uvicorn sqlmodel

Minimal Code Sample

@api.get(“/civs”)

def list_civs(region: Optional[str] = None, start: int = -3000, end: int = 2000):

    data = session.query(Civilization).filter(

        Civilization.start_year <= end,

        Civilization.end_year >= start

    )

    if region:

        data = data.filter(Civilization.region.ilike(f”%{region}%”))

    return data.all()

This is the heart of the idea: query the database, filter by dates and region, then return the results.

The Civilization Timeline Builder

Notes / Lessons Learned

My biggest revelation today: don’t hop between sessions if you value your sanity. Switching can mean duplicated instructions, skipped steps, and missing files—a recipe for confusion.

Another surprise was Swagger’s stubbornness. Typing “Asia” for the region gave me nothing. Turns out the actual values were “East Asia” and “South Asia.” The fix? Using ilike(“%Asia%”), which basically lets the database play “guess what I meant.”

Finally, adding /meta/tags and /meta/regions was a lifesaver. Think of it as a cheat sheet so I don’t embarrass myself with typos.

Optional Ideas for Expansion

  • Add fuzzy matching so “Han” still finds “Han Dynasty.”
  • Return friendly error messages if someone types “Atlantis.”

Leave a Reply

Your email address will not be published. Required fields are marked *