Skip to content

jonathanstelman/indy-explorer

Repository files navigation

Indy Explorer

Indy Explorer helps you navigate resorts in the Indy Pass with ease — filter by region, blackout dates, reservation requirements, and more.

Architecture

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.

Features

  • 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).

Data Sources

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

Quick Start (Streamlit)

  1. Clone the repo and install dependencies:

    git clone https://github.com/jonathanstelman/indy-explorer.git
    cd indy-explorer
    pipx install poetry && poetry install
  2. Add your Mapbox token to .streamlit/secrets.toml:

    MAPBOX_TOKEN = "your_mapbox_token_here"
  3. 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.

Refreshing Resort Data

The pipeline orchestrator handles scraping, geocoding, blackout dates, rankings, and merging.

Before refreshing: back up existing data

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,prep

Available 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

Environment Variables

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)

Testing & CI

poetry run pytest            # run the full test suite
poetry run black --check .   # check formatting
poetry run black .           # fix formatting

GitHub Actions runs tests and Black checks on push/PRs. Coverage is optionally uploaded to Codecov.

Deployment

The React frontend is hosted on Vercel and the FastAPI backend on Fly.io.

Frontend (Vercel)

Vercel deploys automatically on push to main via GitHub integration.

  1. Install the Vercel CLI: npm install -g vercel
  2. Link the project: cd frontend && vercel link
  3. 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)
  4. Deploy manually if needed: vercel --prod

Backend (Fly.io)

  1. Install the Fly CLI: brew install flyctl
  2. Authenticate: flyctl auth login
  3. Create the app (first time only): cd backend && flyctl launch --no-deploy
  4. Set secrets:
    flyctl secrets set GOOGLE_MAPS_API_KEY=your_key_here
  5. Deploy: flyctl deploy
  6. 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).

Contributing

  1. Fork the repository.
  2. Create a new branch (git checkout -b feature/my-change).
  3. Make your changes and run tests.
  4. Open a Pull Request.

License

GNU General Public License v3.0. See LICENSE for details.

Acknowledgements


Made by Jonathan Stelman

About

indy-explorer - a Streamlit app designed to help explore Indy Pass resorts

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors