Repository navigation
Meter proxy traffic per run and stop at a 10 MB budget - #11
Merged
Merged
Conversation
A run through a local proxy now counts the bytes it moves (Playwright request.sizes(), CDP encodedDataLength in pyppeteer and Selenium, every response hop in http_scraper.py), stops once --proxy-budget-mb (default 10, 0 = no cap) is exceeded with stop_reason proxy_budget_exceeded (exit 6 with rows, 5 without), and records proxy_bytes / proxy_budget_bytes / proxy_budget_exceeded in <out>.meta.json and <out>.latest_attempt.meta.json. --concurrency workers share the budget. The canary passes the budget explicitly, reports each run's traffic in the step summary and fails when the cap was hit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CKsd7q25N19WzUZjrAdzx8
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A residential proxy is billed by the byte, and a run had no idea how many bytes it had used. A slow page, a retry loop or a multi-page listing could spend a proxy balance with no record anywhere except the provider's invoice. Nothing capped it either. This site needs a residential exit for every live run, so this is every live run.
What changes
Only when traffic goes through a local proxy (
--proxy/--proxy-file/SLEEPNUMBER_PROXY). Nothing changes without a proxy or over--cdp-endpoint(the 2Captcha Scraping Browser API has its own billing).proxy_meter.py), in every entry point:request.sizes()(request headers + body, response headers + body) onrequestfinished/requestfailed.Network.loadingFinished.encodedDataLength(bytes received, headers included) plus each request's line, headers and body fromNetwork.requestWillBeSent, on a CDP session of its own. Requests the browser blocked itself (media blocking) cost nothing.http_scraper.py: each response's status line, headers and body (itsContent-Length, i.e. the compressed size, when sent) plus the request line, headers and body, for every redirect hop.--proxy-budget-mb(default 10,0= no cap,SLEEPNUMBER_PROXY_BUDGET_MBinENV_KEYSand.env.example). Negative or non-numeric values are a usage error (exit 2). Once the total is over the budget:Network.setBlockedURLs ["*"].stop_reason: proxy_budget_exceeded, exit 6 with rows and exit 5 without.BaseException, so the broadexcept Exceptionretry loops cannot swallow it and retry.--concurrency(Playwright,--mode transfers), the workers share one meter. Each stops at its next page, catches the stop itself instead of dying with a traceback, and the queued pages are reported unattempted.proxy_bytes,proxy_budget_bytes(nullwith no cap) andproxy_budget_exceededgo in<out>.meta.json. Every metered run also writes<out>.latest_attempt.meta.json, so a run that wrote no rows still records what it spent. Without a proxy no such file is written, as before. The log ends withProxy traffic: X.X MB of Y MB budget.http_scraper.pyrun) pass--proxy-budget-mb 10. A new step runs.github/proxy_traffic.pyfor each, appending**live/<category>**: proxy traffic X.X MB of 10 MB(or "not metered" / "unknown") to$GITHUB_STEP_SUMMARY. When any run hit the cap it prints::error::stopped: proxy budget 10 MB exceededand fails.--helpof every entry point,.env.example, Dockerfile COPY list, CHANGELOG[Unreleased].pyproject.tomlpy-modulesgainsproxy_meterand alsoproxy_check, which every engine imports and the list was missing.Evidence
Offline suite, core-only venv:
python smoke_test.py→ 163/163. It covers:sizes()and CDP events (exact byte counts), plus blocked, failed and redirect cases;http_scraper.pythrough a byte-counting stub proxy: metered 30,517 B against 30,793 B carried, 0.9% drift, which includes the uncounted pre-check;proxy_budget_exceeded, exactly one page request;Engine venvs (playwright 1.64, pyppeteer, selenium; no browser download), with the opt-in real-browser check (
PROXY_METER_BROWSER=1, local Chromium): 180/180, 179/179 and 179/179. Each engine:Two
--concurrencyworkers stop once the shared budget is spent: page 2 fetched, pages 3–7 unattempted, no traceback.Real browser, through a local stub proxy that counted every byte it carried (60 kB page + 30 kB CSS + 90 kB JS):
Past a 0.15 MB budget, a request the page made never reached the proxy.
Planted-fault controls. Each went red on the named check and was green again after restoring:
proxy_meter.checkno-op;http_scraper.py, Playwright, pyppeteer and Selenium (each red on its own "over budget, the page fetch stops before …");http_scraper.pynot counting responses;.github/ci_checks.py --secret-check --help-check --sample-check: ok.python env_config.py: ok.No proxy, no paid call and no canary dispatch was used.
Not changed
--cdp-endpoint.🤖 Generated with Claude Code
https://claude.ai/code/session_01CKsd7q25N19WzUZjrAdzx8