Yelp knows every place you have reviewed and every place you have checked into, and it will hand the whole list back to you if you ask. It just gives it to you as a pile of JSON. This turns that pile into two things worth keeping.
output/map.html is an interactive Leaflet map, one pin per place,
colour-coded by whether you reviewed it, checked into it, or both. Click a pin
for the business name, address, visit dates, your star rating, and a snippet of
your review. The legend doubles as a filter.
output/poster.png is a clean, shareable poster of the same data — the kind
of thing you can actually print.
Getting your data
Request the export from yelp.com/profile_privacy.
Yelp emails you a zip within a day or so. Unzip it into ./data.
Running it
pip install -r requirements.txt
python -m wib --email you@example.com
The --email is not optional in spirit. It goes into the User-Agent header
for OpenStreetMap's Nominatim geocoder, which
their usage policy asks for.
Please set it to something real.
The first run makes several hundred geocoding requests at a strict one per
second, and downloads the poster's basemap, so give it ten minutes. Everything
lands in cache/, so every run after that finishes in about a second.
Options
| Flag | What it does |
| --- | --- |
| --data-dir PATH | Unzipped Yelp export (default: data) |
| --out-dir PATH | Where the outputs land (default: output) |
| --cache-dir PATH | Geocode and basemap cache (default: cache) |
| --title TEXT | Poster and map heading |
| --overrides PATH | Manual corrections (default: overrides.json) |
| --overture | Also search Overture Maps places (needs duckdb, slower) |
| --yelp | Also search Yelp Fusion (needs an API key) |
| --yelp-key KEY | Yelp Fusion key (default: $YELP_API_KEY) |
| --offline | Use only what is cached, never hit the network |
| --no-reverse | Skip reverse geocoding — faster, popups lose street addresses |
| --retry-failed | Re-request lookups that previously found nothing |
| --skip-map | Poster only |
| --skip-poster | Map only |
When geocoding gets it wrong
It will. Business names are ambiguous, places close, and Nominatim is doing its best with a string like "Joe's". Three escape hatches, in order of effort:
overrides.json— hand-correct a specific place by name. Highest priority, always wins, survives re-runs.--overture— searches the Overture Maps places dataset via DuckDB. Much better coverage for chains and recently-closed businesses.--yelp— asks Yelp itself, scoped to the right city. Capped at 300 calls a day to stay inside the free Fusion tier.
Failed lookups are logged to unplaced.log so you can see exactly what did not
resolve rather than silently losing pins.
Why it is local-first
Your restaurant history is a detailed record of where you go and who you go with.
This runs entirely on your machine — the only outbound requests are the geocoding
lookups, and --offline turns even those off once the cache is warm. Nothing is
uploaded anywhere.