Skip to content

Commit e1761c5

Browse files
author
stlc-bot
committed
fix(scrape): preserve successful formats when other outputs fail (#1263)
Stainless-Generated-From: b3de6c4
1 parent a76377d commit e1761c5

3 files changed

Lines changed: 105 additions & 45 deletions

File tree

‎src/context/dev/resources/web.py‎

Lines changed: 48 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -418,14 +418,20 @@ def scrape(
418418
extraction. Cached outputs can come from different visits within maxAgeMs; use 0
419419
for a fresh capture. HTML-only requests use the existing fast acquisition path.
420420
Highlights return the plain-text passages most relevant to
421-
highlightsParams.query. One credit per request, including cache hits and missing
422-
pages, or two with browser actions; highlights add 3 credits when passages are
423-
returned; JSON extraction adds four credits and runs an LLM over the page
424-
Markdown on every request that has text to extract; PDF OCR adds one credit per
425-
recovered page on fresh extraction; the product output adds one credit, plus six
426-
more when the specialized model is used. Original response bytes and screenshots
427-
are limited to 20 MiB each, screenshots to 40 megapixels, and the combined
428-
browser capture to 60 MiB.
421+
highlightsParams.query. Requests with at least one successful output cost one
422+
base credit, including cache hits, or two with browser actions. All-failed
423+
responses are unbilled except missing pages, which retain the base price and the
424+
one-credit product charge when product was requested. Highlights add 3 credits
425+
when passages are returned. JSON extraction runs an LLM over nonempty page
426+
Markdown and adds four credits only when its result is returned successfully.
427+
PDF OCR adds one credit per recovered page on fresh extraction. Product adds one
428+
credit when its successful result is returned, plus six if that result used the
429+
specialized model. Original response bytes and screenshots are limited to 20 MiB
430+
each, screenshots to 40 megapixels, and the combined response to 60 MiB. An
431+
oversized output has success: false and data: null. If the combined response
432+
exceeds its limit, the largest outputs are marked failed until the remaining
433+
outputs fit. Valid captured pieces may still be cached when omitted to meet the
434+
response size limit.
429435
430436
Args:
431437
formats: Outputs to return. Enable at least one; omitted formats are false.
@@ -457,12 +463,16 @@ def scrape(
457463
tags: Labels for tracking request usage. Not retained when zdr is enabled.
458464
459465
timeout_opts: Total deadline, including navigation, actions, waiting, and all outputs.
460-
Defaults to 60000 milliseconds with behavior fail. Use return-partial to capture
461-
the current page state and return captured images if image processing cannot
462-
finish before the deadline; these responses set isPartial and are not cached.
463-
Every requested format must still be available. Fixed waits must fit before a
464-
response reserve of up to 5000 milliseconds (at most one quarter of the timeout)
465-
when using return-partial.
466+
Defaults to 60000 milliseconds with behavior fail. Individual outputs have
467+
internal deadlines that reserve time to return completed outputs; timed-out
468+
outputs have success: false and data: null under either behavior. The overall
469+
request deadline remains enforced: fail returns an error if that deadline is
470+
reached. Use return-partial to allow the current page state and available
471+
outputs when the page is still loading. Partial responses set isPartial. Failed
472+
retrievals and incomplete captures are not cached; valid captured pieces may be
473+
cached independently. Fixed waits must fit before a response reserve of up to
474+
5000 milliseconds (at most one quarter of the timeout) when using
475+
return-partial.
466476
467477
zdr: Zero data retention. Bypasses caches and uploads; excludes request/response
468478
content and tags from logs. Must be enabled for your organization.
@@ -1913,14 +1923,20 @@ async def scrape(
19131923
extraction. Cached outputs can come from different visits within maxAgeMs; use 0
19141924
for a fresh capture. HTML-only requests use the existing fast acquisition path.
19151925
Highlights return the plain-text passages most relevant to
1916-
highlightsParams.query. One credit per request, including cache hits and missing
1917-
pages, or two with browser actions; highlights add 3 credits when passages are
1918-
returned; JSON extraction adds four credits and runs an LLM over the page
1919-
Markdown on every request that has text to extract; PDF OCR adds one credit per
1920-
recovered page on fresh extraction; the product output adds one credit, plus six
1921-
more when the specialized model is used. Original response bytes and screenshots
1922-
are limited to 20 MiB each, screenshots to 40 megapixels, and the combined
1923-
browser capture to 60 MiB.
1926+
highlightsParams.query. Requests with at least one successful output cost one
1927+
base credit, including cache hits, or two with browser actions. All-failed
1928+
responses are unbilled except missing pages, which retain the base price and the
1929+
one-credit product charge when product was requested. Highlights add 3 credits
1930+
when passages are returned. JSON extraction runs an LLM over nonempty page
1931+
Markdown and adds four credits only when its result is returned successfully.
1932+
PDF OCR adds one credit per recovered page on fresh extraction. Product adds one
1933+
credit when its successful result is returned, plus six if that result used the
1934+
specialized model. Original response bytes and screenshots are limited to 20 MiB
1935+
each, screenshots to 40 megapixels, and the combined response to 60 MiB. An
1936+
oversized output has success: false and data: null. If the combined response
1937+
exceeds its limit, the largest outputs are marked failed until the remaining
1938+
outputs fit. Valid captured pieces may still be cached when omitted to meet the
1939+
response size limit.
19241940
19251941
Args:
19261942
formats: Outputs to return. Enable at least one; omitted formats are false.
@@ -1952,12 +1968,16 @@ async def scrape(
19521968
tags: Labels for tracking request usage. Not retained when zdr is enabled.
19531969
19541970
timeout_opts: Total deadline, including navigation, actions, waiting, and all outputs.
1955-
Defaults to 60000 milliseconds with behavior fail. Use return-partial to capture
1956-
the current page state and return captured images if image processing cannot
1957-
finish before the deadline; these responses set isPartial and are not cached.
1958-
Every requested format must still be available. Fixed waits must fit before a
1959-
response reserve of up to 5000 milliseconds (at most one quarter of the timeout)
1960-
when using return-partial.
1971+
Defaults to 60000 milliseconds with behavior fail. Individual outputs have
1972+
internal deadlines that reserve time to return completed outputs; timed-out
1973+
outputs have success: false and data: null under either behavior. The overall
1974+
request deadline remains enforced: fail returns an error if that deadline is
1975+
reached. Use return-partial to allow the current page state and available
1976+
outputs when the page is still loading. Partial responses set isPartial. Failed
1977+
retrievals and incomplete captures are not cached; valid captured pieces may be
1978+
cached independently. Fixed waits must fit before a response reserve of up to
1979+
5000 milliseconds (at most one quarter of the timeout) when using
1980+
return-partial.
19611981
19621982
zdr: Zero data retention. Bypasses caches and uploads; excludes request/response
19631983
content and tags from logs. Must be enabled for your organization.

‎src/context/dev/types/web_scrape_params.py‎

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,16 @@ class WebScrapeParams(TypedDict, total=False):
8484
timeout_opts: Annotated[TimeoutOpts, PropertyInfo(alias="timeoutOpts")]
8585
"""Total deadline, including navigation, actions, waiting, and all outputs.
8686
87-
Defaults to 60000 milliseconds with behavior fail. Use return-partial to capture
88-
the current page state and return captured images if image processing cannot
89-
finish before the deadline; these responses set isPartial and are not cached.
90-
Every requested format must still be available. Fixed waits must fit before a
91-
response reserve of up to 5000 milliseconds (at most one quarter of the timeout)
92-
when using return-partial.
87+
Defaults to 60000 milliseconds with behavior fail. Individual outputs have
88+
internal deadlines that reserve time to return completed outputs; timed-out
89+
outputs have success: false and data: null under either behavior. The overall
90+
request deadline remains enforced: fail returns an error if that deadline is
91+
reached. Use return-partial to allow the current page state and available
92+
outputs when the page is still loading. Partial responses set isPartial. Failed
93+
retrievals and incomplete captures are not cached; valid captured pieces may be
94+
cached independently. Fixed waits must fit before a response reserve of up to
95+
5000 milliseconds (at most one quarter of the timeout) when using
96+
return-partial.
9397
"""
9498

9599
zdr: Literal["enabled", "disabled"]
@@ -109,7 +113,7 @@ class Formats(TypedDict, total=False):
109113
highlights: bool
110114
"""
111115
Relevant passages for your question or topic, with headings included when needed
112-
for context. Adds 3 credits.
116+
for context. Adds 3 credits when passages are returned.
113117
"""
114118

115119
html: bool
@@ -119,7 +123,10 @@ class Formats(TypedDict, total=False):
119123
"""Images found on the page."""
120124

121125
json: bool
122-
"""Page data extracted using your schema. Adds 4 credits."""
126+
"""Page data extracted using your schema.
127+
128+
Adds 4 credits when extraction succeeds and its result is returned.
129+
"""
123130

124131
markdown: bool
125132
"""Page content as Markdown."""
@@ -128,7 +135,11 @@ class Formats(TypedDict, total=False):
128135
"""Fields selected by parseParams.rules."""
129136

130137
product: bool
131-
"""Product details such as name, price, and availability. Adds 1 credit."""
138+
"""Product details such as name, price, and availability.
139+
140+
Adds 1 credit when its successful result is returned or the target page is
141+
missing.
142+
"""
132143

133144
screenshot: bool
134145
"""An inline image of the page."""
@@ -216,9 +227,10 @@ class ProductParams(TypedDict, total=False):
216227
use_ai_fallback: Annotated[bool, PropertyInfo(alias="useAIFallback")]
217228
"""
218229
Extract the product with a specialized model when the page has no structured
219-
product data. Adds six credits when the model returns a verdict. If the fallback
220-
fails, returns a partial response with the deterministic result and no fallback
221-
charge. Request deadlines and client disconnects still apply.
230+
product data. Adds six credits when the model verdict is returned successfully.
231+
If the fallback fails, the product output has success: false and data: null with
232+
no fallback charge; other outputs remain available. Request deadlines and client
233+
disconnects still apply.
222234
"""
223235

224236

@@ -387,7 +399,7 @@ class SharedParams(TypedDict, total=False):
387399
class TimeoutOpts(TypedDict, total=False):
388400
"""Total deadline, including navigation, actions, waiting, and all outputs.
389401
390-
Defaults to 60000 milliseconds with behavior fail. Use return-partial to capture the current page state and return captured images if image processing cannot finish before the deadline; these responses set isPartial and are not cached. Every requested format must still be available. Fixed waits must fit before a response reserve of up to 5000 milliseconds (at most one quarter of the timeout) when using return-partial.
402+
Defaults to 60000 milliseconds with behavior fail. Individual outputs have internal deadlines that reserve time to return completed outputs; timed-out outputs have success: false and data: null under either behavior. The overall request deadline remains enforced: fail returns an error if that deadline is reached. Use return-partial to allow the current page state and available outputs when the page is still loading. Partial responses set isPartial. Failed retrievals and incomplete captures are not cached; valid captured pieces may be cached independently. Fixed waits must fit before a response reserve of up to 5000 milliseconds (at most one quarter of the timeout) when using return-partial.
391403
"""
392404

393405
milliseconds: Required[int]

‎src/context/dev/types/web_scrape_response.py‎

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ class Bytes(BaseModel):
5151

5252
requested: bool
5353

54+
success: Optional[bool] = None
55+
"""True when retrieved, false when retrieval failed, and null when not requested."""
56+
5457

5558
class CacheMetadata(BaseModel):
5659
"""Cache outcome for this response.
@@ -78,6 +81,9 @@ class Highlights(BaseModel):
7881

7982
requested: bool
8083

84+
success: Optional[bool] = None
85+
"""True when retrieved, false when retrieval failed, and null when not requested."""
86+
8187

8288
class HTML(BaseModel):
8389
"""Rendered HTML after content filters."""
@@ -86,6 +92,9 @@ class HTML(BaseModel):
8692

8793
requested: bool
8894

95+
success: Optional[bool] = None
96+
"""True when retrieved, false when retrieval failed, and null when not requested."""
97+
8998

9099
class ImagesData(BaseModel):
91100
alt: Optional[str] = None
@@ -116,6 +125,9 @@ class Images(BaseModel):
116125

117126
requested: bool
118127

128+
success: Optional[bool] = None
129+
"""True when retrieved, false when retrieval failed, and null when not requested."""
130+
119131

120132
class Json(BaseModel):
121133
"""Page data extracted using your schema."""
@@ -124,6 +136,9 @@ class Json(BaseModel):
124136

125137
requested: bool
126138

139+
success: Optional[bool] = None
140+
"""True when retrieved, false when retrieval failed, and null when not requested."""
141+
127142

128143
class Markdown(BaseModel):
129144
"""Markdown after content filters."""
@@ -132,6 +147,9 @@ class Markdown(BaseModel):
132147

133148
requested: bool
134149

150+
success: Optional[bool] = None
151+
"""True when retrieved, false when retrieval failed, and null when not requested."""
152+
135153

136154
class MetadataAlternate(BaseModel):
137155
href: str
@@ -223,6 +241,9 @@ class Parsed(BaseModel):
223241

224242
requested: bool
225243

244+
success: Optional[bool] = None
245+
"""True when retrieved, false when retrieval failed, and null when not requested."""
246+
226247

227248
class ProductDataProductVariant(BaseModel):
228249
attributes: Dict[str, str]
@@ -315,6 +336,9 @@ class Product(BaseModel):
315336

316337
requested: bool
317338

339+
success: Optional[bool] = None
340+
"""True when retrieved, false when retrieval failed, and null when not requested."""
341+
318342

319343
class Screenshot(BaseModel):
320344
"""An image data URL. Use directly as an image src."""
@@ -323,6 +347,9 @@ class Screenshot(BaseModel):
323347

324348
requested: bool
325349

350+
success: Optional[bool] = None
351+
"""True when retrieved, false when retrieval failed, and null when not requested."""
352+
326353

327354
class KeyMetadata(BaseModel):
328355
"""Credit usage, included whenever a valid API key is provided."""
@@ -390,10 +417,11 @@ class WebScrapeResponse(BaseModel):
390417

391418
is_partial: Optional[Literal[True]] = FieldInfo(alias="isPartial", default=None)
392419
"""
393-
Present when return-partial captures a page that is still loading, returns
394-
images before image processing finishes, or cuts product AI extraction short.
395-
Also present if the optional product AI fallback fails. Partial responses are
396-
not cached.
420+
Present when a requested output fails, capture returns a page that is still
421+
loading, images return before processing finishes, or the optional product AI
422+
fallback fails or is cut short. Check each output's success field for its
423+
result. Valid captured pieces may be cached independently; failed retrievals and
424+
incomplete captures are not cached.
397425
"""
398426

399427
key_metadata: Optional[KeyMetadata] = None

0 commit comments

Comments
 (0)