v2.5.0: CLI-credentials auth, scraper-core dedup, X scraper - #47

Merged
artemo-brd merged 8 commits into
mainfrom
dev
Jul 30, 2026
Merged

v2.5.0: CLI-credentials auth, scraper-core dedup, X scraper#47
artemo-brd merged 8 commits into
mainfrom
dev

Conversation

@artemo-brd

@artemo-brdartemo-brd commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Release PR: syncs main with dev, bringing in everything merged into dev since the last release (v2.4.1 on main).

Included PRs

#46 — v2.5.0: CLI-credentials auth + scraper-core dedup

Python half of the cross-SDK task "SDKs resolve credentials from the CLI store + report auth source in user-agent" (the JS half lives in sdk-js).

Before: the SDK only accepted a token via the token= parameter or the BRIGHTDATA_API_TOKEN env var — a user who had already run brightdata login still had to copy an API key by hand.

Now: with no token given, the SDK falls back to the key the CLI already saved. One login authenticates everything:

client=BrightDataClient() # zero configuration on a logged-in machine

Resolution order (first hit wins):

  1. token= parameter → auth=param
  2. BRIGHTDATA_API_TOKEN, then BRIGHTDATA_API_KEY env vars → auth=env
  3. CLI store …/brightdata-cli/credentials.json (read-only) → auth=cli_credentials
  4. Nothing found → actionable error (mentions brightdata login, the env var, and the token page)

Every request now reports how the token was obtained — making SDK onboarding measurable (feeds the sdk_auth_source Mixpanel property):

User-Agent: brightdata-sdk-python/2.5.0 (auth=cli_credentials)

Ticket checklist:

  • src/brightdata/cli_credentials.py — per-platform path (Linux / macOS / Windows %APPDATA%) + read_cli_credentials() that never raises and never writes
  • Same precedence in BrightDataClientandSyncBrightDataClient (sync delegates to async — pinned by test)
  • Read-only: never writes into brightdata-cli/, never reads config.json (pinned by test)
  • The token never appears in logs; only the source name is reported
  • README Configuration: "Already logged in with the CLI? The SDK works with no configuration."
  • Tests: every resolution path, precedence order, all 3 platform paths (mocked home / APPDATA), malformed / missing / empty credentials, and the no-credentials error — 25 new tests

Note: engines created by standalone scraper construction (e.g. AmazonScraper(bearer_token=...) without a client) keep today's behavior and omit the (auth=…) field — the ticket scopes the fallback to the client constructors; extending it there is a small follow-up.

Also included: Internal shared ScraperCore. The 7 search classes each hand-copied the base scraper's __init__ + context manager and had drifted (Amazon/ChatGPT/LinkedIn search lacked the env-token fallback). They now inherit one shared core: −174 lines, drift gone.

Tests: 321 passing (57 new). Version → 2.5.0.

Post-merge fix included in this release PR: test_raises_without_token was updated to mock read_cli_credentials(), since the new CLI fallback meant the test was not hermetic on machines with real brightdata login credentials present.


#43 — v2.4.1: X (Twitter) scraper + limit_per_input

Adds the X (Twitter) Web Scraper (client.scrape.x) — previously missing from the SDK.

  • 5 variants: posts, posts_by_profile, posts_by_profiles_array, profiles, profiles_by_username (collect-by-URL and discover), each with async/sync + trigger/status/fetch.
  • Adds limit_per_input to cap records per input (additive — other scrapers unchanged).
  • Sync parity, tests, and a notebook walkthrough.
  • Version → 2.4.1.

shahar-brdand others added 8 commits June 22, 2026 14:09
v2.4.1: X (Twitter) scraper + limit_per_input
The 7 search classes hand-copied the base's __init__ and context manager;
they now inherit a shared core. Amazon/ChatGPT/LinkedIn search gain the
standard env-token fallback. No public API or behavior removed.
…gent
Token resolution: param → env (BRIGHTDATA_API_TOKEN, BRIGHTDATA_API_KEY) →
~/.../brightdata-cli/credentials.json (read-only) → actionable error.
User-agent is now brightdata-sdk-python/<ver> (auth=param|env|cli_credentials).
Prevents a false pass/failure depending on whether the local machine
has ~/.config/brightdata-cli/credentials.json (e.g. after 'brightdata
login'). The new CLI-credentials fallback means an empty environment
no longer guarantees no token is found.
v2.5.0: CLI-credentials auth + scraper-core dedup
@artemo-brdartemo-brd changed the title Release v2.5.0: CLI-credentials auth, scraper-core dedup, X scraperv2.5.0: CLI-credentials auth, scraper-core dedup, X scraperJul 30, 2026
@artemo-brd
artemo-brd merged commit 35e8880 into mainJul 30, 2026
0 of 3 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@artemo-brd@shahar-brd@karaposu
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

v2.5.0: CLI-credentials auth, scraper-core dedup, X scraper - #47

Merged
artemo-brd merged 8 commits into
mainfrom
dev
Jul 30, 2026
Merged

v2.5.0: CLI-credentials auth, scraper-core dedup, X scraper#47
artemo-brd merged 8 commits into
mainfrom
dev

Conversation

@artemo-brd

@artemo-brdartemo-brd commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Release PR: syncs main with dev, bringing in everything merged into dev since the last release (v2.4.1 on main).

Included PRs

#46 — v2.5.0: CLI-credentials auth + scraper-core dedup

Python half of the cross-SDK task "SDKs resolve credentials from the CLI store + report auth source in user-agent" (the JS half lives in sdk-js).

Before: the SDK only accepted a token via the token= parameter or the BRIGHTDATA_API_TOKEN env var — a user who had already run brightdata login still had to copy an API key by hand.

Now: with no token given, the SDK falls back to the key the CLI already saved. One login authenticates everything:

client=BrightDataClient() # zero configuration on a logged-in machine

Resolution order (first hit wins):

  1. token= parameter → auth=param
  2. BRIGHTDATA_API_TOKEN, then BRIGHTDATA_API_KEY env vars → auth=env
  3. CLI store …/brightdata-cli/credentials.json (read-only) → auth=cli_credentials
  4. Nothing found → actionable error (mentions brightdata login, the env var, and the token page)

Every request now reports how the token was obtained — making SDK onboarding measurable (feeds the sdk_auth_source Mixpanel property):

User-Agent: brightdata-sdk-python/2.5.0 (auth=cli_credentials)

Ticket checklist:

  • src/brightdata/cli_credentials.py — per-platform path (Linux / macOS / Windows %APPDATA%) + read_cli_credentials() that never raises and never writes
  • Same precedence in BrightDataClientandSyncBrightDataClient (sync delegates to async — pinned by test)
  • Read-only: never writes into brightdata-cli/, never reads config.json (pinned by test)
  • The token never appears in logs; only the source name is reported
  • README Configuration: "Already logged in with the CLI? The SDK works with no configuration."
  • Tests: every resolution path, precedence order, all 3 platform paths (mocked home / APPDATA), malformed / missing / empty credentials, and the no-credentials error — 25 new tests

Note: engines created by standalone scraper construction (e.g. AmazonScraper(bearer_token=...) without a client) keep today's behavior and omit the (auth=…) field — the ticket scopes the fallback to the client constructors; extending it there is a small follow-up.

Also included: Internal shared ScraperCore. The 7 search classes each hand-copied the base scraper's __init__ + context manager and had drifted (Amazon/ChatGPT/LinkedIn search lacked the env-token fallback). They now inherit one shared core: −174 lines, drift gone.

Tests: 321 passing (57 new). Version → 2.5.0.

Post-merge fix included in this release PR: test_raises_without_token was updated to mock read_cli_credentials(), since the new CLI fallback meant the test was not hermetic on machines with real brightdata login credentials present.


#43 — v2.4.1: X (Twitter) scraper + limit_per_input

Adds the X (Twitter) Web Scraper (client.scrape.x) — previously missing from the SDK.

  • 5 variants: posts, posts_by_profile, posts_by_profiles_array, profiles, profiles_by_username (collect-by-URL and discover), each with async/sync + trigger/status/fetch.
  • Adds limit_per_input to cap records per input (additive — other scrapers unchanged).
  • Sync parity, tests, and a notebook walkthrough.
  • Version → 2.4.1.

shahar-brdand others added 8 commits June 22, 2026 14:09
v2.4.1: X (Twitter) scraper + limit_per_input
The 7 search classes hand-copied the base's __init__ and context manager;
they now inherit a shared core. Amazon/ChatGPT/LinkedIn search gain the
standard env-token fallback. No public API or behavior removed.
…gent
Token resolution: param → env (BRIGHTDATA_API_TOKEN, BRIGHTDATA_API_KEY) →
~/.../brightdata-cli/credentials.json (read-only) → actionable error.
User-agent is now brightdata-sdk-python/<ver> (auth=param|env|cli_credentials).
Prevents a false pass/failure depending on whether the local machine
has ~/.config/brightdata-cli/credentials.json (e.g. after 'brightdata
login'). The new CLI-credentials fallback means an empty environment
no longer guarantees no token is found.
v2.5.0: CLI-credentials auth + scraper-core dedup
@artemo-brdartemo-brd changed the title Release v2.5.0: CLI-credentials auth, scraper-core dedup, X scraperv2.5.0: CLI-credentials auth, scraper-core dedup, X scraperJul 30, 2026
@artemo-brd
artemo-brd merged commit 35e8880 into mainJul 30, 2026
0 of 3 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@artemo-brd@shahar-brd@karaposu
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

v2.5.0: CLI-credentials auth, scraper-core dedup, X scraper - #47

Merged
artemo-brd merged 8 commits into
mainfrom
dev
Jul 30, 2026
Merged

v2.5.0: CLI-credentials auth, scraper-core dedup, X scraper#47
artemo-brd merged 8 commits into
mainfrom
dev

Conversation

@artemo-brd

@artemo-brdartemo-brd commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Release PR: syncs main with dev, bringing in everything merged into dev since the last release (v2.4.1 on main).

Included PRs

#46 — v2.5.0: CLI-credentials auth + scraper-core dedup

Python half of the cross-SDK task "SDKs resolve credentials from the CLI store + report auth source in user-agent" (the JS half lives in sdk-js).

Before: the SDK only accepted a token via the token= parameter or the BRIGHTDATA_API_TOKEN env var — a user who had already run brightdata login still had to copy an API key by hand.

Now: with no token given, the SDK falls back to the key the CLI already saved. One login authenticates everything:

client=BrightDataClient() # zero configuration on a logged-in machine

Resolution order (first hit wins):

  1. token= parameter → auth=param
  2. BRIGHTDATA_API_TOKEN, then BRIGHTDATA_API_KEY env vars → auth=env
  3. CLI store …/brightdata-cli/credentials.json (read-only) → auth=cli_credentials
  4. Nothing found → actionable error (mentions brightdata login, the env var, and the token page)

Every request now reports how the token was obtained — making SDK onboarding measurable (feeds the sdk_auth_source Mixpanel property):

User-Agent: brightdata-sdk-python/2.5.0 (auth=cli_credentials)

Ticket checklist:

  • src/brightdata/cli_credentials.py — per-platform path (Linux / macOS / Windows %APPDATA%) + read_cli_credentials() that never raises and never writes
  • Same precedence in BrightDataClientandSyncBrightDataClient (sync delegates to async — pinned by test)
  • Read-only: never writes into brightdata-cli/, never reads config.json (pinned by test)
  • The token never appears in logs; only the source name is reported
  • README Configuration: "Already logged in with the CLI? The SDK works with no configuration."
  • Tests: every resolution path, precedence order, all 3 platform paths (mocked home / APPDATA), malformed / missing / empty credentials, and the no-credentials error — 25 new tests

Note: engines created by standalone scraper construction (e.g. AmazonScraper(bearer_token=...) without a client) keep today's behavior and omit the (auth=…) field — the ticket scopes the fallback to the client constructors; extending it there is a small follow-up.

Also included: Internal shared ScraperCore. The 7 search classes each hand-copied the base scraper's __init__ + context manager and had drifted (Amazon/ChatGPT/LinkedIn search lacked the env-token fallback). They now inherit one shared core: −174 lines, drift gone.

Tests: 321 passing (57 new). Version → 2.5.0.

Post-merge fix included in this release PR: test_raises_without_token was updated to mock read_cli_credentials(), since the new CLI fallback meant the test was not hermetic on machines with real brightdata login credentials present.


#43 — v2.4.1: X (Twitter) scraper + limit_per_input

Adds the X (Twitter) Web Scraper (client.scrape.x) — previously missing from the SDK.

  • 5 variants: posts, posts_by_profile, posts_by_profiles_array, profiles, profiles_by_username (collect-by-URL and discover), each with async/sync + trigger/status/fetch.
  • Adds limit_per_input to cap records per input (additive — other scrapers unchanged).
  • Sync parity, tests, and a notebook walkthrough.
  • Version → 2.4.1.

shahar-brdand others added 8 commits June 22, 2026 14:09
v2.4.1: X (Twitter) scraper + limit_per_input
The 7 search classes hand-copied the base's __init__ and context manager;
they now inherit a shared core. Amazon/ChatGPT/LinkedIn search gain the
standard env-token fallback. No public API or behavior removed.
…gent
Token resolution: param → env (BRIGHTDATA_API_TOKEN, BRIGHTDATA_API_KEY) →
~/.../brightdata-cli/credentials.json (read-only) → actionable error.
User-agent is now brightdata-sdk-python/<ver> (auth=param|env|cli_credentials).
Prevents a false pass/failure depending on whether the local machine
has ~/.config/brightdata-cli/credentials.json (e.g. after 'brightdata
login'). The new CLI-credentials fallback means an empty environment
no longer guarantees no token is found.
v2.5.0: CLI-credentials auth + scraper-core dedup
@artemo-brdartemo-brd changed the title Release v2.5.0: CLI-credentials auth, scraper-core dedup, X scraperv2.5.0: CLI-credentials auth, scraper-core dedup, X scraperJul 30, 2026
@artemo-brd
artemo-brd merged commit 35e8880 into mainJul 30, 2026
0 of 3 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@artemo-brd@shahar-brd@karaposu
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

v2.5.0: CLI-credentials auth, scraper-core dedup, X scraper - #47

Merged
artemo-brd merged 8 commits into
mainfrom
dev
Jul 30, 2026
Merged

v2.5.0: CLI-credentials auth, scraper-core dedup, X scraper#47
artemo-brd merged 8 commits into
mainfrom
dev

Conversation

@artemo-brd

@artemo-brdartemo-brd commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Release PR: syncs main with dev, bringing in everything merged into dev since the last release (v2.4.1 on main).

Included PRs

#46 — v2.5.0: CLI-credentials auth + scraper-core dedup

Python half of the cross-SDK task "SDKs resolve credentials from the CLI store + report auth source in user-agent" (the JS half lives in sdk-js).

Before: the SDK only accepted a token via the token= parameter or the BRIGHTDATA_API_TOKEN env var — a user who had already run brightdata login still had to copy an API key by hand.

Now: with no token given, the SDK falls back to the key the CLI already saved. One login authenticates everything:

client=BrightDataClient() # zero configuration on a logged-in machine

Resolution order (first hit wins):

  1. token= parameter → auth=param
  2. BRIGHTDATA_API_TOKEN, then BRIGHTDATA_API_KEY env vars → auth=env
  3. CLI store …/brightdata-cli/credentials.json (read-only) → auth=cli_credentials
  4. Nothing found → actionable error (mentions brightdata login, the env var, and the token page)

Every request now reports how the token was obtained — making SDK onboarding measurable (feeds the sdk_auth_source Mixpanel property):

User-Agent: brightdata-sdk-python/2.5.0 (auth=cli_credentials)

Ticket checklist:

  • src/brightdata/cli_credentials.py — per-platform path (Linux / macOS / Windows %APPDATA%) + read_cli_credentials() that never raises and never writes
  • Same precedence in BrightDataClientandSyncBrightDataClient (sync delegates to async — pinned by test)
  • Read-only: never writes into brightdata-cli/, never reads config.json (pinned by test)
  • The token never appears in logs; only the source name is reported
  • README Configuration: "Already logged in with the CLI? The SDK works with no configuration."
  • Tests: every resolution path, precedence order, all 3 platform paths (mocked home / APPDATA), malformed / missing / empty credentials, and the no-credentials error — 25 new tests

Note: engines created by standalone scraper construction (e.g. AmazonScraper(bearer_token=...) without a client) keep today's behavior and omit the (auth=…) field — the ticket scopes the fallback to the client constructors; extending it there is a small follow-up.

Also included: Internal shared ScraperCore. The 7 search classes each hand-copied the base scraper's __init__ + context manager and had drifted (Amazon/ChatGPT/LinkedIn search lacked the env-token fallback). They now inherit one shared core: −174 lines, drift gone.

Tests: 321 passing (57 new). Version → 2.5.0.

Post-merge fix included in this release PR: test_raises_without_token was updated to mock read_cli_credentials(), since the new CLI fallback meant the test was not hermetic on machines with real brightdata login credentials present.


#43 — v2.4.1: X (Twitter) scraper + limit_per_input

Adds the X (Twitter) Web Scraper (client.scrape.x) — previously missing from the SDK.

  • 5 variants: posts, posts_by_profile, posts_by_profiles_array, profiles, profiles_by_username (collect-by-URL and discover), each with async/sync + trigger/status/fetch.
  • Adds limit_per_input to cap records per input (additive — other scrapers unchanged).
  • Sync parity, tests, and a notebook walkthrough.
  • Version → 2.4.1.

shahar-brdand others added 8 commits June 22, 2026 14:09
v2.4.1: X (Twitter) scraper + limit_per_input
The 7 search classes hand-copied the base's __init__ and context manager;
they now inherit a shared core. Amazon/ChatGPT/LinkedIn search gain the
standard env-token fallback. No public API or behavior removed.
…gent
Token resolution: param → env (BRIGHTDATA_API_TOKEN, BRIGHTDATA_API_KEY) →
~/.../brightdata-cli/credentials.json (read-only) → actionable error.
User-agent is now brightdata-sdk-python/<ver> (auth=param|env|cli_credentials).
Prevents a false pass/failure depending on whether the local machine
has ~/.config/brightdata-cli/credentials.json (e.g. after 'brightdata
login'). The new CLI-credentials fallback means an empty environment
no longer guarantees no token is found.
v2.5.0: CLI-credentials auth + scraper-core dedup
@artemo-brdartemo-brd changed the title Release v2.5.0: CLI-credentials auth, scraper-core dedup, X scraperv2.5.0: CLI-credentials auth, scraper-core dedup, X scraperJul 30, 2026
@artemo-brd
artemo-brd merged commit 35e8880 into mainJul 30, 2026
0 of 3 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@artemo-brd@shahar-brd@karaposu
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

v2.5.0: CLI-credentials auth, scraper-core dedup, X scraper - #47

Merged
artemo-brd merged 8 commits into
mainfrom
dev
Jul 30, 2026
Merged

v2.5.0: CLI-credentials auth, scraper-core dedup, X scraper#47
artemo-brd merged 8 commits into
mainfrom
dev

Conversation

@artemo-brd

@artemo-brdartemo-brd commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Release PR: syncs main with dev, bringing in everything merged into dev since the last release (v2.4.1 on main).

Included PRs

#46 — v2.5.0: CLI-credentials auth + scraper-core dedup

Python half of the cross-SDK task "SDKs resolve credentials from the CLI store + report auth source in user-agent" (the JS half lives in sdk-js).

Before: the SDK only accepted a token via the token= parameter or the BRIGHTDATA_API_TOKEN env var — a user who had already run brightdata login still had to copy an API key by hand.

Now: with no token given, the SDK falls back to the key the CLI already saved. One login authenticates everything:

client=BrightDataClient() # zero configuration on a logged-in machine

Resolution order (first hit wins):

  1. token= parameter → auth=param
  2. BRIGHTDATA_API_TOKEN, then BRIGHTDATA_API_KEY env vars → auth=env
  3. CLI store …/brightdata-cli/credentials.json (read-only) → auth=cli_credentials
  4. Nothing found → actionable error (mentions brightdata login, the env var, and the token page)

Every request now reports how the token was obtained — making SDK onboarding measurable (feeds the sdk_auth_source Mixpanel property):

User-Agent: brightdata-sdk-python/2.5.0 (auth=cli_credentials)

Ticket checklist:

  • src/brightdata/cli_credentials.py — per-platform path (Linux / macOS / Windows %APPDATA%) + read_cli_credentials() that never raises and never writes
  • Same precedence in BrightDataClientandSyncBrightDataClient (sync delegates to async — pinned by test)
  • Read-only: never writes into brightdata-cli/, never reads config.json (pinned by test)
  • The token never appears in logs; only the source name is reported
  • README Configuration: "Already logged in with the CLI? The SDK works with no configuration."
  • Tests: every resolution path, precedence order, all 3 platform paths (mocked home / APPDATA), malformed / missing / empty credentials, and the no-credentials error — 25 new tests

Note: engines created by standalone scraper construction (e.g. AmazonScraper(bearer_token=...) without a client) keep today's behavior and omit the (auth=…) field — the ticket scopes the fallback to the client constructors; extending it there is a small follow-up.

Also included: Internal shared ScraperCore. The 7 search classes each hand-copied the base scraper's __init__ + context manager and had drifted (Amazon/ChatGPT/LinkedIn search lacked the env-token fallback). They now inherit one shared core: −174 lines, drift gone.

Tests: 321 passing (57 new). Version → 2.5.0.

Post-merge fix included in this release PR: test_raises_without_token was updated to mock read_cli_credentials(), since the new CLI fallback meant the test was not hermetic on machines with real brightdata login credentials present.


#43 — v2.4.1: X (Twitter) scraper + limit_per_input

Adds the X (Twitter) Web Scraper (client.scrape.x) — previously missing from the SDK.

  • 5 variants: posts, posts_by_profile, posts_by_profiles_array, profiles, profiles_by_username (collect-by-URL and discover), each with async/sync + trigger/status/fetch.
  • Adds limit_per_input to cap records per input (additive — other scrapers unchanged).
  • Sync parity, tests, and a notebook walkthrough.
  • Version → 2.4.1.

shahar-brdand others added 8 commits June 22, 2026 14:09
v2.4.1: X (Twitter) scraper + limit_per_input
The 7 search classes hand-copied the base's __init__ and context manager;
they now inherit a shared core. Amazon/ChatGPT/LinkedIn search gain the
standard env-token fallback. No public API or behavior removed.
…gent
Token resolution: param → env (BRIGHTDATA_API_TOKEN, BRIGHTDATA_API_KEY) →
~/.../brightdata-cli/credentials.json (read-only) → actionable error.
User-agent is now brightdata-sdk-python/<ver> (auth=param|env|cli_credentials).
Prevents a false pass/failure depending on whether the local machine
has ~/.config/brightdata-cli/credentials.json (e.g. after 'brightdata
login'). The new CLI-credentials fallback means an empty environment
no longer guarantees no token is found.
v2.5.0: CLI-credentials auth + scraper-core dedup
@artemo-brdartemo-brd changed the title Release v2.5.0: CLI-credentials auth, scraper-core dedup, X scraperv2.5.0: CLI-credentials auth, scraper-core dedup, X scraperJul 30, 2026
@artemo-brd
artemo-brd merged commit 35e8880 into mainJul 30, 2026
0 of 3 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@artemo-brd@shahar-brd@karaposu
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

v2.5.0: CLI-credentials auth, scraper-core dedup, X scraper - #47

Merged
artemo-brd merged 8 commits into
mainfrom
dev
Jul 30, 2026
Merged

v2.5.0: CLI-credentials auth, scraper-core dedup, X scraper#47
artemo-brd merged 8 commits into
mainfrom
dev

Conversation

@artemo-brd

@artemo-brdartemo-brd commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Release PR: syncs main with dev, bringing in everything merged into dev since the last release (v2.4.1 on main).

Included PRs

#46 — v2.5.0: CLI-credentials auth + scraper-core dedup

Python half of the cross-SDK task "SDKs resolve credentials from the CLI store + report auth source in user-agent" (the JS half lives in sdk-js).

Before: the SDK only accepted a token via the token= parameter or the BRIGHTDATA_API_TOKEN env var — a user who had already run brightdata login still had to copy an API key by hand.

Now: with no token given, the SDK falls back to the key the CLI already saved. One login authenticates everything:

client=BrightDataClient() # zero configuration on a logged-in machine

Resolution order (first hit wins):

  1. token= parameter → auth=param
  2. BRIGHTDATA_API_TOKEN, then BRIGHTDATA_API_KEY env vars → auth=env
  3. CLI store …/brightdata-cli/credentials.json (read-only) → auth=cli_credentials
  4. Nothing found → actionable error (mentions brightdata login, the env var, and the token page)

Every request now reports how the token was obtained — making SDK onboarding measurable (feeds the sdk_auth_source Mixpanel property):

User-Agent: brightdata-sdk-python/2.5.0 (auth=cli_credentials)

Ticket checklist:

  • src/brightdata/cli_credentials.py — per-platform path (Linux / macOS / Windows %APPDATA%) + read_cli_credentials() that never raises and never writes
  • Same precedence in BrightDataClientandSyncBrightDataClient (sync delegates to async — pinned by test)
  • Read-only: never writes into brightdata-cli/, never reads config.json (pinned by test)
  • The token never appears in logs; only the source name is reported
  • README Configuration: "Already logged in with the CLI? The SDK works with no configuration."
  • Tests: every resolution path, precedence order, all 3 platform paths (mocked home / APPDATA), malformed / missing / empty credentials, and the no-credentials error — 25 new tests

Note: engines created by standalone scraper construction (e.g. AmazonScraper(bearer_token=...) without a client) keep today's behavior and omit the (auth=…) field — the ticket scopes the fallback to the client constructors; extending it there is a small follow-up.

Also included: Internal shared ScraperCore. The 7 search classes each hand-copied the base scraper's __init__ + context manager and had drifted (Amazon/ChatGPT/LinkedIn search lacked the env-token fallback). They now inherit one shared core: −174 lines, drift gone.

Tests: 321 passing (57 new). Version → 2.5.0.

Post-merge fix included in this release PR: test_raises_without_token was updated to mock read_cli_credentials(), since the new CLI fallback meant the test was not hermetic on machines with real brightdata login credentials present.


#43 — v2.4.1: X (Twitter) scraper + limit_per_input

Adds the X (Twitter) Web Scraper (client.scrape.x) — previously missing from the SDK.

  • 5 variants: posts, posts_by_profile, posts_by_profiles_array, profiles, profiles_by_username (collect-by-URL and discover), each with async/sync + trigger/status/fetch.
  • Adds limit_per_input to cap records per input (additive — other scrapers unchanged).
  • Sync parity, tests, and a notebook walkthrough.
  • Version → 2.4.1.

shahar-brdand others added 8 commits June 22, 2026 14:09
v2.4.1: X (Twitter) scraper + limit_per_input
The 7 search classes hand-copied the base's __init__ and context manager;
they now inherit a shared core. Amazon/ChatGPT/LinkedIn search gain the
standard env-token fallback. No public API or behavior removed.
…gent
Token resolution: param → env (BRIGHTDATA_API_TOKEN, BRIGHTDATA_API_KEY) →
~/.../brightdata-cli/credentials.json (read-only) → actionable error.
User-agent is now brightdata-sdk-python/<ver> (auth=param|env|cli_credentials).
Prevents a false pass/failure depending on whether the local machine
has ~/.config/brightdata-cli/credentials.json (e.g. after 'brightdata
login'). The new CLI-credentials fallback means an empty environment
no longer guarantees no token is found.
v2.5.0: CLI-credentials auth + scraper-core dedup
@artemo-brdartemo-brd changed the title Release v2.5.0: CLI-credentials auth, scraper-core dedup, X scraperv2.5.0: CLI-credentials auth, scraper-core dedup, X scraperJul 30, 2026
@artemo-brd
artemo-brd merged commit 35e8880 into mainJul 30, 2026
0 of 3 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@artemo-brd@shahar-brd@karaposu
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

v2.5.0: CLI-credentials auth, scraper-core dedup, X scraper - #47

Merged
artemo-brd merged 8 commits into
mainfrom
dev
Jul 30, 2026
Merged

v2.5.0: CLI-credentials auth, scraper-core dedup, X scraper#47
artemo-brd merged 8 commits into
mainfrom
dev

Conversation

@artemo-brd

@artemo-brdartemo-brd commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Release PR: syncs main with dev, bringing in everything merged into dev since the last release (v2.4.1 on main).

Included PRs

#46 — v2.5.0: CLI-credentials auth + scraper-core dedup

Python half of the cross-SDK task "SDKs resolve credentials from the CLI store + report auth source in user-agent" (the JS half lives in sdk-js).

Before: the SDK only accepted a token via the token= parameter or the BRIGHTDATA_API_TOKEN env var — a user who had already run brightdata login still had to copy an API key by hand.

Now: with no token given, the SDK falls back to the key the CLI already saved. One login authenticates everything:

client=BrightDataClient() # zero configuration on a logged-in machine

Resolution order (first hit wins):

  1. token= parameter → auth=param
  2. BRIGHTDATA_API_TOKEN, then BRIGHTDATA_API_KEY env vars → auth=env
  3. CLI store …/brightdata-cli/credentials.json (read-only) → auth=cli_credentials
  4. Nothing found → actionable error (mentions brightdata login, the env var, and the token page)

Every request now reports how the token was obtained — making SDK onboarding measurable (feeds the sdk_auth_source Mixpanel property):

User-Agent: brightdata-sdk-python/2.5.0 (auth=cli_credentials)

Ticket checklist:

  • src/brightdata/cli_credentials.py — per-platform path (Linux / macOS / Windows %APPDATA%) + read_cli_credentials() that never raises and never writes
  • Same precedence in BrightDataClientandSyncBrightDataClient (sync delegates to async — pinned by test)
  • Read-only: never writes into brightdata-cli/, never reads config.json (pinned by test)
  • The token never appears in logs; only the source name is reported
  • README Configuration: "Already logged in with the CLI? The SDK works with no configuration."
  • Tests: every resolution path, precedence order, all 3 platform paths (mocked home / APPDATA), malformed / missing / empty credentials, and the no-credentials error — 25 new tests

Note: engines created by standalone scraper construction (e.g. AmazonScraper(bearer_token=...) without a client) keep today's behavior and omit the (auth=…) field — the ticket scopes the fallback to the client constructors; extending it there is a small follow-up.

Also included: Internal shared ScraperCore. The 7 search classes each hand-copied the base scraper's __init__ + context manager and had drifted (Amazon/ChatGPT/LinkedIn search lacked the env-token fallback). They now inherit one shared core: −174 lines, drift gone.

Tests: 321 passing (57 new). Version → 2.5.0.

Post-merge fix included in this release PR: test_raises_without_token was updated to mock read_cli_credentials(), since the new CLI fallback meant the test was not hermetic on machines with real brightdata login credentials present.


#43 — v2.4.1: X (Twitter) scraper + limit_per_input

Adds the X (Twitter) Web Scraper (client.scrape.x) — previously missing from the SDK.

  • 5 variants: posts, posts_by_profile, posts_by_profiles_array, profiles, profiles_by_username (collect-by-URL and discover), each with async/sync + trigger/status/fetch.
  • Adds limit_per_input to cap records per input (additive — other scrapers unchanged).
  • Sync parity, tests, and a notebook walkthrough.
  • Version → 2.4.1.

shahar-brdand others added 8 commits June 22, 2026 14:09
v2.4.1: X (Twitter) scraper + limit_per_input
The 7 search classes hand-copied the base's __init__ and context manager;
they now inherit a shared core. Amazon/ChatGPT/LinkedIn search gain the
standard env-token fallback. No public API or behavior removed.
…gent
Token resolution: param → env (BRIGHTDATA_API_TOKEN, BRIGHTDATA_API_KEY) →
~/.../brightdata-cli/credentials.json (read-only) → actionable error.
User-agent is now brightdata-sdk-python/<ver> (auth=param|env|cli_credentials).
Prevents a false pass/failure depending on whether the local machine
has ~/.config/brightdata-cli/credentials.json (e.g. after 'brightdata
login'). The new CLI-credentials fallback means an empty environment
no longer guarantees no token is found.
v2.5.0: CLI-credentials auth + scraper-core dedup
@artemo-brdartemo-brd changed the title Release v2.5.0: CLI-credentials auth, scraper-core dedup, X scraperv2.5.0: CLI-credentials auth, scraper-core dedup, X scraperJul 30, 2026
@artemo-brd
artemo-brd merged commit 35e8880 into mainJul 30, 2026
0 of 3 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@artemo-brd@shahar-brd@karaposu
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

v2.5.0: CLI-credentials auth, scraper-core dedup, X scraper - #47

Merged
artemo-brd merged 8 commits into
mainfrom
dev
Jul 30, 2026
Merged

v2.5.0: CLI-credentials auth, scraper-core dedup, X scraper#47
artemo-brd merged 8 commits into
mainfrom
dev

Conversation

@artemo-brd

@artemo-brdartemo-brd commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Release PR: syncs main with dev, bringing in everything merged into dev since the last release (v2.4.1 on main).

Included PRs

#46 — v2.5.0: CLI-credentials auth + scraper-core dedup

Python half of the cross-SDK task "SDKs resolve credentials from the CLI store + report auth source in user-agent" (the JS half lives in sdk-js).

Before: the SDK only accepted a token via the token= parameter or the BRIGHTDATA_API_TOKEN env var — a user who had already run brightdata login still had to copy an API key by hand.

Now: with no token given, the SDK falls back to the key the CLI already saved. One login authenticates everything:

client=BrightDataClient() # zero configuration on a logged-in machine

Resolution order (first hit wins):

  1. token= parameter → auth=param
  2. BRIGHTDATA_API_TOKEN, then BRIGHTDATA_API_KEY env vars → auth=env
  3. CLI store …/brightdata-cli/credentials.json (read-only) → auth=cli_credentials
  4. Nothing found → actionable error (mentions brightdata login, the env var, and the token page)

Every request now reports how the token was obtained — making SDK onboarding measurable (feeds the sdk_auth_source Mixpanel property):

User-Agent: brightdata-sdk-python/2.5.0 (auth=cli_credentials)

Ticket checklist:

  • src/brightdata/cli_credentials.py — per-platform path (Linux / macOS / Windows %APPDATA%) + read_cli_credentials() that never raises and never writes
  • Same precedence in BrightDataClientandSyncBrightDataClient (sync delegates to async — pinned by test)
  • Read-only: never writes into brightdata-cli/, never reads config.json (pinned by test)
  • The token never appears in logs; only the source name is reported
  • README Configuration: "Already logged in with the CLI? The SDK works with no configuration."
  • Tests: every resolution path, precedence order, all 3 platform paths (mocked home / APPDATA), malformed / missing / empty credentials, and the no-credentials error — 25 new tests

Note: engines created by standalone scraper construction (e.g. AmazonScraper(bearer_token=...) without a client) keep today's behavior and omit the (auth=…) field — the ticket scopes the fallback to the client constructors; extending it there is a small follow-up.

Also included: Internal shared ScraperCore. The 7 search classes each hand-copied the base scraper's __init__ + context manager and had drifted (Amazon/ChatGPT/LinkedIn search lacked the env-token fallback). They now inherit one shared core: −174 lines, drift gone.

Tests: 321 passing (57 new). Version → 2.5.0.

Post-merge fix included in this release PR: test_raises_without_token was updated to mock read_cli_credentials(), since the new CLI fallback meant the test was not hermetic on machines with real brightdata login credentials present.


#43 — v2.4.1: X (Twitter) scraper + limit_per_input

Adds the X (Twitter) Web Scraper (client.scrape.x) — previously missing from the SDK.

  • 5 variants: posts, posts_by_profile, posts_by_profiles_array, profiles, profiles_by_username (collect-by-URL and discover), each with async/sync + trigger/status/fetch.
  • Adds limit_per_input to cap records per input (additive — other scrapers unchanged).
  • Sync parity, tests, and a notebook walkthrough.
  • Version → 2.4.1.

shahar-brdand others added 8 commits June 22, 2026 14:09
v2.4.1: X (Twitter) scraper + limit_per_input
The 7 search classes hand-copied the base's __init__ and context manager;
they now inherit a shared core. Amazon/ChatGPT/LinkedIn search gain the
standard env-token fallback. No public API or behavior removed.
…gent
Token resolution: param → env (BRIGHTDATA_API_TOKEN, BRIGHTDATA_API_KEY) →
~/.../brightdata-cli/credentials.json (read-only) → actionable error.
User-agent is now brightdata-sdk-python/<ver> (auth=param|env|cli_credentials).
Prevents a false pass/failure depending on whether the local machine
has ~/.config/brightdata-cli/credentials.json (e.g. after 'brightdata
login'). The new CLI-credentials fallback means an empty environment
no longer guarantees no token is found.
v2.5.0: CLI-credentials auth + scraper-core dedup
@artemo-brdartemo-brd changed the title Release v2.5.0: CLI-credentials auth, scraper-core dedup, X scraperv2.5.0: CLI-credentials auth, scraper-core dedup, X scraperJul 30, 2026
@artemo-brd
artemo-brd merged commit 35e8880 into mainJul 30, 2026
0 of 3 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@artemo-brd@shahar-brd@karaposu