Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.15.0"
".": "0.16.0"
}
4 changes: 2 additions & 2 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 22
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-4a46f38182c87694de28ad72b2ebb873d3004533dbe8db3276637d6d80cf9a33.yml
openapi_spec_hash: b10ee8536928665190a110738964fccb
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-bfa54d26b675d92a0b3db3e3c2147dc98250fb1e4cb82bb6bd6f9af544763506.yml
openapi_spec_hash: 7d834a5553262d0a2538bc066f39d549
config_hash: 70354330f92ce169beabc98696ebb9a3
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## 0.16.0 (2026-05-06)

Full Changelog: [v0.15.0...v0.16.0](https://github.com/context-dot-dev/context-python-sdk/compare/v0.15.0...v0.16.0)

### Features

* **api:** api update ([aed2184](https://github.com/context-dot-dev/context-python-sdk/commit/aed2184efdd3c73b45e3df6993147b3d92414070))

## 0.15.0 (2026-05-05)

Full Changelog: [v0.14.0...v0.15.0](https://github.com/context-dot-dev/context-python-sdk/compare/v0.14.0...v0.15.0)
Expand Down
16 changes: 4 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,19 +130,11 @@ from context.dev import ContextDev

client = ContextDev()

response = client.ai.ai_query(
data_to_extract=[
{
"datapoint_description": "datapoint_description",
"datapoint_example": "datapoint_example",
"datapoint_name": "datapoint_name",
"datapoint_type": "text",
}
],
domain="domain",
specific_pages={},
response = client.web.web_scrape_images(
url="https://example.com",
enrichment={},
)
print(response.specific_pages)
print(response.enrichment)
```

## Handling errors
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "context.dev"
version = "0.15.0"
version = "0.16.0"
description = "The official Python library for the context.dev API"
dynamic = ["readme"]
license = "Apache-2.0"
Expand Down
2 changes: 1 addition & 1 deletion src/context/dev/_version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

__title__ = "context.dev"
__version__ = "0.15.0" # x-release-please-version
__version__ = "0.16.0" # x-release-please-version
58 changes: 44 additions & 14 deletions src/context/dev/resources/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -398,21 +398,29 @@ def web_scrape_images(
self,
*,
url: str,
enrichment: web_web_scrape_images_params.Enrichment | Omit = omit,
max_age_ms: int | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> WebWebScrapeImagesResponse:
"""Scrapes all images from the given URL.

Extracts images from img, svg,
picture/source, link, and video elements including inline SVGs, base64 data
URIs, and standard URLs.
"""
Extract image assets from a web page, including standard URLs, inline SVGs, data
URIs, responsive image sources, metadata, CSS backgrounds, video posters, and
embeds. The base request costs 1 credit; enrichment costs 1 credit per returned
image.

Args:
url: Full URL to scrape images from (must include http:// or https:// protocol)
url: Page URL to inspect. Must include http:// or https://.

enrichment: Optional per-image processing, sent as deep-object query params such as
enrichment[resolution]=true.

max_age_ms: Reuse a cached result this many milliseconds old or newer. Default: 86400000 (1
day). Set to 0 to bypass cache. Maximum: 2592000000 (30 days).

extra_headers: Send extra headers

Expand All @@ -429,7 +437,14 @@ def web_scrape_images(
extra_query=extra_query,
extra_body=extra_body,
timeout=timeout,
query=maybe_transform({"url": url}, web_web_scrape_images_params.WebWebScrapeImagesParams),
query=maybe_transform(
{
"url": url,
"enrichment": enrichment,
"max_age_ms": max_age_ms,
},
web_web_scrape_images_params.WebWebScrapeImagesParams,
),
),
cast_to=WebWebScrapeImagesResponse,
)
Expand Down Expand Up @@ -922,21 +937,29 @@ async def web_scrape_images(
self,
*,
url: str,
enrichment: web_web_scrape_images_params.Enrichment | Omit = omit,
max_age_ms: int | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> WebWebScrapeImagesResponse:
"""Scrapes all images from the given URL.

Extracts images from img, svg,
picture/source, link, and video elements including inline SVGs, base64 data
URIs, and standard URLs.
"""
Extract image assets from a web page, including standard URLs, inline SVGs, data
URIs, responsive image sources, metadata, CSS backgrounds, video posters, and
embeds. The base request costs 1 credit; enrichment costs 1 credit per returned
image.

Args:
url: Full URL to scrape images from (must include http:// or https:// protocol)
url: Page URL to inspect. Must include http:// or https://.

enrichment: Optional per-image processing, sent as deep-object query params such as
enrichment[resolution]=true.

max_age_ms: Reuse a cached result this many milliseconds old or newer. Default: 86400000 (1
day). Set to 0 to bypass cache. Maximum: 2592000000 (30 days).

extra_headers: Send extra headers

Expand All @@ -953,7 +976,14 @@ async def web_scrape_images(
extra_query=extra_query,
extra_body=extra_body,
timeout=timeout,
query=await async_maybe_transform({"url": url}, web_web_scrape_images_params.WebWebScrapeImagesParams),
query=await async_maybe_transform(
{
"url": url,
"enrichment": enrichment,
"max_age_ms": max_age_ms,
},
web_web_scrape_images_params.WebWebScrapeImagesParams,
),
),
cast_to=WebWebScrapeImagesResponse,
)
Expand Down
42 changes: 39 additions & 3 deletions src/context/dev/types/web_web_scrape_images_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,47 @@

from __future__ import annotations

from typing_extensions import Required, TypedDict
from typing_extensions import Required, Annotated, TypedDict

__all__ = ["WebWebScrapeImagesParams"]
from .._utils import PropertyInfo

__all__ = ["WebWebScrapeImagesParams", "Enrichment"]


class WebWebScrapeImagesParams(TypedDict, total=False):
url: Required[str]
"""Full URL to scrape images from (must include http:// or https:// protocol)"""
"""Page URL to inspect. Must include http:// or https://."""

enrichment: Enrichment
"""
Optional per-image processing, sent as deep-object query params such as
enrichment[resolution]=true.
"""

max_age_ms: Annotated[int, PropertyInfo(alias="maxAgeMs")]
"""Reuse a cached result this many milliseconds old or newer.

Default: 86400000 (1 day). Set to 0 to bypass cache. Maximum: 2592000000 (30
days).
"""


class Enrichment(TypedDict, total=False):
"""
Optional per-image processing, sent as deep-object query params such as enrichment[resolution]=true.
"""

classification: bool
"""Classify each image by visual asset type."""

hosted_url: Annotated[bool, PropertyInfo(alias="hostedUrl")]
"""
Host materializable images on the Brand.dev CDN and return their URL and MIME
type.
"""

max_time_per_ms: Annotated[int, PropertyInfo(alias="maxTimePerMs")]
"""Per-image enrichment timeout in milliseconds. Default: 6000. Maximum: 60000."""

resolution: bool
"""Measure image width and height when possible."""
40 changes: 32 additions & 8 deletions src/context/dev/types/web_web_scrape_images_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,53 @@

from .._models import BaseModel

__all__ = ["WebWebScrapeImagesResponse", "Image"]
__all__ = ["WebWebScrapeImagesResponse", "Image", "ImageEnrichment"]


class ImageEnrichment(BaseModel):
"""Requested metadata for images that could be processed."""

height: Optional[int] = None
"""Image height in pixels, when measured."""

mimetype: Optional[str] = None
"""Detected MIME type, when hosted."""

type: Optional[
Literal["photography", "illustration", "logo", "wordmark", "icon", "pattern", "graphic", "other"]
] = None
"""Visual asset category, when classified."""

url: Optional[str] = None
"""Brand.dev CDN URL, when hosted."""

width: Optional[int] = None
"""Image width in pixels, when measured."""


class Image(BaseModel):
alt: Optional[str] = None
"""Alt text of the image, or null if not present"""
"""Image alt text, or null when unavailable."""

element: Literal["img", "svg", "link", "source", "video", "css", "object", "meta", "background"]
"""The HTML element the image was found in"""
"""Where the image was found."""

src: str
"""The image source - can be a URL, inline HTML (for SVGs), or a base64 data URI"""
"""Original image value: URL, inline SVG or HTML, or base64 data URI."""

type: Literal["url", "html", "base64"]
"""The type/format of the src value"""
"""Format of src."""

enrichment: Optional[ImageEnrichment] = None
"""Requested metadata for images that could be processed."""


class WebWebScrapeImagesResponse(BaseModel):
images: List[Image]
"""Array of scraped images"""
"""Images found on the page."""

success: Literal[True]
"""Indicates success"""
"""Always true on success."""

url: str
"""The URL that was scraped"""
"""Page URL that was scraped."""
30 changes: 30 additions & 0 deletions tests/api_resources/test_web.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,21 @@ def test_method_web_scrape_images(self, client: ContextDev) -> None:
)
assert_matches_type(WebWebScrapeImagesResponse, web, path=["response"])

@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
def test_method_web_scrape_images_with_all_params(self, client: ContextDev) -> None:
web = client.web.web_scrape_images(
url="https://example.com",
enrichment={
"classification": True,
"hosted_url": True,
"max_time_per_ms": 1,
"resolution": True,
},
max_age_ms=0,
)
assert_matches_type(WebWebScrapeImagesResponse, web, path=["response"])

@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
def test_raw_response_web_scrape_images(self, client: ContextDev) -> None:
Expand Down Expand Up @@ -595,6 +610,21 @@ async def test_method_web_scrape_images(self, async_client: AsyncContextDev) ->
)
assert_matches_type(WebWebScrapeImagesResponse, web, path=["response"])

@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
async def test_method_web_scrape_images_with_all_params(self, async_client: AsyncContextDev) -> None:
web = await async_client.web.web_scrape_images(
url="https://example.com",
enrichment={
"classification": True,
"hosted_url": True,
"max_time_per_ms": 1,
"resolution": True,
},
max_age_ms=0,
)
assert_matches_type(WebWebScrapeImagesResponse, web, path=["response"])

@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
async def test_raw_response_web_scrape_images(self, async_client: AsyncContextDev) -> None:
Expand Down
Loading