Matiné
Competitive intelligence for movie theaters in Mexico: it captures every showtime, price, and seat map three times a day and turns them into data a cinema chain can compare.
- Year
- 2026
- Stack
- Python, SQLite, Streamlit, FastAPI, Next.js, AWS

The goal
A cinema chain wants to know what its competitors do every day: which shows they schedule, cancel, or move, what they charge, how full their rooms get, and what they sell at the snack bar. Until now, that meant checking listings by hand.
Matiné does it automatically. It captures the full listings of the two largest cinema chains in Mexico across all 32 states, plus cinematheques in Mexico City, Guadalajara, and Monterrey, compares them show by show, and surfaces only the changes that matter.
What it captures
- Listings, three times a day (7:30, 13:30, and 20:30). Each capture is compared with the previous one to detect five kinds of change: a new show, a canceled one, a moved one, a change of language or format, and a change in occupancy.
- Attendance, by reading seat maps every hour, 15 to 75 minutes after each show starts.
- Presales, read once a day before a film opens.
- Ticket prices by cinema, format, and type of day, snack bar menus, and the prices of the same snacks on delivery apps.
- Room capacity, refreshed monthly.
Every raw response is kept, so any capture can be recalculated later.
How it's built
- One database, one writer. Everything lives in SQLite, with a single process writing at a time and daily backups. Each chain is downloaded in units that fail independently, so a failed region keeps its previous listings instead of breaking the whole capture.
- Business logic in one place. All the analysis lives in pure Python functions with no dependencies, shared by the dashboard and the public API, so nothing is written twice.
- One schedule. Every job is defined once in a registry, and from it come the server's systemd timers, the local agents on my Mac, and the health checks that know which captures to expect.
- Continuous deployment. Every push runs linting and tests against recorded real responses. When
mainpasses, CI moves astablebranch, and the server picks it up within 15 minutes. - A small server. It runs on a 2 GB AWS instance behind Caddy, with HTTPS.
Three products on the same data
The dashboard, built with Streamlit, compares the chains by city or nationwide: listings, a map, snack bar prices, independent cinemas, and a data explorer. It has its own accounts and sessions, with invitation and password-reset emails, and an operations page for admins with the live health of every capture.
Every finding is written as a decision, with the numbers that support it next to it, and the page is split into three layers: what matters today, the evidence, and the full detail.


"¿A dónde ir?" ("Where should we go?") is a public demo that answers a simple question: which shows near me fit my group's budget? You set a starting point, the group (adults, kids, and seniors), and a budget. It adds up the tickets, finds the cheapest snack combos that cover the whole group at each cinema, applies the day's promotions, and links straight to buying.



The public API, built with FastAPI, answers those searches. The demo used to download a static catalog, but that exposed every price, which is exactly the competitive data the product sells. Now the API returns only the answer to each search, with a per-IP limit and compressed responses.
The marketing site is a static Next.js site on Vercel. It never names the chains, because naming the pilot client would reveal it to its competitors.