Skip to content

Commit 5d45957

Browse files
author
stlc-bot
committed
feat(web): add raw bytes scraping endpoint (#1081)
Stainless-Generated-From: 8c17db7388df4327e1396492725dcd8847491418
1 parent 8f226f8 commit 5d45957

4 files changed

Lines changed: 103 additions & 1 deletion

File tree

‎.stats.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
configured_endpoints: 48
1+
configured_endpoints: 49

‎pkg/cmd/cmd.go‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ func init() {
105105
&webScreenshot,
106106
&webSearch,
107107
&webWebCrawlMd,
108+
&webWebScrapeBytes,
108109
&webWebScrapeHTML,
109110
&webWebScrapeImages,
110111
&webWebScrapeMd,

‎pkg/cmd/web.go‎

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,48 @@ var webWebCrawlMd = requestflag.WithInnerFlags(cli.Command{
647647
},
648648
})
649649

650+
var webWebScrapeBytes = cli.Command{
651+
Name: "web-scrape-bytes",
652+
Usage: "Downloads a resource and returns its bytes as base64. Supports images, PDFs,\nHTML pages, and any other content type without image conversion, text\nextraction, or character-encoding changes. HTTP compression is decoded before\nbase64 encoding. HTML is the original HTTP response; JavaScript is not rendered.\nFollows public redirects and retries failed downloads through ISP and\nresidential proxies, with a direct fallback. When country is specified, only a\nresidential proxy in that country is used. Supply headers such as Referer for\nimages that require a referring page. Downloads are not cached. Maximum decoded\nresource size: 20 MiB (20971520 bytes), before base64 encoding. Successful\nrequests cost 1 credit; errors are not billed.",
653+
Suggest: true,
654+
Flags: []cli.Flag{
655+
&requestflag.Flag[string]{
656+
Name: "url",
657+
Usage: "Full HTTP(S) URL of the resource to download, such as an image, PDF, or page.",
658+
Required: true,
659+
QueryPath: "url",
660+
},
661+
&requestflag.Flag[string]{
662+
Name: "country",
663+
Usage: "Fetch the target page through a residential proxy in this country (ISO 3166-1 alpha-2).",
664+
QueryPath: "country",
665+
},
666+
&requestflag.Flag[map[string]any]{
667+
Name: "headers",
668+
Usage: "Optional outbound HTTP headers, such as Referer, Cookie, or Authorization. Send as a JSON object or deep-object query params such as headers[Referer]=https://example.com/. Host, Content-Length, and hop-by-hop transport headers are rejected. Authorization and cookies are removed when a redirect changes origin.",
669+
QueryPath: "headers",
670+
},
671+
&requestflag.Flag[[]string]{
672+
Name: "tag",
673+
Usage: "Comma-separated tags for tracking request usage. Up to 20 tags, each 1-50 characters.",
674+
QueryPath: "tags",
675+
},
676+
&requestflag.Flag[int64]{
677+
Name: "timeout-ms",
678+
Usage: "Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).",
679+
QueryPath: "timeoutMS",
680+
},
681+
&requestflag.Flag[string]{
682+
Name: "zdr",
683+
Usage: "Set to enabled to bypass shared caches and omit request and response content from retained usage logs. Requires zero data retention to be enabled for your organization (contact support@context.dev), otherwise the request fails with ZDR_NOT_ENABLED. Successful ZDR responses include X-Context-ZDR: true.",
684+
Default: "disabled",
685+
QueryPath: "zdr",
686+
},
687+
},
688+
Action: handleWebWebScrapeBytes,
689+
HideHelpCommand: true,
690+
}
691+
650692
var webWebScrapeHTML = requestflag.WithInnerFlags(cli.Command{
651693
Name: "web-scrape-html",
652694
Usage: "Scrapes the given URL and returns the raw HTML content of the page. The base\nrequest costs 1 credit; requests with browser actions cost 2 credits.",
@@ -1374,6 +1416,47 @@ func handleWebWebCrawlMd(ctx context.Context, cmd *cli.Command) error {
13741416
})
13751417
}
13761418

1419+
func handleWebWebScrapeBytes(ctx context.Context, cmd *cli.Command) error {
1420+
client := contextdev.NewClient(getDefaultRequestOptions(cmd)...)
1421+
unusedArgs := cmd.Args().Slice()
1422+
1423+
if len(unusedArgs) > 0 {
1424+
return fmt.Errorf("Unexpected extra arguments: %v", unusedArgs)
1425+
}
1426+
1427+
options, err := flagOptions(
1428+
cmd,
1429+
apiquery.NestedQueryFormatBrackets,
1430+
apiquery.ArrayQueryFormatComma,
1431+
EmptyBody,
1432+
false,
1433+
)
1434+
if err != nil {
1435+
return err
1436+
}
1437+
1438+
params := contextdev.WebWebScrapeBytesParams{}
1439+
1440+
var res []byte
1441+
options = append(options, option.WithResponseBodyInto(&res))
1442+
_, err = client.Web.WebScrapeBytes(ctx, params, options...)
1443+
if err != nil {
1444+
return err
1445+
}
1446+
1447+
obj := gjson.ParseBytes(res)
1448+
format := cmd.Root().String("format")
1449+
explicitFormat := cmd.Root().IsSet("format")
1450+
transform := cmd.Root().String("transform")
1451+
return ShowJSON(obj, ShowJSONOpts{
1452+
ExplicitFormat: explicitFormat,
1453+
Format: format,
1454+
RawOutput: cmd.Root().Bool("raw-output"),
1455+
Title: "web web-scrape-bytes",
1456+
Transform: transform,
1457+
})
1458+
}
1459+
13771460
func handleWebWebScrapeHTML(ctx context.Context, cmd *cli.Command) error {
13781461
client := contextdev.NewClient(getDefaultRequestOptions(cmd)...)
13791462
unusedArgs := cmd.Args().Slice()

‎pkg/cmd/web_test.go‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,24 @@ func TestWebWebCrawlMd(t *testing.T) {
448448
})
449449
}
450450

451+
func TestWebWebScrapeBytes(t *testing.T) {
452+
t.Skip("Mock server tests are disabled")
453+
t.Run("regular flags", func(t *testing.T) {
454+
mocktest.TestRunMockTestWithFlags(
455+
t,
456+
"--api-key", "string",
457+
"web", "web-scrape-bytes",
458+
"--url", "https://example.com",
459+
"--country", "de",
460+
"--headers", "{foo: J!}",
461+
"--tag", "production",
462+
"--tag", "team-alpha",
463+
"--timeout-ms", "1",
464+
"--zdr", "enabled",
465+
)
466+
})
467+
}
468+
451469
func TestWebWebScrapeHTML(t *testing.T) {
452470
t.Skip("Mock server tests are disabled")
453471
t.Run("regular flags", func(t *testing.T) {

0 commit comments

Comments
 (0)