Indy Explorer helps you navigate resorts in the Indy Pass with ease — filter by region, blackout dates, reservation requirements, and more.
This repo is structured as a monorepo undergoing a rewrite from Streamlit to React + FastAPI:
/
├── backend/ # FastAPI app (in progress)
├── frontend/ # Vite + React app (in progress)
├── pipeline/ # Data pipeline (scraping, geocoding, merging)
│ ├── pipeline.py # Pipeline orchestrator
│ ├── page_scraper.py
│ ├── blackout.py
│ ├── reservations.py
│ ├── prep_resort_data.py
│ └── utils.py (+ others)
├── app.py # Legacy Streamlit app (live during transition)
├── data/ # Committed CSV data consumed by the app
└── tests/ # Test suite
The Streamlit app at app.py remains live on Streamlit Community Cloud during the transition. The pipeline in pipeline/ feeds data/resorts.csv, which is committed to the repo and read at startup by both the Streamlit app and (eventually) the FastAPI backend.
- Resort Data Extraction: Scrapes resort pages from indyskipass.com with BeautifulSoup.
- Location Normalization: Google Maps Geocoding API normalizes city, state, and country.
- Blackout Date Filtering: Filter by blackout dates for both standard Indy Pass and Learn To Turn (LTT).
- LTT Pass Support: Filter for resorts in the Learn To Turn program with their own blackout calendar.
- Peak Rankings Integration: Resort quality scores from peakrankings.com.
- Interactive Map: Pydeck/Mapbox map with filterable table (Streamlit); deck.gl (React, in progress).
| Source | What it provides |
|---|---|
| indyskipass.com | Resort details, stats, coordinates, blackout dates, reservation requirements |
| Indy Pass LTT Google Sheet | Learn To Turn participating resorts and blackout dates |
| peakrankings.com | Resort quality scores and rankings |
| Google Maps Geocoding API | Normalized city, state, and country |
-
Clone the repo and install dependencies:
git clone https://github.com/jonathanstelman/indy-explorer.git cd indy-explorer pipx install poetry && poetry install
-
Add your Mapbox token to
.streamlit/secrets.toml:MAPBOX_TOKEN = "your_mapbox_token_here"
-
Run the Streamlit app:
poetry run streamlit run app.py
The app ships with pre-built data in data/resorts.csv — no pipeline run needed.
The pipeline orchestrator handles scraping, geocoding, blackout dates, rankings, and merging.
cp -r cache/ backups/cache_backup_$(date +%Y%m%d_%H%M%S)
cp -r data/ backups/data_backup_$(date +%Y%m%d_%H%M%S)# Incremental refresh (uses cached HTML, fetches new resorts only)
poetry run python pipeline/pipeline.py
# Full refresh (re-scrape all pages, regenerate geocoded locations)
poetry run python pipeline/pipeline.py --full
# Run specific steps only
poetry run python pipeline/pipeline.py --steps fetch_peak_rankings,prepAvailable pipeline steps (run in order):
| Step | Description |
|---|---|
scrape_resorts |
Scrape Indy Pass resort pages |
scrape_reservations |
Scrape reservation requirements |
fetch_blackout_dates |
Fetch blackout dates from Google Sheets |
fetch_ltt_dates |
Fetch LTT blackout dates from Google Sheets |
fetch_peak_rankings |
Fetch Peak Rankings from Google Sheets |
geocode |
Geocode resort locations via Google Maps |
prep |
Merge all data into data/resorts.csv |
| Variable | Location | Required for |
|---|---|---|
MAPBOX_TOKEN |
.streamlit/secrets.toml |
Map rendering in Streamlit |
GOOGLE_MAPS_API_KEY |
.env |
Geocoding (only when regenerating data/resort_locations.csv) |
poetry run pytest # run the full test suite
poetry run black --check . # check formatting
poetry run black . # fix formattingGitHub Actions runs tests and Black checks on push/PRs. Coverage is optionally uploaded to Codecov.
The React frontend is hosted on Vercel and the FastAPI backend on Fly.io.
Vercel deploys automatically on push to main via GitHub integration.
- Install the Vercel CLI:
npm install -g vercel - Link the project:
cd frontend && vercel link - Set the Mapbox token as an environment variable in the Vercel dashboard:
- Key:
VITE_MAPBOX_TOKEN - Value: your Mapbox token
- Environment: Production (and Preview if desired)
- Key:
- Deploy manually if needed:
vercel --prod
- Install the Fly CLI:
brew install flyctl - Authenticate:
flyctl auth login - Create the app (first time only):
cd backend && flyctl launch --no-deploy - Set secrets:
flyctl secrets set GOOGLE_MAPS_API_KEY=your_key_here - Deploy:
flyctl deploy - Check health:
curl https://indy-explorer-backend.fly.dev/health
Subsequent deploys run automatically on push to main via the CI/CD pipeline (to be configured in a later issue).
- Fork the repository.
- Create a new branch (
git checkout -b feature/my-change). - Make your changes and run tests.
- Open a Pull Request.
GNU General Public License v3.0. See LICENSE for details.
Made by Jonathan Stelman