🎬 The Indie Cini
A data-driven planner for Chicago's independent cinemas.
Chicago is home to fantastic independent cinemas and many eager moviegoers. But these cinemas and moviegoers are often separated by a digital gulf, one largely unnoticed despite its expanse.
- Fandango and other major showtime aggregators tend not to list screenings from these venues.
- Critical reviews and aggregated scores are strewn across innumerable websites, making movie discovery needlessly difficult.
To address these gaps, The Indie Cini consolidates showtimes and film metadata from Chicago’s leading independent cinemas and enriches them with aggregated critic reviews. It currently covers the programming of the Gene Siskel Film Center, the Music Box Theatre, and FACETS.
Built on an end-to-end pipeline of scrapers, data modeling, and a tailored UI, The Indie Cini delivers an interactive calendar, a critic-score dashboard, flexible filters, and a responsive layout, all designed to simplify the discovery of Chicago's indie film culture.
🧭 Overview
The Indie Cini automates the collection, normalization, and transformation of cinema slate data from Chicago’s top independent venues, alongside film review data from a major aggregator. The result is a unified and consistently updated view of the city’s indie screening landscape.
Core outcomes include:
-
Unified dataset of all screening events across Chicago's major indie venues
-
Aggregated critic reviews powering a sortable, detail-rich dashboard
-
Interactive calendar interface, with filters that refine both the calendar and the review dashboard
-
Analytics-ready data foundation for analyzing score dynamics and theatrical longevity, with initial support for capturing user interaction events.
🏗️ Architecture
The system follows a modular, AWS-hosted architecture that separates data collection, observability, ingestion, transformation, application serving, and cloud operations into distinct layers.
Data Pipeline
High-level data pipeline architecture for The Indie Cini (click to enlarge).
The core data flow remains ETL-style: scrapers generate structured artifacts, observability checks validate them before loading, ingestion refreshes the production warehouse, and dbt models produce application-facing marts.
Production Platform
Architecture of The Indie Cini’s AWS-hosted production platform (click to enlarge).
In production, the public frontend and scheduled pipeline run as containerized workloads on ECS/Fargate, with artifacts in S3, PostgreSQL on RDS, and HTTPS traffic routed through Route 53, ACM, and an Application Load Balancer.
Layer Breakdown
-
Venue Scraping Layer (Python + Selenium + BeautifulSoup)
- Separate scrapers for Siskel, Music Box, and FACETS, with seasonal expansion support for CIFF
- Custom
RotatingDrivermanages browser restarts, stalled sessions, and JS-heavy pages ScrapeResultbundles parsed DataFrames, source HTML, and run metadata
-
Review Scraping Layer (Python + Selenium + BeautifulSoup)
- Metacritic pages identified via automated search with empirically tuned relevance ranking
- Dynamically loaded content retrieved through simulated browser interaction, including scrolling, “Load more" handling, cookie dismissal, and targeted JavaScript execution through Selenium
- Master files (
mc_<data_type>_accum) reduce redundant scraping - (Planned): Letterboxd score integration
-
Observability Layer (Python + pandas)
- Artifact inventory reports verify that each expected scrape artifact exists, loads successfully, and is fresh enough to trust
- Artifact quality reports inspect the latest artifacts for structural validity, empty datasets, duplicate identifiers, missing values, invalid runtimes or review scores, unmatched Metacritic searches, and source-specific volume anomalies
- Findings are classified by operational severity, distinguishing routine observations from warnings and pipeline-blocking issues
- The main observability runner acts as a pre-load quality gate, preserving diagnostic reports while preventing invalid scrape artifacts from reaching production tables
- Post-load database freshness reports verify core PostgreSQL tables after ingestion, checking row counts, latest scrape timestamps, and table-level freshness status
-
Ingestion Layer (Python + pandas + SQLAlchemy):
- Standardized loading routines prepare validated scrape artifacts for relational storage by normalizing column names and enforcing expected dtypes
- Loads only the latest artifacts that have passed the observability gate
- Core scrape-derived tables follow a deterministic full-refresh pattern, keeping the warehouse synchronized with the latest validated scrape
- Data is routed to either a local MySQL dev database or the production AWS RDS PostgreSQL warehouse
-
Storage Layer (AWS S3 + AWS RDS PostgreSQL)
- Unified
StorageBackendabstraction for consistent local/S3 file I/O pathing.pydefines centralized naming conventions and directory structureScrapeResultobjects serialize directly into versioned S3 archives
- Raw scrape artifacts persist in S3/local storage, while AWS RDS PostgreSQL houses the application's raw, transformed, and analytics tables
- Unified
-
Transformation Layer (dbt)
- dbt transforms raw PostgreSQL tables into layered models spanning staging, intermediate, and mart tiers:
- Staging: Standardizes venue slate and review data
- Intermediate: Constructs stable join keys, deduplicates Metacritic records, and aggregates film reviews by publication and film
- Marts: Two feature-specific marts power the frontend:
mart_show_calendarandmart_review_dashboard
- dbt tests enforce core data integrity assumptions, including null, uniqueness, and composite-key checks.
- dbt transforms raw PostgreSQL tables into layered models spanning staging, intermediate, and mart tiers:
-
Frontend (Next.js + React Big Calendar)
- Public Next.js application runs as a containerized ECS/Fargate service behind an Application Load Balancer
- Interactive calendar with daily/weekly/agenda views
- Event blocks sized by runtime and color-coded by venue
- Tooltips preview event details and link directly to booking pages
- Critic-score dashboard with sorting, hovercards, and click-to-highlight behavior
- Filter controls for venue, release type, and runtime
- Fully responsive layout, plus a desktop resizable split panel between calendar and dashboard
-
Usage Analytics (Next.js API routes + PostgreSQL)
- Lightweight frontend instrumentation captures user interaction events, including page views and outbound clicks
- Events are sent via a server-side API route and persisted to an append-only
analytics_eventstable in AWS RDS PostgreSQL - A dbt staging model (
stg_analytics_events) standardizes this data for potential downstream analysis - This layer establishes a foundation for future behavioral insights, without being a core feature of the current application
-
Cloud Deployment & Operations (AWS)
- Frontend and pipeline workloads run as separate Docker images stored in Amazon ECR and executed on ECS/Fargate
- EventBridge Scheduler launches the recurring production pipeline task, replacing the former Render cron workflow
- Route 53, ACM, and an Application Load Balancer provide public DNS, HTTPS, and canonical-domain routing for
https://indiecini.org - Secrets Manager injects runtime database and API configuration into ECS tasks without storing sensitive values in the codebase
- CloudWatch Logs and pipeline alerting provide operational visibility into scheduled runs and production services
🧩 Key Features
| Category | Feature |
|---|---|
| Data Integration | Unified cinema slate and review datasets spanning Chicago's leading independent cinemas |
| Transformation & Modeling | Layered dbt architecture (staging → intermediate → marts) with surrogate key construction, deduplication pipelines, and feature-specific data marts |
| Automation | A scheduled ECS/Fargate pipeline, launched by EventBridge Scheduler, automates daily web scraping, artifact validation, ingestion, and dbt transformation |
| Cloud Deployment | AWS-hosted production platform with separate ECS/Fargate workloads for the Next.js frontend and Python/dbt pipeline; container images in ECR; HTTPS routing through ALB/ACM/Route 53; and runtime configuration via Secrets Manager |
| Artifact Observability | Pre-load inventory and quality reports validate scrape freshness, structural integrity, dataset emptiness, identifier consistency, and source-specific anomalies; blocking findings stop ingestion before invalid artifacts reach production tables |
| Data Validation & Testing | Ingestion checks, structured logging, post-load database freshness reports, and dbt tests verify pipeline behavior, warehouse health, and modeled data integrity across the ingestion and transformation layers |
| Storage Architecture | AWS S3 stores versioned scrape artifacts, while AWS RDS PostgreSQL serves as the canonical warehouse for ingested, transformed, and analytics data; centralized storage abstractions standardize artifact I/O across local and S3 environments |
| Frontend | Interactive screening calendar and review dashboard with dynamic filtering, tooltips, and responsive layout |
| User Analytics | Lightweight tracking of user interaction events (page views, outbound clicks) via a custom API route, with events stored in PostgreSQL and standardized in dbt for potential downstream analysis |
🗂️ Data Sources
| Source | Purpose |
|---|---|
| Gene Siskel Film Center | Primary showtime data and film metadata |
| Music Box Theatre | Primary showtime data and film metadata |
| FACETS | Primary showtime data and film metadata |
| Chicago International Film Festival (CIFF) | Seasonal expansion of the above sources |
| Metacritic | Aggregated critic reviews and associated film metadata |
| Letterboxd (in development) | Audience score enrichment |
🧮 Technologies Used
| Layer | Stack |
|---|---|
| Backend & Ingestion | Python, Selenium, BeautifulSoup, pandas, SQLAlchemy |
| Storage & Warehouse | AWS S3, AWS RDS PostgreSQL |
| Transformation | dbt |
| Frontend | Next.js / React, React Big Calendar, TailwindCSS |
| Deployment & Orchestration | Docker, AWS ECS/Fargate, Amazon ECR, EventBridge Scheduler, Application Load Balancer |
| DNS, TLS & Secrets | Route 53, AWS Certificate Manager, AWS Secrets Manager |
| Logging & Observability | CloudWatch Logs, SNS/CloudWatch alerting, custom structured logger, and reporting on artifact inventory, artifact quality, and database freshness |
| Version Control | Git / GitHub (private repository) |
🧰 Development Notes
- Environment: Windows-based local development with Dockerized Linux production workloads and ChromeDriver-backed Selenium scraping
- Storage Structure:
data/andtest/directories mirror production vs. sandbox runs - Output Format: CSV and PKL scrape outputs archived under
/data/pkl/{venue or review source}/{category}/ - Observability Outputs: Timestamped inventory, quality, and database freshness reports are archived under
/data/pkl/observability/ - Containerization: Separate Docker images support the Next.js frontend service and the Python/dbt ingestion pipeline
- Cloud Runtime: Production workloads run on AWS ECS/Fargate, with runtime configuration injected through AWS Secrets Manager
- Logging: Timestamped, structured application logs are supplemented by CloudWatch logs for AWS-hosted services and scheduled pipeline runs (e.g.,
facets_scrape | +0.01s | https://facets.org/...)
📸 Showcase
Live Demo
- Direct: indiecini.org
Visual Highlights
- 📅 Main Calendar: Weekly and agenda views with color-coded venues
- 🔍 Filters Panel: Filter by release type, runtime, and venue
- 🗞️ ReviewSpew Dashboard: Sortable critic-review table with hovercards
- 🎯 Click-to-Highlight: Selecting a film or director isolates its screenings in the calendar
- 🖥️ Resizable Split-Panel Layout: Drag to adjust the space between the ReviewSpew dashboard and the calendar.
- 📱 Responsive Mobile Layout
- 🧩 Architecture Diagrams:: indiecini.org/architecture
🚀 Future Work
- Integrate Letterboxd audience review scores
- Add a scrollable film-poster ribbon beneath the ReviewSpew dashboard for quick visual browsing.
- Implement predictive models for audience–critic divergence and for the duration of a film's theatrical run.
- Expand coverage to additional Chicago-area independent venues.
- Codify the AWS infrastructure with Terraform, AWS CDK, or CloudFormation to improve repeatability and reduce configuration drift.
Frontend-specific
- Add filters for review scores, specified date ranges, and polarizing genres.
- Surface subtle features (like click-to-highlight) through small UX cues.
👤 Author
Max Ruther
M.S. Computer Science (Data Science concentration) — DePaul University
Solo developer and data engineer behind The Indie Cini.
💌 Portfolio
This repository remains private to protect proprietary logic and sensitive API configurations.
Public assets, screenshots, and diagrams are available on the case-study page.


