From 8dd01a1e69d82ccbc4f05b72bd980d16cb93e5e5 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 19 Feb 2025 04:39:14 +0000 Subject: [PATCH 1/6] chore(internal): codegen related update (#551) --- README.md | 19 +++++++++++++++++++ src/runloop_api_client/_files.py | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f480d2d45..cf864f391 100644 --- a/README.md +++ b/README.md @@ -136,6 +136,25 @@ for devbox in first_page.devboxes: # Remove `await` for non-async usage. ``` +## File uploads + +Request parameters that correspond to file uploads can be passed as `bytes`, a [`PathLike`](https://docs.python.org/3/library/os.html#os.PathLike) instance or a tuple of `(filename, contents, media type)`. + +```python +from pathlib import Path +from runloop_api_client import Runloop + +client = Runloop() + +client.devboxes.upload_file( + id="id", + path="path", + file=Path("/path/to/file"), +) +``` + +The async client uses the exact same interface. If you pass a [`PathLike`](https://docs.python.org/3/library/os.html#os.PathLike) instance, the file contents will be read asynchronously automatically. + ## Handling errors When the library is unable to connect to the API (for example, due to network connection problems or a timeout), a subclass of `runloop_api_client.APIConnectionError` is raised. diff --git a/src/runloop_api_client/_files.py b/src/runloop_api_client/_files.py index 715cc2078..1b1825115 100644 --- a/src/runloop_api_client/_files.py +++ b/src/runloop_api_client/_files.py @@ -34,7 +34,7 @@ def assert_is_file_content(obj: object, *, key: str | None = None) -> None: if not is_file_content(obj): prefix = f"Expected entry at `{key}`" if key is not None else f"Expected file input `{obj!r}`" raise RuntimeError( - f"{prefix} to be bytes, an io.IOBase instance, PathLike or a tuple but received {type(obj)} instead." + f"{prefix} to be bytes, an io.IOBase instance, PathLike or a tuple but received {type(obj)} instead. See https://github.com/runloopai/api-client-python/tree/main#file-uploads" ) from None From dc21caec97e15ccde2c396c6a2f0fce0f2bad313 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 21 Feb 2025 06:31:28 +0000 Subject: [PATCH 2/6] feat(client): allow passing `NotGiven` for body (#553) fix(client): mark some request bodies as optional --- src/runloop_api_client/_base_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/runloop_api_client/_base_client.py b/src/runloop_api_client/_base_client.py index 22e3bc630..6ed767c04 100644 --- a/src/runloop_api_client/_base_client.py +++ b/src/runloop_api_client/_base_client.py @@ -518,7 +518,7 @@ def _build_request( # so that passing a `TypedDict` doesn't cause an error. # https://github.com/microsoft/pyright/issues/3526#event-6715453066 params=self.qs.stringify(cast(Mapping[str, Any], params)) if params else None, - json=json_data, + json=json_data if is_given(json_data) else None, files=files, **kwargs, ) From 9260eb4443fc50ecb07e99af2307896e32027158 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 22 Feb 2025 04:47:09 +0000 Subject: [PATCH 3/6] chore(internal): fix devcontainers setup (#554) --- .devcontainer/Dockerfile | 2 +- .devcontainer/devcontainer.json | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index ac9a2e752..55d20255c 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -6,4 +6,4 @@ USER vscode RUN curl -sSf https://rye.astral.sh/get | RYE_VERSION="0.35.0" RYE_INSTALL_OPTION="--yes" bash ENV PATH=/home/vscode/.rye/shims:$PATH -RUN echo "[[ -d .venv ]] && source .venv/bin/activate" >> /home/vscode/.bashrc +RUN echo "[[ -d .venv ]] && source .venv/bin/activate || export PATH=\$PATH" >> /home/vscode/.bashrc diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index bbeb30b14..c17fdc169 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -24,6 +24,9 @@ } } } + }, + "features": { + "ghcr.io/devcontainers/features/node:1": {} } // Features to add to the dev container. More info: https://containers.dev/features. From 7c1d55de7fe3f157a30080ddc7e7f0ea5053304a Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 26 Feb 2025 01:47:17 +0000 Subject: [PATCH 4/6] feat(api): api update (#555) --- .stats.yml | 4 +- api.md | 1 + .../resources/scenarios/scenarios.py | 157 +++++++++++ src/runloop_api_client/types/__init__.py | 1 + .../types/scenario_update_params.py | 36 +++ .../types/scoring_function.py | 2 +- .../types/scoring_function_param.py | 2 +- tests/api_resources/test_scenarios.py | 246 ++++++++++++++++++ 8 files changed, 445 insertions(+), 4 deletions(-) create mode 100644 src/runloop_api_client/types/scenario_update_params.py diff --git a/.stats.yml b/.stats.yml index 89dc8775e..08c183bf8 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,2 +1,2 @@ -configured_endpoints: 77 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-cb8add05a7b418d6f8a5624be8477564853da49e8bf9671ae89b8ce49a04b6cd.yml +configured_endpoints: 78 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-4ccbc7c04012cbcca678f13e39f66bb770b8b3a9d6f1815ce1b9c20fee099128.yml diff --git a/api.md b/api.md index 90c237349..aaecbbfdd 100644 --- a/api.md +++ b/api.md @@ -278,6 +278,7 @@ Methods: - client.scenarios.create(\*\*params) -> ScenarioView - client.scenarios.retrieve(id) -> ScenarioView +- client.scenarios.update(id, \*\*params) -> ScenarioView - client.scenarios.list(\*\*params) -> SyncScenariosCursorIDPage[ScenarioView] - client.scenarios.list_public(\*\*params) -> SyncScenariosCursorIDPage[ScenarioView] - client.scenarios.start_run(\*\*params) -> ScenarioRunView diff --git a/src/runloop_api_client/resources/scenarios/scenarios.py b/src/runloop_api_client/resources/scenarios/scenarios.py index 54a3dfbbd..d76cae28d 100644 --- a/src/runloop_api_client/resources/scenarios/scenarios.py +++ b/src/runloop_api_client/resources/scenarios/scenarios.py @@ -17,6 +17,7 @@ from ...types import ( scenario_list_params, scenario_create_params, + scenario_update_params, scenario_start_run_params, scenario_list_public_params, ) @@ -183,6 +184,78 @@ def retrieve( cast_to=ScenarioView, ) + def update( + self, + id: str, + *, + input_context: InputContextParam, + name: str, + scoring_contract: ScoringContractParam, + environment_parameters: Optional[ScenarioEnvironmentParam] | NotGiven = NOT_GIVEN, + metadata: Optional[Dict[str, str]] | NotGiven = NOT_GIVEN, + reference_output: Optional[str] | NotGiven = NOT_GIVEN, + # 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, + idempotency_key: str | None = None, + ) -> ScenarioView: + """ + Update a Scenario, a repeatable AI coding evaluation test that defines the + starting environment as well as evaluation success criteria. + + Args: + input_context: The input context for the Scenario. + + name: Name of the scenario. + + scoring_contract: The scoring contract for the Scenario. + + environment_parameters: The Environment in which the Scenario will run. + + metadata: User defined metadata to attach to the scenario for organization. + + reference_output: A string representation of the reference output to solve the scenario. Commonly + can be the result of a git diff or a sequence of command actions to apply to the + environment. + + 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 + + idempotency_key: Specify a custom idempotency key for this request + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return self._post( + f"/v1/scenarios/{id}", + body=maybe_transform( + { + "input_context": input_context, + "name": name, + "scoring_contract": scoring_contract, + "environment_parameters": environment_parameters, + "metadata": metadata, + "reference_output": reference_output, + }, + scenario_update_params.ScenarioUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, + ), + cast_to=ScenarioView, + ) + def list( self, *, @@ -532,6 +605,78 @@ async def retrieve( cast_to=ScenarioView, ) + async def update( + self, + id: str, + *, + input_context: InputContextParam, + name: str, + scoring_contract: ScoringContractParam, + environment_parameters: Optional[ScenarioEnvironmentParam] | NotGiven = NOT_GIVEN, + metadata: Optional[Dict[str, str]] | NotGiven = NOT_GIVEN, + reference_output: Optional[str] | NotGiven = NOT_GIVEN, + # 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, + idempotency_key: str | None = None, + ) -> ScenarioView: + """ + Update a Scenario, a repeatable AI coding evaluation test that defines the + starting environment as well as evaluation success criteria. + + Args: + input_context: The input context for the Scenario. + + name: Name of the scenario. + + scoring_contract: The scoring contract for the Scenario. + + environment_parameters: The Environment in which the Scenario will run. + + metadata: User defined metadata to attach to the scenario for organization. + + reference_output: A string representation of the reference output to solve the scenario. Commonly + can be the result of a git diff or a sequence of command actions to apply to the + environment. + + 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 + + idempotency_key: Specify a custom idempotency key for this request + """ + if not id: + raise ValueError(f"Expected a non-empty value for `id` but received {id!r}") + return await self._post( + f"/v1/scenarios/{id}", + body=await async_maybe_transform( + { + "input_context": input_context, + "name": name, + "scoring_contract": scoring_contract, + "environment_parameters": environment_parameters, + "metadata": metadata, + "reference_output": reference_output, + }, + scenario_update_params.ScenarioUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, + ), + cast_to=ScenarioView, + ) + def list( self, *, @@ -738,6 +883,9 @@ def __init__(self, scenarios: ScenariosResource) -> None: self.retrieve = to_raw_response_wrapper( scenarios.retrieve, ) + self.update = to_raw_response_wrapper( + scenarios.update, + ) self.list = to_raw_response_wrapper( scenarios.list, ) @@ -767,6 +915,9 @@ def __init__(self, scenarios: AsyncScenariosResource) -> None: self.retrieve = async_to_raw_response_wrapper( scenarios.retrieve, ) + self.update = async_to_raw_response_wrapper( + scenarios.update, + ) self.list = async_to_raw_response_wrapper( scenarios.list, ) @@ -796,6 +947,9 @@ def __init__(self, scenarios: ScenariosResource) -> None: self.retrieve = to_streamed_response_wrapper( scenarios.retrieve, ) + self.update = to_streamed_response_wrapper( + scenarios.update, + ) self.list = to_streamed_response_wrapper( scenarios.list, ) @@ -825,6 +979,9 @@ def __init__(self, scenarios: AsyncScenariosResource) -> None: self.retrieve = async_to_streamed_response_wrapper( scenarios.retrieve, ) + self.update = async_to_streamed_response_wrapper( + scenarios.update, + ) self.list = async_to_streamed_response_wrapper( scenarios.list, ) diff --git a/src/runloop_api_client/types/__init__.py b/src/runloop_api_client/types/__init__.py index 62b6d30e3..31b76176f 100644 --- a/src/runloop_api_client/types/__init__.py +++ b/src/runloop_api_client/types/__init__.py @@ -35,6 +35,7 @@ from .repository_list_params import RepositoryListParams as RepositoryListParams from .scenario_create_params import ScenarioCreateParams as ScenarioCreateParams from .scenario_run_list_view import ScenarioRunListView as ScenarioRunListView +from .scenario_update_params import ScenarioUpdateParams as ScenarioUpdateParams from .scoring_contract_param import ScoringContractParam as ScoringContractParam from .scoring_function_param import ScoringFunctionParam as ScoringFunctionParam from .benchmark_create_params import BenchmarkCreateParams as BenchmarkCreateParams diff --git a/src/runloop_api_client/types/scenario_update_params.py b/src/runloop_api_client/types/scenario_update_params.py new file mode 100644 index 000000000..1004e7bc8 --- /dev/null +++ b/src/runloop_api_client/types/scenario_update_params.py @@ -0,0 +1,36 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Optional +from typing_extensions import Required, TypedDict + +from .input_context_param import InputContextParam +from .scoring_contract_param import ScoringContractParam +from .scenario_environment_param import ScenarioEnvironmentParam + +__all__ = ["ScenarioUpdateParams"] + + +class ScenarioUpdateParams(TypedDict, total=False): + input_context: Required[InputContextParam] + """The input context for the Scenario.""" + + name: Required[str] + """Name of the scenario.""" + + scoring_contract: Required[ScoringContractParam] + """The scoring contract for the Scenario.""" + + environment_parameters: Optional[ScenarioEnvironmentParam] + """The Environment in which the Scenario will run.""" + + metadata: Optional[Dict[str, str]] + """User defined metadata to attach to the scenario for organization.""" + + reference_output: Optional[str] + """A string representation of the reference output to solve the scenario. + + Commonly can be the result of a git diff or a sequence of command actions to + apply to the environment. + """ diff --git a/src/runloop_api_client/types/scoring_function.py b/src/runloop_api_client/types/scoring_function.py index bef775eca..f7a2a6e0d 100644 --- a/src/runloop_api_client/types/scoring_function.py +++ b/src/runloop_api_client/types/scoring_function.py @@ -20,7 +20,7 @@ class ScoringFunction(BaseModel): """ weight: float - """Wight to apply to scoring function score. + """Weight to apply to scoring function score. Weights of all scoring functions should sum to 1.0. """ diff --git a/src/runloop_api_client/types/scoring_function_param.py b/src/runloop_api_client/types/scoring_function_param.py index 0caa61468..5bcbacc58 100644 --- a/src/runloop_api_client/types/scoring_function_param.py +++ b/src/runloop_api_client/types/scoring_function_param.py @@ -21,7 +21,7 @@ class ScoringFunctionParam(TypedDict, total=False): """ weight: Required[float] - """Wight to apply to scoring function score. + """Weight to apply to scoring function score. Weights of all scoring functions should sum to 1.0. """ diff --git a/tests/api_resources/test_scenarios.py b/tests/api_resources/test_scenarios.py index 245da96bd..218ebb542 100644 --- a/tests/api_resources/test_scenarios.py +++ b/tests/api_resources/test_scenarios.py @@ -160,6 +160,129 @@ def test_path_params_retrieve(self, client: Runloop) -> None: "", ) + @parametrize + def test_method_update(self, client: Runloop) -> None: + scenario = client.scenarios.update( + id="id", + input_context={"problem_statement": "problem_statement"}, + name="name", + scoring_contract={ + "scoring_function_parameters": [ + { + "name": "name", + "type": "type", + "weight": 0, + } + ] + }, + ) + assert_matches_type(ScenarioView, scenario, path=["response"]) + + @parametrize + def test_method_update_with_all_params(self, client: Runloop) -> None: + scenario = client.scenarios.update( + id="id", + input_context={ + "problem_statement": "problem_statement", + "additional_context": {}, + }, + name="name", + scoring_contract={ + "scoring_function_parameters": [ + { + "name": "name", + "type": "type", + "weight": 0, + "bash_script": "bash_script", + "scorer_params": {}, + } + ] + }, + environment_parameters={ + "blueprint_id": "blueprint_id", + "launch_parameters": { + "after_idle": { + "idle_time_seconds": 0, + "on_idle": "shutdown", + }, + "available_ports": [0], + "keep_alive_time_seconds": 0, + "launch_commands": ["string"], + "resource_size_request": "SMALL", + }, + "prebuilt_id": "prebuilt_id", + "snapshot_id": "snapshot_id", + "working_directory": "working_directory", + }, + metadata={"foo": "string"}, + reference_output="reference_output", + ) + assert_matches_type(ScenarioView, scenario, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: Runloop) -> None: + response = client.scenarios.with_raw_response.update( + id="id", + input_context={"problem_statement": "problem_statement"}, + name="name", + scoring_contract={ + "scoring_function_parameters": [ + { + "name": "name", + "type": "type", + "weight": 0, + } + ] + }, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + scenario = response.parse() + assert_matches_type(ScenarioView, scenario, path=["response"]) + + @parametrize + def test_streaming_response_update(self, client: Runloop) -> None: + with client.scenarios.with_streaming_response.update( + id="id", + input_context={"problem_statement": "problem_statement"}, + name="name", + scoring_contract={ + "scoring_function_parameters": [ + { + "name": "name", + "type": "type", + "weight": 0, + } + ] + }, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + scenario = response.parse() + assert_matches_type(ScenarioView, scenario, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_update(self, client: Runloop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + client.scenarios.with_raw_response.update( + id="", + input_context={"problem_statement": "problem_statement"}, + name="name", + scoring_contract={ + "scoring_function_parameters": [ + { + "name": "name", + "type": "type", + "weight": 0, + } + ] + }, + ) + @parametrize def test_method_list(self, client: Runloop) -> None: scenario = client.scenarios.list() @@ -412,6 +535,129 @@ async def test_path_params_retrieve(self, async_client: AsyncRunloop) -> None: "", ) + @parametrize + async def test_method_update(self, async_client: AsyncRunloop) -> None: + scenario = await async_client.scenarios.update( + id="id", + input_context={"problem_statement": "problem_statement"}, + name="name", + scoring_contract={ + "scoring_function_parameters": [ + { + "name": "name", + "type": "type", + "weight": 0, + } + ] + }, + ) + assert_matches_type(ScenarioView, scenario, path=["response"]) + + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncRunloop) -> None: + scenario = await async_client.scenarios.update( + id="id", + input_context={ + "problem_statement": "problem_statement", + "additional_context": {}, + }, + name="name", + scoring_contract={ + "scoring_function_parameters": [ + { + "name": "name", + "type": "type", + "weight": 0, + "bash_script": "bash_script", + "scorer_params": {}, + } + ] + }, + environment_parameters={ + "blueprint_id": "blueprint_id", + "launch_parameters": { + "after_idle": { + "idle_time_seconds": 0, + "on_idle": "shutdown", + }, + "available_ports": [0], + "keep_alive_time_seconds": 0, + "launch_commands": ["string"], + "resource_size_request": "SMALL", + }, + "prebuilt_id": "prebuilt_id", + "snapshot_id": "snapshot_id", + "working_directory": "working_directory", + }, + metadata={"foo": "string"}, + reference_output="reference_output", + ) + assert_matches_type(ScenarioView, scenario, path=["response"]) + + @parametrize + async def test_raw_response_update(self, async_client: AsyncRunloop) -> None: + response = await async_client.scenarios.with_raw_response.update( + id="id", + input_context={"problem_statement": "problem_statement"}, + name="name", + scoring_contract={ + "scoring_function_parameters": [ + { + "name": "name", + "type": "type", + "weight": 0, + } + ] + }, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + scenario = await response.parse() + assert_matches_type(ScenarioView, scenario, path=["response"]) + + @parametrize + async def test_streaming_response_update(self, async_client: AsyncRunloop) -> None: + async with async_client.scenarios.with_streaming_response.update( + id="id", + input_context={"problem_statement": "problem_statement"}, + name="name", + scoring_contract={ + "scoring_function_parameters": [ + { + "name": "name", + "type": "type", + "weight": 0, + } + ] + }, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + scenario = await response.parse() + assert_matches_type(ScenarioView, scenario, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_update(self, async_client: AsyncRunloop) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"): + await async_client.scenarios.with_raw_response.update( + id="", + input_context={"problem_statement": "problem_statement"}, + name="name", + scoring_contract={ + "scoring_function_parameters": [ + { + "name": "name", + "type": "type", + "weight": 0, + } + ] + }, + ) + @parametrize async def test_method_list(self, async_client: AsyncRunloop) -> None: scenario = await async_client.scenarios.list() From 449683002d1fb31b01c4d167973058684b7ee654 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 26 Feb 2025 03:59:14 +0000 Subject: [PATCH 5/6] chore(internal): properly set __pydantic_private__ (#556) --- src/runloop_api_client/_base_client.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/runloop_api_client/_base_client.py b/src/runloop_api_client/_base_client.py index 6ed767c04..7e97db227 100644 --- a/src/runloop_api_client/_base_client.py +++ b/src/runloop_api_client/_base_client.py @@ -63,7 +63,7 @@ ModelBuilderProtocol, ) from ._utils import is_dict, is_list, asyncify, is_given, lru_cache, is_mapping -from ._compat import model_copy, model_dump +from ._compat import PYDANTIC_V2, model_copy, model_dump from ._models import GenericModel, FinalRequestOptions, validate_type, construct_type from ._response import ( APIResponse, @@ -207,6 +207,9 @@ def _set_private_attributes( model: Type[_T], options: FinalRequestOptions, ) -> None: + if PYDANTIC_V2 and getattr(self, "__pydantic_private__", None) is None: + self.__pydantic_private__ = {} + self._model = model self._client = client self._options = options @@ -292,6 +295,9 @@ def _set_private_attributes( client: AsyncAPIClient, options: FinalRequestOptions, ) -> None: + if PYDANTIC_V2 and getattr(self, "__pydantic_private__", None) is None: + self.__pydantic_private__ = {} + self._model = model self._client = client self._options = options From 6e07d96968f46936ce69ee25a14238dce5d41e37 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 26 Feb 2025 03:59:35 +0000 Subject: [PATCH 6/6] release: 0.25.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 21 +++++++++++++++++++++ pyproject.toml | 2 +- src/runloop_api_client/_version.py | 2 +- 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index d2d60a3df..a36746b8b 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.24.0" + ".": "0.25.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index a27f0172d..8bceee61e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,26 @@ # Changelog +## 0.25.0 (2025-02-26) + +Full Changelog: [v0.24.0...v0.25.0](https://github.com/runloopai/api-client-python/compare/v0.24.0...v0.25.0) + +### Features + +* **api:** api update ([#555](https://github.com/runloopai/api-client-python/issues/555)) ([7c1d55d](https://github.com/runloopai/api-client-python/commit/7c1d55de7fe3f157a30080ddc7e7f0ea5053304a)) +* **client:** allow passing `NotGiven` for body ([#553](https://github.com/runloopai/api-client-python/issues/553)) ([dc21cae](https://github.com/runloopai/api-client-python/commit/dc21caec97e15ccde2c396c6a2f0fce0f2bad313)) + + +### Bug Fixes + +* **client:** mark some request bodies as optional ([dc21cae](https://github.com/runloopai/api-client-python/commit/dc21caec97e15ccde2c396c6a2f0fce0f2bad313)) + + +### Chores + +* **internal:** codegen related update ([#551](https://github.com/runloopai/api-client-python/issues/551)) ([8dd01a1](https://github.com/runloopai/api-client-python/commit/8dd01a1e69d82ccbc4f05b72bd980d16cb93e5e5)) +* **internal:** fix devcontainers setup ([#554](https://github.com/runloopai/api-client-python/issues/554)) ([9260eb4](https://github.com/runloopai/api-client-python/commit/9260eb4443fc50ecb07e99af2307896e32027158)) +* **internal:** properly set __pydantic_private__ ([#556](https://github.com/runloopai/api-client-python/issues/556)) ([4496830](https://github.com/runloopai/api-client-python/commit/449683002d1fb31b01c4d167973058684b7ee654)) + ## 0.24.0 (2025-02-19) Full Changelog: [v0.23.0...v0.24.0](https://github.com/runloopai/api-client-python/compare/v0.23.0...v0.24.0) diff --git a/pyproject.toml b/pyproject.toml index 1e703a82d..377bb5507 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "runloop_api_client" -version = "0.24.0" +version = "0.25.0" description = "The official Python library for the runloop API" dynamic = ["readme"] license = "MIT" diff --git a/src/runloop_api_client/_version.py b/src/runloop_api_client/_version.py index c03b20ee6..2bb1b212e 100644 --- a/src/runloop_api_client/_version.py +++ b/src/runloop_api_client/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "runloop_api_client" -__version__ = "0.24.0" # x-release-please-version +__version__ = "0.25.0" # x-release-please-version