Repository navigation
Meter proxy traffic per run and stop at a 10 MB budget - #14
Merged
Merged
Conversation
A run through a local proxy now counts the bytes it moves (Playwright request.sizes(), CDP encodedDataLength in pyppeteer and Selenium), 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. Playwright's --concurrency workers share one meter and all stop at the cap. 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 long paginated run could spend a proxy balance with no record anywhere except the provider's invoice. Nothing capped it either.
What changes
Only when traffic goes through a local proxy (
--proxy/--proxy-file/WELLFOUND_PROXY). Nothing changes without a proxy or over--cdp-endpoint(the 2Captcha Scraping Browser API has its own billing).proxy_meter.py), in all three engines: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.--proxy-budget-mb(default 10,0= no cap,WELLFOUND_PROXY_BUDGET_MB). Negative or non-numeric values are a usage error (exit 2). An unparseable env value stops the run rather than falling back. Once the total is over the budget:Network.setBlockedURLs ["*"].--concurrencyworkers share one meter (its add now takes a lock). The first worker to hit the cap stops dispatch for all of them.stop_reason: proxy_budget_exceeded, exit 6 with rows and exit 5 without.BaseException, so the engines' broadexcept Exceptionretry loops cannot swallow it and retry.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.--proxy-budget-mb 10:listing, throughWELLFOUND_PROXY, and the baredatacentrejob, which has no proxy and reports "not metered". After each run,.github/proxy_traffic.pyappends**listing**: proxy traffic X.X MB of 10 MBto$GITHUB_STEP_SUMMARY. When the cap was hit it prints::error::stopped: proxy budget 10 MB exceededand fails.env_config.applyfilled any falsy destination, so an explicit--proxy-budget-mb 0would have been replaced byWELLFOUND_PROXY_BUDGET_MB. A typed number is now kept. Every mapped default is None, False or "", so a number can only have come from the command line. The variable ships commented out in.env.example.pyproject.tomllistsproxy_check(missing since the savers PR) andproxy_meter.--help,.env.example, Dockerfile COPY list, CHANGELOG[Unreleased].Evidence
Offline suite, core-only venv:
python smoke_test.py→ 0 failed. The new groups cover:sizes()and CDP events (exact byte counts), plus blocked, failed and redirect cases;Engine venvs (playwright 1.64, pyppeteer, selenium; no browser download), with the opt-in real-browser check (
PROXY_METER_BROWSER=1, local Chromium): each suite → 0 failed (679 / 664 / 664 checks passed). Each engine:--concurrency 2past the budget on page 1: exit 6, and the workers stop at their first navigation.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, and
check()stopped the run.Planted-fault controls. Each went red on the named check and was green again after restoring:
ProxyMeter.addcounts nothing): "1 MB budget: exactly 1,000,000 bytes…" and the following checks;proxy_meter.checkno-op): "proxy_meter.check(args) stops a run that is over budget";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