DEV Community

API Serpent
API Serpent

Posted on

Build a Daily Reddit Trend Tracker in ~15 Lines of Python

I wanted a script that checks a handful of subreddits every morning, ranks the top posts, and drops a CSV I can diff day over day. No dashboard, no scraper, just a cron job and a JSON response. Here's the whole thing.

The request
`import os, requests

h = {"X-API-Key": os.environ["SERPENT_API_KEY"]}

# 50, not 40 — most block-billed APIs charge a started block whole,
# so round to a clean boundary (25/50/75/100 here) instead of a random number.
p = {"subreddit": "python", "sort": "top", "t": "week", "limit": 50}

data = requests.get("https://apiserpent.com/api/reddit/posts",
                    params=p, headers=h, timeout=120).json()

if "delivery" in data:
    d = data["delivery"]
    print(d["returned"], "of", d["requested"], "—", d["reason"])

for post in data["posts"]:
    print(post["score"], post["num_comments"], post["title"])`
Enter fullscreen mode Exit fullscreen mode

That's it — no HTML to parse, no headless browser, no rate-limit dance. Every field (score, num_comments, upvote_ratio, flair, is_nsfw, etc.) comes back named, and an absent value is null rather than a missing key, so you don't need defensive .get() chains everywhere.

The one gotcha worth knowing

Paginated endpoints like this one bill in blocks of 25 items. If your limit isn't a clean multiple of 25, you're paying for a full extra block for a partial one. Snap it before you send the request:

def snap_to_block(limit, block=25, cap=100):
    return min(cap, ((limit + block - 1) // block) * block)
Enter fullscreen mode Exit fullscreen mode

Turning it into a daily sweep

Wrap the same request in a loop over a subreddit list and a cron entry, and you've got a diffable daily CSV with zero infrastructure:

while IFS= read -r sub; do
  curl -s -G "https://apiserpent.com/api/reddit/posts" \
      --data-urlencode "subreddit=$sub" -d "sort=top" -d "t=day" -d "limit=25" \
      -H "X-API-Key: $SERPENT_API_KEY" \
    | jq -r --arg s "$sub" \
        '[$s, (.count|tostring), ([.posts[].score] | max | tostring),
          (.delivery.reason // "complete")] | @csv' \
    | sed "s|^|$(date -u +%F),|" >> reddit-daily.csv
done < subreddits.txt
Enter fullscreen mode Exit fullscreen mode

I'm using Serpent API's Reddit endpoint here (10 free calls to try it, no card), but the pattern — snap to block boundaries, check for a delivery/short-response field before trusting a count — applies to any block-billed API you're wiring up. Happy to answer questions on the request shape in the comments.

Top comments (0)