diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 2ed3b71..3d2ac0b 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.0.4" + ".": "0.1.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 50b64cc..df4c089 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 27 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/dedalus-labs%2Fdedalus-6a258bad8212a32bd01b1908ab115e08736d156d6907697a7e556b1809383790.yml -openapi_spec_hash: d80976534189646de029c562bb3ca9a1 -config_hash: 795e855c41188604a3e270623e39c126 +configured_endpoints: 29 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/dedalus-labs%2Fdedalus-018f649c40452f64a7454d2841a410297ef931793d4f6dbfebab541b060a2b21.yml +openapi_spec_hash: 7fd462f39c9dcf835904c06fea51ef46 +config_hash: 89f7a7d317d1c89fd73ebaf74c5918cf diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d924d0..15cf848 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 0.1.0 (2026-04-02) + +Full Changelog: [v0.0.4...v0.1.0](https://github.com/dedalus-labs/dedalus-python/compare/v0.0.4...v0.1.0) + +### Features + +* **api:** add sleep & wake methods ([e9709ab](https://github.com/dedalus-labs/dedalus-python/commit/e9709abd85042a51ca1fab6bc4270e3b0ddbe602)) + ## 0.0.4 (2026-04-01) Full Changelog: [v0.0.3...v0.0.4](https://github.com/dedalus-labs/dedalus-python/compare/v0.0.3...v0.0.4) diff --git a/api.md b/api.md index 21d79de..99c0772 100644 --- a/api.md +++ b/api.md @@ -20,6 +20,8 @@ Methods: - client.machines.update(\*, machine_id, \*\*params) -> Machine - client.machines.list(\*\*params) -> SyncCursorPage[MachineListItem] - client.machines.delete(\*, machine_id) -> Machine +- client.machines.sleep(\*, machine_id) -> Machine +- client.machines.wake(\*, machine_id) -> Machine - client.machines.watch(\*, machine_id) -> Machine ## Artifacts diff --git a/pyproject.toml b/pyproject.toml index 9186892..f155fc1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "dedalus-sdk" -version = "0.0.4" +version = "0.1.0" description = "The official Python library for the Dedalus API" dynamic = ["readme"] license = "MIT" diff --git a/src/dedalus_sdk/_version.py b/src/dedalus_sdk/_version.py index 8004aa5..5288701 100644 --- a/src/dedalus_sdk/_version.py +++ b/src/dedalus_sdk/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "dedalus_sdk" -__version__ = "0.0.4" # x-release-please-version +__version__ = "0.1.0" # x-release-please-version diff --git a/src/dedalus_sdk/resources/machines/machines.py b/src/dedalus_sdk/resources/machines/machines.py index d70fa20..70ad0d1 100644 --- a/src/dedalus_sdk/resources/machines/machines.py +++ b/src/dedalus_sdk/resources/machines/machines.py @@ -335,6 +335,90 @@ def delete( cast_to=Machine, ) + def sleep( + self, + *, + machine_id: str, + if_match: str, + # 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, + ) -> Machine: + """ + Sleep a running machine + + 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 + + idempotency_key: Specify a custom idempotency key for this request + """ + if not machine_id: + raise ValueError(f"Expected a non-empty value for `machine_id` but received {machine_id!r}") + extra_headers = {"If-Match": if_match, **(extra_headers or {})} + return self._post( + path_template("/v1/machines/{machine_id}/sleep", machine_id=machine_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, + ), + cast_to=Machine, + ) + + def wake( + self, + *, + machine_id: str, + if_match: str, + # 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, + ) -> Machine: + """ + Wake a sleeping machine + + 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 + + idempotency_key: Specify a custom idempotency key for this request + """ + if not machine_id: + raise ValueError(f"Expected a non-empty value for `machine_id` but received {machine_id!r}") + extra_headers = {"If-Match": if_match, **(extra_headers or {})} + return self._post( + path_template("/v1/machines/{machine_id}/wake", machine_id=machine_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, + ), + cast_to=Machine, + ) + def watch( self, *, @@ -648,6 +732,90 @@ async def delete( cast_to=Machine, ) + async def sleep( + self, + *, + machine_id: str, + if_match: str, + # 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, + ) -> Machine: + """ + Sleep a running machine + + 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 + + idempotency_key: Specify a custom idempotency key for this request + """ + if not machine_id: + raise ValueError(f"Expected a non-empty value for `machine_id` but received {machine_id!r}") + extra_headers = {"If-Match": if_match, **(extra_headers or {})} + return await self._post( + path_template("/v1/machines/{machine_id}/sleep", machine_id=machine_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, + ), + cast_to=Machine, + ) + + async def wake( + self, + *, + machine_id: str, + if_match: str, + # 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, + ) -> Machine: + """ + Wake a sleeping machine + + 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 + + idempotency_key: Specify a custom idempotency key for this request + """ + if not machine_id: + raise ValueError(f"Expected a non-empty value for `machine_id` but received {machine_id!r}") + extra_headers = {"If-Match": if_match, **(extra_headers or {})} + return await self._post( + path_template("/v1/machines/{machine_id}/wake", machine_id=machine_id), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + idempotency_key=idempotency_key, + ), + cast_to=Machine, + ) + async def watch( self, *, @@ -709,6 +877,12 @@ def __init__(self, machines: MachinesResource) -> None: self.delete = to_raw_response_wrapper( machines.delete, ) + self.sleep = to_raw_response_wrapper( + machines.sleep, + ) + self.wake = to_raw_response_wrapper( + machines.wake, + ) self.watch = to_raw_response_wrapper( machines.watch, ) @@ -753,6 +927,12 @@ def __init__(self, machines: AsyncMachinesResource) -> None: self.delete = async_to_raw_response_wrapper( machines.delete, ) + self.sleep = async_to_raw_response_wrapper( + machines.sleep, + ) + self.wake = async_to_raw_response_wrapper( + machines.wake, + ) self.watch = async_to_raw_response_wrapper( machines.watch, ) @@ -797,6 +977,12 @@ def __init__(self, machines: MachinesResource) -> None: self.delete = to_streamed_response_wrapper( machines.delete, ) + self.sleep = to_streamed_response_wrapper( + machines.sleep, + ) + self.wake = to_streamed_response_wrapper( + machines.wake, + ) self.watch = to_streamed_response_wrapper( machines.watch, ) @@ -841,6 +1027,12 @@ def __init__(self, machines: AsyncMachinesResource) -> None: self.delete = async_to_streamed_response_wrapper( machines.delete, ) + self.sleep = async_to_streamed_response_wrapper( + machines.sleep, + ) + self.wake = async_to_streamed_response_wrapper( + machines.wake, + ) self.watch = async_to_streamed_response_wrapper( machines.watch, ) diff --git a/tests/api_resources/test_machines.py b/tests/api_resources/test_machines.py index 6962809..7b868f7 100644 --- a/tests/api_resources/test_machines.py +++ b/tests/api_resources/test_machines.py @@ -224,6 +224,90 @@ def test_path_params_delete(self, client: Dedalus) -> None: if_match="If-Match", ) + @parametrize + def test_method_sleep(self, client: Dedalus) -> None: + machine = client.machines.sleep( + machine_id="machine_id", + if_match="If-Match", + ) + assert_matches_type(Machine, machine, path=["response"]) + + @parametrize + def test_raw_response_sleep(self, client: Dedalus) -> None: + response = client.machines.with_raw_response.sleep( + machine_id="machine_id", + if_match="If-Match", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + machine = response.parse() + assert_matches_type(Machine, machine, path=["response"]) + + @parametrize + def test_streaming_response_sleep(self, client: Dedalus) -> None: + with client.machines.with_streaming_response.sleep( + machine_id="machine_id", + if_match="If-Match", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + machine = response.parse() + assert_matches_type(Machine, machine, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_sleep(self, client: Dedalus) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `machine_id` but received ''"): + client.machines.with_raw_response.sleep( + machine_id="", + if_match="If-Match", + ) + + @parametrize + def test_method_wake(self, client: Dedalus) -> None: + machine = client.machines.wake( + machine_id="machine_id", + if_match="If-Match", + ) + assert_matches_type(Machine, machine, path=["response"]) + + @parametrize + def test_raw_response_wake(self, client: Dedalus) -> None: + response = client.machines.with_raw_response.wake( + machine_id="machine_id", + if_match="If-Match", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + machine = response.parse() + assert_matches_type(Machine, machine, path=["response"]) + + @parametrize + def test_streaming_response_wake(self, client: Dedalus) -> None: + with client.machines.with_streaming_response.wake( + machine_id="machine_id", + if_match="If-Match", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + machine = response.parse() + assert_matches_type(Machine, machine, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_path_params_wake(self, client: Dedalus) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `machine_id` but received ''"): + client.machines.with_raw_response.wake( + machine_id="", + if_match="If-Match", + ) + @parametrize def test_method_watch(self, client: Dedalus) -> None: machine_stream = client.machines.watch( @@ -478,6 +562,90 @@ async def test_path_params_delete(self, async_client: AsyncDedalus) -> None: if_match="If-Match", ) + @parametrize + async def test_method_sleep(self, async_client: AsyncDedalus) -> None: + machine = await async_client.machines.sleep( + machine_id="machine_id", + if_match="If-Match", + ) + assert_matches_type(Machine, machine, path=["response"]) + + @parametrize + async def test_raw_response_sleep(self, async_client: AsyncDedalus) -> None: + response = await async_client.machines.with_raw_response.sleep( + machine_id="machine_id", + if_match="If-Match", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + machine = await response.parse() + assert_matches_type(Machine, machine, path=["response"]) + + @parametrize + async def test_streaming_response_sleep(self, async_client: AsyncDedalus) -> None: + async with async_client.machines.with_streaming_response.sleep( + machine_id="machine_id", + if_match="If-Match", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + machine = await response.parse() + assert_matches_type(Machine, machine, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_sleep(self, async_client: AsyncDedalus) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `machine_id` but received ''"): + await async_client.machines.with_raw_response.sleep( + machine_id="", + if_match="If-Match", + ) + + @parametrize + async def test_method_wake(self, async_client: AsyncDedalus) -> None: + machine = await async_client.machines.wake( + machine_id="machine_id", + if_match="If-Match", + ) + assert_matches_type(Machine, machine, path=["response"]) + + @parametrize + async def test_raw_response_wake(self, async_client: AsyncDedalus) -> None: + response = await async_client.machines.with_raw_response.wake( + machine_id="machine_id", + if_match="If-Match", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + machine = await response.parse() + assert_matches_type(Machine, machine, path=["response"]) + + @parametrize + async def test_streaming_response_wake(self, async_client: AsyncDedalus) -> None: + async with async_client.machines.with_streaming_response.wake( + machine_id="machine_id", + if_match="If-Match", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + machine = await response.parse() + assert_matches_type(Machine, machine, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_path_params_wake(self, async_client: AsyncDedalus) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `machine_id` but received ''"): + await async_client.machines.with_raw_response.wake( + machine_id="", + if_match="If-Match", + ) + @parametrize async def test_method_watch(self, async_client: AsyncDedalus) -> None: machine_stream = await async_client.machines.watch(