|
10 | 10 |
|
11 | 11 | import os |
12 | 12 | import asyncio |
| 13 | +import warnings |
13 | 14 | from typing import Optional, Dict, Any, Union, List |
14 | 15 | from datetime import datetime, timezone |
15 | 16 |
|
|
27 | 28 | from .api.crawler_service import CrawlerService |
28 | 29 | from .models import ScrapeResult, SearchResult |
29 | 30 | from .types import AccountInfo, URLParam, OptionalURLParam |
| 31 | +from .constants import ( |
| 32 | + HTTP_OK, |
| 33 | + HTTP_UNAUTHORIZED, |
| 34 | + HTTP_FORBIDDEN, |
| 35 | +) |
30 | 36 | from .exceptions import ( |
31 | 37 | ValidationError, |
32 | 38 | AuthenticationError, |
@@ -62,9 +68,9 @@ class BrightDataClient: |
62 | 68 |
|
63 | 69 | # Default configuration |
64 | 70 | DEFAULT_TIMEOUT = 30 |
65 | | - DEFAULT_WEB_UNLOCKER_ZONE = "sdk_unlocker" |
66 | | - DEFAULT_SERP_ZONE = "sdk_serp" |
67 | | - DEFAULT_BROWSER_ZONE = "sdk_browser" |
| 71 | + DEFAULT_WEB_UNLOCKER_ZONE = "web_unlocker1" |
| 72 | + DEFAULT_SERP_ZONE = "serp_api1" |
| 73 | + DEFAULT_BROWSER_ZONE = "browser_api1" |
68 | 74 |
|
69 | 75 | # Environment variable name for API token |
70 | 76 | TOKEN_ENV_VAR = "BRIGHTDATA_API_TOKEN" |
@@ -93,9 +99,9 @@ def __init__( |
93 | 99 | (supports .env files via python-dotenv) |
94 | 100 | customer_id: Customer ID (optional, can also be set via BRIGHTDATA_CUSTOMER_ID) |
95 | 101 | timeout: Default timeout in seconds for all requests (default: 30) |
96 | | - web_unlocker_zone: Zone name for web unlocker (default: "sdk_unlocker") |
97 | | - serp_zone: Zone name for SERP API (default: "sdk_serp") |
98 | | - browser_zone: Zone name for browser API (default: "sdk_browser") |
| 102 | + web_unlocker_zone: Zone name for web unlocker (default: "web_unlocker1") |
| 103 | + serp_zone: Zone name for SERP API (default: "serp_api1") |
| 104 | + browser_zone: Zone name for browser API (default: "browser_api1") |
99 | 105 | auto_create_zones: Automatically create zones if they don't exist (default: False) |
100 | 106 | validate_token: Validate token by testing connection on init (default: False) |
101 | 107 | rate_limit: Maximum requests per rate_period (default: 10). Set to None to disable. |
@@ -324,14 +330,14 @@ async def test_connection(self) -> bool: |
324 | 330 | async with self.engine.get_from_url( |
325 | 331 | f"{self.engine.BASE_URL}/zone/get_active_zones" |
326 | 332 | ) as response: |
327 | | - if response.status == 200: |
| 333 | + if response.status == HTTP_OK: |
328 | 334 | self._is_connected = True |
329 | 335 | return True |
330 | 336 | else: |
331 | 337 | self._is_connected = False |
332 | 338 | return False |
333 | 339 |
|
334 | | - except Exception: |
| 340 | + except (asyncio.TimeoutError, OSError, Exception): |
335 | 341 | self._is_connected = False |
336 | 342 | return False |
337 | 343 |
|
@@ -366,21 +372,34 @@ async def get_account_info(self) -> AccountInfo: |
366 | 372 | async with self.engine.get_from_url( |
367 | 373 | f"{self.engine.BASE_URL}/zone/get_active_zones" |
368 | 374 | ) as zones_response: |
369 | | - if zones_response.status == 200: |
| 375 | + if zones_response.status == HTTP_OK: |
370 | 376 | zones = await zones_response.json() |
| 377 | + zones = zones or [] |
| 378 | + |
| 379 | + # Warn user if no active zones found (they might be inactive) |
| 380 | + if not zones: |
| 381 | + warnings.warn( |
| 382 | + "No active zones found. This could mean:\n" |
| 383 | + "1. Your zones might be inactive - activate them in the Bright Data dashboard\n" |
| 384 | + "2. You might need to create zones first\n" |
| 385 | + "3. Check your dashboard at https://brightdata.com for zone status\n\n" |
| 386 | + "Note: The API only returns active zones. Inactive zones won't appear here.", |
| 387 | + UserWarning, |
| 388 | + stacklevel=2 |
| 389 | + ) |
371 | 390 |
|
372 | 391 | account_info = { |
373 | 392 | "customer_id": self.customer_id, |
374 | | - "zones": zones or [], |
375 | | - "zone_count": len(zones or []), |
| 393 | + "zones": zones, |
| 394 | + "zone_count": len(zones), |
376 | 395 | "token_valid": True, |
377 | 396 | "retrieved_at": datetime.now(timezone.utc).isoformat(), |
378 | 397 | } |
379 | 398 |
|
380 | 399 | self._account_info = account_info |
381 | 400 | return account_info |
382 | 401 |
|
383 | | - elif zones_response.status in (401, 403): |
| 402 | + elif zones_response.status in (HTTP_UNAUTHORIZED, HTTP_FORBIDDEN): |
384 | 403 | error_text = await zones_response.text() |
385 | 404 | raise AuthenticationError( |
386 | 405 | f"Invalid token (HTTP {zones_response.status}): {error_text}" |
|
0 commit comments