diff --git a/README.md b/README.md index 9550c8e..3275531 100644 --- a/README.md +++ b/README.md @@ -189,7 +189,7 @@ asyncio.run(main()) ### Extract -[Extract](https://docs.zenrows.com) (beta) runs a page through Zenrows' AI-powered structured extraction instead of returning raw HTML. Use `client.extract()` — it's the same request as `fetch()`, with the `extract` param set for you (defaults to `"auto"`; pass `"native"` or `"standard"` for the other contracts). +[Extract](https://docs.zenrows.com/extract/introduction) (beta) runs a page through Zenrows' AI-powered structured extraction instead of returning raw HTML. Use `client.extract()` — it's the same request as `fetch()`, with the `extract` param set for you (defaults to `"auto"`; pass `"native"` or `"standard"` for the other contracts). ```python from zenrows import ZenRowsClient diff --git a/pyproject.toml b/pyproject.toml index b33978e..5b9273f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,13 +5,13 @@ build-backend = "hatchling.build" [project] name = "zenrows" version = "1.6.0" -description = "ZenRows Python SDK — synchronous scraping + Batch (async job) API" +description = "Zenrows Python SDK: Fetch, Extract (structured data), Batch and Crawl APIs" readme = "README.md" license = { text = "MIT" } authors = [ { name = "ZenRows", email = "support@zenrows.com" }, ] -keywords = ["zenrows", "scraper", "scraping", "async", "batch"] +keywords = ["zenrows", "scraper", "scraping", "web-scraping", "extract", "structured-data", "async", "batch", "crawl"] classifiers = [ "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", diff --git a/src/zenrows/client.py b/src/zenrows/client.py index e9db1b8..e4b3d07 100644 --- a/src/zenrows/client.py +++ b/src/zenrows/client.py @@ -125,11 +125,14 @@ def extract( or "standard". Thin wrapper over `fetch()` with the `extract` param set — no separate endpoint or auth. - `mode="auto"` is a domain-gated open beta: when the target domain isn't - enabled yet, the API returns a 402 with `code: "AUTH010"`. By default - this retries once with `autoparse=True` instead of returning the error - response — pass `fallback_to_autoparse=False` to disable that and get - the raw AUTH010 response back. + Extract works on any domain once Zenrows has prepared it, with any + active API key. A domain that isn't prepared yet answers 403 with + `code: "REQS007"`, returned as is; prepare it with + `POST /v1/extract/prepared-domains`. If the API answers with + `code: "AUTH010"` (domain not enabled), this retries once with + `autoparse=True` instead of returning the error response — pass + `fallback_to_autoparse=False` to disable that and get the raw AUTH010 + response back. `adaptive_stealth=True` (default) also sends Adaptive Stealth Mode (`mode: "auto"` at the wire-param level - unrelated to this method's own diff --git a/tests/test_fetch_extract.py b/tests/test_fetch_extract.py index 4ea18ac..32102d2 100644 --- a/tests/test_fetch_extract.py +++ b/tests/test_fetch_extract.py @@ -125,8 +125,8 @@ def test_extract_does_not_mutate_caller_supplied_params_dict(self, mock_request) class TestExtractAutoparseFallback(TestCase): - """`extract(mode="auto")` is a domain-gated open beta: AUTH010 means the - target domain isn't enabled yet. By default this retries once with + """`extract(mode="auto")`: AUTH010 means the target domain isn't enabled + for Extract. By default this retries once with Autoparse instead of raising - same behavior as the CLI's extract adapter.""" @@ -173,7 +173,7 @@ def test_402_without_auth010_does_not_fall_back(self, mock_request): @mock.patch.object(Session, "request") def test_no_fallback_for_non_auto_mode(self, mock_request): """AUTH010 shouldn't trigger a fallback for native/standard modes - - only "auto" is the domain-gated beta path.""" + only "auto" takes the fallback path.""" mock_request.return_value = _fake_response(402, b'{"code": "AUTH010"}') response = self.client.extract(url, mode="native")