Adds browser helper, expands calendar sync, and documents handoff status.
EventRate
Local Python application that identifies upcoming Toronto events likely to increase Airbnb demand, sends Telegram alerts, and optionally adjusts nightly prices via Playwright automation.
Quick start
# 1. Clone and enter
git clone https://git.levkin.ca/ilia/AtAnyRate.git
cd AtAnyRate
# 2. Create a virtual environment
python3 -m venv .venv
source .venv/bin/activate
# 3. Install dependencies
pip install -r requirements.txt
playwright install chromium
# 4. Configure
cp .env.example .env
# Edit .env with your API keys (see below)
# 5. Run
python -m src.main --dry-run # preview only, no side effects
python -m src.main --alerts-only # fetch events + send Telegram
python -m src.main # full flow (alerts + Airbnb update)
Environment variables
| Variable | Required | Description |
|---|---|---|
TICKETMASTER_KEY |
Yes | Ticketmaster Discovery API key (free tier) |
SEATGEEK_CLIENT_ID |
Yes | SeatGeek API client ID (free tier) |
TELEGRAM_BOT_TOKEN |
Yes | Telegram bot token from @BotFather |
TELEGRAM_CHAT_ID |
Yes | Your Telegram chat/user ID |
AIRBNB_LISTING_ID |
No | Airbnb listing ID for calendar automation |
AIRBNB_BASE_PRICE |
No | Base nightly price (CAD) |
PRICE_INCREASE_PCT |
No | Price increase percentage for event dates (default: 20) |
LOOKAHEAD_DAYS |
No | Days ahead to scan for events (default: 30) |
LOG_LEVEL |
No | Logging level (default: INFO) |
Airbnb session setup (one-time / refresh)
Airbnb requires a logged-in browser session saved to state.json. Headless servers cannot complete 2FA — run login on a machine with a display, then copy the file to the server.
Local login (Mac)
python scripts/airbnb_login.py
Chromium opens. Log in, complete any 2FA, then press Enter in the terminal. Session cookies are saved to state.json.
Production (automationlab @ 10.0.10.45)
Recommended: login on your Mac, then copy:
scp state.json root@10.0.10.45:/opt/atanyrate/state.json
ssh root@10.0.10.45 'chmod 600 /opt/atanyrate/state.json'
Or use the ansible deploy script: ATANYRATE_STATE=~/path/to/state.json make deploy-atanyrate (see docs/guides/atanyrate-deploy.md in the ansible repo).
Session expiry
Airbnb sessions expire (weeks to months). When calendar automation fails with login/auth errors or empty calendar pages, re-run scripts/airbnb_login.py and push a fresh state.json. Weekly cron uses --alerts-only by default so Telegram alerts keep working if Airbnb auth is stale.
Stealth browser (optional)
If Airbnb blocks or challenges stock Playwright Chromium, try invisible_playwright (patched Firefox, anti-detect):
pip install 'git+https://github.com/feder-cr/invisible_playwright.git'
python -m invisible_playwright fetch # ~100 MB one-time
AIRBNB_STEALTH=1 python scripts/airbnb_login.py # login + save state.json
AIRBNB_STEALTH=1 python -m src.main # headless calendar run
Use the same engine for login and automation — state.json from Chromium does not work in Firefox and vice versa. Stealth mode does not bypass 2FA; you still log in manually in the headed window.
Running on cron
# Weekly Monday 8 AM
0 8 * * 1 cd /path/to/AtAnyRate && .venv/bin/python -m src.main --alerts-only >> /var/log/eventrate.log 2>&1
Docker
docker build -t eventrate .
docker run --rm --env-file .env -v $(pwd)/state.json:/app/state.json eventrate
Production deploy
Deployed on automationlab (10.0.10.45) at /opt/atanyrate. Full guide: ansible repo docs/guides/atanyrate-deploy.md.
# From ~/Documents/code/ansible
ATANYRATE_ENV=~/Documents/code/@AnyRate/.env make deploy-atanyrate
Project docs
- PROJECT.md — goals, scope, constraints
- ARCHITECTURE.md — system design and module map
- BACKLOG.md — feature backlog and task breakdown