This repository is an independent, provider-specific GitHub traffic client.
Its httpx transport, GitHub auth/version headers, pagination, rate-limit
behavior, and exception mapping remain local because they encode GitHub API
policy. The reusable package stays database-free; the optional
scripts/sync_local.py host owns SQLite persistence and scheduling. See
docs/FLEET_CONSOLIDATION.md for the audited
boundary and rollback contract.
A small client for GitHub's traffic API (views, clones, referrers, popular content paths) - with no database layer, no session persistence, and no web-framework assumptions.
pip install capsize-github-trafficGitHub only retains 14 days of traffic history per repo, with no way to see anything older through the UI or API. If you want to know how a repo's traffic trended over the last year, you have to have been recording it yourself the whole time - this package is exactly that recording step, not a replacement for GitHub's own dashboard.
GitHub's traffic endpoints require push access to the repo, not
just read access - a token that can view a repo fine may still be
rejected for its traffic stats specifically. A personal access token
(classic, repo scope) or gh auth token from an already-logged-in
gh CLI both work.
from capsize_github_traffic import GitHubTrafficClient
client = GitHubTrafficClient(token)
repos = client.list_repos("Capsize-Games", "org") # or "user"
for repo in repos:
views = client.get_views(repo.owner, repo.name)
clones = client.get_clones(repo.owner, repo.name)
referrers = client.get_referrers(repo.owner, repo.name)
paths = client.get_paths(repo.owner, repo.name)get_views/get_clones return a 14-day daily series. get_referrers/
get_paths are rolling 14-day totals - GitHub doesn't offer a daily
breakdown for those, which is why the local mirror below stores them
as dated snapshots instead of a true daily series.
GitHubTrafficClient's methods raise:
GitHubTrafficAuthError- the token was rejected, or lacks push access to that specific repo.GitHubTrafficAPIError- any other failure (network, rate limit, 404, ...).
Both subclass GitHubTrafficError.
A standalone script - deliberately outside the
capsize_github_traffic package itself, which stays database-free by
design (see above) - that archives traffic stats for every public,
non-fork repo under a configurable set of owners into a local SQLite
database. Safe to run daily indefinitely: daily_views/daily_clones
are upserted by (owner, repo, date), so re-running never duplicates
a day; referrer_snapshots/path_snapshots get one new row per
(owner, repo, day) since GitHub only ever returns a rolling total
for those.
export GITHUB_TRAFFIC_OWNERS="octocat:user,my-org:org" # required, comma-separated "name:user"/"name:org" pairs
export GITHUB_TRAFFIC_DB=/path/to/traffic.db # optional, defaults to a per-user XDG data directory
python scripts/sync_local.pyNo GITHUB_TOKEN needed if gh auth token already works in the
environment the script runs in - it falls back to that automatically.
0 6 * * * /path/to/.venv/bin/python /path/to/capsize-github-traffic/scripts/sync_local.py >> /path/to/sync.log 2>&1A repo the token doesn't have push access to is logged and skipped, not fatal to the whole run - the exit code is non-zero if any repo failed, so a monitoring/alerting setup can still notice, without one inaccessible repo blocking every other repo's sync that day.