Automating market reports lets you track a portfolio of ZIP codes daily without manual effort. This tutorial builds a Python script that generates an HTML report and sends it via email.

Script Structure

#!/usr/bin/env python3 # daily_report.py - generates HTML market report for tracked ZIP codes # Schedule with cron: 0 7 * * * /usr/bin/python3 /scripts/daily_report.py import requests, smtplib, os from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from datetime import date ZIPS = ["78701", "30301", "37201", "85001"] KEY = os.environ["ZIPMARKET_KEY"] def fetch(zip_code): r = requests.get("https://zipmarketdata.com/market-stats", params={"zip_code": zip_code}, headers={"x-rapidapi-proxy-secret": KEY}, timeout=10) return r.json() rows = [fetch(z) for z in ZIPS]

HTML Report Generation

def build_html(rows): cells = "" for r in rows: color = "green" if r["yoy_price_change"] > 0 else "red" cells += ( f"<tr><td>{r['zip_code']}</td>" f"<td>${r['median_sale_price']:,}</td>" f"<td>{r['median_days_on_market']} days</td>" f"<td style='color:{color}'>{r['yoy_price_change']:+.1f}%</td>" f"<td>{r['market_temperature']}</td></tr> " ) return f"<h2>Market Report - {date.today()}</h2><table>{cells}</table>"

Sending via Email

msg = MIMEMultipart("alternative") msg["Subject"] = f"ZIP Market Report — {date.today()}" msg["From"] = os.environ["EMAIL_FROM"] msg["To"] = os.environ["EMAIL_TO"] msg.attach(MIMEText(build_html(rows), "html")) with smtplib.SMTP_SSL("smtp.gmail.com", 465) as s: s.login(os.environ["EMAIL_FROM"], os.environ["EMAIL_PASS"]) s.send_message(msg)