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(