From 9c293e60c0730a5dea1d53506c2c7ad42d6de698 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2026 20:50:21 +0000 Subject: [PATCH 1/3] =?UTF-8?q?feat(closes=20OPEN-9425):=20document=20/row?= =?UTF-8?q?s=20endpoint=20in=20API=20reference=20and=20=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .stats.yml | 6 +- api.md | 3 +- .../resources/inference_pipelines/rows.py | 175 +++++++++++++++++- .../types/inference_pipelines/__init__.py | 2 + .../inference_pipelines/row_create_params.py | 77 ++++++++ .../row_create_response.py | 15 ++ .../inference_pipelines/test_rows.py | 129 ++++++++++++- 7 files changed, 399 insertions(+), 8 deletions(-) create mode 100644 src/openlayer/types/inference_pipelines/row_create_params.py create mode 100644 src/openlayer/types/inference_pipelines/row_create_response.py diff --git a/.stats.yml b/.stats.yml index f4bb289c..9d8ddf87 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,3 +1,3 @@ -configured_endpoints: 27 -openapi_spec_hash: c70c3eccfe803e99c14e97e650b1e314 -config_hash: 1f7626e569e1a74574a58d7883170a0e +configured_endpoints: 28 +openapi_spec_hash: 5f7962599290c70cb47c05c3b29fdbd8 +config_hash: 38b7fc7dfc9af970e9e1cb7b81ccc56b diff --git a/api.md b/api.md index 5e96f44e..ca63fc50 100644 --- a/api.md +++ b/api.md @@ -150,11 +150,12 @@ Methods: Types: ```python -from openlayer.types.inference_pipelines import RowUpdateResponse +from openlayer.types.inference_pipelines import RowCreateResponse, RowUpdateResponse ``` Methods: +- client.inference_pipelines.rows.create(inference_pipeline_id, \*\*params) -> RowCreateResponse - client.inference_pipelines.rows.update(inference_pipeline_id, \*\*params) -> RowUpdateResponse ## TestResults diff --git a/src/openlayer/resources/inference_pipelines/rows.py b/src/openlayer/resources/inference_pipelines/rows.py index 0c77dfb1..251a0e0c 100644 --- a/src/openlayer/resources/inference_pipelines/rows.py +++ b/src/openlayer/resources/inference_pipelines/rows.py @@ -2,11 +2,11 @@ from __future__ import annotations -from typing import Optional +from typing import Iterable, Optional import httpx -from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from ..._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given from ..._utils import maybe_transform, async_maybe_transform from ..._compat import cached_property from ..._resource import SyncAPIResource, AsyncAPIResource @@ -17,7 +17,8 @@ async_to_streamed_response_wrapper, ) from ..._base_client import make_request_options -from ...types.inference_pipelines import row_update_params +from ...types.inference_pipelines import row_create_params, row_update_params +from ...types.inference_pipelines.row_create_response import RowCreateResponse from ...types.inference_pipelines.row_update_response import RowUpdateResponse __all__ = ["RowsResource", "AsyncRowsResource"] @@ -43,6 +44,84 @@ def with_streaming_response(self) -> RowsResourceWithStreamingResponse: """ return RowsResourceWithStreamingResponse(self) + def create( + self, + inference_pipeline_id: str, + *, + asc: bool | Omit = omit, + page: int | Omit = omit, + per_page: int | Omit = omit, + sort_column: str | Omit = omit, + column_filters: Optional[Iterable[row_create_params.ColumnFilter]] | Omit = omit, + exclude_row_id_list: Optional[Iterable[int]] | Omit = omit, + not_search_query_and: Optional[SequenceNotStr[str]] | Omit = omit, + not_search_query_or: Optional[SequenceNotStr[str]] | Omit = omit, + row_id_list: Optional[Iterable[int]] | Omit = omit, + search_query_and: Optional[SequenceNotStr[str]] | Omit = omit, + search_query_or: Optional[SequenceNotStr[str]] | 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, + ) -> RowCreateResponse: + """ + A list of rows for an inference pipeline. + + Args: + asc: Whether or not to sort on the sortColumn in ascending order. + + page: The page to return in a paginated query. + + per_page: Maximum number of items to return per page. + + sort_column: Name of the column to sort on + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not inference_pipeline_id: + raise ValueError( + f"Expected a non-empty value for `inference_pipeline_id` but received {inference_pipeline_id!r}" + ) + return self._post( + f"/inference-pipelines/{inference_pipeline_id}/rows", + body=maybe_transform( + { + "column_filters": column_filters, + "exclude_row_id_list": exclude_row_id_list, + "not_search_query_and": not_search_query_and, + "not_search_query_or": not_search_query_or, + "row_id_list": row_id_list, + "search_query_and": search_query_and, + "search_query_or": search_query_or, + }, + row_create_params.RowCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "asc": asc, + "page": page, + "per_page": per_page, + "sort_column": sort_column, + }, + row_create_params.RowCreateParams, + ), + ), + cast_to=RowCreateResponse, + ) + def update( self, inference_pipeline_id: str, @@ -115,6 +194,84 @@ def with_streaming_response(self) -> AsyncRowsResourceWithStreamingResponse: """ return AsyncRowsResourceWithStreamingResponse(self) + async def create( + self, + inference_pipeline_id: str, + *, + asc: bool | Omit = omit, + page: int | Omit = omit, + per_page: int | Omit = omit, + sort_column: str | Omit = omit, + column_filters: Optional[Iterable[row_create_params.ColumnFilter]] | Omit = omit, + exclude_row_id_list: Optional[Iterable[int]] | Omit = omit, + not_search_query_and: Optional[SequenceNotStr[str]] | Omit = omit, + not_search_query_or: Optional[SequenceNotStr[str]] | Omit = omit, + row_id_list: Optional[Iterable[int]] | Omit = omit, + search_query_and: Optional[SequenceNotStr[str]] | Omit = omit, + search_query_or: Optional[SequenceNotStr[str]] | 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, + ) -> RowCreateResponse: + """ + A list of rows for an inference pipeline. + + Args: + asc: Whether or not to sort on the sortColumn in ascending order. + + page: The page to return in a paginated query. + + per_page: Maximum number of items to return per page. + + sort_column: Name of the column to sort on + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not inference_pipeline_id: + raise ValueError( + f"Expected a non-empty value for `inference_pipeline_id` but received {inference_pipeline_id!r}" + ) + return await self._post( + f"/inference-pipelines/{inference_pipeline_id}/rows", + body=await async_maybe_transform( + { + "column_filters": column_filters, + "exclude_row_id_list": exclude_row_id_list, + "not_search_query_and": not_search_query_and, + "not_search_query_or": not_search_query_or, + "row_id_list": row_id_list, + "search_query_and": search_query_and, + "search_query_or": search_query_or, + }, + row_create_params.RowCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=await async_maybe_transform( + { + "asc": asc, + "page": page, + "per_page": per_page, + "sort_column": sort_column, + }, + row_create_params.RowCreateParams, + ), + ), + cast_to=RowCreateResponse, + ) + async def update( self, inference_pipeline_id: str, @@ -171,6 +328,9 @@ class RowsResourceWithRawResponse: def __init__(self, rows: RowsResource) -> None: self._rows = rows + self.create = to_raw_response_wrapper( + rows.create, + ) self.update = to_raw_response_wrapper( rows.update, ) @@ -180,6 +340,9 @@ class AsyncRowsResourceWithRawResponse: def __init__(self, rows: AsyncRowsResource) -> None: self._rows = rows + self.create = async_to_raw_response_wrapper( + rows.create, + ) self.update = async_to_raw_response_wrapper( rows.update, ) @@ -189,6 +352,9 @@ class RowsResourceWithStreamingResponse: def __init__(self, rows: RowsResource) -> None: self._rows = rows + self.create = to_streamed_response_wrapper( + rows.create, + ) self.update = to_streamed_response_wrapper( rows.update, ) @@ -198,6 +364,9 @@ class AsyncRowsResourceWithStreamingResponse: def __init__(self, rows: AsyncRowsResource) -> None: self._rows = rows + self.create = async_to_streamed_response_wrapper( + rows.create, + ) self.update = async_to_streamed_response_wrapper( rows.update, ) diff --git a/src/openlayer/types/inference_pipelines/__init__.py b/src/openlayer/types/inference_pipelines/__init__.py index 3ccedd4e..ebdd9679 100644 --- a/src/openlayer/types/inference_pipelines/__init__.py +++ b/src/openlayer/types/inference_pipelines/__init__.py @@ -2,8 +2,10 @@ from __future__ import annotations +from .row_create_params import RowCreateParams as RowCreateParams from .row_update_params import RowUpdateParams as RowUpdateParams from .data_stream_params import DataStreamParams as DataStreamParams +from .row_create_response import RowCreateResponse as RowCreateResponse from .row_update_response import RowUpdateResponse as RowUpdateResponse from .data_stream_response import DataStreamResponse as DataStreamResponse from .test_result_list_params import TestResultListParams as TestResultListParams diff --git a/src/openlayer/types/inference_pipelines/row_create_params.py b/src/openlayer/types/inference_pipelines/row_create_params.py new file mode 100644 index 00000000..9078bbb9 --- /dev/null +++ b/src/openlayer/types/inference_pipelines/row_create_params.py @@ -0,0 +1,77 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union, Iterable, Optional +from typing_extensions import Literal, Required, Annotated, TypeAlias, TypedDict + +from ..._types import SequenceNotStr +from ..._utils import PropertyInfo + +__all__ = [ + "RowCreateParams", + "ColumnFilter", + "ColumnFilterSetColumnFilter", + "ColumnFilterNumericColumnFilter", + "ColumnFilterStringColumnFilter", +] + + +class RowCreateParams(TypedDict, total=False): + asc: bool + """Whether or not to sort on the sortColumn in ascending order.""" + + page: int + """The page to return in a paginated query.""" + + per_page: Annotated[int, PropertyInfo(alias="perPage")] + """Maximum number of items to return per page.""" + + sort_column: Annotated[str, PropertyInfo(alias="sortColumn")] + """Name of the column to sort on""" + + column_filters: Annotated[Optional[Iterable[ColumnFilter]], PropertyInfo(alias="columnFilters")] + + exclude_row_id_list: Annotated[Optional[Iterable[int]], PropertyInfo(alias="excludeRowIdList")] + + not_search_query_and: Annotated[Optional[SequenceNotStr[str]], PropertyInfo(alias="notSearchQueryAnd")] + + not_search_query_or: Annotated[Optional[SequenceNotStr[str]], PropertyInfo(alias="notSearchQueryOr")] + + row_id_list: Annotated[Optional[Iterable[int]], PropertyInfo(alias="rowIdList")] + + search_query_and: Annotated[Optional[SequenceNotStr[str]], PropertyInfo(alias="searchQueryAnd")] + + search_query_or: Annotated[Optional[SequenceNotStr[str]], PropertyInfo(alias="searchQueryOr")] + + +class ColumnFilterSetColumnFilter(TypedDict, total=False): + measurement: Required[str] + """The name of the column.""" + + operator: Required[Literal["contains_none", "contains_any", "contains_all", "one_of", "none_of"]] + + value: Required[SequenceNotStr[Union[str, float]]] + + +class ColumnFilterNumericColumnFilter(TypedDict, total=False): + measurement: Required[str] + """The name of the column.""" + + operator: Required[Literal[">", ">=", "is", "<", "<=", "!="]] + + value: Required[Optional[float]] + + +class ColumnFilterStringColumnFilter(TypedDict, total=False): + measurement: Required[str] + """The name of the column.""" + + operator: Required[Literal["is", "!="]] + + value: Required[Union[str, bool]] + + +ColumnFilter: TypeAlias = Union[ + ColumnFilterSetColumnFilter, ColumnFilterNumericColumnFilter, ColumnFilterStringColumnFilter +] diff --git a/src/openlayer/types/inference_pipelines/row_create_response.py b/src/openlayer/types/inference_pipelines/row_create_response.py new file mode 100644 index 00000000..da1dfb70 --- /dev/null +++ b/src/openlayer/types/inference_pipelines/row_create_response.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List + +from ..._models import BaseModel + +__all__ = ["RowCreateResponse", "Item"] + + +class Item(BaseModel): + openlayer_row_id: int + + +class RowCreateResponse(BaseModel): + items: List[Item] diff --git a/tests/api_resources/inference_pipelines/test_rows.py b/tests/api_resources/inference_pipelines/test_rows.py index 1c3da6d1..ffe95a35 100644 --- a/tests/api_resources/inference_pipelines/test_rows.py +++ b/tests/api_resources/inference_pipelines/test_rows.py @@ -9,7 +9,10 @@ from openlayer import Openlayer, AsyncOpenlayer from tests.utils import assert_matches_type -from openlayer.types.inference_pipelines import RowUpdateResponse +from openlayer.types.inference_pipelines import ( + RowCreateResponse, + RowUpdateResponse, +) base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -17,6 +20,68 @@ class TestRows: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + @parametrize + def test_method_create(self, client: Openlayer) -> None: + row = client.inference_pipelines.rows.create( + inference_pipeline_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(RowCreateResponse, row, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: Openlayer) -> None: + row = client.inference_pipelines.rows.create( + inference_pipeline_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + asc=True, + page=1, + per_page=1, + sort_column="sortColumn", + column_filters=[ + { + "measurement": "openlayer_token_set", + "operator": "contains_none", + "value": ["cat"], + } + ], + exclude_row_id_list=[0], + not_search_query_and=["string"], + not_search_query_or=["string"], + row_id_list=[0], + search_query_and=["string"], + search_query_or=["string"], + ) + assert_matches_type(RowCreateResponse, row, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: Openlayer) -> None: + response = client.inference_pipelines.rows.with_raw_response.create( + inference_pipeline_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + row = response.parse() + assert_matches_type(RowCreateResponse, row, path=["response"]) + + @parametrize + def test_streaming_response_create(self, client: Openlayer) -> None: + with client.inference_pipelines.rows.with_streaming_response.create( + inference_pipeline_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + row = response.parse() + assert_matches_type(RowCreateResponse, row, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_create(self, client: Openlayer) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `inference_pipeline_id` but received ''"): + client.inference_pipelines.rows.with_raw_response.create( + inference_pipeline_id="", + ) + @parametrize def test_method_update(self, client: Openlayer) -> None: row = client.inference_pipelines.rows.update( @@ -85,6 +150,68 @@ class TestAsyncRows: "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] ) + @parametrize + async def test_method_create(self, async_client: AsyncOpenlayer) -> None: + row = await async_client.inference_pipelines.rows.create( + inference_pipeline_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(RowCreateResponse, row, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncOpenlayer) -> None: + row = await async_client.inference_pipelines.rows.create( + inference_pipeline_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + asc=True, + page=1, + per_page=1, + sort_column="sortColumn", + column_filters=[ + { + "measurement": "openlayer_token_set", + "operator": "contains_none", + "value": ["cat"], + } + ], + exclude_row_id_list=[0], + not_search_query_and=["string"], + not_search_query_or=["string"], + row_id_list=[0], + search_query_and=["string"], + search_query_or=["string"], + ) + assert_matches_type(RowCreateResponse, row, path=["response"]) + + @parametrize + async def test_raw_response_create(self, async_client: AsyncOpenlayer) -> None: + response = await async_client.inference_pipelines.rows.with_raw_response.create( + inference_pipeline_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + row = await response.parse() + assert_matches_type(RowCreateResponse, row, path=["response"]) + + @parametrize + async def test_streaming_response_create(self, async_client: AsyncOpenlayer) -> None: + async with async_client.inference_pipelines.rows.with_streaming_response.create( + inference_pipeline_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + row = await response.parse() + assert_matches_type(RowCreateResponse, row, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_create(self, async_client: AsyncOpenlayer) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `inference_pipeline_id` but received ''"): + await async_client.inference_pipelines.rows.with_raw_response.create( + inference_pipeline_id="", + ) + @parametrize async def test_method_update(self, async_client: AsyncOpenlayer) -> None: row = await async_client.inference_pipelines.rows.update( From 675f01562b6e284e31fb0170a827df5036ab4555 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2026 20:51:12 +0000 Subject: [PATCH 2/3] feat(api): update POST /rows to use list method name --- .stats.yml | 2 +- api.md | 4 +- .../resources/inference_pipelines/rows.py | 204 +++++++++--------- .../types/inference_pipelines/__init__.py | 4 +- ...ow_create_params.py => row_list_params.py} | 4 +- ...reate_response.py => row_list_response.py} | 4 +- .../inference_pipelines/test_rows.py | 173 ++++++++------- 7 files changed, 196 insertions(+), 199 deletions(-) rename src/openlayer/types/inference_pipelines/{row_create_params.py => row_list_params.py} (97%) rename src/openlayer/types/inference_pipelines/{row_create_response.py => row_list_response.py} (74%) diff --git a/.stats.yml b/.stats.yml index 9d8ddf87..a47d0ba9 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,3 +1,3 @@ configured_endpoints: 28 openapi_spec_hash: 5f7962599290c70cb47c05c3b29fdbd8 -config_hash: 38b7fc7dfc9af970e9e1cb7b81ccc56b +config_hash: f1c0c034bd832878eb47146c51afdd55 diff --git a/api.md b/api.md index ca63fc50..64d5c73b 100644 --- a/api.md +++ b/api.md @@ -150,13 +150,13 @@ Methods: Types: ```python -from openlayer.types.inference_pipelines import RowCreateResponse, RowUpdateResponse +from openlayer.types.inference_pipelines import RowUpdateResponse, RowListResponse ``` Methods: -- client.inference_pipelines.rows.create(inference_pipeline_id, \*\*params) -> RowCreateResponse - client.inference_pipelines.rows.update(inference_pipeline_id, \*\*params) -> RowUpdateResponse +- client.inference_pipelines.rows.list(inference_pipeline_id, \*\*params) -> RowListResponse ## TestResults diff --git a/src/openlayer/resources/inference_pipelines/rows.py b/src/openlayer/resources/inference_pipelines/rows.py index 251a0e0c..4fa059f6 100644 --- a/src/openlayer/resources/inference_pipelines/rows.py +++ b/src/openlayer/resources/inference_pipelines/rows.py @@ -17,8 +17,8 @@ async_to_streamed_response_wrapper, ) from ..._base_client import make_request_options -from ...types.inference_pipelines import row_create_params, row_update_params -from ...types.inference_pipelines.row_create_response import RowCreateResponse +from ...types.inference_pipelines import row_list_params, row_update_params +from ...types.inference_pipelines.row_list_response import RowListResponse from ...types.inference_pipelines.row_update_response import RowUpdateResponse __all__ = ["RowsResource", "AsyncRowsResource"] @@ -44,7 +44,58 @@ def with_streaming_response(self) -> RowsResourceWithStreamingResponse: """ return RowsResourceWithStreamingResponse(self) - def create( + def update( + self, + inference_pipeline_id: str, + *, + inference_id: str, + row: object, + config: Optional[row_update_params.Config] | 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, + ) -> RowUpdateResponse: + """ + Update an inference data point in an inference pipeline. + + Args: + inference_id: Specify the inference id as a query param. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + if not inference_pipeline_id: + raise ValueError( + f"Expected a non-empty value for `inference_pipeline_id` but received {inference_pipeline_id!r}" + ) + return self._put( + f"/inference-pipelines/{inference_pipeline_id}/rows", + body=maybe_transform( + { + "row": row, + "config": config, + }, + row_update_params.RowUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform({"inference_id": inference_id}, row_update_params.RowUpdateParams), + ), + cast_to=RowUpdateResponse, + ) + + def list( self, inference_pipeline_id: str, *, @@ -52,7 +103,7 @@ def create( page: int | Omit = omit, per_page: int | Omit = omit, sort_column: str | Omit = omit, - column_filters: Optional[Iterable[row_create_params.ColumnFilter]] | Omit = omit, + column_filters: Optional[Iterable[row_list_params.ColumnFilter]] | Omit = omit, exclude_row_id_list: Optional[Iterable[int]] | Omit = omit, not_search_query_and: Optional[SequenceNotStr[str]] | Omit = omit, not_search_query_or: Optional[SequenceNotStr[str]] | Omit = omit, @@ -65,7 +116,7 @@ def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> RowCreateResponse: + ) -> RowListResponse: """ A list of rows for an inference pipeline. @@ -102,7 +153,7 @@ def create( "search_query_and": search_query_and, "search_query_or": search_query_or, }, - row_create_params.RowCreateParams, + row_list_params.RowListParams, ), options=make_request_options( extra_headers=extra_headers, @@ -116,13 +167,34 @@ def create( "per_page": per_page, "sort_column": sort_column, }, - row_create_params.RowCreateParams, + row_list_params.RowListParams, ), ), - cast_to=RowCreateResponse, + cast_to=RowListResponse, ) - def update( + +class AsyncRowsResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncRowsResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/openlayer-ai/openlayer-python#accessing-raw-response-data-eg-headers + """ + return AsyncRowsResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncRowsResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/openlayer-ai/openlayer-python#with_streaming_response + """ + return AsyncRowsResourceWithStreamingResponse(self) + + async def update( self, inference_pipeline_id: str, *, @@ -154,9 +226,9 @@ def update( raise ValueError( f"Expected a non-empty value for `inference_pipeline_id` but received {inference_pipeline_id!r}" ) - return self._put( + return await self._put( f"/inference-pipelines/{inference_pipeline_id}/rows", - body=maybe_transform( + body=await async_maybe_transform( { "row": row, "config": config, @@ -168,33 +240,12 @@ def update( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=maybe_transform({"inference_id": inference_id}, row_update_params.RowUpdateParams), + query=await async_maybe_transform({"inference_id": inference_id}, row_update_params.RowUpdateParams), ), cast_to=RowUpdateResponse, ) - -class AsyncRowsResource(AsyncAPIResource): - @cached_property - def with_raw_response(self) -> AsyncRowsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/openlayer-ai/openlayer-python#accessing-raw-response-data-eg-headers - """ - return AsyncRowsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncRowsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/openlayer-ai/openlayer-python#with_streaming_response - """ - return AsyncRowsResourceWithStreamingResponse(self) - - async def create( + async def list( self, inference_pipeline_id: str, *, @@ -202,7 +253,7 @@ async def create( page: int | Omit = omit, per_page: int | Omit = omit, sort_column: str | Omit = omit, - column_filters: Optional[Iterable[row_create_params.ColumnFilter]] | Omit = omit, + column_filters: Optional[Iterable[row_list_params.ColumnFilter]] | Omit = omit, exclude_row_id_list: Optional[Iterable[int]] | Omit = omit, not_search_query_and: Optional[SequenceNotStr[str]] | Omit = omit, not_search_query_or: Optional[SequenceNotStr[str]] | Omit = omit, @@ -215,7 +266,7 @@ async def create( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> RowCreateResponse: + ) -> RowListResponse: """ A list of rows for an inference pipeline. @@ -252,7 +303,7 @@ async def create( "search_query_and": search_query_and, "search_query_or": search_query_or, }, - row_create_params.RowCreateParams, + row_list_params.RowListParams, ), options=make_request_options( extra_headers=extra_headers, @@ -266,61 +317,10 @@ async def create( "per_page": per_page, "sort_column": sort_column, }, - row_create_params.RowCreateParams, + row_list_params.RowListParams, ), ), - cast_to=RowCreateResponse, - ) - - async def update( - self, - inference_pipeline_id: str, - *, - inference_id: str, - row: object, - config: Optional[row_update_params.Config] | 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, - ) -> RowUpdateResponse: - """ - Update an inference data point in an inference pipeline. - - Args: - inference_id: Specify the inference id as a query param. - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - if not inference_pipeline_id: - raise ValueError( - f"Expected a non-empty value for `inference_pipeline_id` but received {inference_pipeline_id!r}" - ) - return await self._put( - f"/inference-pipelines/{inference_pipeline_id}/rows", - body=await async_maybe_transform( - { - "row": row, - "config": config, - }, - row_update_params.RowUpdateParams, - ), - options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=await async_maybe_transform({"inference_id": inference_id}, row_update_params.RowUpdateParams), - ), - cast_to=RowUpdateResponse, + cast_to=RowListResponse, ) @@ -328,45 +328,45 @@ class RowsResourceWithRawResponse: def __init__(self, rows: RowsResource) -> None: self._rows = rows - self.create = to_raw_response_wrapper( - rows.create, - ) self.update = to_raw_response_wrapper( rows.update, ) + self.list = to_raw_response_wrapper( + rows.list, + ) class AsyncRowsResourceWithRawResponse: def __init__(self, rows: AsyncRowsResource) -> None: self._rows = rows - self.create = async_to_raw_response_wrapper( - rows.create, - ) self.update = async_to_raw_response_wrapper( rows.update, ) + self.list = async_to_raw_response_wrapper( + rows.list, + ) class RowsResourceWithStreamingResponse: def __init__(self, rows: RowsResource) -> None: self._rows = rows - self.create = to_streamed_response_wrapper( - rows.create, - ) self.update = to_streamed_response_wrapper( rows.update, ) + self.list = to_streamed_response_wrapper( + rows.list, + ) class AsyncRowsResourceWithStreamingResponse: def __init__(self, rows: AsyncRowsResource) -> None: self._rows = rows - self.create = async_to_streamed_response_wrapper( - rows.create, - ) self.update = async_to_streamed_response_wrapper( rows.update, ) + self.list = async_to_streamed_response_wrapper( + rows.list, + ) diff --git a/src/openlayer/types/inference_pipelines/__init__.py b/src/openlayer/types/inference_pipelines/__init__.py index ebdd9679..d18f6463 100644 --- a/src/openlayer/types/inference_pipelines/__init__.py +++ b/src/openlayer/types/inference_pipelines/__init__.py @@ -2,10 +2,10 @@ from __future__ import annotations -from .row_create_params import RowCreateParams as RowCreateParams +from .row_list_params import RowListParams as RowListParams +from .row_list_response import RowListResponse as RowListResponse from .row_update_params import RowUpdateParams as RowUpdateParams from .data_stream_params import DataStreamParams as DataStreamParams -from .row_create_response import RowCreateResponse as RowCreateResponse from .row_update_response import RowUpdateResponse as RowUpdateResponse from .data_stream_response import DataStreamResponse as DataStreamResponse from .test_result_list_params import TestResultListParams as TestResultListParams diff --git a/src/openlayer/types/inference_pipelines/row_create_params.py b/src/openlayer/types/inference_pipelines/row_list_params.py similarity index 97% rename from src/openlayer/types/inference_pipelines/row_create_params.py rename to src/openlayer/types/inference_pipelines/row_list_params.py index 9078bbb9..f7691dc3 100644 --- a/src/openlayer/types/inference_pipelines/row_create_params.py +++ b/src/openlayer/types/inference_pipelines/row_list_params.py @@ -9,7 +9,7 @@ from ..._utils import PropertyInfo __all__ = [ - "RowCreateParams", + "RowListParams", "ColumnFilter", "ColumnFilterSetColumnFilter", "ColumnFilterNumericColumnFilter", @@ -17,7 +17,7 @@ ] -class RowCreateParams(TypedDict, total=False): +class RowListParams(TypedDict, total=False): asc: bool """Whether or not to sort on the sortColumn in ascending order.""" diff --git a/src/openlayer/types/inference_pipelines/row_create_response.py b/src/openlayer/types/inference_pipelines/row_list_response.py similarity index 74% rename from src/openlayer/types/inference_pipelines/row_create_response.py rename to src/openlayer/types/inference_pipelines/row_list_response.py index da1dfb70..ed36eb85 100644 --- a/src/openlayer/types/inference_pipelines/row_create_response.py +++ b/src/openlayer/types/inference_pipelines/row_list_response.py @@ -4,12 +4,12 @@ from ..._models import BaseModel -__all__ = ["RowCreateResponse", "Item"] +__all__ = ["RowListResponse", "Item"] class Item(BaseModel): openlayer_row_id: int -class RowCreateResponse(BaseModel): +class RowListResponse(BaseModel): items: List[Item] diff --git a/tests/api_resources/inference_pipelines/test_rows.py b/tests/api_resources/inference_pipelines/test_rows.py index ffe95a35..4111e517 100644 --- a/tests/api_resources/inference_pipelines/test_rows.py +++ b/tests/api_resources/inference_pipelines/test_rows.py @@ -9,10 +9,7 @@ from openlayer import Openlayer, AsyncOpenlayer from tests.utils import assert_matches_type -from openlayer.types.inference_pipelines import ( - RowCreateResponse, - RowUpdateResponse, -) +from openlayer.types.inference_pipelines import RowListResponse, RowUpdateResponse base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -20,68 +17,6 @@ class TestRows: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - @parametrize - def test_method_create(self, client: Openlayer) -> None: - row = client.inference_pipelines.rows.create( - inference_pipeline_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - assert_matches_type(RowCreateResponse, row, path=["response"]) - - @parametrize - def test_method_create_with_all_params(self, client: Openlayer) -> None: - row = client.inference_pipelines.rows.create( - inference_pipeline_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - asc=True, - page=1, - per_page=1, - sort_column="sortColumn", - column_filters=[ - { - "measurement": "openlayer_token_set", - "operator": "contains_none", - "value": ["cat"], - } - ], - exclude_row_id_list=[0], - not_search_query_and=["string"], - not_search_query_or=["string"], - row_id_list=[0], - search_query_and=["string"], - search_query_or=["string"], - ) - assert_matches_type(RowCreateResponse, row, path=["response"]) - - @parametrize - def test_raw_response_create(self, client: Openlayer) -> None: - response = client.inference_pipelines.rows.with_raw_response.create( - inference_pipeline_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - row = response.parse() - assert_matches_type(RowCreateResponse, row, path=["response"]) - - @parametrize - def test_streaming_response_create(self, client: Openlayer) -> None: - with client.inference_pipelines.rows.with_streaming_response.create( - inference_pipeline_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ) as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - row = response.parse() - assert_matches_type(RowCreateResponse, row, path=["response"]) - - assert cast(Any, response.is_closed) is True - - @parametrize - def test_path_params_create(self, client: Openlayer) -> None: - with pytest.raises(ValueError, match=r"Expected a non-empty value for `inference_pipeline_id` but received ''"): - client.inference_pipelines.rows.with_raw_response.create( - inference_pipeline_id="", - ) - @parametrize def test_method_update(self, client: Openlayer) -> None: row = client.inference_pipelines.rows.update( @@ -144,22 +79,16 @@ def test_path_params_update(self, client: Openlayer) -> None: row={}, ) - -class TestAsyncRows: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - @parametrize - async def test_method_create(self, async_client: AsyncOpenlayer) -> None: - row = await async_client.inference_pipelines.rows.create( + def test_method_list(self, client: Openlayer) -> None: + row = client.inference_pipelines.rows.list( inference_pipeline_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) - assert_matches_type(RowCreateResponse, row, path=["response"]) + assert_matches_type(RowListResponse, row, path=["response"]) @parametrize - async def test_method_create_with_all_params(self, async_client: AsyncOpenlayer) -> None: - row = await async_client.inference_pipelines.rows.create( + def test_method_list_with_all_params(self, client: Openlayer) -> None: + row = client.inference_pipelines.rows.list( inference_pipeline_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", asc=True, page=1, @@ -179,39 +108,45 @@ async def test_method_create_with_all_params(self, async_client: AsyncOpenlayer) search_query_and=["string"], search_query_or=["string"], ) - assert_matches_type(RowCreateResponse, row, path=["response"]) + assert_matches_type(RowListResponse, row, path=["response"]) @parametrize - async def test_raw_response_create(self, async_client: AsyncOpenlayer) -> None: - response = await async_client.inference_pipelines.rows.with_raw_response.create( + def test_raw_response_list(self, client: Openlayer) -> None: + response = client.inference_pipelines.rows.with_raw_response.list( inference_pipeline_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" - row = await response.parse() - assert_matches_type(RowCreateResponse, row, path=["response"]) + row = response.parse() + assert_matches_type(RowListResponse, row, path=["response"]) @parametrize - async def test_streaming_response_create(self, async_client: AsyncOpenlayer) -> None: - async with async_client.inference_pipelines.rows.with_streaming_response.create( + def test_streaming_response_list(self, client: Openlayer) -> None: + with client.inference_pipelines.rows.with_streaming_response.list( inference_pipeline_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" - row = await response.parse() - assert_matches_type(RowCreateResponse, row, path=["response"]) + row = response.parse() + assert_matches_type(RowListResponse, row, path=["response"]) assert cast(Any, response.is_closed) is True @parametrize - async def test_path_params_create(self, async_client: AsyncOpenlayer) -> None: + def test_path_params_list(self, client: Openlayer) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `inference_pipeline_id` but received ''"): - await async_client.inference_pipelines.rows.with_raw_response.create( + client.inference_pipelines.rows.with_raw_response.list( inference_pipeline_id="", ) + +class TestAsyncRows: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + @parametrize async def test_method_update(self, async_client: AsyncOpenlayer) -> None: row = await async_client.inference_pipelines.rows.update( @@ -273,3 +208,65 @@ async def test_path_params_update(self, async_client: AsyncOpenlayer) -> None: inference_id="inferenceId", row={}, ) + + @parametrize + async def test_method_list(self, async_client: AsyncOpenlayer) -> None: + row = await async_client.inference_pipelines.rows.list( + inference_pipeline_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + assert_matches_type(RowListResponse, row, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncOpenlayer) -> None: + row = await async_client.inference_pipelines.rows.list( + inference_pipeline_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + asc=True, + page=1, + per_page=1, + sort_column="sortColumn", + column_filters=[ + { + "measurement": "openlayer_token_set", + "operator": "contains_none", + "value": ["cat"], + } + ], + exclude_row_id_list=[0], + not_search_query_and=["string"], + not_search_query_or=["string"], + row_id_list=[0], + search_query_and=["string"], + search_query_or=["string"], + ) + assert_matches_type(RowListResponse, row, path=["response"]) + + @parametrize + async def test_raw_response_list(self, async_client: AsyncOpenlayer) -> None: + response = await async_client.inference_pipelines.rows.with_raw_response.list( + inference_pipeline_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + row = await response.parse() + assert_matches_type(RowListResponse, row, path=["response"]) + + @parametrize + async def test_streaming_response_list(self, async_client: AsyncOpenlayer) -> None: + async with async_client.inference_pipelines.rows.with_streaming_response.list( + inference_pipeline_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + row = await response.parse() + assert_matches_type(RowListResponse, row, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_list(self, async_client: AsyncOpenlayer) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `inference_pipeline_id` but received ''"): + await async_client.inference_pipelines.rows.with_raw_response.list( + inference_pipeline_id="", + ) From 197db73199888e68f91e9d5d8abab8c6c3182181 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2026 20:51:32 +0000 Subject: [PATCH 3/3] release: 0.18.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 9 +++++++++ pyproject.toml | 2 +- src/openlayer/_version.py | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 2cf44ba6..4ad3fef3 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.17.12" + ".": "0.18.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e7808c1..e536715b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## 0.18.0 (2026-03-06) + +Full Changelog: [v0.17.12...v0.18.0](https://github.com/openlayer-ai/openlayer-python/compare/v0.17.12...v0.18.0) + +### Features + +* **api:** update POST /rows to use list method name ([675f015](https://github.com/openlayer-ai/openlayer-python/commit/675f01562b6e284e31fb0170a827df5036ab4555)) +* **closes OPEN-9425:** document /rows endpoint in API reference and … ([9c293e6](https://github.com/openlayer-ai/openlayer-python/commit/9c293e60c0730a5dea1d53506c2c7ad42d6de698)) + ## 0.17.12 (2026-03-06) Full Changelog: [v0.17.11...v0.17.12](https://github.com/openlayer-ai/openlayer-python/compare/v0.17.11...v0.17.12) diff --git a/pyproject.toml b/pyproject.toml index 5ed916d3..bf96abb9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "openlayer" -version = "0.17.12" +version = "0.18.0" description = "The official Python library for the openlayer API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/openlayer/_version.py b/src/openlayer/_version.py index ecca63ed..8cb28e8d 100644 --- a/src/openlayer/_version.py +++ b/src/openlayer/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "openlayer" -__version__ = "0.17.12" # x-release-please-version +__version__ = "0.18.0" # x-release-please-version