Project Overview & FastAPI + Redis Setup
Premier League Predictor: FastAPI & Redis
Chapter 1 · Project Overview & FastAPI + Redis Setup
The Shared Spec
This app tracks weekly predictions for every fixture across a real 38-gameweek Premier League season, scoring four genuinely different prediction sources against what actually happened:
- The user's own prediction — entered by hand each week
- The BBC's expert (currently Chris Sutton) — their own published scoreline pick
- The week's guest(s) — genuinely variable; some weeks have more than one guest, whose individual scores are averaged into a single "guest" figure for that fixture
- The BBC's own AI prediction — manually transcribed each week from the BBC's own published article, not scraped or generated by this app
Scoring uses the real point values confirmed directly by the user during this project's own reference implementation, back in Premier League Predictor: FastAPI & PostgreSQL's own Chapter 6: 40 points for a correct score (the exact scoreline matched) and 10 points for a correct result (the W/D/L outcome matched even if the scoreline didn't). A real league table (3/1/0 points, goal difference, won/drawn/lost) sits alongside a second, parallel prediction league table ranking how each of the four real sources is actually performing across the season. The season itself holds 20 teams across 38 gameweeks, with the bottom 3 auto-calculated for relegation and the 3 promoted teams entered by hand. The fixture-entry UI stays deliberately fast — paired click targets and 20 team buttons, not a dropdown-heavy form repeated ten times a week.
This Variant's Own Real Angle
The already-completed Premier League Predictor: FastAPI & PostgreSQL course built this exact spec as a real, ordinary relational schema — teams, fixtures, and predictions as tables, joined and aggregated with real SQL. This course asks a genuinely different question: what happens if the database underneath it is Redis instead?
Redis isn't a relational database with SQL removed — it's a fundamentally different kind of store,
built around a small set of real data structures (strings, hashes, lists, sets, and — the one this
course leans on hardest — sorted sets) rather than tables and rows. A sorted set stores members each
tagged with a real numeric score, kept continuously ordered by that score, with real
O(log n) insertion and real O(log n + m) range reads. That's not a
workaround for a league table — it's close to the data structure a league table actually is.
Real Stack Setup: FastAPI + redis-py
redis-py — installed as the plain redis package — is the real, official
Python client for Redis. Its own async support used to live in a separate package,
aioredis; that project is now archived, with its functionality merged directly into
redis-py itself as redis.asyncio, confirmed directly against Redis's own
current client documentation.
@app.on_event('startup')
hook. Checked directly against FastAPI's own current documentation, that decorator is real but
explicitly deprecated: FastAPI's own docs now recommend the lifespan async context
manager instead, and are direct about why — startup and shutdown code sharing one function and one
scope, rather than two separately registered handlers. This chapter uses the current recommended
pattern, not the one shown in even a freshly-published official tutorial — a genuine reminder that
"recently published" and "reflects the current recommendation" aren't always the same thing.
Building this app's own connection lifecycle the current way:
Run against a real, local Redis instance and confirmed with a real request:
A Real Preview of the Primitive This Course Is Built Around
Chapter 2 builds the full real data model on top of Redis's own sorted sets — this chapter closes with a small, genuine taste of the exact command shape the rest of the course leans on, so the real payoff isn't abstract:
ORDER BY, no application-side
.sort() call, and no separate query at all. This is the real, structural case for
choosing Redis for a live league table: the ordering isn't computed on read, it's maintained
continuously as members are added, exactly the property a table that updates every time a result is
entered actually wants.
Hands-On Exercises
Point this chapter's own /health endpoint at a port with no Redis instance listening at all, and run it for real. Report the exact real exception type and message you get back, and explain what the current /health endpoint's own code would actually do with it (hint: nothing catches it).
📄 View solutionReproduce this chapter's own tie-breaking warning with real code: add three teams to a sorted set with the exact same score, read them back with ZRANGE in descending order, and explain the real order you get by working out what Redis's own tie-breaking rule (ascending by member name) would produce once the whole set is reversed for a descending read.
📄 View solutionIn your own words, explain why this course frames itself as "deliberately narrower" than its own PostgreSQL sibling, rather than simply "a different but equally capable" implementation of the same spec. What real question is this course trying to honestly answer that a course confident Redis can do everything wouldn't actually be answering?
📄 View solutionChapter 1 Quick Reference
- Same spec, different store — the identical four-source prediction/scoring system already built once on PostgreSQL, now built on Redis
- redis.asyncio — the real, current async client, merged from the now-archived aioredis package
- lifespan, not on_event — the real current FastAPI pattern, diverging deliberately from even a freshly-published official Redis tutorial
- Sorted sets stay ordered on write — verified: no sort step needed on read, the real reason this course reaches for Redis at all
- An honest, upfront limitation — tied scores break by member name, not by anything meaningful; Chapter 7 builds the real fix