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)