Top 10 Movies
A personal movie ranking web app built with Flask and SQLAlchemy 2.0. Users search for films by title through the TMDB API, which auto-populates the poster, release year, and description. Each movie gets a personal rating and review, and rankings (1 = best) are recalculated automatically on every home-page load. The flip-card UI uses CSS 3D transforms to display the collection in a visually engaging way.
Quick Facts
Overview
Problem
Keeping track of your favourite movies usually means a notes app, a spreadsheet, or relying on an existing service — none of which let you build a fully custom ranked list with your own ratings and reviews in a web UI you control. Building something from scratch means wrestling with database setup, form handling, and third-party API integration all at once. For a Day 64 project, the real challenge is pulling those pieces together cleanly while learning SQLAlchemy's newer 2.0 ORM syntax for the first time.
Solution
I built a Flask app with five routes (home, add, select, edit, delete) backed by SQLite via SQLAlchemy 2.0's DeclarativeBase and Mapped typed column syntax. Movie metadata is fetched from the TMDB search and movie-detail endpoints — the user types a title, picks from results, and the app auto-fills the poster, year, and description. Flask-WTF handles form rendering and CSRF protection, Bootstrap-Flask provides responsive layout, and rankings are assigned dynamically on every home load by sorting the rating column and re-numbering. All secrets load from a .env file via config.py, keeping the codebase fully credential-free.
Challenges
The trickiest part was getting comfortable with SQLAlchemy 2.0's new ORM style — DeclarativeBase, Mapped, and mapped_column are a significant departure from the older db.Column pattern shown in most tutorials, and the typed syntax took some getting used to. Getting the seed logic right (only insert if the table is empty) and running it safely inside an app context also needed a few iterations. On the UI side, the CSS 3D card-flip effect requires careful layering of perspective, backface-visibility, and rotateY transforms — getting even and odd cards to flip in opposite directions without visual glitches took more experimentation than expected.
Results / Metrics
The project demonstrates end-to-end Flask development: REST API consumption, ORM-backed CRUD, form validation, and a polished CSS-animated UI — all wired together cleanly across separate modules. I came away with a solid feel for SQLAlchemy 2.0's typed ORM syntax and why it's an improvement over the older style for readability and IDE support. If I were to extend it, I'd add sort and filter controls on the home page and replace the ranking recalculation-on-every-load approach with a targeted update after each edit or delete to avoid unnecessary writes.
Screenshots
Click to enlarge.
Click to enlarge.