diff --git a/.release-please-manifest.json b/.release-please-manifest.json index b9781c02..c1c6163c 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.2.0-alpha.58" + ".": "0.2.0-alpha.59" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 1dee8043..09980137 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,3 +1,3 @@ -configured_endpoints: 17 -openapi_spec_hash: 8827ead72aa0c635ccafac5e008fe247 -config_hash: 087e6b8013c398a6d24031d24594fdec +configured_endpoints: 18 +openapi_spec_hash: 4f09f95fd31c148d1be80b7e643346ce +config_hash: 30422a4611d93ca69e4f1aff60b9ddb5 diff --git a/CHANGELOG.md b/CHANGELOG.md index f790a36f..2c558de1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,16 @@ 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.2.0-alpha.59 (2025-04-25) + +Full Changelog: [v0.2.0-alpha.58...v0.2.0-alpha.59](https://github.com/openlayer-ai/openlayer-python/compare/v0.2.0-alpha.58...v0.2.0-alpha.59) + +### Features + +* **api:** api update ([fb9c6ee](https://github.com/openlayer-ai/openlayer-python/commit/fb9c6ee1555b764a00c313ef0cd0520782de2e09)) +* **api:** api update ([1a25da2](https://github.com/openlayer-ai/openlayer-python/commit/1a25da24c4c3c0fd589348718425d4b61d1d1298)) +* **api:** expose test update endpoint ([ef1427e](https://github.com/openlayer-ai/openlayer-python/commit/ef1427ebc91a1f569b68f4b853758cdc7adac586)) + ## 0.2.0-alpha.58 (2025-04-24) Full Changelog: [v0.2.0-alpha.57...v0.2.0-alpha.58](https://github.com/openlayer-ai/openlayer-python/compare/v0.2.0-alpha.57...v0.2.0-alpha.58) diff --git a/api.md b/api.md index bfc07c13..c7e4123b 100644 --- a/api.md +++ b/api.md @@ -42,12 +42,13 @@ Methods: Types: ```python -from openlayer.types.projects import TestCreateResponse, TestListResponse +from openlayer.types.projects import TestCreateResponse, TestUpdateResponse, TestListResponse ``` Methods: - client.projects.tests.create(project_id, \*\*params) -> TestCreateResponse +- client.projects.tests.update(project_id, \*\*params) -> TestUpdateResponse - client.projects.tests.list(project_id, \*\*params) -> TestListResponse # Commits diff --git a/pyproject.toml b/pyproject.toml index 0a4ff541..96057cc9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "openlayer" -version = "0.2.0-alpha.58" +version = "0.2.0-alpha.59" 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 4477fdd8..329ceb20 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.2.0-alpha.58" # x-release-please-version +__version__ = "0.2.0-alpha.59" # x-release-please-version diff --git a/src/openlayer/resources/projects/tests.py b/src/openlayer/resources/projects/tests.py index e8f3efc3..a795c811 100644 --- a/src/openlayer/resources/projects/tests.py +++ b/src/openlayer/resources/projects/tests.py @@ -18,9 +18,10 @@ async_to_streamed_response_wrapper, ) from ..._base_client import make_request_options -from ...types.projects import test_list_params, test_create_params +from ...types.projects import test_list_params, test_create_params, test_update_params from ...types.projects.test_list_response import TestListResponse from ...types.projects.test_create_response import TestCreateResponse +from ...types.projects.test_update_response import TestUpdateResponse __all__ = ["TestsResource", "AsyncTestsResource"] @@ -178,6 +179,41 @@ def create( cast_to=TestCreateResponse, ) + def update( + self, + project_id: str, + *, + payloads: Iterable[test_update_params.Payload], + # 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, + ) -> TestUpdateResponse: + """ + Update tests. + + Args: + 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 project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") + return self._put( + f"/projects/{project_id}/tests", + body=maybe_transform({"payloads": payloads}, test_update_params.TestUpdateParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=TestUpdateResponse, + ) + def list( self, project_id: str, @@ -400,6 +436,41 @@ async def create( cast_to=TestCreateResponse, ) + async def update( + self, + project_id: str, + *, + payloads: Iterable[test_update_params.Payload], + # 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, + ) -> TestUpdateResponse: + """ + Update tests. + + Args: + 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 project_id: + raise ValueError(f"Expected a non-empty value for `project_id` but received {project_id!r}") + return await self._put( + f"/projects/{project_id}/tests", + body=await async_maybe_transform({"payloads": payloads}, test_update_params.TestUpdateParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=TestUpdateResponse, + ) + async def list( self, project_id: str, @@ -480,6 +551,9 @@ def __init__(self, tests: TestsResource) -> None: self.create = to_raw_response_wrapper( tests.create, ) + self.update = to_raw_response_wrapper( + tests.update, + ) self.list = to_raw_response_wrapper( tests.list, ) @@ -492,6 +566,9 @@ def __init__(self, tests: AsyncTestsResource) -> None: self.create = async_to_raw_response_wrapper( tests.create, ) + self.update = async_to_raw_response_wrapper( + tests.update, + ) self.list = async_to_raw_response_wrapper( tests.list, ) @@ -506,6 +583,9 @@ def __init__(self, tests: TestsResource) -> None: self.create = to_streamed_response_wrapper( tests.create, ) + self.update = to_streamed_response_wrapper( + tests.update, + ) self.list = to_streamed_response_wrapper( tests.list, ) @@ -518,6 +598,9 @@ def __init__(self, tests: AsyncTestsResource) -> None: self.create = async_to_streamed_response_wrapper( tests.create, ) + self.update = async_to_streamed_response_wrapper( + tests.update, + ) self.list = async_to_streamed_response_wrapper( tests.list, ) diff --git a/src/openlayer/types/commits/test_result_list_response.py b/src/openlayer/types/commits/test_result_list_response.py index f3dc6e6c..8a0a2091 100644 --- a/src/openlayer/types/commits/test_result_list_response.py +++ b/src/openlayer/types/commits/test_result_list_response.py @@ -19,13 +19,55 @@ class ItemGoalThresholdInsightParameter(BaseModel): class ItemGoalThreshold(BaseModel): - insight_name: Optional[str] = FieldInfo(alias="insightName", default=None) + insight_name: Optional[ + Literal[ + "characterLength", + "classImbalance", + "expectColumnAToBeInColumnB", + "columnAverage", + "columnDrift", + "columnValuesMatch", + "confidenceDistribution", + "conflictingLabelRowCount", + "containsPii", + "containsValidUrl", + "correlatedFeatures", + "customMetric", + "duplicateRowCount", + "emptyFeatures", + "featureDrift", + "featureProfile", + "greatExpectations", + "groupByColumnStatsCheck", + "illFormedRowCount", + "isCode", + "isJson", + "llmRubricV2", + "labelDrift", + "metrics", + "newCategories", + "newLabels", + "nullRowCount", + "ppScore", + "quasiConstantFeatures", + "sentenceLength", + "sizeRatio", + "specialCharacters", + "stringValidation", + "trainValLeakageRowCount", + ] + ] = FieldInfo(alias="insightName", default=None) """The insight name to be evaluated.""" insight_parameters: Optional[List[ItemGoalThresholdInsightParameter]] = FieldInfo( alias="insightParameters", default=None ) - """The insight parameters. Required only for some test subtypes.""" + """The insight parameters. + + Required only for some test subtypes. For example, for tests that require a + column name, the insight parameters will be [{'name': 'column_name', 'value': + 'Age'}] + """ measurement: Optional[str] = None """The measurement to be evaluated.""" diff --git a/src/openlayer/types/inference_pipelines/test_result_list_response.py b/src/openlayer/types/inference_pipelines/test_result_list_response.py index f3dc6e6c..8a0a2091 100644 --- a/src/openlayer/types/inference_pipelines/test_result_list_response.py +++ b/src/openlayer/types/inference_pipelines/test_result_list_response.py @@ -19,13 +19,55 @@ class ItemGoalThresholdInsightParameter(BaseModel): class ItemGoalThreshold(BaseModel): - insight_name: Optional[str] = FieldInfo(alias="insightName", default=None) + insight_name: Optional[ + Literal[ + "characterLength", + "classImbalance", + "expectColumnAToBeInColumnB", + "columnAverage", + "columnDrift", + "columnValuesMatch", + "confidenceDistribution", + "conflictingLabelRowCount", + "containsPii", + "containsValidUrl", + "correlatedFeatures", + "customMetric", + "duplicateRowCount", + "emptyFeatures", + "featureDrift", + "featureProfile", + "greatExpectations", + "groupByColumnStatsCheck", + "illFormedRowCount", + "isCode", + "isJson", + "llmRubricV2", + "labelDrift", + "metrics", + "newCategories", + "newLabels", + "nullRowCount", + "ppScore", + "quasiConstantFeatures", + "sentenceLength", + "sizeRatio", + "specialCharacters", + "stringValidation", + "trainValLeakageRowCount", + ] + ] = FieldInfo(alias="insightName", default=None) """The insight name to be evaluated.""" insight_parameters: Optional[List[ItemGoalThresholdInsightParameter]] = FieldInfo( alias="insightParameters", default=None ) - """The insight parameters. Required only for some test subtypes.""" + """The insight parameters. + + Required only for some test subtypes. For example, for tests that require a + column name, the insight parameters will be [{'name': 'column_name', 'value': + 'Age'}] + """ measurement: Optional[str] = None """The measurement to be evaluated.""" diff --git a/src/openlayer/types/projects/__init__.py b/src/openlayer/types/projects/__init__.py index 6b471427..305a81a6 100644 --- a/src/openlayer/types/projects/__init__.py +++ b/src/openlayer/types/projects/__init__.py @@ -6,9 +6,11 @@ from .commit_list_params import CommitListParams as CommitListParams from .test_create_params import TestCreateParams as TestCreateParams from .test_list_response import TestListResponse as TestListResponse +from .test_update_params import TestUpdateParams as TestUpdateParams from .commit_create_params import CommitCreateParams as CommitCreateParams from .commit_list_response import CommitListResponse as CommitListResponse from .test_create_response import TestCreateResponse as TestCreateResponse +from .test_update_response import TestUpdateResponse as TestUpdateResponse from .commit_create_response import CommitCreateResponse as CommitCreateResponse from .inference_pipeline_list_params import InferencePipelineListParams as InferencePipelineListParams from .inference_pipeline_create_params import InferencePipelineCreateParams as InferencePipelineCreateParams diff --git a/src/openlayer/types/projects/test_create_params.py b/src/openlayer/types/projects/test_create_params.py index 9f39962a..ff3aeedb 100644 --- a/src/openlayer/types/projects/test_create_params.py +++ b/src/openlayer/types/projects/test_create_params.py @@ -105,13 +105,56 @@ class ThresholdInsightParameter(TypedDict, total=False): class Threshold(TypedDict, total=False): - insight_name: Annotated[str, PropertyInfo(alias="insightName")] + insight_name: Annotated[ + Literal[ + "characterLength", + "classImbalance", + "expectColumnAToBeInColumnB", + "columnAverage", + "columnDrift", + "columnValuesMatch", + "confidenceDistribution", + "conflictingLabelRowCount", + "containsPii", + "containsValidUrl", + "correlatedFeatures", + "customMetric", + "duplicateRowCount", + "emptyFeatures", + "featureDrift", + "featureProfile", + "greatExpectations", + "groupByColumnStatsCheck", + "illFormedRowCount", + "isCode", + "isJson", + "llmRubricV2", + "labelDrift", + "metrics", + "newCategories", + "newLabels", + "nullRowCount", + "ppScore", + "quasiConstantFeatures", + "sentenceLength", + "sizeRatio", + "specialCharacters", + "stringValidation", + "trainValLeakageRowCount", + ], + PropertyInfo(alias="insightName"), + ] """The insight name to be evaluated.""" insight_parameters: Annotated[ Optional[Iterable[ThresholdInsightParameter]], PropertyInfo(alias="insightParameters") ] - """The insight parameters. Required only for some test subtypes.""" + """The insight parameters. + + Required only for some test subtypes. For example, for tests that require a + column name, the insight parameters will be [{'name': 'column_name', 'value': + 'Age'}] + """ measurement: str """The measurement to be evaluated.""" diff --git a/src/openlayer/types/projects/test_create_response.py b/src/openlayer/types/projects/test_create_response.py index d0290659..91d6d6de 100644 --- a/src/openlayer/types/projects/test_create_response.py +++ b/src/openlayer/types/projects/test_create_response.py @@ -19,11 +19,53 @@ class ThresholdInsightParameter(BaseModel): class Threshold(BaseModel): - insight_name: Optional[str] = FieldInfo(alias="insightName", default=None) + insight_name: Optional[ + Literal[ + "characterLength", + "classImbalance", + "expectColumnAToBeInColumnB", + "columnAverage", + "columnDrift", + "columnValuesMatch", + "confidenceDistribution", + "conflictingLabelRowCount", + "containsPii", + "containsValidUrl", + "correlatedFeatures", + "customMetric", + "duplicateRowCount", + "emptyFeatures", + "featureDrift", + "featureProfile", + "greatExpectations", + "groupByColumnStatsCheck", + "illFormedRowCount", + "isCode", + "isJson", + "llmRubricV2", + "labelDrift", + "metrics", + "newCategories", + "newLabels", + "nullRowCount", + "ppScore", + "quasiConstantFeatures", + "sentenceLength", + "sizeRatio", + "specialCharacters", + "stringValidation", + "trainValLeakageRowCount", + ] + ] = FieldInfo(alias="insightName", default=None) """The insight name to be evaluated.""" insight_parameters: Optional[List[ThresholdInsightParameter]] = FieldInfo(alias="insightParameters", default=None) - """The insight parameters. Required only for some test subtypes.""" + """The insight parameters. + + Required only for some test subtypes. For example, for tests that require a + column name, the insight parameters will be [{'name': 'column_name', 'value': + 'Age'}] + """ measurement: Optional[str] = None """The measurement to be evaluated.""" diff --git a/src/openlayer/types/projects/test_list_response.py b/src/openlayer/types/projects/test_list_response.py index 969b7376..c8afd5f5 100644 --- a/src/openlayer/types/projects/test_list_response.py +++ b/src/openlayer/types/projects/test_list_response.py @@ -8,21 +8,7 @@ from ..._models import BaseModel -__all__ = ["TestListResponse", "_Meta", "Item", "ItemThreshold", "ItemThresholdInsightParameter"] - - -class _Meta(BaseModel): - page: int - """The current page.""" - - per_page: int = FieldInfo(alias="perPage") - """The number of items per page.""" - - total_items: int = FieldInfo(alias="totalItems") - """The total number of items.""" - - total_pages: int = FieldInfo(alias="totalPages") - """The total number of pages.""" +__all__ = ["TestListResponse", "Item", "ItemThreshold", "ItemThresholdInsightParameter"] class ItemThresholdInsightParameter(BaseModel): @@ -33,13 +19,55 @@ class ItemThresholdInsightParameter(BaseModel): class ItemThreshold(BaseModel): - insight_name: Optional[str] = FieldInfo(alias="insightName", default=None) + insight_name: Optional[ + Literal[ + "characterLength", + "classImbalance", + "expectColumnAToBeInColumnB", + "columnAverage", + "columnDrift", + "columnValuesMatch", + "confidenceDistribution", + "conflictingLabelRowCount", + "containsPii", + "containsValidUrl", + "correlatedFeatures", + "customMetric", + "duplicateRowCount", + "emptyFeatures", + "featureDrift", + "featureProfile", + "greatExpectations", + "groupByColumnStatsCheck", + "illFormedRowCount", + "isCode", + "isJson", + "llmRubricV2", + "labelDrift", + "metrics", + "newCategories", + "newLabels", + "nullRowCount", + "ppScore", + "quasiConstantFeatures", + "sentenceLength", + "sizeRatio", + "specialCharacters", + "stringValidation", + "trainValLeakageRowCount", + ] + ] = FieldInfo(alias="insightName", default=None) """The insight name to be evaluated.""" insight_parameters: Optional[List[ItemThresholdInsightParameter]] = FieldInfo( alias="insightParameters", default=None ) - """The insight parameters. Required only for some test subtypes.""" + """The insight parameters. + + Required only for some test subtypes. For example, for tests that require a + column name, the insight parameters will be [{'name': 'column_name', 'value': + 'Age'}] + """ measurement: Optional[str] = None """The measurement to be evaluated.""" @@ -168,6 +196,4 @@ class Item(BaseModel): class TestListResponse(BaseModel): __test__ = False - api_meta: _Meta = FieldInfo(alias="_meta") - items: List[Item] diff --git a/src/openlayer/types/projects/test_update_params.py b/src/openlayer/types/projects/test_update_params.py new file mode 100644 index 00000000..53f6c3fe --- /dev/null +++ b/src/openlayer/types/projects/test_update_params.py @@ -0,0 +1,103 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import List, Union, Iterable, Optional +from typing_extensions import Literal, Required, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["TestUpdateParams", "Payload", "PayloadThreshold", "PayloadThresholdInsightParameter"] + + +class TestUpdateParams(TypedDict, total=False): + payloads: Required[Iterable[Payload]] + + +class PayloadThresholdInsightParameter(TypedDict, total=False): + name: Required[str] + """The name of the insight filter.""" + + value: Required[object] + + +class PayloadThreshold(TypedDict, total=False): + insight_name: Annotated[ + Literal[ + "characterLength", + "classImbalance", + "expectColumnAToBeInColumnB", + "columnAverage", + "columnDrift", + "columnValuesMatch", + "confidenceDistribution", + "conflictingLabelRowCount", + "containsPii", + "containsValidUrl", + "correlatedFeatures", + "customMetric", + "duplicateRowCount", + "emptyFeatures", + "featureDrift", + "featureProfile", + "greatExpectations", + "groupByColumnStatsCheck", + "illFormedRowCount", + "isCode", + "isJson", + "llmRubricV2", + "labelDrift", + "metrics", + "newCategories", + "newLabels", + "nullRowCount", + "ppScore", + "quasiConstantFeatures", + "sentenceLength", + "sizeRatio", + "specialCharacters", + "stringValidation", + "trainValLeakageRowCount", + ], + PropertyInfo(alias="insightName"), + ] + """The insight name to be evaluated.""" + + insight_parameters: Annotated[ + Optional[Iterable[PayloadThresholdInsightParameter]], PropertyInfo(alias="insightParameters") + ] + """The insight parameters. + + Required only for some test subtypes. For example, for tests that require a + column name, the insight parameters will be [{'name': 'column_name', 'value': + 'Age'}] + """ + + measurement: str + """The measurement to be evaluated.""" + + operator: Literal["is", ">", ">=", "<", "<=", "!="] + """The operator to be used for the evaluation.""" + + threshold_mode: Annotated[Literal["automatic", "manual"], PropertyInfo(alias="thresholdMode")] + """Whether to use automatic anomaly detection or manual thresholds""" + + value: Union[float, bool, str, List[str]] + """The value to be compared.""" + + +class Payload(TypedDict, total=False): + id: Required[str] + + archived: bool + """Whether the test is archived.""" + + description: Optional[object] + """The test description.""" + + name: str + """The test name.""" + + suggested: Literal[False] + + thresholds: Iterable[PayloadThreshold] diff --git a/src/openlayer/types/projects/test_update_response.py b/src/openlayer/types/projects/test_update_response.py new file mode 100644 index 00000000..6f9cb72c --- /dev/null +++ b/src/openlayer/types/projects/test_update_response.py @@ -0,0 +1,16 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["TestUpdateResponse"] + + +class TestUpdateResponse(BaseModel): + __test__ = False + task_result_id: Optional[str] = FieldInfo(alias="taskResultId", default=None) + + task_result_url: Optional[str] = FieldInfo(alias="taskResultUrl", default=None) diff --git a/tests/api_resources/projects/test_tests.py b/tests/api_resources/projects/test_tests.py index f46b66af..eaf8e170 100644 --- a/tests/api_resources/projects/test_tests.py +++ b/tests/api_resources/projects/test_tests.py @@ -9,7 +9,11 @@ from openlayer import Openlayer, AsyncOpenlayer from tests.utils import assert_matches_type -from openlayer.types.projects import TestListResponse, TestCreateResponse +from openlayer.types.projects import ( + TestListResponse, + TestCreateResponse, + TestUpdateResponse, +) base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -109,6 +113,48 @@ def test_path_params_create(self, client: Openlayer) -> None: type="integrity", ) + @parametrize + def test_method_update(self, client: Openlayer) -> None: + test = client.projects.tests.update( + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + payloads=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) + assert_matches_type(TestUpdateResponse, test, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: Openlayer) -> None: + response = client.projects.tests.with_raw_response.update( + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + payloads=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + test = response.parse() + assert_matches_type(TestUpdateResponse, test, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: Openlayer) -> None: + with client.projects.tests.with_streaming_response.update( + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + payloads=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + test = response.parse() + assert_matches_type(TestUpdateResponse, test, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_update(self, client: Openlayer) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + client.projects.tests.with_raw_response.update( + project_id="", + payloads=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) + @parametrize def test_method_list(self, client: Openlayer) -> None: test = client.projects.tests.list( @@ -257,6 +303,48 @@ async def test_path_params_create(self, async_client: AsyncOpenlayer) -> None: type="integrity", ) + @parametrize + async def test_method_update(self, async_client: AsyncOpenlayer) -> None: + test = await async_client.projects.tests.update( + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + payloads=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) + assert_matches_type(TestUpdateResponse, test, path=["response"]) + + @parametrize + async def test_raw_response_update(self, async_client: AsyncOpenlayer) -> None: + response = await async_client.projects.tests.with_raw_response.update( + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + payloads=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + test = await response.parse() + assert_matches_type(TestUpdateResponse, test, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncOpenlayer) -> None: + async with async_client.projects.tests.with_streaming_response.update( + project_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + payloads=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + test = await response.parse() + assert_matches_type(TestUpdateResponse, test, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_update(self, async_client: AsyncOpenlayer) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `project_id` but received ''"): + await async_client.projects.tests.with_raw_response.update( + project_id="", + payloads=[{"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}], + ) + @parametrize async def test_method_list(self, async_client: AsyncOpenlayer) -> None: test = await async_client.projects.tests.list(