Skip to main content

birddog

PyPI

demo

Audited Bright Data egress for AI agents. Drop one context manager around an agent that scrapes the web and you get:

  1. Domain allowlist — deny everything outside it, log the attempt
  2. Per-domain rate caps — simple token bucket per host
  3. Response audit log — one JSONL line per fetch (url, status, bytes, ms)
  4. Bright Data Web Unlocker proxy — opt-in: route via Bright Data
  5. Streamlit dashboard — point it at the JSONL, get per-host bytes, denial counts, latency p50

Built for the kind of agent that hits live sites: research bots, price trackers, RAG ingest jobs. If you've ever watched an agent rip through a sponsor's free tier in 30 seconds, this is for you.

Install

pip install birddog                    # core
pip install "birddog[dashboard]"       # + Streamlit dashboard

Python 3.10+.

Why

LLM agents don't know what a sane scraping cadence looks like. They'll hammer a site, ignore robots.txt, follow links into spammy subdomains, and burn through a Bright Data quota in a single run.

birddog puts a leash on the egress side:

Concern What birddog does
Wandering off-domain Allowlist with example.com + *.example.com
Burst scraping Token bucket per host (qps + burst)
"What did it fetch?" JSONL audit log, one event per fetch
Anti-bot blocks Optional Bright Data Web Unlocker proxy
Post-run review Bundled Streamlit dashboard

It does not parse HTML, manage cookies, render JS, or rotate user agents. That's what Bright Data + your scraping code are for.

Usage

from birddog import Birddog

bd = Birddog(
    allowed_domains={"docs.brightdata.com", "*.example.com"},
    per_domain_qps=1.0,
    per_domain_burst=2.0,
    audit_path="runs/scrape.jsonl",
    # Optional — route through Bright Data Web Unlocker:
    bright_data={
        "host": "brd.superproxy.io:33335",
        "username": "brd-customer-...-zone-web_unlocker",
        "password": "...",
    },
)

with bd.session("research-bot") as s:
    r = s.fetch("https://docs.brightdata.com/api")
    print(r.status, r.bytes_len, "bytes")

    # second hit within 1s -> RateLimitedError (qps cap = 1)
    s.fetch("https://docs.brightdata.com/pricing")

    # off-allowlist -> DomainDeniedError, also logged
    s.fetch("https://evil.example/exfil")

FetchResult carries url, status, text, headers, elapsed_ms, and a via_brightdata flag so downstream code can tell whether the response came through the proxy.

Audit log

One JSON object per line, e.g.:

{"ts":1747779600.12,"session_id":"research-bot","kind":"fetch_ok",
 "url":"https://docs.brightdata.com/api","host":"docs.brightdata.com",
 "status":200,"bytes":4221,"elapsed_ms":312.4}
{"ts":1747779600.45,"session_id":"research-bot","kind":"domain_denied",
 "url":"https://evil.example/exfil","host":"evil.example",
 "error":"host 'evil.example' not in allowlist"}

Kinds: session_open, fetch_ok, fetch_failed, domain_denied, rate_limited, session_close.

Dashboard

pip install "birddog[dashboard]"
streamlit run -m birddog.dashboard -- --audit runs/scrape.jsonl

Shows total fetches, denials, bytes, and a per-host breakdown of fetches + bytes + p50 latency.

Demos

Two runnable examples in examples/:

1. Smoke test — scrape_demo.py

python examples/scrape_demo.py

Hits each feature once: happy path, domain denial, rate-limit burst, summary. Offline via httpx.MockTransport.

2. Realistic agent — watchdog_agent.py

python examples/watchdog_agent.py

A small price-tracker agent. Polls a watchlist of product pages, extracts prices, alerts when something moves more than a per-product threshold. Three passes show:

  • allowlist denials (off-domain mirror URL is dropped)
  • per-domain rate cap kicking in on pass 3
  • threshold alerts (Δ -6.4% > 3.0%)
  • a runs/watchdog.jsonl audit log you can dashboard

Set BIRDDOG_USE_BRIGHTDATA=1 + your Bright Data Web Unlocker env vars to flip the demo to a real proxy.

Companion libraries

birddog is the egress half of a small agent-stack:

  • agentleash — USD/call budget cap + tool-arg schema gate
  • agentvet — tool-arg validation with LLM-friendly retry hints
  • agentsnap — snapshot tests for agent traces
  • agenttrace — cost + latency aggregation per run

Pair birddog with agentleash and you have egress allowlist + budget cap on the same agent.

License

MIT

Metadata

Release files for birddog 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for birddog 0.2.0
File Size Uploaded Provenance
birddog-0.2.0.tar.gz 95.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for birddog 0.2.0
File Interpreter ABI Platform
birddog-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 108.2 kB

Release files / birddog-0.2.0.tar.gz

Download URL birddog-0.2.0.tar.gz
Size 95.7 kB
Tags Source
SHA-256 checksum
How to use checksums
63dba4335ee1b2eaaaaa8039b64f6e322e3414f19d35ab2678638fd2c51c9b37
BLAKE2b-256 checksum
How to use checksums
c5b7c53cd00eabe95746098bac37cf906cdb9785b1bea6fbb2ae9fa9b044016c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.4

Release files / birddog-0.2.0-py3-none-any.whl

Download URL birddog-0.2.0-py3-none-any.whl
Size 12.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e140d6e53c839571070d31b5ce5aba053aa18cefbb9dffc4d457f82f4796b630
BLAKE2b-256 checksum
How to use checksums
804310232792349bdc747276e6508a55d7b60b8d9ea74ddc4c78b9509a9bca48
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.4

Security for birddog 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page