Skip to content

Commit 82e418c

Browse files
committed
Zone Manager and CLI fix
1 parent 129fef4 commit 82e418c

File tree

2 files changed

+57
-16
lines changed

2 files changed

+57
-16
lines changed

README.md

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,8 @@ brightdata search google \
624624
# Generic web scraping (URL is positional argument)
625625
brightdata scrape generic \
626626
"https://example.com" \
627-
--response-format pretty
627+
--response-format raw \
628+
--output-format pretty
628629
```
629630

630631
### Available Commands
@@ -643,6 +644,44 @@ brightdata scrape generic \
643644
- `brightdata search google/bing/yandex`
644645
- `brightdata search chatgpt`
645646

647+
### CLI Output Formats
648+
649+
The CLI supports two different format parameters for different purposes:
650+
651+
#### Global Output Format (`--output-format`)
652+
653+
Controls **how results are displayed** (available for ALL commands):
654+
655+
```bash
656+
# JSON format (default) - Full structured output
657+
brightdata scrape amazon products "https://amazon.com/dp/B123" --output-format json
658+
659+
# Pretty format - Human-readable with formatted output
660+
brightdata scrape amazon products "https://amazon.com/dp/B123" --output-format pretty
661+
662+
# Minimal format - Just the data, no metadata
663+
brightdata scrape amazon products "https://amazon.com/dp/B123" --output-format minimal
664+
```
665+
666+
#### Generic Scraper Response Format (`--response-format`)
667+
668+
Controls **what the API returns** (generic scraper only):
669+
670+
```bash
671+
# Raw format (default) - Returns HTML/text as-is
672+
brightdata scrape generic "https://example.com" --response-format raw
673+
674+
# JSON format - API attempts to parse as JSON
675+
brightdata scrape generic "https://api.example.com/data" --response-format json
676+
```
677+
678+
**Note:** You can combine both:
679+
```bash
680+
brightdata scrape generic "https://example.com" \
681+
--response-format raw \
682+
--output-format pretty
683+
```
684+
646685
---
647686

648687
## 🐼 Pandas Integration

tests/unit/test_zone_manager.py

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -308,13 +308,12 @@ async def test_ensure_zones_only_web_unlocker(self, mock_engine):
308308

309309
@pytest.mark.asyncio
310310
async def test_ensure_zones_with_browser(self, mock_engine):
311-
"""Test ensuring all three zone types."""
311+
"""Test ensuring unblocker and SERP zones (browser zones NOT auto-created)."""
312312
mock_engine.get.side_effect = [
313313
MockResponse(200, json_data=[]),
314314
MockResponse(200, json_data=[
315315
{"name": "sdk_unlocker"},
316-
{"name": "sdk_serp"},
317-
{"name": "sdk_browser"}
316+
{"name": "sdk_serp"}
318317
])
319318
]
320319
mock_engine.post.return_value = MockResponse(201)
@@ -323,31 +322,34 @@ async def test_ensure_zones_with_browser(self, mock_engine):
323322
await zone_manager.ensure_required_zones(
324323
web_unlocker_zone="sdk_unlocker",
325324
serp_zone="sdk_serp",
326-
browser_zone="sdk_browser"
325+
browser_zone="sdk_browser" # This is passed but NOT created (by design)
327326
)
328327

329-
# Should create all three zones
330-
assert mock_engine.post.call_count == 3
328+
# Should only create unblocker + SERP zones (browser zones require manual setup)
329+
assert mock_engine.post.call_count == 2
331330

332331
@pytest.mark.asyncio
333-
async def test_ensure_zones_verification_fails(self, mock_engine):
334-
"""Test zone creation when verification fails."""
335-
# Zones never appear in verification
332+
async def test_ensure_zones_verification_fails(self, mock_engine, caplog):
333+
"""Test zone creation when verification fails (logs warning but doesn't raise)."""
334+
# Zones never appear in verification (max_attempts = 5, so need 6 total responses)
336335
mock_engine.get.side_effect = [
337336
MockResponse(200, json_data=[]), # Initial list
338337
MockResponse(200, json_data=[]), # Verification attempt 1
339338
MockResponse(200, json_data=[]), # Verification attempt 2
340-
MockResponse(200, json_data=[]) # Verification attempt 3
339+
MockResponse(200, json_data=[]), # Verification attempt 3
340+
MockResponse(200, json_data=[]), # Verification attempt 4
341+
MockResponse(200, json_data=[]) # Verification attempt 5 (final)
341342
]
342343
mock_engine.post.return_value = MockResponse(201)
343344

344345
zone_manager = ZoneManager(mock_engine)
345-
with pytest.raises(ZoneError) as exc_info:
346-
await zone_manager.ensure_required_zones(
347-
web_unlocker_zone="sdk_unlocker"
348-
)
346+
# Verification failure should log warning but NOT raise exception
347+
await zone_manager.ensure_required_zones(
348+
web_unlocker_zone="sdk_unlocker"
349+
)
349350

350-
assert "verification failed" in str(exc_info.value).lower()
351+
# Should have logged warning about verification failure
352+
assert any("Zone verification failed" in record.message for record in caplog.records)
351353

352354

353355
class TestZoneManagerIntegration:

0 commit comments

Comments
 (0)