From 6040b909d9505719a9439b0351c14bdad5ed5c6a Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 15 May 2026 18:44:37 +0000
Subject: [PATCH 01/18] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index bc3166c..5881d87 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 32
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/dedalus-labs/dedalus-a63ad804ae8ee532d57afae307595dae02d2a6924f83657430b3579193560775.yml
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/dedalus-labs/dedalus-496eeda72044dcdea7432ae162e71388cc0010253739b4d517caea45a4a73278.yml
openapi_spec_hash: ccb02923079d91569a17162c88da590b
-config_hash: 0e31b0b75cafdbc25febc2b7ca219799
+config_hash: 1496c4ae7adec54338483c55916ef732
From 526842c65902305c976856acc1e89088d3caa543 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 15 May 2026 18:45:02 +0000
Subject: [PATCH 02/18] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 5881d87..0c1f5e5 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 32
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/dedalus-labs/dedalus-496eeda72044dcdea7432ae162e71388cc0010253739b4d517caea45a4a73278.yml
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/dedalus-labs/dedalus-255658cb585ca9e0e22d6522136a94c0a7ee92b2133cebc9d93b956d70ebc833.yml
openapi_spec_hash: ccb02923079d91569a17162c88da590b
-config_hash: 1496c4ae7adec54338483c55916ef732
+config_hash: 469332dcd8ac2679070aaf2297c43d10
From d78b9b0f1a0aa59dc11e9d5b041c1853028b30fa Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 15 May 2026 18:45:23 +0000
Subject: [PATCH 03/18] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 0c1f5e5..671136c 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 32
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/dedalus-labs/dedalus-255658cb585ca9e0e22d6522136a94c0a7ee92b2133cebc9d93b956d70ebc833.yml
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/dedalus-labs/dedalus-ce9a5eb38a6a68ee96d0469cdfa54e45f08fcfff291c0eadfcf42670a226f984.yml
openapi_spec_hash: ccb02923079d91569a17162c88da590b
-config_hash: 469332dcd8ac2679070aaf2297c43d10
+config_hash: 71e9d1855bb45e6638b5b0c495cf3c2c
From a0e636cf2a3e45182313388553c025b2f16da326 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 15 May 2026 18:46:37 +0000
Subject: [PATCH 04/18] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 671136c..35dd697 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 32
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/dedalus-labs/dedalus-ce9a5eb38a6a68ee96d0469cdfa54e45f08fcfff291c0eadfcf42670a226f984.yml
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/dedalus-labs/dedalus-06b427a6fe04776a3511029c8880058bb1776bbccf25141f4cd99f82ebb76823.yml
openapi_spec_hash: ccb02923079d91569a17162c88da590b
-config_hash: 71e9d1855bb45e6638b5b0c495cf3c2c
+config_hash: 5fa239988e76deec7821933d3360d19e
From e6867956c7324be0d791f9b73f39ad4cbbab5ea0 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 15 May 2026 18:47:05 +0000
Subject: [PATCH 05/18] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 35dd697..c162152 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 32
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/dedalus-labs/dedalus-06b427a6fe04776a3511029c8880058bb1776bbccf25141f4cd99f82ebb76823.yml
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/dedalus-labs/dedalus-9c86c604b59def4ceca916b9a9673fe2b5d03479ad4494077dbb9dffa9ccf513.yml
openapi_spec_hash: ccb02923079d91569a17162c88da590b
-config_hash: 5fa239988e76deec7821933d3360d19e
+config_hash: f28655c695f7aa7c5aa2fec40b3861cf
From a84b7e508110e3284a96ab209c22e10509a9b645 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 15 May 2026 18:47:48 +0000
Subject: [PATCH 06/18] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index c162152..3478eb5 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 32
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/dedalus-labs/dedalus-9c86c604b59def4ceca916b9a9673fe2b5d03479ad4494077dbb9dffa9ccf513.yml
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/dedalus-labs/dedalus-8612890eae5e55f9236ad984991f4dc3712138acaa0005be3de43dabc6cd54d4.yml
openapi_spec_hash: ccb02923079d91569a17162c88da590b
-config_hash: f28655c695f7aa7c5aa2fec40b3861cf
+config_hash: 8b2f74aaf8a9b5a01242e7c23f721082
From 815e6cf23c12a76a7079852d8f638e312c80a5f1 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 15 May 2026 18:55:28 +0000
Subject: [PATCH 07/18] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 3478eb5..b3016f2 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 32
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/dedalus-labs/dedalus-8612890eae5e55f9236ad984991f4dc3712138acaa0005be3de43dabc6cd54d4.yml
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/dedalus-labs/dedalus-612bc4e434529d5007d868e94cb7951ad9b13d2c6751b21dbe03f66fecae071c.yml
openapi_spec_hash: ccb02923079d91569a17162c88da590b
-config_hash: 8b2f74aaf8a9b5a01242e7c23f721082
+config_hash: cce16da42a2fc50117c5b029105bfed4
From d3b35cc33a8893987156ccf3423cdd9cac5261ef Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 15 May 2026 18:55:48 +0000
Subject: [PATCH 08/18] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index b3016f2..dba28b8 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 32
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/dedalus-labs/dedalus-612bc4e434529d5007d868e94cb7951ad9b13d2c6751b21dbe03f66fecae071c.yml
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/dedalus-labs/dedalus-1146618a914ccbc1ea9f140f6cfcd2afb2e6a4d76a893f08544cdc97ac9675ad.yml
openapi_spec_hash: ccb02923079d91569a17162c88da590b
-config_hash: cce16da42a2fc50117c5b029105bfed4
+config_hash: b0eb655326acff151a95e2ea086d31d8
From f02dd01cb460c7caf9a25f53682d0de331e0bbae Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 15 May 2026 18:56:08 +0000
Subject: [PATCH 09/18] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index dba28b8..f978da4 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 32
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/dedalus-labs/dedalus-1146618a914ccbc1ea9f140f6cfcd2afb2e6a4d76a893f08544cdc97ac9675ad.yml
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/dedalus-labs/dedalus-5d397081e492cd0e3832b7065574c06c90a67312c1c4caed119aa6c7c53c4d28.yml
openapi_spec_hash: ccb02923079d91569a17162c88da590b
-config_hash: b0eb655326acff151a95e2ea086d31d8
+config_hash: f3b61260a0c9a88977fb5fc3b355047b
From 49f99666068e5631520102bb4c0441e0e46dba59 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 15 May 2026 18:56:29 +0000
Subject: [PATCH 10/18] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index f978da4..0d2495a 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 32
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/dedalus-labs/dedalus-5d397081e492cd0e3832b7065574c06c90a67312c1c4caed119aa6c7c53c4d28.yml
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/dedalus-labs/dedalus-2dccfe89b18a8eeb1379dc7286bb65448973493b17fc1cc2af1f08ba674c216a.yml
openapi_spec_hash: ccb02923079d91569a17162c88da590b
-config_hash: f3b61260a0c9a88977fb5fc3b355047b
+config_hash: ca162ca77845038c30f4074f237ae257
From 8338d99194f9f04dbb7a44638df69f4e6e8f16e3 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 15 May 2026 18:56:50 +0000
Subject: [PATCH 11/18] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 0d2495a..97d2606 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 32
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/dedalus-labs/dedalus-2dccfe89b18a8eeb1379dc7286bb65448973493b17fc1cc2af1f08ba674c216a.yml
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/dedalus-labs/dedalus-918ae3967dc06a6b31d32b88cf02e77784d8234c1a9baf78763de249b7f8928a.yml
openapi_spec_hash: ccb02923079d91569a17162c88da590b
-config_hash: ca162ca77845038c30f4074f237ae257
+config_hash: 9cc9389d5c9a7e611f3544ede6b6263a
From 221a201060ee6f9c191704d208ee9ae4569733cf Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 15 May 2026 19:34:03 +0000
Subject: [PATCH 12/18] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 97d2606..dcb3502 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 32
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/dedalus-labs/dedalus-918ae3967dc06a6b31d32b88cf02e77784d8234c1a9baf78763de249b7f8928a.yml
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/dedalus-labs/dedalus-32ccb3c17674e0ee68fd6eafbdd0f210bccfd09fce0702e28b8278e06678deec.yml
openapi_spec_hash: ccb02923079d91569a17162c88da590b
-config_hash: 9cc9389d5c9a7e611f3544ede6b6263a
+config_hash: 3b16603a18779d453842a0d56638384d
From 81f3c288b2ae2e97046344177500714e1e4ce6be Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 17 Jun 2026 17:31:39 +0000
Subject: [PATCH 13/18] fix(auth): prioritize first auth header
---
src/dedalus_sdk/_client.py | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/src/dedalus_sdk/_client.py b/src/dedalus_sdk/_client.py
index c6dc994..ec68f90 100644
--- a/src/dedalus_sdk/_client.py
+++ b/src/dedalus_sdk/_client.py
@@ -161,10 +161,14 @@ def qs(self) -> Querystring:
@override
def _auth_headers(self, security: SecurityOptions) -> dict[str, str]:
- return {
- **(self._api_key_auth if security.get("api_key_auth", False) else {}),
- **(self._bearer_auth if security.get("bearer_auth", False) else {}),
- }
+ headers: dict[str, str] = {}
+ if security.get("api_key_auth", False):
+ for key, value in self._api_key_auth.items():
+ headers.setdefault(key, value)
+ if security.get("bearer_auth", False):
+ for key, value in self._bearer_auth.items():
+ headers.setdefault(key, value)
+ return headers
@property
def _api_key_auth(self) -> dict[str, str]:
@@ -410,10 +414,14 @@ def qs(self) -> Querystring:
@override
def _auth_headers(self, security: SecurityOptions) -> dict[str, str]:
- return {
- **(self._api_key_auth if security.get("api_key_auth", False) else {}),
- **(self._bearer_auth if security.get("bearer_auth", False) else {}),
- }
+ headers: dict[str, str] = {}
+ if security.get("api_key_auth", False):
+ for key, value in self._api_key_auth.items():
+ headers.setdefault(key, value)
+ if security.get("bearer_auth", False):
+ for key, value in self._bearer_auth.items():
+ headers.setdefault(key, value)
+ return headers
@property
def _api_key_auth(self) -> dict[str, str]:
From c10ce00180c146772ec9f390e3d058a1d9462082 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 13 Jul 2026 18:44:14 +0000
Subject: [PATCH 14/18] fix(internal): resolve build failures
---
scripts/lint | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/lint b/scripts/lint
index 5887ad5..371f4fa 100755
--- a/scripts/lint
+++ b/scripts/lint
@@ -13,7 +13,7 @@ else
fi
echo "==> Running pyright"
-uv run pyright
+uv run pyright -p .
echo "==> Running mypy"
uv run mypy .
From 6acb1d303d2a07cf6c01f63005a4f98541c47f40 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 17 Jul 2026 17:22:07 +0000
Subject: [PATCH 15/18] feat(stlc): configurable CI runner and
private-production-repo support in workflow templates
---
.github/workflows/ci.yml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 06b9186..a908819 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -18,7 +18,7 @@ jobs:
lint:
timeout-minutes: 10
name: lint
- runs-on: ${{ github.repository == 'stainless-sdks/dedalus-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
+ runs-on: ${{ startsWith(github.repository, 'stainless-sdks/') && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata')
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -41,7 +41,7 @@ jobs:
permissions:
contents: read
id-token: write
- runs-on: ${{ github.repository == 'stainless-sdks/dedalus-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
+ runs-on: ${{ startsWith(github.repository, 'stainless-sdks/') && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -78,7 +78,7 @@ jobs:
test:
timeout-minutes: 10
name: test
- runs-on: ${{ github.repository == 'stainless-sdks/dedalus-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
+ runs-on: ${{ startsWith(github.repository, 'stainless-sdks/') && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
From aa8a0ee9f29ad6fa93a917baba1ab0ffaebb6959 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 19 Aug 2026 17:33:17 +0000
Subject: [PATCH 16/18] chore(internal): allow the mock server port to be set
with STAINLESS_MOCK_PORT
---
scripts/mock | 13 ++++++++++---
scripts/test | 12 +++++++++---
2 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/scripts/mock b/scripts/mock
index 9c7c439..6376077 100755
--- a/scripts/mock
+++ b/scripts/mock
@@ -4,6 +4,11 @@ set -e
cd "$(dirname "$0")/.."
+if [ "$1" == "--install" ]; then
+ npm exec --package=@stdy/cli@0.22.1 -- steady --version
+ exit 0
+fi
+
if [[ -n "$1" && "$1" != '--'* ]]; then
URL="$1"
shift
@@ -20,16 +25,18 @@ fi
echo "==> Starting mock server with URL ${URL}"
# Run steady mock on the given spec
+MOCK_PORT="${STAINLESS_MOCK_PORT:-4010}"
+
if [ "$1" == "--daemon" ]; then
# Pre-install the package so the download doesn't eat into the startup timeout
npm exec --package=@stdy/cli@0.22.1 -- steady --version
- npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=repeat --validator-form-array-format=repeat --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" &> .stdy.log &
+ npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p "$MOCK_PORT" --validator-query-array-format=repeat --validator-form-array-format=repeat --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" &> .stdy.log &
# Wait for server to come online via health endpoint (max 30s)
echo -n "Waiting for server"
attempts=0
- while ! curl --silent --fail "http://127.0.0.1:4010/_x-steady/health" >/dev/null 2>&1; do
+ while ! curl --silent --fail "http://127.0.0.1:$MOCK_PORT/_x-steady/health" >/dev/null 2>&1; do
if ! kill -0 $! 2>/dev/null; then
echo
cat .stdy.log
@@ -48,5 +55,5 @@ if [ "$1" == "--daemon" ]; then
echo
else
- npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=repeat --validator-form-array-format=repeat --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL"
+ npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p "$MOCK_PORT" --validator-query-array-format=repeat --validator-form-array-format=repeat --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL"
fi
diff --git a/scripts/test b/scripts/test
index f371e71..caf18b7 100755
--- a/scripts/test
+++ b/scripts/test
@@ -9,8 +9,10 @@ GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color
+MOCK_PORT="${STAINLESS_MOCK_PORT:-4010}"
+
function steady_is_running() {
- curl --silent "http://127.0.0.1:4010/_x-steady/health" >/dev/null 2>&1
+ curl --silent "http://127.0.0.1:$MOCK_PORT/_x-steady/health" >/dev/null 2>&1
}
kill_server_on_port() {
@@ -27,7 +29,7 @@ function is_overriding_api_base_url() {
if ! is_overriding_api_base_url && ! steady_is_running ; then
# When we exit this script, make sure to kill the background mock server process
- trap 'kill_server_on_port 4010' EXIT
+ trap 'kill_server_on_port "$MOCK_PORT"' EXIT
# Start the dev server
./scripts/mock --daemon
@@ -43,7 +45,7 @@ elif ! steady_is_running ; then
echo -e "To run the server, pass in the path or url of your OpenAPI"
echo -e "spec to the steady command:"
echo
- echo -e " \$ ${YELLOW}npm exec --package=@stdy/cli@0.22.1 -- steady path/to/your.openapi.yml --host 127.0.0.1 -p 4010 --validator-query-array-format=repeat --validator-form-array-format=repeat --validator-query-object-format=brackets --validator-form-object-format=brackets${NC}"
+ echo -e " \$ ${YELLOW}npm exec --package=@stdy/cli@0.22.1 -- steady path/to/your.openapi.yml --host 127.0.0.1 -p $MOCK_PORT --validator-query-array-format=repeat --validator-form-array-format=repeat --validator-query-object-format=brackets --validator-form-object-format=brackets${NC}"
echo
exit 1
@@ -52,6 +54,10 @@ else
echo
fi
+if [ -n "${STAINLESS_MOCK_PORT:-}" ] && ! is_overriding_api_base_url ; then
+ export TEST_API_BASE_URL="http://127.0.0.1:$MOCK_PORT"
+fi
+
export DEFER_PYDANTIC_BUILD=false
# Note that we need to specify the patch version here so that uv
From 04208ef05cb07426d68717abb57835e089b76205 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 1 Sep 2026 23:01:18 +0000
Subject: [PATCH 17/18] feat(api)!: regenerate SDKs from the current public DCS
contract
Align all generated SDKs and the CLI with the canonical main-branch OpenAPI spec. Remove SDK-hidden usage, status streaming, artifact, preview, and terminal surfaces; retain machine lifecycle, SSH, and execution operations.
---
.stats.yml | 8 +-
README.md | 30 -
api.md | 79 +-
pyproject.toml | 1 -
src/dedalus_sdk/__init__.py | 7 -
src/dedalus_sdk/_client.py | 69 +-
src/dedalus_sdk/_event_handler.py | 85 -
src/dedalus_sdk/_exceptions.py | 18 -
src/dedalus_sdk/_send_queue.py | 90 -
src/dedalus_sdk/_streaming.py | 42 +-
src/dedalus_sdk/resources/__init__.py | 14 -
.../resources/machines/__init__.py | 42 -
.../resources/machines/artifacts.py | 382 -----
.../resources/machines/machines.py | 240 +--
.../resources/machines/previews.py | 498 ------
.../resources/machines/terminals.py | 1503 -----------------
src/dedalus_sdk/resources/usage.py | 411 -----
src/dedalus_sdk/types/__init__.py | 14 +-
src/dedalus_sdk/types/machine.py | 13 +-
.../types/machine_compute_usage.py | 23 -
.../types/machine_compute_usage_row.py | 58 -
.../types/machine_create_params.py | 20 +-
src/dedalus_sdk/types/machine_list_item.py | 13 +-
.../types/machine_retrieve_response.py | 27 +
.../types/machine_storage_usage.py | 20 -
.../types/machine_storage_usage_row.py | 34 -
src/dedalus_sdk/types/machines/__init__.py | 21 -
src/dedalus_sdk/types/machines/artifact.py | 30 -
.../types/machines/artifact_list.py | 14 -
.../types/machines/artifact_list_params.py | 15 -
src/dedalus_sdk/types/machines/preview.py | 37 -
.../types/machines/preview_create_params.py | 17 -
.../types/machines/preview_list.py | 14 -
.../types/machines/preview_list_params.py | 15 -
src/dedalus_sdk/types/machines/terminal.py | 37 -
.../types/machines/terminal_client_event.py | 14 -
.../machines/terminal_client_event_param.py | 13 -
.../types/machines/terminal_closed_event.py | 11 -
.../types/machines/terminal_create_params.py | 22 -
.../types/machines/terminal_error_event.py | 16 -
.../types/machines/terminal_input_event.py | 14 -
.../machines/terminal_input_event_param.py | 22 -
.../types/machines/terminal_list.py | 14 -
.../types/machines/terminal_list_params.py | 15 -
.../types/machines/terminal_output_event.py | 14 -
.../types/machines/terminal_resize_event.py | 15 -
.../machines/terminal_resize_event_param.py | 15 -
.../types/machines/terminal_server_event.py | 15 -
src/dedalus_sdk/types/org_usage.py | 37 -
.../types/usage_machine_compute_params.py | 21 -
.../types/usage_machine_storage_params.py | 18 -
.../types/usage_retrieve_params.py | 12 -
.../types/websocket_connection_options.py | 36 -
.../types/websocket_reconnection.py | 64 -
.../api_resources/machines/test_artifacts.py | 311 ----
.../api_resources/machines/test_executions.py | 100 +-
tests/api_resources/machines/test_previews.py | 415 -----
tests/api_resources/machines/test_ssh.py | 60 +-
.../api_resources/machines/test_terminals.py | 427 -----
tests/api_resources/test_machines.py | 215 +--
tests/api_resources/test_usage.py | 230 ---
tests/test_client.py | 51 +-
tests/test_send_queue.py | 128 --
uv.lock | 82 +-
64 files changed, 237 insertions(+), 6111 deletions(-)
delete mode 100644 src/dedalus_sdk/_event_handler.py
delete mode 100644 src/dedalus_sdk/_send_queue.py
delete mode 100644 src/dedalus_sdk/resources/machines/artifacts.py
delete mode 100644 src/dedalus_sdk/resources/machines/previews.py
delete mode 100644 src/dedalus_sdk/resources/machines/terminals.py
delete mode 100644 src/dedalus_sdk/resources/usage.py
delete mode 100644 src/dedalus_sdk/types/machine_compute_usage.py
delete mode 100644 src/dedalus_sdk/types/machine_compute_usage_row.py
create mode 100644 src/dedalus_sdk/types/machine_retrieve_response.py
delete mode 100644 src/dedalus_sdk/types/machine_storage_usage.py
delete mode 100644 src/dedalus_sdk/types/machine_storage_usage_row.py
delete mode 100644 src/dedalus_sdk/types/machines/artifact.py
delete mode 100644 src/dedalus_sdk/types/machines/artifact_list.py
delete mode 100644 src/dedalus_sdk/types/machines/artifact_list_params.py
delete mode 100644 src/dedalus_sdk/types/machines/preview.py
delete mode 100644 src/dedalus_sdk/types/machines/preview_create_params.py
delete mode 100644 src/dedalus_sdk/types/machines/preview_list.py
delete mode 100644 src/dedalus_sdk/types/machines/preview_list_params.py
delete mode 100644 src/dedalus_sdk/types/machines/terminal.py
delete mode 100644 src/dedalus_sdk/types/machines/terminal_client_event.py
delete mode 100644 src/dedalus_sdk/types/machines/terminal_client_event_param.py
delete mode 100644 src/dedalus_sdk/types/machines/terminal_closed_event.py
delete mode 100644 src/dedalus_sdk/types/machines/terminal_create_params.py
delete mode 100644 src/dedalus_sdk/types/machines/terminal_error_event.py
delete mode 100644 src/dedalus_sdk/types/machines/terminal_input_event.py
delete mode 100644 src/dedalus_sdk/types/machines/terminal_input_event_param.py
delete mode 100644 src/dedalus_sdk/types/machines/terminal_list.py
delete mode 100644 src/dedalus_sdk/types/machines/terminal_list_params.py
delete mode 100644 src/dedalus_sdk/types/machines/terminal_output_event.py
delete mode 100644 src/dedalus_sdk/types/machines/terminal_resize_event.py
delete mode 100644 src/dedalus_sdk/types/machines/terminal_resize_event_param.py
delete mode 100644 src/dedalus_sdk/types/machines/terminal_server_event.py
delete mode 100644 src/dedalus_sdk/types/org_usage.py
delete mode 100644 src/dedalus_sdk/types/usage_machine_compute_params.py
delete mode 100644 src/dedalus_sdk/types/usage_machine_storage_params.py
delete mode 100644 src/dedalus_sdk/types/usage_retrieve_params.py
delete mode 100644 src/dedalus_sdk/types/websocket_connection_options.py
delete mode 100644 src/dedalus_sdk/types/websocket_reconnection.py
delete mode 100644 tests/api_resources/machines/test_artifacts.py
delete mode 100644 tests/api_resources/machines/test_previews.py
delete mode 100644 tests/api_resources/machines/test_terminals.py
delete mode 100644 tests/api_resources/test_usage.py
delete mode 100644 tests/test_send_queue.py
diff --git a/.stats.yml b/.stats.yml
index dcb3502..6d1924d 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 32
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/dedalus-labs/dedalus-32ccb3c17674e0ee68fd6eafbdd0f210bccfd09fce0702e28b8278e06678deec.yml
-openapi_spec_hash: ccb02923079d91569a17162c88da590b
-config_hash: 3b16603a18779d453842a0d56638384d
+configured_endpoints: 17
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/dedalus-labs/dedalus-c0e28b234478af75f61bcf42f5f32818d96ec93b1d8239fa0ff1c801c0e4b64f.yml
+openapi_spec_hash: a70c391bb0957fc90c5dbf251de8afe4
+config_hash: fa45a5bf161b7291cb5ea20c2da83cc0
diff --git a/README.md b/README.md
index 7615cb4..0d2e4f5 100644
--- a/README.md
+++ b/README.md
@@ -118,36 +118,6 @@ async def main() -> None:
asyncio.run(main())
```
-## Streaming responses
-
-We provide support for streaming responses using Server Side Events (SSE).
-
-```python
-from dedalus_sdk import Dedalus
-
-client = Dedalus()
-
-stream = client.machines.watch(
- machine_id="dm-3",
-)
-for machine in stream:
- print(machine.machine_id)
-```
-
-The async client uses the exact same interface.
-
-```python
-from dedalus_sdk import AsyncDedalus
-
-client = AsyncDedalus()
-
-stream = await client.machines.watch(
- machine_id="dm-3",
-)
-async for machine in stream:
- print(machine.machine_id)
-```
-
## Using types
Nested request parameters are [TypedDicts](https://docs.python.org/3/library/typing.html#typing.TypedDict). Responses are [Pydantic models](https://docs.pydantic.dev) which also provide helper methods for things like:
diff --git a/api.md b/api.md
index 0f1d5dd..7941ddf 100644
--- a/api.md
+++ b/api.md
@@ -1,23 +1,3 @@
-# Usage
-
-Types:
-
-```python
-from dedalus_sdk.types import (
- MachineComputeUsage,
- MachineComputeUsageRow,
- MachineStorageUsage,
- MachineStorageUsageRow,
- OrgUsage,
-)
-```
-
-Methods:
-
-- client.usage.retrieve(\*\*params) -> OrgUsage
-- client.usage.machine_compute(\*\*params) -> MachineComputeUsage
-- client.usage.machine_storage(\*\*params) -> MachineStorageUsage
-
# Machines
Types:
@@ -30,48 +10,19 @@ from dedalus_sdk.types import (
MachineList,
MachineListItem,
UpdateParams,
+ MachineRetrieveResponse,
)
```
Methods:
- client.machines.create(\*\*params) -> Machine
-- client.machines.retrieve(\*, machine_id) -> Machine
+- client.machines.retrieve(\*, machine_id) -> MachineRetrieveResponse
- 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
-
-Types:
-
-```python
-from dedalus_sdk.types.machines import Artifact, ArtifactList
-```
-
-Methods:
-
-- client.machines.artifacts.retrieve(\*, machine_id, artifact_id) -> Artifact
-- client.machines.artifacts.list(\*, machine_id, \*\*params) -> SyncCursorPage[Artifact]
-- client.machines.artifacts.delete(\*, machine_id, artifact_id) -> Artifact
-
-## Previews
-
-Types:
-
-```python
-from dedalus_sdk.types.machines import Preview, PreviewCreateParams, PreviewList
-```
-
-Methods:
-
-- client.machines.previews.create(\*, machine_id, \*\*params) -> Preview
-- client.machines.previews.retrieve(\*, machine_id, preview_id) -> Preview
-- client.machines.previews.list(\*, machine_id, \*\*params) -> SyncCursorPage[Preview]
-- client.machines.previews.delete(\*, machine_id, preview_id) -> Preview
## SSH
@@ -118,29 +69,3 @@ Methods:
- client.machines.executions.delete(\*, machine_id, execution_id) -> Execution
- client.machines.executions.events(\*, machine_id, execution_id, \*\*params) -> SyncCursorPage[ExecutionEvent]
- client.machines.executions.output(\*, machine_id, execution_id) -> ExecutionOutput
-
-## Terminals
-
-Types:
-
-```python
-from dedalus_sdk.types.machines import (
- Terminal,
- TerminalClientEvent,
- TerminalClosedEvent,
- TerminalCreateParams,
- TerminalErrorEvent,
- TerminalInputEvent,
- TerminalList,
- TerminalOutputEvent,
- TerminalResizeEvent,
- TerminalServerEvent,
-)
-```
-
-Methods:
-
-- client.machines.terminals.create(\*, machine_id, \*\*params) -> Terminal
-- client.machines.terminals.retrieve(\*, machine_id, terminal_id) -> Terminal
-- client.machines.terminals.list(\*, machine_id, \*\*params) -> SyncCursorPage[Terminal]
-- client.machines.terminals.delete(\*, machine_id, terminal_id) -> Terminal
diff --git a/pyproject.toml b/pyproject.toml
index 9fa189c..16fdcbd 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -42,7 +42,6 @@ Repository = "https://github.com/dedalus-labs/dedalus-python"
[project.optional-dependencies]
aiohttp = ["aiohttp", "httpx_aiohttp>=0.1.9"]
-websockets = ["websockets >= 13, < 16"]
[tool.uv]
managed = true
diff --git a/src/dedalus_sdk/__init__.py b/src/dedalus_sdk/__init__.py
index 2aa7c7c..140521a 100644
--- a/src/dedalus_sdk/__init__.py
+++ b/src/dedalus_sdk/__init__.py
@@ -23,14 +23,11 @@
AuthenticationError,
InternalServerError,
PermissionDeniedError,
- WebSocketQueueFullError,
UnprocessableEntityError,
APIResponseValidationError,
- WebSocketConnectionClosedError,
)
from ._base_client import DefaultHttpxClient, DefaultAioHttpClient, DefaultAsyncHttpxClient
from ._utils._logs import setup_logging as _setup_logging
-from .types.websocket_reconnection import ReconnectingEvent, ReconnectingOverrides
__all__ = [
"types",
@@ -74,10 +71,6 @@
"DefaultHttpxClient",
"DefaultAsyncHttpxClient",
"DefaultAioHttpClient",
- "ReconnectingEvent",
- "ReconnectingOverrides",
- "WebSocketQueueFullError",
- "WebSocketConnectionClosedError",
]
if not _t.TYPE_CHECKING:
diff --git a/src/dedalus_sdk/_client.py b/src/dedalus_sdk/_client.py
index ec68f90..53fbd0e 100644
--- a/src/dedalus_sdk/_client.py
+++ b/src/dedalus_sdk/_client.py
@@ -37,8 +37,7 @@
)
if TYPE_CHECKING:
- from .resources import usage, machines
- from .resources.usage import UsageResource, AsyncUsageResource
+ from .resources import machines
from .resources.machines.machines import MachinesResource, AsyncMachinesResource
__all__ = ["Timeout", "Transport", "ProxiesTypes", "RequestOptions", "Dedalus", "AsyncDedalus", "Client", "AsyncClient"]
@@ -50,14 +49,6 @@ class Dedalus(SyncAPIClient):
x_api_key: str | None
dedalus_org_id: str | None
- websocket_base_url: str | httpx.URL | None
- """Base URL for WebSocket connections.
-
- If not specified, the default base URL will be used, with 'wss://' replacing the
- 'http://' or 'https://' scheme. For example: 'http://example.com' becomes
- 'wss://example.com'
- """
-
def __init__(
self,
*,
@@ -65,7 +56,6 @@ def __init__(
x_api_key: str | None = None,
dedalus_org_id: str | None = None,
base_url: str | httpx.URL | None = None,
- websocket_base_url: str | httpx.URL | None = None,
timeout: float | Timeout | None | NotGiven = not_given,
max_retries: int = DEFAULT_MAX_RETRIES,
default_headers: Mapping[str, str] | None = None,
@@ -103,8 +93,6 @@ def __init__(
dedalus_org_id = os.environ.get("DEDALUS_ORG_ID")
self.dedalus_org_id = dedalus_org_id
- self.websocket_base_url = websocket_base_url
-
if base_url is None:
base_url = os.environ.get("DEDALUS_BASE_URL")
if base_url is None:
@@ -132,14 +120,6 @@ def __init__(
self._idempotency_header = "Idempotency-Key"
- self._default_stream_cls = Stream
-
- @cached_property
- def usage(self) -> UsageResource:
- from .resources.usage import UsageResource
-
- return UsageResource(self)
-
@cached_property
def machines(self) -> MachinesResource:
from .resources.machines import MachinesResource
@@ -212,7 +192,6 @@ def copy(
api_key: str | None = None,
x_api_key: str | None = None,
dedalus_org_id: str | None = None,
- websocket_base_url: str | httpx.URL | None = None,
base_url: str | httpx.URL | None = None,
timeout: float | Timeout | None | NotGiven = not_given,
http_client: httpx.Client | None = None,
@@ -249,7 +228,6 @@ def copy(
api_key=api_key or self.api_key,
x_api_key=x_api_key or self.x_api_key,
dedalus_org_id=dedalus_org_id or self.dedalus_org_id,
- websocket_base_url=websocket_base_url or self.websocket_base_url,
base_url=base_url or self.base_url,
timeout=self.timeout if isinstance(timeout, NotGiven) else timeout,
http_client=http_client,
@@ -303,14 +281,6 @@ class AsyncDedalus(AsyncAPIClient):
x_api_key: str | None
dedalus_org_id: str | None
- websocket_base_url: str | httpx.URL | None
- """Base URL for WebSocket connections.
-
- If not specified, the default base URL will be used, with 'wss://' replacing the
- 'http://' or 'https://' scheme. For example: 'http://example.com' becomes
- 'wss://example.com'
- """
-
def __init__(
self,
*,
@@ -318,7 +288,6 @@ def __init__(
x_api_key: str | None = None,
dedalus_org_id: str | None = None,
base_url: str | httpx.URL | None = None,
- websocket_base_url: str | httpx.URL | None = None,
timeout: float | Timeout | None | NotGiven = not_given,
max_retries: int = DEFAULT_MAX_RETRIES,
default_headers: Mapping[str, str] | None = None,
@@ -356,8 +325,6 @@ def __init__(
dedalus_org_id = os.environ.get("DEDALUS_ORG_ID")
self.dedalus_org_id = dedalus_org_id
- self.websocket_base_url = websocket_base_url
-
if base_url is None:
base_url = os.environ.get("DEDALUS_BASE_URL")
if base_url is None:
@@ -385,14 +352,6 @@ def __init__(
self._idempotency_header = "Idempotency-Key"
- self._default_stream_cls = AsyncStream
-
- @cached_property
- def usage(self) -> AsyncUsageResource:
- from .resources.usage import AsyncUsageResource
-
- return AsyncUsageResource(self)
-
@cached_property
def machines(self) -> AsyncMachinesResource:
from .resources.machines import AsyncMachinesResource
@@ -465,7 +424,6 @@ def copy(
api_key: str | None = None,
x_api_key: str | None = None,
dedalus_org_id: str | None = None,
- websocket_base_url: str | httpx.URL | None = None,
base_url: str | httpx.URL | None = None,
timeout: float | Timeout | None | NotGiven = not_given,
http_client: httpx.AsyncClient | None = None,
@@ -502,7 +460,6 @@ def copy(
api_key=api_key or self.api_key,
x_api_key=x_api_key or self.x_api_key,
dedalus_org_id=dedalus_org_id or self.dedalus_org_id,
- websocket_base_url=websocket_base_url or self.websocket_base_url,
base_url=base_url or self.base_url,
timeout=self.timeout if isinstance(timeout, NotGiven) else timeout,
http_client=http_client,
@@ -556,12 +513,6 @@ class DedalusWithRawResponse:
def __init__(self, client: Dedalus) -> None:
self._client = client
- @cached_property
- def usage(self) -> usage.UsageResourceWithRawResponse:
- from .resources.usage import UsageResourceWithRawResponse
-
- return UsageResourceWithRawResponse(self._client.usage)
-
@cached_property
def machines(self) -> machines.MachinesResourceWithRawResponse:
from .resources.machines import MachinesResourceWithRawResponse
@@ -575,12 +526,6 @@ class AsyncDedalusWithRawResponse:
def __init__(self, client: AsyncDedalus) -> None:
self._client = client
- @cached_property
- def usage(self) -> usage.AsyncUsageResourceWithRawResponse:
- from .resources.usage import AsyncUsageResourceWithRawResponse
-
- return AsyncUsageResourceWithRawResponse(self._client.usage)
-
@cached_property
def machines(self) -> machines.AsyncMachinesResourceWithRawResponse:
from .resources.machines import AsyncMachinesResourceWithRawResponse
@@ -594,12 +539,6 @@ class DedalusWithStreamedResponse:
def __init__(self, client: Dedalus) -> None:
self._client = client
- @cached_property
- def usage(self) -> usage.UsageResourceWithStreamingResponse:
- from .resources.usage import UsageResourceWithStreamingResponse
-
- return UsageResourceWithStreamingResponse(self._client.usage)
-
@cached_property
def machines(self) -> machines.MachinesResourceWithStreamingResponse:
from .resources.machines import MachinesResourceWithStreamingResponse
@@ -613,12 +552,6 @@ class AsyncDedalusWithStreamedResponse:
def __init__(self, client: AsyncDedalus) -> None:
self._client = client
- @cached_property
- def usage(self) -> usage.AsyncUsageResourceWithStreamingResponse:
- from .resources.usage import AsyncUsageResourceWithStreamingResponse
-
- return AsyncUsageResourceWithStreamingResponse(self._client.usage)
-
@cached_property
def machines(self) -> machines.AsyncMachinesResourceWithStreamingResponse:
from .resources.machines import AsyncMachinesResourceWithStreamingResponse
diff --git a/src/dedalus_sdk/_event_handler.py b/src/dedalus_sdk/_event_handler.py
deleted file mode 100644
index d9a3a59..0000000
--- a/src/dedalus_sdk/_event_handler.py
+++ /dev/null
@@ -1,85 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import threading
-from typing import Any, Callable
-
-EventHandler = Callable[..., Any]
-
-
-class EventHandlerRegistry:
- """Thread-safe (optional) registry of event handlers."""
-
- def __init__(self, *, use_lock: bool = False) -> None:
- self._handlers: dict[str, list[EventHandler]] = {}
- self._once_ids: set[int] = set()
- self._lock: threading.Lock | None = threading.Lock() if use_lock else None
-
- def _acquire(self) -> None:
- if self._lock is not None:
- self._lock.acquire()
-
- def _release(self) -> None:
- if self._lock is not None:
- self._lock.release()
-
- def add(self, event_type: str, handler: EventHandler, *, once: bool = False) -> None:
- self._acquire()
- try:
- handlers = self._handlers.setdefault(event_type, [])
- handlers.append(handler)
- if once:
- self._once_ids.add(id(handler))
- finally:
- self._release()
-
- def remove(self, event_type: str, handler: EventHandler) -> None:
- self._acquire()
- try:
- handlers = self._handlers.get(event_type)
- if handlers is not None:
- try:
- handlers.remove(handler)
- except ValueError:
- pass
- self._once_ids.discard(id(handler))
- finally:
- self._release()
-
- def get_handlers(self, event_type: str) -> list[EventHandler]:
- """Return a snapshot of handlers for the given event type, removing once-handlers."""
- self._acquire()
- try:
- handlers = self._handlers.get(event_type)
- if not handlers:
- return []
- result = list(handlers)
- to_remove = [h for h in result if id(h) in self._once_ids]
- for h in to_remove:
- handlers.remove(h)
- self._once_ids.discard(id(h))
- return result
- finally:
- self._release()
-
- def has_handlers(self, event_type: str) -> bool:
- self._acquire()
- try:
- handlers = self._handlers.get(event_type)
- return bool(handlers)
- finally:
- self._release()
-
- def merge_into(self, target: EventHandlerRegistry) -> None:
- """Move all handlers from this registry into *target*, then clear self."""
- self._acquire()
- try:
- for event_type, handlers in self._handlers.items():
- for handler in handlers:
- once = id(handler) in self._once_ids
- target.add(event_type, handler, once=once)
- self._handlers.clear()
- self._once_ids.clear()
- finally:
- self._release()
diff --git a/src/dedalus_sdk/_exceptions.py b/src/dedalus_sdk/_exceptions.py
index f0c7fe2..b1b6b06 100644
--- a/src/dedalus_sdk/_exceptions.py
+++ b/src/dedalus_sdk/_exceptions.py
@@ -15,8 +15,6 @@
"UnprocessableEntityError",
"RateLimitError",
"InternalServerError",
- "WebSocketConnectionClosedError",
- "WebSocketQueueFullError",
]
@@ -108,19 +106,3 @@ class RateLimitError(APIStatusError):
class InternalServerError(APIStatusError):
pass
-
-
-class WebSocketConnectionClosedError(DedalusError):
- """Raised when a WebSocket connection closes with unsent messages."""
-
- unsent_messages: list[str]
-
- def __init__(self, message: str, *, unsent_messages: list[str]) -> None:
- super().__init__(message)
- self.unsent_messages = unsent_messages
-
-
-class WebSocketQueueFullError(DedalusError):
- """Raised when the outgoing WebSocket message queue exceeds its byte-size limit."""
-
- pass
diff --git a/src/dedalus_sdk/_send_queue.py b/src/dedalus_sdk/_send_queue.py
deleted file mode 100644
index b35d0fb..0000000
--- a/src/dedalus_sdk/_send_queue.py
+++ /dev/null
@@ -1,90 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import typing
-import threading
-
-from ._exceptions import WebSocketQueueFullError
-
-
-class SendQueue:
- """Bounded byte-size queue for outgoing WebSocket messages.
-
- Messages are stored as pre-serialized strings. The queue enforces a
- maximum byte budget so that unbounded buffering cannot occur during
- reconnection windows.
- """
-
- def __init__(self, max_bytes: int = 1_048_576) -> None:
- self._queue: list[tuple[str, int]] = [] # (data, byte_length)
- self._bytes: int = 0
- self._max_bytes = max_bytes
- self._lock = threading.Lock()
-
- def enqueue(self, data: str) -> None:
- """Append *data* to the queue.
-
- Raises :class:`WebSocketQueueFullError` if the message would
- exceed the byte-size limit.
- """
- byte_length = len(data.encode("utf-8"))
- with self._lock:
- if self._bytes + byte_length > self._max_bytes:
- raise WebSocketQueueFullError("send queue is full, message discarded")
- self._queue.append((data, byte_length))
- self._bytes += byte_length
-
- def flush_sync(self, send: typing.Callable[[str], object]) -> None:
- """Send every queued message via *send*.
-
- If *send* raises, the failing message and all subsequent messages
- are re-queued and the error is re-raised.
- """
- with self._lock:
- pending = list(self._queue)
- self._queue.clear()
- self._bytes = 0
-
- for i, (data, _byte_length) in enumerate(pending):
- try:
- send(data)
- except Exception:
- with self._lock:
- remaining = pending[i:]
- self._queue = remaining + self._queue
- self._bytes = sum(bl for _, bl in self._queue)
- raise
-
- async def flush_async(self, send: typing.Callable[[str], typing.Awaitable[object]]) -> None:
- """Async variant of :meth:`flush_sync`."""
- with self._lock:
- pending = list(self._queue)
- self._queue.clear()
- self._bytes = 0
-
- for i, (data, _byte_length) in enumerate(pending):
- try:
- await send(data)
- except Exception:
- with self._lock:
- remaining = pending[i:]
- self._queue = remaining + self._queue
- self._bytes = sum(bl for _, bl in self._queue)
- raise
-
- def drain(self) -> list[str]:
- """Remove and return all queued messages."""
- with self._lock:
- items = [data for data, _ in self._queue]
- self._queue.clear()
- self._bytes = 0
- return items
-
- def __len__(self) -> int:
- with self._lock:
- return len(self._queue)
-
- def __bool__(self) -> bool:
- with self._lock:
- return len(self._queue) > 0
diff --git a/src/dedalus_sdk/_streaming.py b/src/dedalus_sdk/_streaming.py
index d7c0ff2..d71126c 100644
--- a/src/dedalus_sdk/_streaming.py
+++ b/src/dedalus_sdk/_streaming.py
@@ -59,26 +59,7 @@ def __stream__(self) -> Iterator[_T]:
try:
for sse in iterator:
- if sse.event == "bookmark":
- continue
-
- if sse.event == "error":
- body = sse.data
-
- try:
- body = sse.json()
- err_msg = f"{body}"
- except Exception:
- err_msg = sse.data or f"Error code: {response.status_code}"
-
- raise self._client._make_status_error(
- err_msg,
- body=body,
- response=self.response,
- )
-
- if sse.event == "status":
- yield process_data(data=sse.json(), cast_to=cast_to, response=response)
+ yield process_data(data=sse.json(), cast_to=cast_to, response=response)
finally:
# Ensure the response is closed even if the consumer doesn't read all data
response.close()
@@ -144,26 +125,7 @@ async def __stream__(self) -> AsyncIterator[_T]:
try:
async for sse in iterator:
- if sse.event == "bookmark":
- continue
-
- if sse.event == "error":
- body = sse.data
-
- try:
- body = sse.json()
- err_msg = f"{body}"
- except Exception:
- err_msg = sse.data or f"Error code: {response.status_code}"
-
- raise self._client._make_status_error(
- err_msg,
- body=body,
- response=self.response,
- )
-
- if sse.event == "status":
- yield process_data(data=sse.json(), cast_to=cast_to, response=response)
+ yield process_data(data=sse.json(), cast_to=cast_to, response=response)
finally:
# Ensure the response is closed even if the consumer doesn't read all data
await response.aclose()
diff --git a/src/dedalus_sdk/resources/__init__.py b/src/dedalus_sdk/resources/__init__.py
index 5365a1e..2967015 100644
--- a/src/dedalus_sdk/resources/__init__.py
+++ b/src/dedalus_sdk/resources/__init__.py
@@ -1,13 +1,5 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from .usage import (
- UsageResource,
- AsyncUsageResource,
- UsageResourceWithRawResponse,
- AsyncUsageResourceWithRawResponse,
- UsageResourceWithStreamingResponse,
- AsyncUsageResourceWithStreamingResponse,
-)
from .machines import (
MachinesResource,
AsyncMachinesResource,
@@ -18,12 +10,6 @@
)
__all__ = [
- "UsageResource",
- "AsyncUsageResource",
- "UsageResourceWithRawResponse",
- "AsyncUsageResourceWithRawResponse",
- "UsageResourceWithStreamingResponse",
- "AsyncUsageResourceWithStreamingResponse",
"MachinesResource",
"AsyncMachinesResource",
"MachinesResourceWithRawResponse",
diff --git a/src/dedalus_sdk/resources/machines/__init__.py b/src/dedalus_sdk/resources/machines/__init__.py
index 75f56d8..dfb0fcf 100644
--- a/src/dedalus_sdk/resources/machines/__init__.py
+++ b/src/dedalus_sdk/resources/machines/__init__.py
@@ -16,30 +16,6 @@
MachinesResourceWithStreamingResponse,
AsyncMachinesResourceWithStreamingResponse,
)
-from .previews import (
- PreviewsResource,
- AsyncPreviewsResource,
- PreviewsResourceWithRawResponse,
- AsyncPreviewsResourceWithRawResponse,
- PreviewsResourceWithStreamingResponse,
- AsyncPreviewsResourceWithStreamingResponse,
-)
-from .artifacts import (
- ArtifactsResource,
- AsyncArtifactsResource,
- ArtifactsResourceWithRawResponse,
- AsyncArtifactsResourceWithRawResponse,
- ArtifactsResourceWithStreamingResponse,
- AsyncArtifactsResourceWithStreamingResponse,
-)
-from .terminals import (
- TerminalsResource,
- AsyncTerminalsResource,
- TerminalsResourceWithRawResponse,
- AsyncTerminalsResourceWithRawResponse,
- TerminalsResourceWithStreamingResponse,
- AsyncTerminalsResourceWithStreamingResponse,
-)
from .executions import (
ExecutionsResource,
AsyncExecutionsResource,
@@ -50,18 +26,6 @@
)
__all__ = [
- "ArtifactsResource",
- "AsyncArtifactsResource",
- "ArtifactsResourceWithRawResponse",
- "AsyncArtifactsResourceWithRawResponse",
- "ArtifactsResourceWithStreamingResponse",
- "AsyncArtifactsResourceWithStreamingResponse",
- "PreviewsResource",
- "AsyncPreviewsResource",
- "PreviewsResourceWithRawResponse",
- "AsyncPreviewsResourceWithRawResponse",
- "PreviewsResourceWithStreamingResponse",
- "AsyncPreviewsResourceWithStreamingResponse",
"SSHResource",
"AsyncSSHResource",
"SSHResourceWithRawResponse",
@@ -74,12 +38,6 @@
"AsyncExecutionsResourceWithRawResponse",
"ExecutionsResourceWithStreamingResponse",
"AsyncExecutionsResourceWithStreamingResponse",
- "TerminalsResource",
- "AsyncTerminalsResource",
- "TerminalsResourceWithRawResponse",
- "AsyncTerminalsResourceWithRawResponse",
- "TerminalsResourceWithStreamingResponse",
- "AsyncTerminalsResourceWithStreamingResponse",
"MachinesResource",
"AsyncMachinesResource",
"MachinesResourceWithRawResponse",
diff --git a/src/dedalus_sdk/resources/machines/artifacts.py b/src/dedalus_sdk/resources/machines/artifacts.py
deleted file mode 100644
index 8856407..0000000
--- a/src/dedalus_sdk/resources/machines/artifacts.py
+++ /dev/null
@@ -1,382 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import httpx
-
-from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ..._utils import path_template, maybe_transform
-from ..._compat import cached_property
-from ..._resource import SyncAPIResource, AsyncAPIResource
-from ..._response import (
- to_raw_response_wrapper,
- to_streamed_response_wrapper,
- async_to_raw_response_wrapper,
- async_to_streamed_response_wrapper,
-)
-from ...pagination import SyncCursorPage, AsyncCursorPage
-from ..._base_client import AsyncPaginator, make_request_options
-from ...types.machines import artifact_list_params
-from ...types.machines.artifact import Artifact
-
-__all__ = ["ArtifactsResource", "AsyncArtifactsResource"]
-
-
-class ArtifactsResource(SyncAPIResource):
- @cached_property
- def with_raw_response(self) -> ArtifactsResourceWithRawResponse:
- """
- 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/dedalus-labs/dedalus-python#accessing-raw-response-data-eg-headers
- """
- return ArtifactsResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> ArtifactsResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/dedalus-labs/dedalus-python#with_streaming_response
- """
- return ArtifactsResourceWithStreamingResponse(self)
-
- def retrieve(
- self,
- *,
- machine_id: str,
- artifact_id: 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,
- ) -> Artifact:
- """
- Get artifact
-
- 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 machine_id:
- raise ValueError(f"Expected a non-empty value for `machine_id` but received {machine_id!r}")
- if not artifact_id:
- raise ValueError(f"Expected a non-empty value for `artifact_id` but received {artifact_id!r}")
- return self._get(
- path_template(
- "/v1/machines/{machine_id}/artifacts/{artifact_id}", machine_id=machine_id, artifact_id=artifact_id
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=Artifact,
- )
-
- def list(
- self,
- *,
- machine_id: str,
- cursor: str | Omit = omit,
- limit: int | 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,
- ) -> SyncCursorPage[Artifact]:
- """
- List artifacts
-
- 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 machine_id:
- raise ValueError(f"Expected a non-empty value for `machine_id` but received {machine_id!r}")
- return self._get_api_list(
- path_template("/v1/machines/{machine_id}/artifacts", machine_id=machine_id),
- page=SyncCursorPage[Artifact],
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "cursor": cursor,
- "limit": limit,
- },
- artifact_list_params.ArtifactListParams,
- ),
- ),
- model=Artifact,
- )
-
- def delete(
- self,
- *,
- machine_id: str,
- artifact_id: 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,
- ) -> Artifact:
- """
- Delete artifact
-
- 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}")
- if not artifact_id:
- raise ValueError(f"Expected a non-empty value for `artifact_id` but received {artifact_id!r}")
- return self._delete(
- path_template(
- "/v1/machines/{machine_id}/artifacts/{artifact_id}", machine_id=machine_id, artifact_id=artifact_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=Artifact,
- )
-
-
-class AsyncArtifactsResource(AsyncAPIResource):
- @cached_property
- def with_raw_response(self) -> AsyncArtifactsResourceWithRawResponse:
- """
- 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/dedalus-labs/dedalus-python#accessing-raw-response-data-eg-headers
- """
- return AsyncArtifactsResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> AsyncArtifactsResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/dedalus-labs/dedalus-python#with_streaming_response
- """
- return AsyncArtifactsResourceWithStreamingResponse(self)
-
- async def retrieve(
- self,
- *,
- machine_id: str,
- artifact_id: 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,
- ) -> Artifact:
- """
- Get artifact
-
- 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 machine_id:
- raise ValueError(f"Expected a non-empty value for `machine_id` but received {machine_id!r}")
- if not artifact_id:
- raise ValueError(f"Expected a non-empty value for `artifact_id` but received {artifact_id!r}")
- return await self._get(
- path_template(
- "/v1/machines/{machine_id}/artifacts/{artifact_id}", machine_id=machine_id, artifact_id=artifact_id
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=Artifact,
- )
-
- def list(
- self,
- *,
- machine_id: str,
- cursor: str | Omit = omit,
- limit: int | 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,
- ) -> AsyncPaginator[Artifact, AsyncCursorPage[Artifact]]:
- """
- List artifacts
-
- 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 machine_id:
- raise ValueError(f"Expected a non-empty value for `machine_id` but received {machine_id!r}")
- return self._get_api_list(
- path_template("/v1/machines/{machine_id}/artifacts", machine_id=machine_id),
- page=AsyncCursorPage[Artifact],
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "cursor": cursor,
- "limit": limit,
- },
- artifact_list_params.ArtifactListParams,
- ),
- ),
- model=Artifact,
- )
-
- async def delete(
- self,
- *,
- machine_id: str,
- artifact_id: 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,
- ) -> Artifact:
- """
- Delete artifact
-
- 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}")
- if not artifact_id:
- raise ValueError(f"Expected a non-empty value for `artifact_id` but received {artifact_id!r}")
- return await self._delete(
- path_template(
- "/v1/machines/{machine_id}/artifacts/{artifact_id}", machine_id=machine_id, artifact_id=artifact_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=Artifact,
- )
-
-
-class ArtifactsResourceWithRawResponse:
- def __init__(self, artifacts: ArtifactsResource) -> None:
- self._artifacts = artifacts
-
- self.retrieve = to_raw_response_wrapper(
- artifacts.retrieve,
- )
- self.list = to_raw_response_wrapper(
- artifacts.list,
- )
- self.delete = to_raw_response_wrapper(
- artifacts.delete,
- )
-
-
-class AsyncArtifactsResourceWithRawResponse:
- def __init__(self, artifacts: AsyncArtifactsResource) -> None:
- self._artifacts = artifacts
-
- self.retrieve = async_to_raw_response_wrapper(
- artifacts.retrieve,
- )
- self.list = async_to_raw_response_wrapper(
- artifacts.list,
- )
- self.delete = async_to_raw_response_wrapper(
- artifacts.delete,
- )
-
-
-class ArtifactsResourceWithStreamingResponse:
- def __init__(self, artifacts: ArtifactsResource) -> None:
- self._artifacts = artifacts
-
- self.retrieve = to_streamed_response_wrapper(
- artifacts.retrieve,
- )
- self.list = to_streamed_response_wrapper(
- artifacts.list,
- )
- self.delete = to_streamed_response_wrapper(
- artifacts.delete,
- )
-
-
-class AsyncArtifactsResourceWithStreamingResponse:
- def __init__(self, artifacts: AsyncArtifactsResource) -> None:
- self._artifacts = artifacts
-
- self.retrieve = async_to_streamed_response_wrapper(
- artifacts.retrieve,
- )
- self.list = async_to_streamed_response_wrapper(
- artifacts.list,
- )
- self.delete = async_to_streamed_response_wrapper(
- artifacts.delete,
- )
diff --git a/src/dedalus_sdk/resources/machines/machines.py b/src/dedalus_sdk/resources/machines/machines.py
index b78a9ca..3971492 100644
--- a/src/dedalus_sdk/resources/machines/machines.py
+++ b/src/dedalus_sdk/resources/machines/machines.py
@@ -14,32 +14,8 @@
)
from ...types import machine_list_params, machine_create_params, machine_update_params
from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ..._utils import path_template, maybe_transform, strip_not_given, async_maybe_transform
-from .previews import (
- PreviewsResource,
- AsyncPreviewsResource,
- PreviewsResourceWithRawResponse,
- AsyncPreviewsResourceWithRawResponse,
- PreviewsResourceWithStreamingResponse,
- AsyncPreviewsResourceWithStreamingResponse,
-)
+from ..._utils import path_template, maybe_transform, async_maybe_transform
from ..._compat import cached_property
-from .artifacts import (
- ArtifactsResource,
- AsyncArtifactsResource,
- ArtifactsResourceWithRawResponse,
- AsyncArtifactsResourceWithRawResponse,
- ArtifactsResourceWithStreamingResponse,
- AsyncArtifactsResourceWithStreamingResponse,
-)
-from .terminals import (
- TerminalsResource,
- AsyncTerminalsResource,
- TerminalsResourceWithRawResponse,
- AsyncTerminalsResourceWithRawResponse,
- TerminalsResourceWithStreamingResponse,
- AsyncTerminalsResourceWithStreamingResponse,
-)
from .executions import (
ExecutionsResource,
AsyncExecutionsResource,
@@ -55,24 +31,16 @@
async_to_raw_response_wrapper,
async_to_streamed_response_wrapper,
)
-from ..._streaming import Stream, AsyncStream
from ...pagination import SyncCursorPage, AsyncCursorPage
from ..._base_client import AsyncPaginator, make_request_options
from ...types.machine import Machine
from ...types.machine_list_item import MachineListItem
+from ...types.machine_retrieve_response import MachineRetrieveResponse
__all__ = ["MachinesResource", "AsyncMachinesResource"]
class MachinesResource(SyncAPIResource):
- @cached_property
- def artifacts(self) -> ArtifactsResource:
- return ArtifactsResource(self._client)
-
- @cached_property
- def previews(self) -> PreviewsResource:
- return PreviewsResource(self._client)
-
@cached_property
def ssh(self) -> SSHResource:
return SSHResource(self._client)
@@ -81,10 +49,6 @@ def ssh(self) -> SSHResource:
def executions(self) -> ExecutionsResource:
return ExecutionsResource(self._client)
- @cached_property
- def terminals(self) -> TerminalsResource:
- return TerminalsResource(self._client)
-
@cached_property
def with_raw_response(self) -> MachinesResourceWithRawResponse:
"""
@@ -107,10 +71,10 @@ def with_streaming_response(self) -> MachinesResourceWithStreamingResponse:
def create(
self,
*,
- memory_mib: int,
- storage_gib: int,
- vcpu: float,
autosleep: str | Omit = omit,
+ memory_mib: int | Omit = omit,
+ storage_gib: int | Omit = omit,
+ vcpu: float | 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,
@@ -119,19 +83,20 @@ def create(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
idempotency_key: str | None = None,
) -> Machine:
- """
- Create machine
+ """Create machine
Args:
+ autosleep: Idle window before autosleep.
+
+ Accepts fixed duration units like 30s, 30m, 2h,
+ 7d3h4s, or 1w3d, raw seconds ("1800"), or never to disable.
+
memory_mib: Memory in MiB.
storage_gib: Storage in GiB.
vcpu: CPU in vCPUs.
- autosleep: Idle window before autosleep. Accepts fixed duration units like 30s, 30m, 2h,
- 7d3h4s, or 1w3d, raw seconds ("1800"), or never to disable.
-
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -146,10 +111,10 @@ def create(
"/v1/machines",
body=maybe_transform(
{
+ "autosleep": autosleep,
"memory_mib": memory_mib,
"storage_gib": storage_gib,
"vcpu": vcpu,
- "autosleep": autosleep,
},
machine_create_params.MachineCreateParams,
),
@@ -173,7 +138,7 @@ def retrieve(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> Machine:
+ ) -> MachineRetrieveResponse:
"""
Get machine
@@ -193,7 +158,7 @@ def retrieve(
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=Machine,
+ cast_to=MachineRetrieveResponse,
)
def update(
@@ -422,57 +387,8 @@ def wake(
cast_to=Machine,
)
- def watch(
- self,
- *,
- machine_id: str,
- last_event_id: 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,
- ) -> Stream[Machine]:
- """Streams machine lifecycle updates over Server-Sent Events.
-
- Each `status` event
- contains a full `LifecycleResponse` payload. The stream closes after the machine
- reaches its current desired state.
-
- 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 machine_id:
- raise ValueError(f"Expected a non-empty value for `machine_id` but received {machine_id!r}")
- extra_headers = {"Accept": "text/event-stream", **(extra_headers or {})}
- extra_headers = {**strip_not_given({"Last-Event-ID": last_event_id}), **(extra_headers or {})}
- return self._get(
- path_template("/v1/machines/{machine_id}/status/stream", machine_id=machine_id),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=Machine,
- stream=True,
- stream_cls=Stream[Machine],
- )
-
class AsyncMachinesResource(AsyncAPIResource):
- @cached_property
- def artifacts(self) -> AsyncArtifactsResource:
- return AsyncArtifactsResource(self._client)
-
- @cached_property
- def previews(self) -> AsyncPreviewsResource:
- return AsyncPreviewsResource(self._client)
-
@cached_property
def ssh(self) -> AsyncSSHResource:
return AsyncSSHResource(self._client)
@@ -481,10 +397,6 @@ def ssh(self) -> AsyncSSHResource:
def executions(self) -> AsyncExecutionsResource:
return AsyncExecutionsResource(self._client)
- @cached_property
- def terminals(self) -> AsyncTerminalsResource:
- return AsyncTerminalsResource(self._client)
-
@cached_property
def with_raw_response(self) -> AsyncMachinesResourceWithRawResponse:
"""
@@ -507,10 +419,10 @@ def with_streaming_response(self) -> AsyncMachinesResourceWithStreamingResponse:
async def create(
self,
*,
- memory_mib: int,
- storage_gib: int,
- vcpu: float,
autosleep: str | Omit = omit,
+ memory_mib: int | Omit = omit,
+ storage_gib: int | Omit = omit,
+ vcpu: float | 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,
@@ -519,19 +431,20 @@ async def create(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
idempotency_key: str | None = None,
) -> Machine:
- """
- Create machine
+ """Create machine
Args:
+ autosleep: Idle window before autosleep.
+
+ Accepts fixed duration units like 30s, 30m, 2h,
+ 7d3h4s, or 1w3d, raw seconds ("1800"), or never to disable.
+
memory_mib: Memory in MiB.
storage_gib: Storage in GiB.
vcpu: CPU in vCPUs.
- autosleep: Idle window before autosleep. Accepts fixed duration units like 30s, 30m, 2h,
- 7d3h4s, or 1w3d, raw seconds ("1800"), or never to disable.
-
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -546,10 +459,10 @@ async def create(
"/v1/machines",
body=await async_maybe_transform(
{
+ "autosleep": autosleep,
"memory_mib": memory_mib,
"storage_gib": storage_gib,
"vcpu": vcpu,
- "autosleep": autosleep,
},
machine_create_params.MachineCreateParams,
),
@@ -573,7 +486,7 @@ async def retrieve(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> Machine:
+ ) -> MachineRetrieveResponse:
"""
Get machine
@@ -593,7 +506,7 @@ async def retrieve(
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=Machine,
+ cast_to=MachineRetrieveResponse,
)
async def update(
@@ -822,47 +735,6 @@ async def wake(
cast_to=Machine,
)
- async def watch(
- self,
- *,
- machine_id: str,
- last_event_id: 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,
- ) -> AsyncStream[Machine]:
- """Streams machine lifecycle updates over Server-Sent Events.
-
- Each `status` event
- contains a full `LifecycleResponse` payload. The stream closes after the machine
- reaches its current desired state.
-
- 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 machine_id:
- raise ValueError(f"Expected a non-empty value for `machine_id` but received {machine_id!r}")
- extra_headers = {"Accept": "text/event-stream", **(extra_headers or {})}
- extra_headers = {**strip_not_given({"Last-Event-ID": last_event_id}), **(extra_headers or {})}
- return await self._get(
- path_template("/v1/machines/{machine_id}/status/stream", machine_id=machine_id),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=Machine,
- stream=True,
- stream_cls=AsyncStream[Machine],
- )
-
class MachinesResourceWithRawResponse:
def __init__(self, machines: MachinesResource) -> None:
@@ -889,17 +761,6 @@ def __init__(self, machines: MachinesResource) -> None:
self.wake = to_raw_response_wrapper(
machines.wake,
)
- self.watch = to_raw_response_wrapper(
- machines.watch,
- )
-
- @cached_property
- def artifacts(self) -> ArtifactsResourceWithRawResponse:
- return ArtifactsResourceWithRawResponse(self._machines.artifacts)
-
- @cached_property
- def previews(self) -> PreviewsResourceWithRawResponse:
- return PreviewsResourceWithRawResponse(self._machines.previews)
@cached_property
def ssh(self) -> SSHResourceWithRawResponse:
@@ -909,10 +770,6 @@ def ssh(self) -> SSHResourceWithRawResponse:
def executions(self) -> ExecutionsResourceWithRawResponse:
return ExecutionsResourceWithRawResponse(self._machines.executions)
- @cached_property
- def terminals(self) -> TerminalsResourceWithRawResponse:
- return TerminalsResourceWithRawResponse(self._machines.terminals)
-
class AsyncMachinesResourceWithRawResponse:
def __init__(self, machines: AsyncMachinesResource) -> None:
@@ -939,17 +796,6 @@ def __init__(self, machines: AsyncMachinesResource) -> None:
self.wake = async_to_raw_response_wrapper(
machines.wake,
)
- self.watch = async_to_raw_response_wrapper(
- machines.watch,
- )
-
- @cached_property
- def artifacts(self) -> AsyncArtifactsResourceWithRawResponse:
- return AsyncArtifactsResourceWithRawResponse(self._machines.artifacts)
-
- @cached_property
- def previews(self) -> AsyncPreviewsResourceWithRawResponse:
- return AsyncPreviewsResourceWithRawResponse(self._machines.previews)
@cached_property
def ssh(self) -> AsyncSSHResourceWithRawResponse:
@@ -959,10 +805,6 @@ def ssh(self) -> AsyncSSHResourceWithRawResponse:
def executions(self) -> AsyncExecutionsResourceWithRawResponse:
return AsyncExecutionsResourceWithRawResponse(self._machines.executions)
- @cached_property
- def terminals(self) -> AsyncTerminalsResourceWithRawResponse:
- return AsyncTerminalsResourceWithRawResponse(self._machines.terminals)
-
class MachinesResourceWithStreamingResponse:
def __init__(self, machines: MachinesResource) -> None:
@@ -989,17 +831,6 @@ def __init__(self, machines: MachinesResource) -> None:
self.wake = to_streamed_response_wrapper(
machines.wake,
)
- self.watch = to_streamed_response_wrapper(
- machines.watch,
- )
-
- @cached_property
- def artifacts(self) -> ArtifactsResourceWithStreamingResponse:
- return ArtifactsResourceWithStreamingResponse(self._machines.artifacts)
-
- @cached_property
- def previews(self) -> PreviewsResourceWithStreamingResponse:
- return PreviewsResourceWithStreamingResponse(self._machines.previews)
@cached_property
def ssh(self) -> SSHResourceWithStreamingResponse:
@@ -1009,10 +840,6 @@ def ssh(self) -> SSHResourceWithStreamingResponse:
def executions(self) -> ExecutionsResourceWithStreamingResponse:
return ExecutionsResourceWithStreamingResponse(self._machines.executions)
- @cached_property
- def terminals(self) -> TerminalsResourceWithStreamingResponse:
- return TerminalsResourceWithStreamingResponse(self._machines.terminals)
-
class AsyncMachinesResourceWithStreamingResponse:
def __init__(self, machines: AsyncMachinesResource) -> None:
@@ -1039,17 +866,6 @@ def __init__(self, machines: AsyncMachinesResource) -> None:
self.wake = async_to_streamed_response_wrapper(
machines.wake,
)
- self.watch = async_to_streamed_response_wrapper(
- machines.watch,
- )
-
- @cached_property
- def artifacts(self) -> AsyncArtifactsResourceWithStreamingResponse:
- return AsyncArtifactsResourceWithStreamingResponse(self._machines.artifacts)
-
- @cached_property
- def previews(self) -> AsyncPreviewsResourceWithStreamingResponse:
- return AsyncPreviewsResourceWithStreamingResponse(self._machines.previews)
@cached_property
def ssh(self) -> AsyncSSHResourceWithStreamingResponse:
@@ -1058,7 +874,3 @@ def ssh(self) -> AsyncSSHResourceWithStreamingResponse:
@cached_property
def executions(self) -> AsyncExecutionsResourceWithStreamingResponse:
return AsyncExecutionsResourceWithStreamingResponse(self._machines.executions)
-
- @cached_property
- def terminals(self) -> AsyncTerminalsResourceWithStreamingResponse:
- return AsyncTerminalsResourceWithStreamingResponse(self._machines.terminals)
diff --git a/src/dedalus_sdk/resources/machines/previews.py b/src/dedalus_sdk/resources/machines/previews.py
deleted file mode 100644
index 074ef9b..0000000
--- a/src/dedalus_sdk/resources/machines/previews.py
+++ /dev/null
@@ -1,498 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Literal
-
-import httpx
-
-from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ..._utils import path_template, maybe_transform, async_maybe_transform
-from ..._compat import cached_property
-from ..._resource import SyncAPIResource, AsyncAPIResource
-from ..._response import (
- to_raw_response_wrapper,
- to_streamed_response_wrapper,
- async_to_raw_response_wrapper,
- async_to_streamed_response_wrapper,
-)
-from ...pagination import SyncCursorPage, AsyncCursorPage
-from ..._base_client import AsyncPaginator, make_request_options
-from ...types.machines import preview_list_params, preview_create_params
-from ...types.machines.preview import Preview
-
-__all__ = ["PreviewsResource", "AsyncPreviewsResource"]
-
-
-class PreviewsResource(SyncAPIResource):
- @cached_property
- def with_raw_response(self) -> PreviewsResourceWithRawResponse:
- """
- 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/dedalus-labs/dedalus-python#accessing-raw-response-data-eg-headers
- """
- return PreviewsResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> PreviewsResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/dedalus-labs/dedalus-python#with_streaming_response
- """
- return PreviewsResourceWithStreamingResponse(self)
-
- def create(
- self,
- *,
- machine_id: str,
- port: int,
- protocol: Literal["http", "https"] | Omit = omit,
- visibility: Literal["public", "private", "org"] | 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,
- idempotency_key: str | None = None,
- ) -> Preview:
- """
- Create preview
-
- 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}")
- return self._post(
- path_template("/v1/machines/{machine_id}/previews", machine_id=machine_id),
- body=maybe_transform(
- {
- "port": port,
- "protocol": protocol,
- "visibility": visibility,
- },
- preview_create_params.PreviewCreateParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- idempotency_key=idempotency_key,
- ),
- cast_to=Preview,
- )
-
- def retrieve(
- self,
- *,
- machine_id: str,
- preview_id: 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,
- ) -> Preview:
- """
- Get preview
-
- 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 machine_id:
- raise ValueError(f"Expected a non-empty value for `machine_id` but received {machine_id!r}")
- if not preview_id:
- raise ValueError(f"Expected a non-empty value for `preview_id` but received {preview_id!r}")
- return self._get(
- path_template(
- "/v1/machines/{machine_id}/previews/{preview_id}", machine_id=machine_id, preview_id=preview_id
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=Preview,
- )
-
- def list(
- self,
- *,
- machine_id: str,
- cursor: str | Omit = omit,
- limit: int | 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,
- ) -> SyncCursorPage[Preview]:
- """
- List previews
-
- 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 machine_id:
- raise ValueError(f"Expected a non-empty value for `machine_id` but received {machine_id!r}")
- return self._get_api_list(
- path_template("/v1/machines/{machine_id}/previews", machine_id=machine_id),
- page=SyncCursorPage[Preview],
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "cursor": cursor,
- "limit": limit,
- },
- preview_list_params.PreviewListParams,
- ),
- ),
- model=Preview,
- )
-
- def delete(
- self,
- *,
- machine_id: str,
- preview_id: 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,
- ) -> Preview:
- """
- Delete preview
-
- 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}")
- if not preview_id:
- raise ValueError(f"Expected a non-empty value for `preview_id` but received {preview_id!r}")
- return self._delete(
- path_template(
- "/v1/machines/{machine_id}/previews/{preview_id}", machine_id=machine_id, preview_id=preview_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=Preview,
- )
-
-
-class AsyncPreviewsResource(AsyncAPIResource):
- @cached_property
- def with_raw_response(self) -> AsyncPreviewsResourceWithRawResponse:
- """
- 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/dedalus-labs/dedalus-python#accessing-raw-response-data-eg-headers
- """
- return AsyncPreviewsResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> AsyncPreviewsResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/dedalus-labs/dedalus-python#with_streaming_response
- """
- return AsyncPreviewsResourceWithStreamingResponse(self)
-
- async def create(
- self,
- *,
- machine_id: str,
- port: int,
- protocol: Literal["http", "https"] | Omit = omit,
- visibility: Literal["public", "private", "org"] | 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,
- idempotency_key: str | None = None,
- ) -> Preview:
- """
- Create preview
-
- 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}")
- return await self._post(
- path_template("/v1/machines/{machine_id}/previews", machine_id=machine_id),
- body=await async_maybe_transform(
- {
- "port": port,
- "protocol": protocol,
- "visibility": visibility,
- },
- preview_create_params.PreviewCreateParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- idempotency_key=idempotency_key,
- ),
- cast_to=Preview,
- )
-
- async def retrieve(
- self,
- *,
- machine_id: str,
- preview_id: 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,
- ) -> Preview:
- """
- Get preview
-
- 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 machine_id:
- raise ValueError(f"Expected a non-empty value for `machine_id` but received {machine_id!r}")
- if not preview_id:
- raise ValueError(f"Expected a non-empty value for `preview_id` but received {preview_id!r}")
- return await self._get(
- path_template(
- "/v1/machines/{machine_id}/previews/{preview_id}", machine_id=machine_id, preview_id=preview_id
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=Preview,
- )
-
- def list(
- self,
- *,
- machine_id: str,
- cursor: str | Omit = omit,
- limit: int | 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,
- ) -> AsyncPaginator[Preview, AsyncCursorPage[Preview]]:
- """
- List previews
-
- 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 machine_id:
- raise ValueError(f"Expected a non-empty value for `machine_id` but received {machine_id!r}")
- return self._get_api_list(
- path_template("/v1/machines/{machine_id}/previews", machine_id=machine_id),
- page=AsyncCursorPage[Preview],
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "cursor": cursor,
- "limit": limit,
- },
- preview_list_params.PreviewListParams,
- ),
- ),
- model=Preview,
- )
-
- async def delete(
- self,
- *,
- machine_id: str,
- preview_id: 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,
- ) -> Preview:
- """
- Delete preview
-
- 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}")
- if not preview_id:
- raise ValueError(f"Expected a non-empty value for `preview_id` but received {preview_id!r}")
- return await self._delete(
- path_template(
- "/v1/machines/{machine_id}/previews/{preview_id}", machine_id=machine_id, preview_id=preview_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=Preview,
- )
-
-
-class PreviewsResourceWithRawResponse:
- def __init__(self, previews: PreviewsResource) -> None:
- self._previews = previews
-
- self.create = to_raw_response_wrapper(
- previews.create,
- )
- self.retrieve = to_raw_response_wrapper(
- previews.retrieve,
- )
- self.list = to_raw_response_wrapper(
- previews.list,
- )
- self.delete = to_raw_response_wrapper(
- previews.delete,
- )
-
-
-class AsyncPreviewsResourceWithRawResponse:
- def __init__(self, previews: AsyncPreviewsResource) -> None:
- self._previews = previews
-
- self.create = async_to_raw_response_wrapper(
- previews.create,
- )
- self.retrieve = async_to_raw_response_wrapper(
- previews.retrieve,
- )
- self.list = async_to_raw_response_wrapper(
- previews.list,
- )
- self.delete = async_to_raw_response_wrapper(
- previews.delete,
- )
-
-
-class PreviewsResourceWithStreamingResponse:
- def __init__(self, previews: PreviewsResource) -> None:
- self._previews = previews
-
- self.create = to_streamed_response_wrapper(
- previews.create,
- )
- self.retrieve = to_streamed_response_wrapper(
- previews.retrieve,
- )
- self.list = to_streamed_response_wrapper(
- previews.list,
- )
- self.delete = to_streamed_response_wrapper(
- previews.delete,
- )
-
-
-class AsyncPreviewsResourceWithStreamingResponse:
- def __init__(self, previews: AsyncPreviewsResource) -> None:
- self._previews = previews
-
- self.create = async_to_streamed_response_wrapper(
- previews.create,
- )
- self.retrieve = async_to_streamed_response_wrapper(
- previews.retrieve,
- )
- self.list = async_to_streamed_response_wrapper(
- previews.list,
- )
- self.delete = async_to_streamed_response_wrapper(
- previews.delete,
- )
diff --git a/src/dedalus_sdk/resources/machines/terminals.py b/src/dedalus_sdk/resources/machines/terminals.py
deleted file mode 100644
index 5ffeb03..0000000
--- a/src/dedalus_sdk/resources/machines/terminals.py
+++ /dev/null
@@ -1,1503 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import json
-import time
-import random
-import logging
-from types import TracebackType
-from typing import TYPE_CHECKING, Any, Dict, Union, Callable, Iterator, Awaitable, cast
-from typing_extensions import AsyncIterator
-
-import httpx
-from pydantic import BaseModel
-
-from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ..._utils import path_template, maybe_transform, async_maybe_transform
-from ..._compat import cached_property
-from ..._models import construct_type_unchecked
-from ..._resource import SyncAPIResource, AsyncAPIResource
-from ..._response import (
- to_raw_response_wrapper,
- to_streamed_response_wrapper,
- async_to_raw_response_wrapper,
- async_to_streamed_response_wrapper,
-)
-from ...pagination import SyncCursorPage, AsyncCursorPage
-from ..._exceptions import DedalusError, WebSocketConnectionClosedError
-from ..._send_queue import SendQueue
-from ..._base_client import AsyncPaginator, _merge_mappings, make_request_options
-from ..._event_handler import EventHandlerRegistry
-from ...types.machines import terminal_list_params, terminal_create_params
-from ...types.machines.terminal import Terminal
-from ...types.websocket_reconnection import ReconnectingEvent, ReconnectingOverrides, is_recoverable_close
-from ...types.websocket_connection_options import WebSocketConnectionOptions
-from ...types.machines.terminal_error_event import TerminalErrorEvent
-from ...types.machines.terminal_client_event import TerminalClientEvent
-from ...types.machines.terminal_server_event import TerminalServerEvent
-from ...types.machines.terminal_client_event_param import TerminalClientEventParam
-
-if TYPE_CHECKING:
- from websockets.sync.client import ClientConnection as WebSocketConnection
- from websockets.asyncio.client import ClientConnection as AsyncWebSocketConnection
-
- from ..._client import Dedalus, AsyncDedalus
-
-__all__ = ["TerminalsResource", "AsyncTerminalsResource"]
-
-log: logging.Logger = logging.getLogger(__name__)
-
-
-class TerminalsResource(SyncAPIResource):
- @cached_property
- def with_raw_response(self) -> TerminalsResourceWithRawResponse:
- """
- 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/dedalus-labs/dedalus-python#accessing-raw-response-data-eg-headers
- """
- return TerminalsResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> TerminalsResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/dedalus-labs/dedalus-python#with_streaming_response
- """
- return TerminalsResourceWithStreamingResponse(self)
-
- def create(
- self,
- *,
- machine_id: str,
- height: int,
- width: int,
- cwd: str | Omit = omit,
- env: Dict[str, str] | Omit = omit,
- shell: 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,
- idempotency_key: str | None = None,
- ) -> Terminal:
- """
- Create terminal
-
- 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}")
- return self._post(
- path_template("/v1/machines/{machine_id}/terminals", machine_id=machine_id),
- body=maybe_transform(
- {
- "height": height,
- "width": width,
- "cwd": cwd,
- "env": env,
- "shell": shell,
- },
- terminal_create_params.TerminalCreateParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- idempotency_key=idempotency_key,
- ),
- cast_to=Terminal,
- )
-
- def retrieve(
- self,
- *,
- machine_id: str,
- terminal_id: 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,
- ) -> Terminal:
- """
- Get terminal
-
- 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 machine_id:
- raise ValueError(f"Expected a non-empty value for `machine_id` but received {machine_id!r}")
- if not terminal_id:
- raise ValueError(f"Expected a non-empty value for `terminal_id` but received {terminal_id!r}")
- return self._get(
- path_template(
- "/v1/machines/{machine_id}/terminals/{terminal_id}", machine_id=machine_id, terminal_id=terminal_id
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=Terminal,
- )
-
- def list(
- self,
- *,
- machine_id: str,
- cursor: str | Omit = omit,
- limit: int | 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,
- ) -> SyncCursorPage[Terminal]:
- """
- List terminals
-
- 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 machine_id:
- raise ValueError(f"Expected a non-empty value for `machine_id` but received {machine_id!r}")
- return self._get_api_list(
- path_template("/v1/machines/{machine_id}/terminals", machine_id=machine_id),
- page=SyncCursorPage[Terminal],
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "cursor": cursor,
- "limit": limit,
- },
- terminal_list_params.TerminalListParams,
- ),
- ),
- model=Terminal,
- )
-
- def delete(
- self,
- *,
- machine_id: str,
- terminal_id: 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,
- ) -> Terminal:
- """
- Delete terminal
-
- 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}")
- if not terminal_id:
- raise ValueError(f"Expected a non-empty value for `terminal_id` but received {terminal_id!r}")
- return self._delete(
- path_template(
- "/v1/machines/{machine_id}/terminals/{terminal_id}", machine_id=machine_id, terminal_id=terminal_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=Terminal,
- )
-
- def connect(
- self,
- *,
- machine_id: str,
- terminal_id: str,
- extra_query: Query = {},
- extra_headers: Headers = {},
- websocket_connection_options: WebSocketConnectionOptions = {},
- on_reconnecting: Callable[[ReconnectingEvent], ReconnectingOverrides | None] | None = None,
- max_retries: int = 5,
- initial_delay: float = 0.5,
- max_delay: float = 8.0,
- max_queue_size: int = 1_048_576,
- ) -> TerminalsResourceConnectionManager:
- return TerminalsResourceConnectionManager(
- client=self._client,
- extra_query=extra_query,
- extra_headers=extra_headers,
- websocket_connection_options=websocket_connection_options,
- on_reconnecting=on_reconnecting,
- max_retries=max_retries,
- initial_delay=initial_delay,
- max_delay=max_delay,
- max_queue_size=max_queue_size,
- machine_id=machine_id,
- terminal_id=terminal_id,
- )
-
-
-class AsyncTerminalsResource(AsyncAPIResource):
- @cached_property
- def with_raw_response(self) -> AsyncTerminalsResourceWithRawResponse:
- """
- 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/dedalus-labs/dedalus-python#accessing-raw-response-data-eg-headers
- """
- return AsyncTerminalsResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> AsyncTerminalsResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/dedalus-labs/dedalus-python#with_streaming_response
- """
- return AsyncTerminalsResourceWithStreamingResponse(self)
-
- async def create(
- self,
- *,
- machine_id: str,
- height: int,
- width: int,
- cwd: str | Omit = omit,
- env: Dict[str, str] | Omit = omit,
- shell: 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,
- idempotency_key: str | None = None,
- ) -> Terminal:
- """
- Create terminal
-
- 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}")
- return await self._post(
- path_template("/v1/machines/{machine_id}/terminals", machine_id=machine_id),
- body=await async_maybe_transform(
- {
- "height": height,
- "width": width,
- "cwd": cwd,
- "env": env,
- "shell": shell,
- },
- terminal_create_params.TerminalCreateParams,
- ),
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- idempotency_key=idempotency_key,
- ),
- cast_to=Terminal,
- )
-
- async def retrieve(
- self,
- *,
- machine_id: str,
- terminal_id: 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,
- ) -> Terminal:
- """
- Get terminal
-
- 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 machine_id:
- raise ValueError(f"Expected a non-empty value for `machine_id` but received {machine_id!r}")
- if not terminal_id:
- raise ValueError(f"Expected a non-empty value for `terminal_id` but received {terminal_id!r}")
- return await self._get(
- path_template(
- "/v1/machines/{machine_id}/terminals/{terminal_id}", machine_id=machine_id, terminal_id=terminal_id
- ),
- options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
- ),
- cast_to=Terminal,
- )
-
- def list(
- self,
- *,
- machine_id: str,
- cursor: str | Omit = omit,
- limit: int | 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,
- ) -> AsyncPaginator[Terminal, AsyncCursorPage[Terminal]]:
- """
- List terminals
-
- 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 machine_id:
- raise ValueError(f"Expected a non-empty value for `machine_id` but received {machine_id!r}")
- return self._get_api_list(
- path_template("/v1/machines/{machine_id}/terminals", machine_id=machine_id),
- page=AsyncCursorPage[Terminal],
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "cursor": cursor,
- "limit": limit,
- },
- terminal_list_params.TerminalListParams,
- ),
- ),
- model=Terminal,
- )
-
- async def delete(
- self,
- *,
- machine_id: str,
- terminal_id: 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,
- ) -> Terminal:
- """
- Delete terminal
-
- 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}")
- if not terminal_id:
- raise ValueError(f"Expected a non-empty value for `terminal_id` but received {terminal_id!r}")
- return await self._delete(
- path_template(
- "/v1/machines/{machine_id}/terminals/{terminal_id}", machine_id=machine_id, terminal_id=terminal_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=Terminal,
- )
-
- def connect(
- self,
- *,
- machine_id: str,
- terminal_id: str,
- extra_query: Query = {},
- extra_headers: Headers = {},
- websocket_connection_options: WebSocketConnectionOptions = {},
- on_reconnecting: Callable[[ReconnectingEvent], ReconnectingOverrides | None] | None = None,
- max_retries: int = 5,
- initial_delay: float = 0.5,
- max_delay: float = 8.0,
- max_queue_size: int = 1_048_576,
- ) -> AsyncTerminalsResourceConnectionManager:
- return AsyncTerminalsResourceConnectionManager(
- client=self._client,
- extra_query=extra_query,
- extra_headers=extra_headers,
- websocket_connection_options=websocket_connection_options,
- on_reconnecting=on_reconnecting,
- max_retries=max_retries,
- initial_delay=initial_delay,
- max_delay=max_delay,
- max_queue_size=max_queue_size,
- machine_id=machine_id,
- terminal_id=terminal_id,
- )
-
-
-class TerminalsResourceWithRawResponse:
- def __init__(self, terminals: TerminalsResource) -> None:
- self._terminals = terminals
-
- self.create = to_raw_response_wrapper(
- terminals.create,
- )
- self.retrieve = to_raw_response_wrapper(
- terminals.retrieve,
- )
- self.list = to_raw_response_wrapper(
- terminals.list,
- )
- self.delete = to_raw_response_wrapper(
- terminals.delete,
- )
-
-
-class AsyncTerminalsResourceWithRawResponse:
- def __init__(self, terminals: AsyncTerminalsResource) -> None:
- self._terminals = terminals
-
- self.create = async_to_raw_response_wrapper(
- terminals.create,
- )
- self.retrieve = async_to_raw_response_wrapper(
- terminals.retrieve,
- )
- self.list = async_to_raw_response_wrapper(
- terminals.list,
- )
- self.delete = async_to_raw_response_wrapper(
- terminals.delete,
- )
-
-
-class TerminalsResourceWithStreamingResponse:
- def __init__(self, terminals: TerminalsResource) -> None:
- self._terminals = terminals
-
- self.create = to_streamed_response_wrapper(
- terminals.create,
- )
- self.retrieve = to_streamed_response_wrapper(
- terminals.retrieve,
- )
- self.list = to_streamed_response_wrapper(
- terminals.list,
- )
- self.delete = to_streamed_response_wrapper(
- terminals.delete,
- )
-
-
-class AsyncTerminalsResourceWithStreamingResponse:
- def __init__(self, terminals: AsyncTerminalsResource) -> None:
- self._terminals = terminals
-
- self.create = async_to_streamed_response_wrapper(
- terminals.create,
- )
- self.retrieve = async_to_streamed_response_wrapper(
- terminals.retrieve,
- )
- self.list = async_to_streamed_response_wrapper(
- terminals.list,
- )
- self.delete = async_to_streamed_response_wrapper(
- terminals.delete,
- )
-
-
-class AsyncTerminalsResourceConnection:
- """Represents a live WebSocket connection to the Terminals API"""
-
- _connection: AsyncWebSocketConnection
-
- def __init__(
- self,
- connection: AsyncWebSocketConnection,
- *,
- make_ws: Callable[[Query, Headers], Awaitable[AsyncWebSocketConnection]] | None = None,
- on_reconnecting: Callable[[ReconnectingEvent], ReconnectingOverrides | None] | None = None,
- max_retries: int = 5,
- initial_delay: float = 0.5,
- max_delay: float = 8.0,
- extra_query: Query = {},
- extra_headers: Headers = {},
- send_queue: SendQueue | None = None,
- ) -> None:
- self._connection = connection
- self._make_ws = make_ws
- self._on_reconnecting = on_reconnecting
- self._max_retries = max_retries
- self._initial_delay = initial_delay
- self._max_delay = max_delay
- self._extra_query = extra_query
- self._extra_headers = extra_headers
- self._intentionally_closed = False
- self._is_reconnecting = False
- self._send_queue = send_queue or SendQueue()
- self._event_handler_registry = EventHandlerRegistry(use_lock=False)
-
- async def __aiter__(self) -> AsyncIterator[TerminalServerEvent]:
- """
- An infinite-iterator that will continue to yield events until
- the connection is closed.
- """
- from websockets.exceptions import ConnectionClosedOK, ConnectionClosedError
-
- while True:
- try:
- yield await self.recv()
- except ConnectionClosedOK:
- return
- except ConnectionClosedError as exc:
- if not await self._reconnect(exc):
- unsent = self._send_queue.drain()
- if unsent:
- raise WebSocketConnectionClosedError(
- "WebSocket connection closed with unsent messages",
- unsent_messages=unsent,
- ) from exc
- raise
-
- async def recv(self) -> TerminalServerEvent:
- """
- Receive the next message from the connection and parses it into a `TerminalServerEvent` object.
-
- Canceling this method is safe. There's no risk of losing data.
- """
- return self.parse_event(await self.recv_bytes())
-
- async def recv_bytes(self) -> bytes:
- """Receive the next message from the connection as raw bytes.
-
- Canceling this method is safe. There's no risk of losing data.
-
- If you want to parse the message into a `TerminalServerEvent` object like `.recv()` does,
- then you can call `.parse_event(data)`.
- """
- message = await self._connection.recv(decode=False)
- log.debug(f"Received WebSocket message: %s", message)
- return message
-
- async def send(self, event: TerminalClientEvent | TerminalClientEventParam) -> None:
- data = (
- event.to_json(use_api_names=True, exclude_defaults=True, exclude_unset=True)
- if isinstance(event, BaseModel)
- else json.dumps(await async_maybe_transform(event, TerminalClientEventParam))
- )
- if self._is_reconnecting:
- self._send_queue.enqueue(data)
- return
- try:
- await self._connection.send(data)
- except Exception:
- self._send_queue.enqueue(data)
- raise
-
- async def send_raw(self, data: bytes | str) -> None:
- if self._is_reconnecting:
- raw = data if isinstance(data, str) else data.decode("utf-8")
- self._send_queue.enqueue(raw)
- return
- await self._connection.send(data)
-
- async def close(self, *, code: int = 1000, reason: str = "") -> None:
- self._intentionally_closed = True
- await self._connection.close(code=code, reason=reason)
-
- def parse_event(self, data: str | bytes) -> TerminalServerEvent:
- """
- Converts a raw `str` or `bytes` message into a `TerminalServerEvent` object.
-
- This is helpful if you're using `.recv_bytes()`.
- """
- return cast(
- TerminalServerEvent, construct_type_unchecked(value=json.loads(data), type_=cast(Any, TerminalServerEvent))
- )
-
- async def _reconnect(self, exc: Exception) -> bool:
- """Attempt to reconnect after a connection failure.
-
- Returns ``True`` if a new connection was established, ``False`` if the
- caller should re-raise the original exception.
- """
- import asyncio
-
- if self._on_reconnecting is None or self._make_ws is None:
- return False
-
- from websockets.exceptions import ConnectionClosedError
-
- close_code = 1006
- if isinstance(exc, ConnectionClosedError) and exc.rcvd is not None:
- close_code = exc.rcvd.code
-
- if not is_recoverable_close(close_code):
- return False
-
- self._is_reconnecting = True
-
- for attempt in range(1, self._max_retries + 1):
- base_delay = min(self._initial_delay * (2 ** (attempt - 1)), self._max_delay)
- jitter = 0.75 + random.random() * 0.25
- delay = base_delay * jitter
-
- event = ReconnectingEvent(
- attempt=attempt,
- max_attempts=self._max_retries,
- delay=delay,
- close_code=close_code,
- extra_query=self._extra_query,
- extra_headers=self._extra_headers,
- )
-
- try:
- result = self._on_reconnecting(event)
- except Exception:
- self._is_reconnecting = False
- return False
-
- if result is not None and result.get("abort"):
- self._is_reconnecting = False
- return False
-
- if result is not None:
- if "extra_query" in result:
- self._extra_query = result["extra_query"]
- if "extra_headers" in result:
- self._extra_headers = result["extra_headers"]
-
- log.info(
- "Reconnecting to WebSocket API (attempt %d/%d) after %.1fs delay",
- attempt,
- self._max_retries,
- delay,
- )
- await asyncio.sleep(delay)
-
- if self._intentionally_closed:
- self._is_reconnecting = False
- return False
-
- try:
- self._connection = await self._make_ws(self._extra_query, self._extra_headers)
- log.info("Reconnected to WebSocket API")
- self._is_reconnecting = False
- await self._flush_send_queue()
- return True
- except Exception:
- pass
-
- self._is_reconnecting = False
- return False
-
- async def _flush_send_queue(self) -> None:
- """Send all queued messages over the current connection."""
-
- async def _send(data: str) -> None:
- await self._connection.send(data)
-
- try:
- await self._send_queue.flush_async(_send)
- except Exception:
- log.warning("Failed to flush send queue after reconnect", exc_info=True)
-
- def on(
- self, event_type: str, handler: Callable[..., Any] | None = None
- ) -> Union[AsyncTerminalsResourceConnection, Callable[[Callable[..., Any]], Callable[..., Any]]]:
- """Adds the handler to the end of the handlers list for the given event type.
-
- No checks are made to see if the handler has already been added. Multiple calls
- passing the same combination of event type and handler will result in the handler
- being added, and called, multiple times.
-
- Can be used as a method (returns ``self`` for chaining)::
-
- connection.on("output", my_handler)
-
- Or as a decorator::
-
- @connection.on("output")
- async def my_handler(event): ...
- """
- if handler is not None:
- self._event_handler_registry.add(event_type, handler)
- return self
-
- def decorator(fn: Callable[..., Any]) -> Callable[..., Any]:
- self._event_handler_registry.add(event_type, fn)
- return fn
-
- return decorator
-
- def off(self, event_type: str, handler: Callable[..., Any]) -> AsyncTerminalsResourceConnection:
- """Remove a previously registered event handler."""
- self._event_handler_registry.remove(event_type, handler)
- return self
-
- def once(
- self, event_type: str, handler: Callable[..., Any] | None = None
- ) -> Union[AsyncTerminalsResourceConnection, Callable[[Callable[..., Any]], Callable[..., Any]]]:
- """Register a one-time event handler.
-
- Automatically removed after first invocation.
- """
- if handler is not None:
- self._event_handler_registry.add(event_type, handler, once=True)
- return self
-
- def decorator(fn: Callable[..., Any]) -> Callable[..., Any]:
- self._event_handler_registry.add(event_type, fn, once=True)
- return fn
-
- return decorator
-
- async def dispatch_events(self) -> None:
- """Run the event loop, dispatching received events to registered handlers.
-
- Blocks until the connection is closed. This is the push-based
- alternative to iterating with ``async for event in connection``.
-
- If an ``"error"`` event arrives and no handler is registered for
- ``"error"`` or ``"event"``, an ``DedalusError`` is raised.
- """
- import asyncio
-
- async for event in self:
- event_type = event.type
- specific = self._event_handler_registry.get_handlers(event_type)
- generic = self._event_handler_registry.get_handlers("event")
-
- if event_type == "error" and not specific and not generic:
- if isinstance(event, TerminalErrorEvent):
- raise DedalusError(f"WebSocket error: {event}")
-
- for handler in specific:
- result = handler(event)
- if asyncio.iscoroutine(result):
- await result
-
- for handler in generic:
- result = handler(event)
- if asyncio.iscoroutine(result):
- await result
-
-
-class AsyncTerminalsResourceConnectionManager:
- """
- Context manager over a `AsyncTerminalsResourceConnection` that is returned by `machines.terminals.connect()`
-
- This context manager ensures that the connection will be closed when it exits.
-
- ---
-
- Note that if your application doesn't work well with the context manager approach then you
- can call the `.enter()` method directly to initiate a connection.
-
- **Warning**: You must remember to close the connection with `.close()`.
-
- ```py
- connection = await client.machines.terminals.connect(...).enter()
- # ...
- await connection.close()
- ```
- """
-
- def __init__(
- self,
- *,
- client: AsyncDedalus,
- machine_id: str,
- terminal_id: str,
- extra_query: Query,
- extra_headers: Headers,
- websocket_connection_options: WebSocketConnectionOptions,
- on_reconnecting: Callable[[ReconnectingEvent], ReconnectingOverrides | None] | None = None,
- max_retries: int = 5,
- initial_delay: float = 0.5,
- max_delay: float = 8.0,
- max_queue_size: int = 1_048_576,
- ) -> None:
- self.__client = client
- self.__machine_id = machine_id
- self.__terminal_id = terminal_id
- self.__connection: AsyncTerminalsResourceConnection | None = None
- self.__extra_query = extra_query
- self.__extra_headers = extra_headers
- self.__websocket_connection_options = websocket_connection_options
- self.__on_reconnecting = on_reconnecting
- self.__max_retries = max_retries
- self.__initial_delay = initial_delay
- self.__max_delay = max_delay
- self.__send_queue = SendQueue(max_bytes=max_queue_size)
- self.__event_handler_registry = EventHandlerRegistry(use_lock=False)
-
- def send(self, event: TerminalClientEvent | TerminalClientEventParam) -> None:
- """Queue a message to be sent when the connection is established.
-
- This can be called before entering the context manager. Queued messages
- are automatically sent once the WebSocket connection opens.
- """
- data = (
- event.to_json(use_api_names=True, exclude_defaults=True, exclude_unset=True)
- if isinstance(event, BaseModel)
- else json.dumps(event)
- )
- self.__send_queue.enqueue(data)
-
- def on(
- self, event_type: str, handler: Callable[..., Any] | None = None
- ) -> Union[AsyncTerminalsResourceConnectionManager, Callable[[Callable[..., Any]], Callable[..., Any]]]:
- """Register an event handler before the connection is established.
-
- Handlers are transferred to the connection on enter. Supports the
- same method and decorator forms as ``AsyncTerminalsResourceConnection.on``.
- """
- if handler is not None:
- self.__event_handler_registry.add(event_type, handler)
- return self
-
- def decorator(fn: Callable[..., Any]) -> Callable[..., Any]:
- self.__event_handler_registry.add(event_type, fn)
- return fn
-
- return decorator
-
- def off(self, event_type: str, handler: Callable[..., Any]) -> AsyncTerminalsResourceConnectionManager:
- """Remove a previously registered event handler."""
- self.__event_handler_registry.remove(event_type, handler)
- return self
-
- def once(
- self, event_type: str, handler: Callable[..., Any] | None = None
- ) -> Union[AsyncTerminalsResourceConnectionManager, Callable[[Callable[..., Any]], Callable[..., Any]]]:
- """Register a one-time event handler before the connection is established."""
- if handler is not None:
- self.__event_handler_registry.add(event_type, handler, once=True)
- return self
-
- def decorator(fn: Callable[..., Any]) -> Callable[..., Any]:
- self.__event_handler_registry.add(event_type, fn, once=True)
- return fn
-
- return decorator
-
- async def __aenter__(self) -> AsyncTerminalsResourceConnection:
- """
- If your application doesn't work well with the context manager approach then you
- can call this method directly to initiate a connection.
-
- **Warning**: You must remember to close the connection with `.close()`.
-
- ```py
- connection = await client.machines.terminals.connect(...).enter()
- # ...
- await connection.close()
- ```
- """
- ws = await self._connect_ws(self.__extra_query, self.__extra_headers)
-
- self.__connection = AsyncTerminalsResourceConnection(
- ws,
- make_ws=self._connect_ws if self.__on_reconnecting is not None else None,
- on_reconnecting=self.__on_reconnecting,
- max_retries=self.__max_retries,
- initial_delay=self.__initial_delay,
- max_delay=self.__max_delay,
- extra_query=self.__extra_query,
- extra_headers=self.__extra_headers,
- send_queue=self.__send_queue,
- )
-
- self.__event_handler_registry.merge_into(self.__connection._event_handler_registry)
- await self.__connection._flush_send_queue()
-
- return self.__connection
-
- enter = __aenter__
-
- async def _connect_ws(self, extra_query: Query, extra_headers: Headers) -> AsyncWebSocketConnection:
- try:
- from websockets.asyncio.client import connect
- except ImportError as exc:
- raise DedalusError("You need to install `dedalus-sdk[websockets]` to use this method") from exc
-
- if not self.__machine_id:
- raise ValueError(f"Expected a non-empty value for `machine_id` but received {self.__machine_id!r}")
- if not self.__terminal_id:
- raise ValueError(f"Expected a non-empty value for `terminal_id` but received {self.__terminal_id!r}")
- url = self._prepare_url().copy_with(
- params={
- **self.__client.base_url.params,
- **extra_query,
- },
- )
- log.debug("Connecting to %s", url)
- if self.__websocket_connection_options:
- log.debug("Connection options: %s", self.__websocket_connection_options)
-
- return await connect(
- str(url),
- user_agent_header=self.__client.user_agent,
- additional_headers=_merge_mappings(
- {
- **self.__client.auth_headers,
- },
- extra_headers,
- ),
- **self.__websocket_connection_options,
- )
-
- def _prepare_url(self) -> httpx.URL:
- if self.__client.websocket_base_url is not None:
- base_url = httpx.URL(self.__client.websocket_base_url)
- else:
- scheme = self.__client._base_url.scheme
- ws_scheme = "ws" if scheme == "http" else "wss"
- base_url = self.__client._base_url.copy_with(scheme=ws_scheme)
-
- merge_raw_path = base_url.raw_path.rstrip(b"/") + path_template(
- "/v1/machines/{machine_id}/terminals/{terminal_id}/stream",
- machine_id=self.__machine_id,
- terminal_id=self.__terminal_id,
- ).encode("utf-8")
- return base_url.copy_with(raw_path=merge_raw_path)
-
- async def __aexit__(
- self, exc_type: type[BaseException] | None, exc: BaseException | None, exc_tb: TracebackType | None
- ) -> None:
- if self.__connection is not None:
- await self.__connection.close()
-
-
-class TerminalsResourceConnection:
- """Represents a live WebSocket connection to the Terminals API"""
-
- _connection: WebSocketConnection
-
- def __init__(
- self,
- connection: WebSocketConnection,
- *,
- make_ws: Callable[[Query, Headers], WebSocketConnection] | None = None,
- on_reconnecting: Callable[[ReconnectingEvent], ReconnectingOverrides | None] | None = None,
- max_retries: int = 5,
- initial_delay: float = 0.5,
- max_delay: float = 8.0,
- extra_query: Query = {},
- extra_headers: Headers = {},
- send_queue: SendQueue | None = None,
- ) -> None:
- self._connection = connection
- self._make_ws = make_ws
- self._on_reconnecting = on_reconnecting
- self._max_retries = max_retries
- self._initial_delay = initial_delay
- self._max_delay = max_delay
- self._extra_query = extra_query
- self._extra_headers = extra_headers
- self._intentionally_closed = False
- self._is_reconnecting = False
- self._send_queue = send_queue or SendQueue()
- self._event_handler_registry = EventHandlerRegistry(use_lock=True)
-
- def __iter__(self) -> Iterator[TerminalServerEvent]:
- """
- An infinite-iterator that will continue to yield events until
- the connection is closed.
- """
- from websockets.exceptions import ConnectionClosedOK, ConnectionClosedError
-
- while True:
- try:
- yield self.recv()
- except ConnectionClosedOK:
- return
- except ConnectionClosedError as exc:
- if not self._reconnect(exc):
- unsent = self._send_queue.drain()
- if unsent:
- raise WebSocketConnectionClosedError(
- "WebSocket connection closed with unsent messages",
- unsent_messages=unsent,
- ) from exc
- raise
-
- def recv(self) -> TerminalServerEvent:
- """
- Receive the next message from the connection and parses it into a `TerminalServerEvent` object.
-
- Canceling this method is safe. There's no risk of losing data.
- """
- return self.parse_event(self.recv_bytes())
-
- def recv_bytes(self) -> bytes:
- """Receive the next message from the connection as raw bytes.
-
- Canceling this method is safe. There's no risk of losing data.
-
- If you want to parse the message into a `TerminalServerEvent` object like `.recv()` does,
- then you can call `.parse_event(data)`.
- """
- message = self._connection.recv(decode=False)
- log.debug(f"Received WebSocket message: %s", message)
- return message
-
- def send(self, event: TerminalClientEvent | TerminalClientEventParam) -> None:
- data = (
- event.to_json(use_api_names=True, exclude_defaults=True, exclude_unset=True)
- if isinstance(event, BaseModel)
- else json.dumps(maybe_transform(event, TerminalClientEventParam))
- )
- if self._is_reconnecting:
- self._send_queue.enqueue(data)
- return
- try:
- self._connection.send(data)
- except Exception:
- self._send_queue.enqueue(data)
- raise
-
- def send_raw(self, data: bytes | str) -> None:
- if self._is_reconnecting:
- raw = data if isinstance(data, str) else data.decode("utf-8")
- self._send_queue.enqueue(raw)
- return
- self._connection.send(data)
-
- def close(self, *, code: int = 1000, reason: str = "") -> None:
- self._intentionally_closed = True
- self._connection.close(code=code, reason=reason)
-
- def parse_event(self, data: str | bytes) -> TerminalServerEvent:
- """
- Converts a raw `str` or `bytes` message into a `TerminalServerEvent` object.
-
- This is helpful if you're using `.recv_bytes()`.
- """
- return cast(
- TerminalServerEvent, construct_type_unchecked(value=json.loads(data), type_=cast(Any, TerminalServerEvent))
- )
-
- def _reconnect(self, exc: Exception) -> bool:
- """Attempt to reconnect after a connection failure.
-
- Returns ``True`` if a new connection was established, ``False`` if the
- caller should re-raise the original exception.
- """
- if self._on_reconnecting is None or self._make_ws is None:
- return False
-
- from websockets.exceptions import ConnectionClosedError
-
- close_code = 1006
- if isinstance(exc, ConnectionClosedError) and exc.rcvd is not None:
- close_code = exc.rcvd.code
-
- if not is_recoverable_close(close_code):
- return False
-
- self._is_reconnecting = True
-
- for attempt in range(1, self._max_retries + 1):
- base_delay = min(self._initial_delay * (2 ** (attempt - 1)), self._max_delay)
- jitter = 0.75 + random.random() * 0.25
- delay = base_delay * jitter
-
- event = ReconnectingEvent(
- attempt=attempt,
- max_attempts=self._max_retries,
- delay=delay,
- close_code=close_code,
- extra_query=self._extra_query,
- extra_headers=self._extra_headers,
- )
-
- try:
- result = self._on_reconnecting(event)
- except Exception:
- self._is_reconnecting = False
- return False
-
- if result is not None and result.get("abort"):
- self._is_reconnecting = False
- return False
-
- if result is not None:
- if "extra_query" in result:
- self._extra_query = result["extra_query"]
- if "extra_headers" in result:
- self._extra_headers = result["extra_headers"]
-
- log.info(
- "Reconnecting to WebSocket API (attempt %d/%d) after %.1fs delay",
- attempt,
- self._max_retries,
- delay,
- )
- time.sleep(delay)
-
- if self._intentionally_closed:
- self._is_reconnecting = False
- return False
-
- try:
- self._connection = self._make_ws(self._extra_query, self._extra_headers)
- log.info("Reconnected to WebSocket API")
- self._is_reconnecting = False
- self._flush_send_queue()
- return True
- except Exception:
- pass
-
- self._is_reconnecting = False
- return False
-
- def _flush_send_queue(self) -> None:
- """Send all queued messages over the current connection."""
- try:
- self._send_queue.flush_sync(lambda data: self._connection.send(data))
- except Exception:
- log.warning("Failed to flush send queue after reconnect", exc_info=True)
-
- def on(
- self, event_type: str, handler: Callable[..., Any] | None = None
- ) -> Union[TerminalsResourceConnection, Callable[[Callable[..., Any]], Callable[..., Any]]]:
- """Adds the handler to the end of the handlers list for the given event type.
-
- No checks are made to see if the handler has already been added. Multiple calls
- passing the same combination of event type and handler will result in the handler
- being added, and called, multiple times.
-
- Can be used as a method (returns ``self`` for chaining)::
-
- connection.on("output", my_handler)
-
- Or as a decorator::
-
- @connection.on("output")
- def my_handler(event): ...
- """
- if handler is not None:
- self._event_handler_registry.add(event_type, handler)
- return self
-
- def decorator(fn: Callable[..., Any]) -> Callable[..., Any]:
- self._event_handler_registry.add(event_type, fn)
- return fn
-
- return decorator
-
- def off(self, event_type: str, handler: Callable[..., Any]) -> TerminalsResourceConnection:
- """Remove a previously registered event handler."""
- self._event_handler_registry.remove(event_type, handler)
- return self
-
- def once(
- self, event_type: str, handler: Callable[..., Any] | None = None
- ) -> Union[TerminalsResourceConnection, Callable[[Callable[..., Any]], Callable[..., Any]]]:
- """Register a one-time event handler.
-
- Automatically removed after first invocation.
- """
- if handler is not None:
- self._event_handler_registry.add(event_type, handler, once=True)
- return self
-
- def decorator(fn: Callable[..., Any]) -> Callable[..., Any]:
- self._event_handler_registry.add(event_type, fn, once=True)
- return fn
-
- return decorator
-
- def dispatch_events(self) -> None:
- """Run the event loop, dispatching received events to registered handlers.
-
- Blocks the current thread until the connection is closed. This is the push-based
- alternative to iterating with ``for event in connection``.
-
- If an ``"error"`` event arrives and no handler is registered for
- ``"error"`` or ``"event"``, an ``DedalusError`` is raised.
- """
- for event in self:
- event_type = event.type
- specific = self._event_handler_registry.get_handlers(event_type)
- generic = self._event_handler_registry.get_handlers("event")
-
- if event_type == "error" and not specific and not generic:
- if isinstance(event, TerminalErrorEvent):
- raise DedalusError(f"WebSocket error: {event}")
-
- for handler in specific:
- handler(event)
-
- for handler in generic:
- handler(event)
-
-
-class TerminalsResourceConnectionManager:
- """
- Context manager over a `TerminalsResourceConnection` that is returned by `machines.terminals.connect()`
-
- This context manager ensures that the connection will be closed when it exits.
-
- ---
-
- Note that if your application doesn't work well with the context manager approach then you
- can call the `.enter()` method directly to initiate a connection.
-
- **Warning**: You must remember to close the connection with `.close()`.
-
- ```py
- connection = client.machines.terminals.connect(...).enter()
- # ...
- connection.close()
- ```
- """
-
- def __init__(
- self,
- *,
- client: Dedalus,
- machine_id: str,
- terminal_id: str,
- extra_query: Query,
- extra_headers: Headers,
- websocket_connection_options: WebSocketConnectionOptions,
- on_reconnecting: Callable[[ReconnectingEvent], ReconnectingOverrides | None] | None = None,
- max_retries: int = 5,
- initial_delay: float = 0.5,
- max_delay: float = 8.0,
- max_queue_size: int = 1_048_576,
- ) -> None:
- self.__client = client
- self.__machine_id = machine_id
- self.__terminal_id = terminal_id
- self.__connection: TerminalsResourceConnection | None = None
- self.__extra_query = extra_query
- self.__extra_headers = extra_headers
- self.__websocket_connection_options = websocket_connection_options
- self.__on_reconnecting = on_reconnecting
- self.__max_retries = max_retries
- self.__initial_delay = initial_delay
- self.__max_delay = max_delay
- self.__send_queue = SendQueue(max_bytes=max_queue_size)
- self.__event_handler_registry = EventHandlerRegistry(use_lock=True)
-
- def send(self, event: TerminalClientEvent | TerminalClientEventParam) -> None:
- """Queue a message to be sent when the connection is established.
-
- This can be called before entering the context manager. Queued messages
- are automatically sent once the WebSocket connection opens.
- """
- data = (
- event.to_json(use_api_names=True, exclude_defaults=True, exclude_unset=True)
- if isinstance(event, BaseModel)
- else json.dumps(event)
- )
- self.__send_queue.enqueue(data)
-
- def on(
- self, event_type: str, handler: Callable[..., Any] | None = None
- ) -> Union[TerminalsResourceConnectionManager, Callable[[Callable[..., Any]], Callable[..., Any]]]:
- """Register an event handler before the connection is established.
-
- Handlers are transferred to the connection on enter. Supports the
- same method and decorator forms as ``TerminalsResourceConnection.on``.
- """
- if handler is not None:
- self.__event_handler_registry.add(event_type, handler)
- return self
-
- def decorator(fn: Callable[..., Any]) -> Callable[..., Any]:
- self.__event_handler_registry.add(event_type, fn)
- return fn
-
- return decorator
-
- def off(self, event_type: str, handler: Callable[..., Any]) -> TerminalsResourceConnectionManager:
- """Remove a previously registered event handler."""
- self.__event_handler_registry.remove(event_type, handler)
- return self
-
- def once(
- self, event_type: str, handler: Callable[..., Any] | None = None
- ) -> Union[TerminalsResourceConnectionManager, Callable[[Callable[..., Any]], Callable[..., Any]]]:
- """Register a one-time event handler before the connection is established."""
- if handler is not None:
- self.__event_handler_registry.add(event_type, handler, once=True)
- return self
-
- def decorator(fn: Callable[..., Any]) -> Callable[..., Any]:
- self.__event_handler_registry.add(event_type, fn, once=True)
- return fn
-
- return decorator
-
- def __enter__(self) -> TerminalsResourceConnection:
- """
- If your application doesn't work well with the context manager approach then you
- can call this method directly to initiate a connection.
-
- **Warning**: You must remember to close the connection with `.close()`.
-
- ```py
- connection = client.machines.terminals.connect(...).enter()
- # ...
- connection.close()
- ```
- """
- ws = self._connect_ws(self.__extra_query, self.__extra_headers)
-
- self.__connection = TerminalsResourceConnection(
- ws,
- make_ws=self._connect_ws if self.__on_reconnecting is not None else None,
- on_reconnecting=self.__on_reconnecting,
- max_retries=self.__max_retries,
- initial_delay=self.__initial_delay,
- max_delay=self.__max_delay,
- extra_query=self.__extra_query,
- extra_headers=self.__extra_headers,
- send_queue=self.__send_queue,
- )
-
- self.__event_handler_registry.merge_into(self.__connection._event_handler_registry)
- self.__connection._flush_send_queue()
-
- return self.__connection
-
- enter = __enter__
-
- def _connect_ws(self, extra_query: Query, extra_headers: Headers) -> WebSocketConnection:
- try:
- from websockets.sync.client import connect
- except ImportError as exc:
- raise DedalusError("You need to install `dedalus-sdk[websockets]` to use this method") from exc
-
- if not self.__machine_id:
- raise ValueError(f"Expected a non-empty value for `machine_id` but received {self.__machine_id!r}")
- if not self.__terminal_id:
- raise ValueError(f"Expected a non-empty value for `terminal_id` but received {self.__terminal_id!r}")
- url = self._prepare_url().copy_with(
- params={
- **self.__client.base_url.params,
- **extra_query,
- },
- )
- log.debug("Connecting to %s", url)
- if self.__websocket_connection_options:
- log.debug("Connection options: %s", self.__websocket_connection_options)
-
- return connect(
- str(url),
- user_agent_header=self.__client.user_agent,
- additional_headers=_merge_mappings(
- {
- **self.__client.auth_headers,
- },
- extra_headers,
- ),
- **self.__websocket_connection_options,
- )
-
- def _prepare_url(self) -> httpx.URL:
- if self.__client.websocket_base_url is not None:
- base_url = httpx.URL(self.__client.websocket_base_url)
- else:
- scheme = self.__client._base_url.scheme
- ws_scheme = "ws" if scheme == "http" else "wss"
- base_url = self.__client._base_url.copy_with(scheme=ws_scheme)
-
- merge_raw_path = base_url.raw_path.rstrip(b"/") + path_template(
- "/v1/machines/{machine_id}/terminals/{terminal_id}/stream",
- machine_id=self.__machine_id,
- terminal_id=self.__terminal_id,
- ).encode("utf-8")
- return base_url.copy_with(raw_path=merge_raw_path)
-
- def __exit__(
- self, exc_type: type[BaseException] | None, exc: BaseException | None, exc_tb: TracebackType | None
- ) -> None:
- if self.__connection is not None:
- self.__connection.close()
diff --git a/src/dedalus_sdk/resources/usage.py b/src/dedalus_sdk/resources/usage.py
deleted file mode 100644
index b55009d..0000000
--- a/src/dedalus_sdk/resources/usage.py
+++ /dev/null
@@ -1,411 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import httpx
-
-from ..types import usage_retrieve_params, usage_machine_compute_params, usage_machine_storage_params
-from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from .._utils import maybe_transform, async_maybe_transform
-from .._compat import cached_property
-from .._resource import SyncAPIResource, AsyncAPIResource
-from .._response import (
- to_raw_response_wrapper,
- to_streamed_response_wrapper,
- async_to_raw_response_wrapper,
- async_to_streamed_response_wrapper,
-)
-from .._base_client import make_request_options
-from ..types.org_usage import OrgUsage
-from ..types.machine_compute_usage import MachineComputeUsage
-from ..types.machine_storage_usage import MachineStorageUsage
-
-__all__ = ["UsageResource", "AsyncUsageResource"]
-
-
-class UsageResource(SyncAPIResource):
- @cached_property
- def with_raw_response(self) -> UsageResourceWithRawResponse:
- """
- 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/dedalus-labs/dedalus-python#accessing-raw-response-data-eg-headers
- """
- return UsageResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> UsageResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/dedalus-labs/dedalus-python#with_streaming_response
- """
- return UsageResourceWithStreamingResponse(self)
-
- def retrieve(
- self,
- *,
- period_start: 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,
- ) -> OrgUsage:
- """Get usage summary
-
- Args:
- period_start: Billing period start (YYYY-MM-DD).
-
- Defaults to first of current month.
-
- 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
- """
- return self._get(
- "/v1/usage",
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform({"period_start": period_start}, usage_retrieve_params.UsageRetrieveParams),
- ),
- cast_to=OrgUsage,
- )
-
- def machine_compute(
- self,
- *,
- granularity: str | Omit = omit,
- machine_id: str | Omit = omit,
- period_end: str | Omit = omit,
- period_start: 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,
- ) -> MachineComputeUsage:
- """
- List machine compute usage breakdown
-
- Args:
- granularity: Usage breakdown granularity: hour or day. Defaults to hour.
-
- machine_id: Optional machine ID filter.
-
- period_end: Last UTC usage date to include (YYYY-MM-DD). Defaults to current time.
-
- period_start: Usage period start (YYYY-MM-DD). Defaults to first of current month.
-
- 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
- """
- return self._get(
- "/v1/usage/machines/compute",
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "granularity": granularity,
- "machine_id": machine_id,
- "period_end": period_end,
- "period_start": period_start,
- },
- usage_machine_compute_params.UsageMachineComputeParams,
- ),
- ),
- cast_to=MachineComputeUsage,
- )
-
- def machine_storage(
- self,
- *,
- machine_id: str | Omit = omit,
- period_end: str | Omit = omit,
- period_start: 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,
- ) -> MachineStorageUsage:
- """
- List machine storage usage breakdown
-
- Args:
- machine_id: Optional machine ID filter.
-
- period_end: Last UTC usage date to include (YYYY-MM-DD). Defaults to current time.
-
- period_start: Usage period start (YYYY-MM-DD). Defaults to first of current month.
-
- 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
- """
- return self._get(
- "/v1/usage/machines/storage",
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "machine_id": machine_id,
- "period_end": period_end,
- "period_start": period_start,
- },
- usage_machine_storage_params.UsageMachineStorageParams,
- ),
- ),
- cast_to=MachineStorageUsage,
- )
-
-
-class AsyncUsageResource(AsyncAPIResource):
- @cached_property
- def with_raw_response(self) -> AsyncUsageResourceWithRawResponse:
- """
- 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/dedalus-labs/dedalus-python#accessing-raw-response-data-eg-headers
- """
- return AsyncUsageResourceWithRawResponse(self)
-
- @cached_property
- def with_streaming_response(self) -> AsyncUsageResourceWithStreamingResponse:
- """
- An alternative to `.with_raw_response` that doesn't eagerly read the response body.
-
- For more information, see https://www.github.com/dedalus-labs/dedalus-python#with_streaming_response
- """
- return AsyncUsageResourceWithStreamingResponse(self)
-
- async def retrieve(
- self,
- *,
- period_start: 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,
- ) -> OrgUsage:
- """Get usage summary
-
- Args:
- period_start: Billing period start (YYYY-MM-DD).
-
- Defaults to first of current month.
-
- 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
- """
- return await self._get(
- "/v1/usage",
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=await async_maybe_transform(
- {"period_start": period_start}, usage_retrieve_params.UsageRetrieveParams
- ),
- ),
- cast_to=OrgUsage,
- )
-
- async def machine_compute(
- self,
- *,
- granularity: str | Omit = omit,
- machine_id: str | Omit = omit,
- period_end: str | Omit = omit,
- period_start: 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,
- ) -> MachineComputeUsage:
- """
- List machine compute usage breakdown
-
- Args:
- granularity: Usage breakdown granularity: hour or day. Defaults to hour.
-
- machine_id: Optional machine ID filter.
-
- period_end: Last UTC usage date to include (YYYY-MM-DD). Defaults to current time.
-
- period_start: Usage period start (YYYY-MM-DD). Defaults to first of current month.
-
- 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
- """
- return await self._get(
- "/v1/usage/machines/compute",
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=await async_maybe_transform(
- {
- "granularity": granularity,
- "machine_id": machine_id,
- "period_end": period_end,
- "period_start": period_start,
- },
- usage_machine_compute_params.UsageMachineComputeParams,
- ),
- ),
- cast_to=MachineComputeUsage,
- )
-
- async def machine_storage(
- self,
- *,
- machine_id: str | Omit = omit,
- period_end: str | Omit = omit,
- period_start: 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,
- ) -> MachineStorageUsage:
- """
- List machine storage usage breakdown
-
- Args:
- machine_id: Optional machine ID filter.
-
- period_end: Last UTC usage date to include (YYYY-MM-DD). Defaults to current time.
-
- period_start: Usage period start (YYYY-MM-DD). Defaults to first of current month.
-
- 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
- """
- return await self._get(
- "/v1/usage/machines/storage",
- options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=await async_maybe_transform(
- {
- "machine_id": machine_id,
- "period_end": period_end,
- "period_start": period_start,
- },
- usage_machine_storage_params.UsageMachineStorageParams,
- ),
- ),
- cast_to=MachineStorageUsage,
- )
-
-
-class UsageResourceWithRawResponse:
- def __init__(self, usage: UsageResource) -> None:
- self._usage = usage
-
- self.retrieve = to_raw_response_wrapper(
- usage.retrieve,
- )
- self.machine_compute = to_raw_response_wrapper(
- usage.machine_compute,
- )
- self.machine_storage = to_raw_response_wrapper(
- usage.machine_storage,
- )
-
-
-class AsyncUsageResourceWithRawResponse:
- def __init__(self, usage: AsyncUsageResource) -> None:
- self._usage = usage
-
- self.retrieve = async_to_raw_response_wrapper(
- usage.retrieve,
- )
- self.machine_compute = async_to_raw_response_wrapper(
- usage.machine_compute,
- )
- self.machine_storage = async_to_raw_response_wrapper(
- usage.machine_storage,
- )
-
-
-class UsageResourceWithStreamingResponse:
- def __init__(self, usage: UsageResource) -> None:
- self._usage = usage
-
- self.retrieve = to_streamed_response_wrapper(
- usage.retrieve,
- )
- self.machine_compute = to_streamed_response_wrapper(
- usage.machine_compute,
- )
- self.machine_storage = to_streamed_response_wrapper(
- usage.machine_storage,
- )
-
-
-class AsyncUsageResourceWithStreamingResponse:
- def __init__(self, usage: AsyncUsageResource) -> None:
- self._usage = usage
-
- self.retrieve = async_to_streamed_response_wrapper(
- usage.retrieve,
- )
- self.machine_compute = async_to_streamed_response_wrapper(
- usage.machine_compute,
- )
- self.machine_storage = async_to_streamed_response_wrapper(
- usage.machine_storage,
- )
diff --git a/src/dedalus_sdk/types/__init__.py b/src/dedalus_sdk/types/__init__.py
index 446e783..6c1da62 100644
--- a/src/dedalus_sdk/types/__init__.py
+++ b/src/dedalus_sdk/types/__init__.py
@@ -3,22 +3,10 @@
from __future__ import annotations
from .machine import Machine as Machine
-from .org_usage import OrgUsage as OrgUsage
from .machine_list import MachineList as MachineList
from .lifecycle_status import LifecycleStatus as LifecycleStatus
from .machine_list_item import MachineListItem as MachineListItem
from .machine_list_params import MachineListParams as MachineListParams
-from .machine_compute_usage import MachineComputeUsage as MachineComputeUsage
from .machine_create_params import MachineCreateParams as MachineCreateParams
-from .machine_storage_usage import MachineStorageUsage as MachineStorageUsage
from .machine_update_params import MachineUpdateParams as MachineUpdateParams
-from .usage_retrieve_params import UsageRetrieveParams as UsageRetrieveParams
-from .websocket_reconnection import (
- ReconnectingEvent as ReconnectingEvent,
- ReconnectingOverrides as ReconnectingOverrides,
-)
-from .machine_compute_usage_row import MachineComputeUsageRow as MachineComputeUsageRow
-from .machine_storage_usage_row import MachineStorageUsageRow as MachineStorageUsageRow
-from .usage_machine_compute_params import UsageMachineComputeParams as UsageMachineComputeParams
-from .usage_machine_storage_params import UsageMachineStorageParams as UsageMachineStorageParams
-from .websocket_connection_options import WebSocketConnectionOptions as WebSocketConnectionOptions
+from .machine_retrieve_response import MachineRetrieveResponse as MachineRetrieveResponse
diff --git a/src/dedalus_sdk/types/machine.py b/src/dedalus_sdk/types/machine.py
index 750a1c1..cc707a2 100644
--- a/src/dedalus_sdk/types/machine.py
+++ b/src/dedalus_sdk/types/machine.py
@@ -3,7 +3,6 @@
from typing_extensions import Literal
from .._models import BaseModel
-from .lifecycle_status import LifecycleStatus
__all__ = ["Machine"]
@@ -19,7 +18,17 @@ class Machine(BaseModel):
memory_mib: int
"""Memory in MiB."""
- status: LifecycleStatus
+ phase: Literal[
+ "accepted",
+ "placement_pending",
+ "starting",
+ "running",
+ "stopping",
+ "sleeping",
+ "destroying",
+ "destroyed",
+ "failed",
+ ]
storage_gib: int
diff --git a/src/dedalus_sdk/types/machine_compute_usage.py b/src/dedalus_sdk/types/machine_compute_usage.py
deleted file mode 100644
index d762f4f..0000000
--- a/src/dedalus_sdk/types/machine_compute_usage.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from datetime import datetime
-
-from .._models import BaseModel
-from .machine_compute_usage_row import MachineComputeUsageRow
-
-__all__ = ["MachineComputeUsage"]
-
-
-class MachineComputeUsage(BaseModel):
- granularity: str
- """Usage breakdown granularity used for rows: hour or day."""
-
- period_end: datetime
- """Exclusive usage period end."""
-
- period_start: datetime
- """Inclusive usage period start."""
-
- rows: Optional[List[MachineComputeUsageRow]] = None
- """Machine-level compute usage breakdown rows."""
diff --git a/src/dedalus_sdk/types/machine_compute_usage_row.py b/src/dedalus_sdk/types/machine_compute_usage_row.py
deleted file mode 100644
index dad85a9..0000000
--- a/src/dedalus_sdk/types/machine_compute_usage_row.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from datetime import datetime
-
-from .._models import BaseModel
-
-__all__ = ["MachineComputeUsageRow"]
-
-
-class MachineComputeUsageRow(BaseModel):
- awake_seconds: int
- """Machine-awake seconds in this bucket."""
-
- bucket_end: datetime
- """Exclusive usage bucket end."""
-
- bucket_start: datetime
- """Inclusive usage bucket start."""
-
- cpu_millicore_seconds: int
- """Requested vCPU millicores multiplied by guest-owned active CPU seconds."""
-
- last_window_end: datetime
- """Latest raw window_end represented by this row."""
-
- machine_id: str
- """Machine identifier."""
-
- memory_mib_seconds: int
- """Requested memory MiB multiplied by running allocation seconds."""
-
- org_metering_bucket_ids: Optional[List[str]] = None
- """Org compute bucket IDs this row contributes to."""
-
- requested_memory_mib: int
- """Requested memory for this shape, in MiB."""
-
- requested_storage_gib: int
- """Requested storage for this shape, in GiB."""
-
- requested_vcpu: float
- """Requested vCPU for this shape."""
-
- spec_fingerprint: str
- """Stable fingerprint for the requested machine shape."""
-
- stripe_cpu_identifiers: Optional[List[str]] = None
- """Stripe CPU meter event identifiers linked to those org buckets."""
-
- stripe_memory_identifiers: Optional[List[str]] = None
- """Stripe memory meter event identifiers linked to those org buckets."""
-
- window_count: int
- """Raw usage windows compacted into this row."""
-
- latest_stripe_emitted_at: Optional[datetime] = None
- """Latest Stripe emission timestamp for linked org buckets, when emitted."""
diff --git a/src/dedalus_sdk/types/machine_create_params.py b/src/dedalus_sdk/types/machine_create_params.py
index 50df48b..1a39a10 100644
--- a/src/dedalus_sdk/types/machine_create_params.py
+++ b/src/dedalus_sdk/types/machine_create_params.py
@@ -2,24 +2,24 @@
from __future__ import annotations
-from typing_extensions import Required, TypedDict
+from typing_extensions import TypedDict
__all__ = ["MachineCreateParams"]
class MachineCreateParams(TypedDict, total=False):
- memory_mib: Required[int]
- """Memory in MiB."""
-
- storage_gib: Required[int]
- """Storage in GiB."""
-
- vcpu: Required[float]
- """CPU in vCPUs."""
-
autosleep: str
"""Idle window before autosleep.
Accepts fixed duration units like 30s, 30m, 2h, 7d3h4s, or 1w3d, raw seconds
("1800"), or never to disable.
"""
+
+ memory_mib: int
+ """Memory in MiB."""
+
+ storage_gib: int
+ """Storage in GiB."""
+
+ vcpu: float
+ """CPU in vCPUs."""
diff --git a/src/dedalus_sdk/types/machine_list_item.py b/src/dedalus_sdk/types/machine_list_item.py
index cb63899..440d90a 100644
--- a/src/dedalus_sdk/types/machine_list_item.py
+++ b/src/dedalus_sdk/types/machine_list_item.py
@@ -4,7 +4,6 @@
from typing_extensions import Literal
from .._models import BaseModel
-from .lifecycle_status import LifecycleStatus
__all__ = ["MachineListItem"]
@@ -22,7 +21,17 @@ class MachineListItem(BaseModel):
memory_mib: int
"""Memory in MiB."""
- status: LifecycleStatus
+ phase: Literal[
+ "accepted",
+ "placement_pending",
+ "starting",
+ "running",
+ "stopping",
+ "sleeping",
+ "destroying",
+ "destroyed",
+ "failed",
+ ]
storage_gib: int
diff --git a/src/dedalus_sdk/types/machine_retrieve_response.py b/src/dedalus_sdk/types/machine_retrieve_response.py
new file mode 100644
index 0000000..009a023
--- /dev/null
+++ b/src/dedalus_sdk/types/machine_retrieve_response.py
@@ -0,0 +1,27 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing_extensions import Literal
+
+from .._models import BaseModel
+from .lifecycle_status import LifecycleStatus
+
+__all__ = ["MachineRetrieveResponse"]
+
+
+class MachineRetrieveResponse(BaseModel):
+ autosleep_seconds: int
+ """Seconds of inactivity before autosleep. 0 disables autosleep."""
+
+ desired_state: Literal["running", "sleeping", "destroyed"]
+
+ machine_id: str
+
+ memory_mib: int
+ """Memory in MiB."""
+
+ status: LifecycleStatus
+
+ storage_gib: int
+
+ vcpu: float
+ """CPU in vCPUs."""
diff --git a/src/dedalus_sdk/types/machine_storage_usage.py b/src/dedalus_sdk/types/machine_storage_usage.py
deleted file mode 100644
index 795d271..0000000
--- a/src/dedalus_sdk/types/machine_storage_usage.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from datetime import datetime
-
-from .._models import BaseModel
-from .machine_storage_usage_row import MachineStorageUsageRow
-
-__all__ = ["MachineStorageUsage"]
-
-
-class MachineStorageUsage(BaseModel):
- period_end: datetime
- """Exclusive usage period end."""
-
- period_start: datetime
- """Inclusive usage period start."""
-
- rows: Optional[List[MachineStorageUsageRow]] = None
- """Machine-level storage usage breakdown rows."""
diff --git a/src/dedalus_sdk/types/machine_storage_usage_row.py b/src/dedalus_sdk/types/machine_storage_usage_row.py
deleted file mode 100644
index 88becc2..0000000
--- a/src/dedalus_sdk/types/machine_storage_usage_row.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-from datetime import datetime
-
-from .._models import BaseModel
-
-__all__ = ["MachineStorageUsageRow"]
-
-
-class MachineStorageUsageRow(BaseModel):
- bucket_end: datetime
- """Exclusive usage bucket end."""
-
- bucket_start: datetime
- """Inclusive usage bucket start."""
-
- logical_storage_bytes: int
- """Machine logical bytes observed for storage allocation."""
-
- machine_id: str
- """Machine identifier."""
-
- org_metering_bucket_id: str
- """Org storage bucket ID this row contributes to."""
-
- storage_mib_seconds: int
- """Allocated logical MiB-seconds for this machine."""
-
- stripe_storage_identifier: str
- """Stripe storage meter event identifier linked to that org bucket."""
-
- latest_stripe_emitted_at: Optional[datetime] = None
- """Latest Stripe emission timestamp for the linked org bucket, when emitted."""
diff --git a/src/dedalus_sdk/types/machines/__init__.py b/src/dedalus_sdk/types/machines/__init__.py
index 56ca47f..bf1af89 100644
--- a/src/dedalus_sdk/types/machines/__init__.py
+++ b/src/dedalus_sdk/types/machines/__init__.py
@@ -2,15 +2,9 @@
from __future__ import annotations
-from .preview import Preview as Preview
-from .artifact import Artifact as Artifact
-from .terminal import Terminal as Terminal
from .execution import Execution as Execution
from .ssh_session import SSHSession as SSHSession
from .artifact_ref import ArtifactRef as ArtifactRef
-from .preview_list import PreviewList as PreviewList
-from .artifact_list import ArtifactList as ArtifactList
-from .terminal_list import TerminalList as TerminalList
from .execution_list import ExecutionList as ExecutionList
from .ssh_connection import SSHConnection as SSHConnection
from .ssh_host_trust import SSHHostTrust as SSHHostTrust
@@ -20,21 +14,6 @@
from .execution_output import ExecutionOutput as ExecutionOutput
from .ssh_session_list import SSHSessionList as SSHSessionList
from .ssh_create_params import SSHCreateParams as SSHCreateParams
-from .preview_list_params import PreviewListParams as PreviewListParams
-from .artifact_list_params import ArtifactListParams as ArtifactListParams
-from .terminal_error_event import TerminalErrorEvent as TerminalErrorEvent
-from .terminal_input_event import TerminalInputEvent as TerminalInputEvent
-from .terminal_list_params import TerminalListParams as TerminalListParams
from .execution_list_params import ExecutionListParams as ExecutionListParams
-from .preview_create_params import PreviewCreateParams as PreviewCreateParams
-from .terminal_client_event import TerminalClientEvent as TerminalClientEvent
-from .terminal_closed_event import TerminalClosedEvent as TerminalClosedEvent
-from .terminal_output_event import TerminalOutputEvent as TerminalOutputEvent
-from .terminal_resize_event import TerminalResizeEvent as TerminalResizeEvent
-from .terminal_server_event import TerminalServerEvent as TerminalServerEvent
-from .terminal_create_params import TerminalCreateParams as TerminalCreateParams
from .execution_create_params import ExecutionCreateParams as ExecutionCreateParams
from .execution_events_params import ExecutionEventsParams as ExecutionEventsParams
-from .terminal_input_event_param import TerminalInputEventParam as TerminalInputEventParam
-from .terminal_client_event_param import TerminalClientEventParam as TerminalClientEventParam
-from .terminal_resize_event_param import TerminalResizeEventParam as TerminalResizeEventParam
diff --git a/src/dedalus_sdk/types/machines/artifact.py b/src/dedalus_sdk/types/machines/artifact.py
deleted file mode 100644
index 2a75d0d..0000000
--- a/src/dedalus_sdk/types/machines/artifact.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-from datetime import datetime
-
-from ..._models import BaseModel
-
-__all__ = ["Artifact"]
-
-
-class Artifact(BaseModel):
- artifact_id: str
-
- created_at: datetime
-
- machine_id: str
-
- name: str
-
- size_bytes: int
-
- download_url: Optional[str] = None
-
- execution_id: Optional[str] = None
-
- expires_at: Optional[datetime] = None
-
- mime_type: Optional[str] = None
-
- sha256: Optional[str] = None
diff --git a/src/dedalus_sdk/types/machines/artifact_list.py b/src/dedalus_sdk/types/machines/artifact_list.py
deleted file mode 100644
index 88ff211..0000000
--- a/src/dedalus_sdk/types/machines/artifact_list.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-
-from .artifact import Artifact
-from ..._models import BaseModel
-
-__all__ = ["ArtifactList"]
-
-
-class ArtifactList(BaseModel):
- items: Optional[List[Artifact]] = None
-
- next_cursor: Optional[str] = None
diff --git a/src/dedalus_sdk/types/machines/artifact_list_params.py b/src/dedalus_sdk/types/machines/artifact_list_params.py
deleted file mode 100644
index 61f41a1..0000000
--- a/src/dedalus_sdk/types/machines/artifact_list_params.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Required, TypedDict
-
-__all__ = ["ArtifactListParams"]
-
-
-class ArtifactListParams(TypedDict, total=False):
- machine_id: Required[str]
-
- cursor: str
-
- limit: int
diff --git a/src/dedalus_sdk/types/machines/preview.py b/src/dedalus_sdk/types/machines/preview.py
deleted file mode 100644
index 760ac82..0000000
--- a/src/dedalus_sdk/types/machines/preview.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-from datetime import datetime
-from typing_extensions import Literal
-
-from ..._models import BaseModel
-
-__all__ = ["Preview"]
-
-
-class Preview(BaseModel):
- created_at: datetime
-
- machine_id: str
-
- port: int
-
- preview_id: str
-
- status: Literal["wake_in_progress", "ready", "closed", "expired", "failed"]
-
- visibility: Literal["public", "private", "org"]
-
- error_code: Optional[str] = None
-
- error_message: Optional[str] = None
-
- expires_at: Optional[datetime] = None
-
- protocol: Optional[Literal["http", "https"]] = None
-
- ready_at: Optional[datetime] = None
-
- retry_after_ms: Optional[int] = None
-
- url: Optional[str] = None
diff --git a/src/dedalus_sdk/types/machines/preview_create_params.py b/src/dedalus_sdk/types/machines/preview_create_params.py
deleted file mode 100644
index 9e9f9e8..0000000
--- a/src/dedalus_sdk/types/machines/preview_create_params.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Literal, Required, TypedDict
-
-__all__ = ["PreviewCreateParams"]
-
-
-class PreviewCreateParams(TypedDict, total=False):
- machine_id: Required[str]
-
- port: Required[int]
-
- protocol: Literal["http", "https"]
-
- visibility: Literal["public", "private", "org"]
diff --git a/src/dedalus_sdk/types/machines/preview_list.py b/src/dedalus_sdk/types/machines/preview_list.py
deleted file mode 100644
index 5cc0abe..0000000
--- a/src/dedalus_sdk/types/machines/preview_list.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-
-from .preview import Preview
-from ..._models import BaseModel
-
-__all__ = ["PreviewList"]
-
-
-class PreviewList(BaseModel):
- items: Optional[List[Preview]] = None
-
- next_cursor: Optional[str] = None
diff --git a/src/dedalus_sdk/types/machines/preview_list_params.py b/src/dedalus_sdk/types/machines/preview_list_params.py
deleted file mode 100644
index e1050f0..0000000
--- a/src/dedalus_sdk/types/machines/preview_list_params.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Required, TypedDict
-
-__all__ = ["PreviewListParams"]
-
-
-class PreviewListParams(TypedDict, total=False):
- machine_id: Required[str]
-
- cursor: str
-
- limit: int
diff --git a/src/dedalus_sdk/types/machines/terminal.py b/src/dedalus_sdk/types/machines/terminal.py
deleted file mode 100644
index 2897d3e..0000000
--- a/src/dedalus_sdk/types/machines/terminal.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-from datetime import datetime
-from typing_extensions import Literal
-
-from ..._models import BaseModel
-
-__all__ = ["Terminal"]
-
-
-class Terminal(BaseModel):
- created_at: datetime
-
- height: int
-
- machine_id: str
-
- status: Literal["wake_in_progress", "ready", "closed", "expired", "failed"]
-
- terminal_id: str
-
- width: int
-
- error_code: Optional[str] = None
-
- error_message: Optional[str] = None
-
- expires_at: Optional[datetime] = None
-
- protocol: Optional[Literal["websocket"]] = None
-
- ready_at: Optional[datetime] = None
-
- retry_after_ms: Optional[int] = None
-
- stream_url: Optional[str] = None
diff --git a/src/dedalus_sdk/types/machines/terminal_client_event.py b/src/dedalus_sdk/types/machines/terminal_client_event.py
deleted file mode 100644
index 94fb770..0000000
--- a/src/dedalus_sdk/types/machines/terminal_client_event.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Union
-from typing_extensions import Annotated, TypeAlias
-
-from ..._utils import PropertyInfo
-from .terminal_input_event import TerminalInputEvent
-from .terminal_resize_event import TerminalResizeEvent
-
-__all__ = ["TerminalClientEvent"]
-
-TerminalClientEvent: TypeAlias = Annotated[
- Union[TerminalInputEvent, TerminalResizeEvent], PropertyInfo(discriminator="type")
-]
diff --git a/src/dedalus_sdk/types/machines/terminal_client_event_param.py b/src/dedalus_sdk/types/machines/terminal_client_event_param.py
deleted file mode 100644
index d309564..0000000
--- a/src/dedalus_sdk/types/machines/terminal_client_event_param.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Union
-from typing_extensions import TypeAlias
-
-from .terminal_input_event_param import TerminalInputEventParam
-from .terminal_resize_event_param import TerminalResizeEventParam
-
-__all__ = ["TerminalClientEventParam"]
-
-TerminalClientEventParam: TypeAlias = Union[TerminalInputEventParam, TerminalResizeEventParam]
diff --git a/src/dedalus_sdk/types/machines/terminal_closed_event.py b/src/dedalus_sdk/types/machines/terminal_closed_event.py
deleted file mode 100644
index 62c9e93..0000000
--- a/src/dedalus_sdk/types/machines/terminal_closed_event.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing_extensions import Literal
-
-from ..._models import BaseModel
-
-__all__ = ["TerminalClosedEvent"]
-
-
-class TerminalClosedEvent(BaseModel):
- type: Literal["closed"]
diff --git a/src/dedalus_sdk/types/machines/terminal_create_params.py b/src/dedalus_sdk/types/machines/terminal_create_params.py
deleted file mode 100644
index 53b2a38..0000000
--- a/src/dedalus_sdk/types/machines/terminal_create_params.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Dict
-from typing_extensions import Required, TypedDict
-
-__all__ = ["TerminalCreateParams"]
-
-
-class TerminalCreateParams(TypedDict, total=False):
- machine_id: Required[str]
-
- height: Required[int]
-
- width: Required[int]
-
- cwd: str
-
- env: Dict[str, str]
-
- shell: str
diff --git a/src/dedalus_sdk/types/machines/terminal_error_event.py b/src/dedalus_sdk/types/machines/terminal_error_event.py
deleted file mode 100644
index d1dd0d1..0000000
--- a/src/dedalus_sdk/types/machines/terminal_error_event.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-from typing_extensions import Literal
-
-from ..._models import BaseModel
-
-__all__ = ["TerminalErrorEvent"]
-
-
-class TerminalErrorEvent(BaseModel):
- type: Literal["error"]
-
- error_code: Optional[str] = None
-
- error_message: Optional[str] = None
diff --git a/src/dedalus_sdk/types/machines/terminal_input_event.py b/src/dedalus_sdk/types/machines/terminal_input_event.py
deleted file mode 100644
index 259f896..0000000
--- a/src/dedalus_sdk/types/machines/terminal_input_event.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing_extensions import Literal
-
-from ..._models import BaseModel
-
-__all__ = ["TerminalInputEvent"]
-
-
-class TerminalInputEvent(BaseModel):
- data: str
- """Base64-encoded terminal input."""
-
- type: Literal["input"]
diff --git a/src/dedalus_sdk/types/machines/terminal_input_event_param.py b/src/dedalus_sdk/types/machines/terminal_input_event_param.py
deleted file mode 100644
index 17f1984..0000000
--- a/src/dedalus_sdk/types/machines/terminal_input_event_param.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Union
-from typing_extensions import Literal, Required, Annotated, TypedDict
-
-from ..._types import Base64FileInput
-from ..._utils import PropertyInfo
-from ..._models import set_pydantic_config
-
-__all__ = ["TerminalInputEventParam"]
-
-
-class TerminalInputEventParam(TypedDict, total=False):
- data: Required[Annotated[Union[str, Base64FileInput], PropertyInfo(format="base64")]]
- """Base64-encoded terminal input."""
-
- type: Required[Literal["input"]]
-
-
-set_pydantic_config(TerminalInputEventParam, {"arbitrary_types_allowed": True})
diff --git a/src/dedalus_sdk/types/machines/terminal_list.py b/src/dedalus_sdk/types/machines/terminal_list.py
deleted file mode 100644
index ebcbdd1..0000000
--- a/src/dedalus_sdk/types/machines/terminal_list.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-
-from .terminal import Terminal
-from ..._models import BaseModel
-
-__all__ = ["TerminalList"]
-
-
-class TerminalList(BaseModel):
- items: Optional[List[Terminal]] = None
-
- next_cursor: Optional[str] = None
diff --git a/src/dedalus_sdk/types/machines/terminal_list_params.py b/src/dedalus_sdk/types/machines/terminal_list_params.py
deleted file mode 100644
index cd723d6..0000000
--- a/src/dedalus_sdk/types/machines/terminal_list_params.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Required, TypedDict
-
-__all__ = ["TerminalListParams"]
-
-
-class TerminalListParams(TypedDict, total=False):
- machine_id: Required[str]
-
- cursor: str
-
- limit: int
diff --git a/src/dedalus_sdk/types/machines/terminal_output_event.py b/src/dedalus_sdk/types/machines/terminal_output_event.py
deleted file mode 100644
index a6fe0c5..0000000
--- a/src/dedalus_sdk/types/machines/terminal_output_event.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing_extensions import Literal
-
-from ..._models import BaseModel
-
-__all__ = ["TerminalOutputEvent"]
-
-
-class TerminalOutputEvent(BaseModel):
- data: str
- """Base64-encoded terminal output."""
-
- type: Literal["output"]
diff --git a/src/dedalus_sdk/types/machines/terminal_resize_event.py b/src/dedalus_sdk/types/machines/terminal_resize_event.py
deleted file mode 100644
index b69dd07..0000000
--- a/src/dedalus_sdk/types/machines/terminal_resize_event.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing_extensions import Literal
-
-from ..._models import BaseModel
-
-__all__ = ["TerminalResizeEvent"]
-
-
-class TerminalResizeEvent(BaseModel):
- height: int
-
- type: Literal["resize"]
-
- width: int
diff --git a/src/dedalus_sdk/types/machines/terminal_resize_event_param.py b/src/dedalus_sdk/types/machines/terminal_resize_event_param.py
deleted file mode 100644
index 3b03e5e..0000000
--- a/src/dedalus_sdk/types/machines/terminal_resize_event_param.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Literal, Required, TypedDict
-
-__all__ = ["TerminalResizeEventParam"]
-
-
-class TerminalResizeEventParam(TypedDict, total=False):
- height: Required[int]
-
- type: Required[Literal["resize"]]
-
- width: Required[int]
diff --git a/src/dedalus_sdk/types/machines/terminal_server_event.py b/src/dedalus_sdk/types/machines/terminal_server_event.py
deleted file mode 100644
index d51df44..0000000
--- a/src/dedalus_sdk/types/machines/terminal_server_event.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Union
-from typing_extensions import Annotated, TypeAlias
-
-from ..._utils import PropertyInfo
-from .terminal_error_event import TerminalErrorEvent
-from .terminal_closed_event import TerminalClosedEvent
-from .terminal_output_event import TerminalOutputEvent
-
-__all__ = ["TerminalServerEvent"]
-
-TerminalServerEvent: TypeAlias = Annotated[
- Union[TerminalOutputEvent, TerminalErrorEvent, TerminalClosedEvent], PropertyInfo(discriminator="type")
-]
diff --git a/src/dedalus_sdk/types/org_usage.py b/src/dedalus_sdk/types/org_usage.py
deleted file mode 100644
index 482c546..0000000
--- a/src/dedalus_sdk/types/org_usage.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from .._models import BaseModel
-
-__all__ = ["OrgUsage"]
-
-
-class OrgUsage(BaseModel):
- billed_awake_seconds: int
- """Closed awake seconds in billed org buckets for the period."""
-
- billed_cpu_millicore_seconds: int
- """
- Closed requested vCPU millicores multiplied by guest-owned active CPU seconds
- for the period.
- """
-
- billed_logical_storage_mib_seconds: int
- """
- Closed billable logical MiB-seconds for the period, matching the Stripe storage
- meter.
- """
-
- billed_memory_mib_seconds: int
- """
- Closed requested memory MiB multiplied by running allocation seconds for the
- period.
- """
-
- included_storage_gib: int
- """Plan-included storage in GiB, used as a local guardrail only."""
-
- plan_slug: str
- """Billing plan in effect for the organization."""
-
- provisioned_storage_gib: int
- """Current provisioned storage summed across machines in GiB."""
diff --git a/src/dedalus_sdk/types/usage_machine_compute_params.py b/src/dedalus_sdk/types/usage_machine_compute_params.py
deleted file mode 100644
index 9cc30c0..0000000
--- a/src/dedalus_sdk/types/usage_machine_compute_params.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import TypedDict
-
-__all__ = ["UsageMachineComputeParams"]
-
-
-class UsageMachineComputeParams(TypedDict, total=False):
- granularity: str
- """Usage breakdown granularity: hour or day. Defaults to hour."""
-
- machine_id: str
- """Optional machine ID filter."""
-
- period_end: str
- """Last UTC usage date to include (YYYY-MM-DD). Defaults to current time."""
-
- period_start: str
- """Usage period start (YYYY-MM-DD). Defaults to first of current month."""
diff --git a/src/dedalus_sdk/types/usage_machine_storage_params.py b/src/dedalus_sdk/types/usage_machine_storage_params.py
deleted file mode 100644
index 35d8e07..0000000
--- a/src/dedalus_sdk/types/usage_machine_storage_params.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import TypedDict
-
-__all__ = ["UsageMachineStorageParams"]
-
-
-class UsageMachineStorageParams(TypedDict, total=False):
- machine_id: str
- """Optional machine ID filter."""
-
- period_end: str
- """Last UTC usage date to include (YYYY-MM-DD). Defaults to current time."""
-
- period_start: str
- """Usage period start (YYYY-MM-DD). Defaults to first of current month."""
diff --git a/src/dedalus_sdk/types/usage_retrieve_params.py b/src/dedalus_sdk/types/usage_retrieve_params.py
deleted file mode 100644
index 5170bf1..0000000
--- a/src/dedalus_sdk/types/usage_retrieve_params.py
+++ /dev/null
@@ -1,12 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import TypedDict
-
-__all__ = ["UsageRetrieveParams"]
-
-
-class UsageRetrieveParams(TypedDict, total=False):
- period_start: str
- """Billing period start (YYYY-MM-DD). Defaults to first of current month."""
diff --git a/src/dedalus_sdk/types/websocket_connection_options.py b/src/dedalus_sdk/types/websocket_connection_options.py
deleted file mode 100644
index 36fcfa9..0000000
--- a/src/dedalus_sdk/types/websocket_connection_options.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import TYPE_CHECKING
-from typing_extensions import Sequence, TypedDict
-
-if TYPE_CHECKING:
- from websockets import Subprotocol
- from websockets.extensions import ClientExtensionFactory
-
-
-class WebSocketConnectionOptions(TypedDict, total=False):
- """WebSocket connection options copied from `websockets`.
-
- For example: https://websockets.readthedocs.io/en/stable/reference/asyncio/client.html#websockets.asyncio.client.connect
- """
-
- extensions: Sequence[ClientExtensionFactory] | None
- """List of supported extensions, in order in which they should be negotiated and run."""
-
- subprotocols: Sequence[Subprotocol] | None
- """List of supported subprotocols, in order of decreasing preference."""
-
- compression: str | None
- """The “permessage-deflate” extension is enabled by default. Set compression to None to disable it. See the [compression guide](https://websockets.readthedocs.io/en/stable/topics/compression.html) for details."""
-
- # limits
- max_size: int | None
- """Maximum size of incoming messages in bytes. None disables the limit."""
-
- max_queue: int | None | tuple[int | None, int | None]
- """High-water mark of the buffer where frames are received. It defaults to 16 frames. The low-water mark defaults to max_queue // 4. You may pass a (high, low) tuple to set the high-water and low-water marks. If you want to disable flow control entirely, you may set it to None, although that’s a bad idea."""
-
- write_limit: int | tuple[int, int | None]
- """High-water mark of write buffer in bytes. It is passed to set_write_buffer_limits(). It defaults to 32 KiB. You may pass a (high, low) tuple to set the high-water and low-water marks."""
diff --git a/src/dedalus_sdk/types/websocket_reconnection.py b/src/dedalus_sdk/types/websocket_reconnection.py
deleted file mode 100644
index 9ba66d0..0000000
--- a/src/dedalus_sdk/types/websocket_reconnection.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import dataclasses
-from typing_extensions import TypedDict
-
-from .._types import Query, Headers
-
-
-@dataclasses.dataclass(frozen=True)
-class ReconnectingEvent:
- """Information about a reconnection attempt, passed to the ``on_reconnecting`` handler."""
-
- attempt: int
- """Which retry attempt this is (1-based)."""
-
- max_attempts: int
- """Total attempts that will be made."""
-
- delay: float
- """Delay in seconds before this attempt connects."""
-
- close_code: int
- """The WebSocket close code that triggered reconnection."""
-
- extra_query: Query
- """The current query parameters."""
-
- extra_headers: Headers
- """The current headers."""
-
-
-class ReconnectingOverrides(TypedDict, total=False):
- """Optional overrides returned from the ``on_reconnecting`` handler
- to customize the next reconnection attempt."""
-
- extra_query: Query
- """If provided, assigns the query parameters for the next connection."""
-
- extra_headers: Headers
- """If provided, assigns the headers for the next connection."""
-
- abort: bool
- """If set to ``True``, will stop attempting to reconnect."""
-
-
-# RFC 6455 §7.4.1
-_RECOVERABLE_CLOSE_CODES: frozenset[int] = frozenset(
- {
- 1001, # Going away (server shutting down)
- 1005, # No status code (abnormal)
- 1006, # Abnormal closure (network drop)
- 1011, # Internal server error
- 1012, # Service restart
- 1013, # Try again later
- 1015, # TLS handshake failure
- }
-)
-
-
-def is_recoverable_close(code: int) -> bool:
- """Return ``True`` if the WebSocket close *code* is worth retrying."""
- return code in _RECOVERABLE_CLOSE_CODES
diff --git a/tests/api_resources/machines/test_artifacts.py b/tests/api_resources/machines/test_artifacts.py
deleted file mode 100644
index b4b6ff8..0000000
--- a/tests/api_resources/machines/test_artifacts.py
+++ /dev/null
@@ -1,311 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import os
-from typing import Any, cast
-
-import pytest
-
-from dedalus_sdk import Dedalus, AsyncDedalus
-from tests.utils import assert_matches_type
-from dedalus_sdk.pagination import SyncCursorPage, AsyncCursorPage
-from dedalus_sdk.types.machines import Artifact
-
-base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
-
-
-class TestArtifacts:
- parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
-
- @parametrize
- def test_method_retrieve(self, client: Dedalus) -> None:
- artifact = client.machines.artifacts.retrieve(
- machine_id="dm-3",
- artifact_id="artifact_id",
- )
- assert_matches_type(Artifact, artifact, path=["response"])
-
- @parametrize
- def test_raw_response_retrieve(self, client: Dedalus) -> None:
- response = client.machines.artifacts.with_raw_response.retrieve(
- machine_id="dm-3",
- artifact_id="artifact_id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- artifact = response.parse()
- assert_matches_type(Artifact, artifact, path=["response"])
-
- @parametrize
- def test_streaming_response_retrieve(self, client: Dedalus) -> None:
- with client.machines.artifacts.with_streaming_response.retrieve(
- machine_id="dm-3",
- artifact_id="artifact_id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- artifact = response.parse()
- assert_matches_type(Artifact, artifact, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_retrieve(self, client: Dedalus) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `machine_id` but received ''"):
- client.machines.artifacts.with_raw_response.retrieve(
- machine_id="",
- artifact_id="artifact_id",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `artifact_id` but received ''"):
- client.machines.artifacts.with_raw_response.retrieve(
- machine_id="dm-3",
- artifact_id="",
- )
-
- @parametrize
- def test_method_list(self, client: Dedalus) -> None:
- artifact = client.machines.artifacts.list(
- machine_id="dm-3",
- )
- assert_matches_type(SyncCursorPage[Artifact], artifact, path=["response"])
-
- @parametrize
- def test_method_list_with_all_params(self, client: Dedalus) -> None:
- artifact = client.machines.artifacts.list(
- machine_id="dm-3",
- cursor="cursor",
- limit=0,
- )
- assert_matches_type(SyncCursorPage[Artifact], artifact, path=["response"])
-
- @parametrize
- def test_raw_response_list(self, client: Dedalus) -> None:
- response = client.machines.artifacts.with_raw_response.list(
- machine_id="dm-3",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- artifact = response.parse()
- assert_matches_type(SyncCursorPage[Artifact], artifact, path=["response"])
-
- @parametrize
- def test_streaming_response_list(self, client: Dedalus) -> None:
- with client.machines.artifacts.with_streaming_response.list(
- machine_id="dm-3",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- artifact = response.parse()
- assert_matches_type(SyncCursorPage[Artifact], artifact, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_list(self, client: Dedalus) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `machine_id` but received ''"):
- client.machines.artifacts.with_raw_response.list(
- machine_id="",
- )
-
- @parametrize
- def test_method_delete(self, client: Dedalus) -> None:
- artifact = client.machines.artifacts.delete(
- machine_id="dm-3",
- artifact_id="artifact_id",
- )
- assert_matches_type(Artifact, artifact, path=["response"])
-
- @parametrize
- def test_raw_response_delete(self, client: Dedalus) -> None:
- response = client.machines.artifacts.with_raw_response.delete(
- machine_id="dm-3",
- artifact_id="artifact_id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- artifact = response.parse()
- assert_matches_type(Artifact, artifact, path=["response"])
-
- @parametrize
- def test_streaming_response_delete(self, client: Dedalus) -> None:
- with client.machines.artifacts.with_streaming_response.delete(
- machine_id="dm-3",
- artifact_id="artifact_id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- artifact = response.parse()
- assert_matches_type(Artifact, artifact, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_delete(self, client: Dedalus) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `machine_id` but received ''"):
- client.machines.artifacts.with_raw_response.delete(
- machine_id="",
- artifact_id="artifact_id",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `artifact_id` but received ''"):
- client.machines.artifacts.with_raw_response.delete(
- machine_id="dm-3",
- artifact_id="",
- )
-
-
-class TestAsyncArtifacts:
- parametrize = pytest.mark.parametrize(
- "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
- )
-
- @parametrize
- async def test_method_retrieve(self, async_client: AsyncDedalus) -> None:
- artifact = await async_client.machines.artifacts.retrieve(
- machine_id="dm-3",
- artifact_id="artifact_id",
- )
- assert_matches_type(Artifact, artifact, path=["response"])
-
- @parametrize
- async def test_raw_response_retrieve(self, async_client: AsyncDedalus) -> None:
- response = await async_client.machines.artifacts.with_raw_response.retrieve(
- machine_id="dm-3",
- artifact_id="artifact_id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- artifact = await response.parse()
- assert_matches_type(Artifact, artifact, path=["response"])
-
- @parametrize
- async def test_streaming_response_retrieve(self, async_client: AsyncDedalus) -> None:
- async with async_client.machines.artifacts.with_streaming_response.retrieve(
- machine_id="dm-3",
- artifact_id="artifact_id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- artifact = await response.parse()
- assert_matches_type(Artifact, artifact, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_retrieve(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.artifacts.with_raw_response.retrieve(
- machine_id="",
- artifact_id="artifact_id",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `artifact_id` but received ''"):
- await async_client.machines.artifacts.with_raw_response.retrieve(
- machine_id="dm-3",
- artifact_id="",
- )
-
- @parametrize
- async def test_method_list(self, async_client: AsyncDedalus) -> None:
- artifact = await async_client.machines.artifacts.list(
- machine_id="dm-3",
- )
- assert_matches_type(AsyncCursorPage[Artifact], artifact, path=["response"])
-
- @parametrize
- async def test_method_list_with_all_params(self, async_client: AsyncDedalus) -> None:
- artifact = await async_client.machines.artifacts.list(
- machine_id="dm-3",
- cursor="cursor",
- limit=0,
- )
- assert_matches_type(AsyncCursorPage[Artifact], artifact, path=["response"])
-
- @parametrize
- async def test_raw_response_list(self, async_client: AsyncDedalus) -> None:
- response = await async_client.machines.artifacts.with_raw_response.list(
- machine_id="dm-3",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- artifact = await response.parse()
- assert_matches_type(AsyncCursorPage[Artifact], artifact, path=["response"])
-
- @parametrize
- async def test_streaming_response_list(self, async_client: AsyncDedalus) -> None:
- async with async_client.machines.artifacts.with_streaming_response.list(
- machine_id="dm-3",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- artifact = await response.parse()
- assert_matches_type(AsyncCursorPage[Artifact], artifact, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_list(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.artifacts.with_raw_response.list(
- machine_id="",
- )
-
- @parametrize
- async def test_method_delete(self, async_client: AsyncDedalus) -> None:
- artifact = await async_client.machines.artifacts.delete(
- machine_id="dm-3",
- artifact_id="artifact_id",
- )
- assert_matches_type(Artifact, artifact, path=["response"])
-
- @parametrize
- async def test_raw_response_delete(self, async_client: AsyncDedalus) -> None:
- response = await async_client.machines.artifacts.with_raw_response.delete(
- machine_id="dm-3",
- artifact_id="artifact_id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- artifact = await response.parse()
- assert_matches_type(Artifact, artifact, path=["response"])
-
- @parametrize
- async def test_streaming_response_delete(self, async_client: AsyncDedalus) -> None:
- async with async_client.machines.artifacts.with_streaming_response.delete(
- machine_id="dm-3",
- artifact_id="artifact_id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- artifact = await response.parse()
- assert_matches_type(Artifact, artifact, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_delete(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.artifacts.with_raw_response.delete(
- machine_id="",
- artifact_id="artifact_id",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `artifact_id` but received ''"):
- await async_client.machines.artifacts.with_raw_response.delete(
- machine_id="dm-3",
- artifact_id="",
- )
diff --git a/tests/api_resources/machines/test_executions.py b/tests/api_resources/machines/test_executions.py
index 85091f9..87ad5c2 100644
--- a/tests/api_resources/machines/test_executions.py
+++ b/tests/api_resources/machines/test_executions.py
@@ -25,7 +25,7 @@ class TestExecutions:
@parametrize
def test_method_create(self, client: Dedalus) -> None:
execution = client.machines.executions.create(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
command=["string"],
)
assert_matches_type(Execution, execution, path=["response"])
@@ -33,7 +33,7 @@ def test_method_create(self, client: Dedalus) -> None:
@parametrize
def test_method_create_with_all_params(self, client: Dedalus) -> None:
execution = client.machines.executions.create(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
command=["string"],
cwd="cwd",
env={"foo": "string"},
@@ -45,7 +45,7 @@ def test_method_create_with_all_params(self, client: Dedalus) -> None:
@parametrize
def test_raw_response_create(self, client: Dedalus) -> None:
response = client.machines.executions.with_raw_response.create(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
command=["string"],
)
@@ -57,7 +57,7 @@ def test_raw_response_create(self, client: Dedalus) -> None:
@parametrize
def test_streaming_response_create(self, client: Dedalus) -> None:
with client.machines.executions.with_streaming_response.create(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
command=["string"],
) as response:
assert not response.is_closed
@@ -79,7 +79,7 @@ def test_path_params_create(self, client: Dedalus) -> None:
@parametrize
def test_method_retrieve(self, client: Dedalus) -> None:
execution = client.machines.executions.retrieve(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="execution_id",
)
assert_matches_type(Execution, execution, path=["response"])
@@ -87,7 +87,7 @@ def test_method_retrieve(self, client: Dedalus) -> None:
@parametrize
def test_raw_response_retrieve(self, client: Dedalus) -> None:
response = client.machines.executions.with_raw_response.retrieve(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="execution_id",
)
@@ -99,7 +99,7 @@ def test_raw_response_retrieve(self, client: Dedalus) -> None:
@parametrize
def test_streaming_response_retrieve(self, client: Dedalus) -> None:
with client.machines.executions.with_streaming_response.retrieve(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="execution_id",
) as response:
assert not response.is_closed
@@ -120,21 +120,21 @@ def test_path_params_retrieve(self, client: Dedalus) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `execution_id` but received ''"):
client.machines.executions.with_raw_response.retrieve(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="",
)
@parametrize
def test_method_list(self, client: Dedalus) -> None:
execution = client.machines.executions.list(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
)
assert_matches_type(SyncCursorPage[Execution], execution, path=["response"])
@parametrize
def test_method_list_with_all_params(self, client: Dedalus) -> None:
execution = client.machines.executions.list(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
cursor="cursor",
limit=0,
)
@@ -143,7 +143,7 @@ def test_method_list_with_all_params(self, client: Dedalus) -> None:
@parametrize
def test_raw_response_list(self, client: Dedalus) -> None:
response = client.machines.executions.with_raw_response.list(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
)
assert response.is_closed is True
@@ -154,7 +154,7 @@ def test_raw_response_list(self, client: Dedalus) -> None:
@parametrize
def test_streaming_response_list(self, client: Dedalus) -> None:
with client.machines.executions.with_streaming_response.list(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -174,7 +174,7 @@ def test_path_params_list(self, client: Dedalus) -> None:
@parametrize
def test_method_delete(self, client: Dedalus) -> None:
execution = client.machines.executions.delete(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="execution_id",
)
assert_matches_type(Execution, execution, path=["response"])
@@ -182,7 +182,7 @@ def test_method_delete(self, client: Dedalus) -> None:
@parametrize
def test_raw_response_delete(self, client: Dedalus) -> None:
response = client.machines.executions.with_raw_response.delete(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="execution_id",
)
@@ -194,7 +194,7 @@ def test_raw_response_delete(self, client: Dedalus) -> None:
@parametrize
def test_streaming_response_delete(self, client: Dedalus) -> None:
with client.machines.executions.with_streaming_response.delete(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="execution_id",
) as response:
assert not response.is_closed
@@ -215,14 +215,14 @@ def test_path_params_delete(self, client: Dedalus) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `execution_id` but received ''"):
client.machines.executions.with_raw_response.delete(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="",
)
@parametrize
def test_method_events(self, client: Dedalus) -> None:
execution = client.machines.executions.events(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="execution_id",
)
assert_matches_type(SyncCursorPage[ExecutionEvent], execution, path=["response"])
@@ -230,7 +230,7 @@ def test_method_events(self, client: Dedalus) -> None:
@parametrize
def test_method_events_with_all_params(self, client: Dedalus) -> None:
execution = client.machines.executions.events(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="execution_id",
cursor="cursor",
limit=0,
@@ -240,7 +240,7 @@ def test_method_events_with_all_params(self, client: Dedalus) -> None:
@parametrize
def test_raw_response_events(self, client: Dedalus) -> None:
response = client.machines.executions.with_raw_response.events(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="execution_id",
)
@@ -252,7 +252,7 @@ def test_raw_response_events(self, client: Dedalus) -> None:
@parametrize
def test_streaming_response_events(self, client: Dedalus) -> None:
with client.machines.executions.with_streaming_response.events(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="execution_id",
) as response:
assert not response.is_closed
@@ -273,14 +273,14 @@ def test_path_params_events(self, client: Dedalus) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `execution_id` but received ''"):
client.machines.executions.with_raw_response.events(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="",
)
@parametrize
def test_method_output(self, client: Dedalus) -> None:
execution = client.machines.executions.output(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="execution_id",
)
assert_matches_type(ExecutionOutput, execution, path=["response"])
@@ -288,7 +288,7 @@ def test_method_output(self, client: Dedalus) -> None:
@parametrize
def test_raw_response_output(self, client: Dedalus) -> None:
response = client.machines.executions.with_raw_response.output(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="execution_id",
)
@@ -300,7 +300,7 @@ def test_raw_response_output(self, client: Dedalus) -> None:
@parametrize
def test_streaming_response_output(self, client: Dedalus) -> None:
with client.machines.executions.with_streaming_response.output(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="execution_id",
) as response:
assert not response.is_closed
@@ -321,7 +321,7 @@ def test_path_params_output(self, client: Dedalus) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `execution_id` but received ''"):
client.machines.executions.with_raw_response.output(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="",
)
@@ -334,7 +334,7 @@ class TestAsyncExecutions:
@parametrize
async def test_method_create(self, async_client: AsyncDedalus) -> None:
execution = await async_client.machines.executions.create(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
command=["string"],
)
assert_matches_type(Execution, execution, path=["response"])
@@ -342,7 +342,7 @@ async def test_method_create(self, async_client: AsyncDedalus) -> None:
@parametrize
async def test_method_create_with_all_params(self, async_client: AsyncDedalus) -> None:
execution = await async_client.machines.executions.create(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
command=["string"],
cwd="cwd",
env={"foo": "string"},
@@ -354,7 +354,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncDedalus) -
@parametrize
async def test_raw_response_create(self, async_client: AsyncDedalus) -> None:
response = await async_client.machines.executions.with_raw_response.create(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
command=["string"],
)
@@ -366,7 +366,7 @@ async def test_raw_response_create(self, async_client: AsyncDedalus) -> None:
@parametrize
async def test_streaming_response_create(self, async_client: AsyncDedalus) -> None:
async with async_client.machines.executions.with_streaming_response.create(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
command=["string"],
) as response:
assert not response.is_closed
@@ -388,7 +388,7 @@ async def test_path_params_create(self, async_client: AsyncDedalus) -> None:
@parametrize
async def test_method_retrieve(self, async_client: AsyncDedalus) -> None:
execution = await async_client.machines.executions.retrieve(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="execution_id",
)
assert_matches_type(Execution, execution, path=["response"])
@@ -396,7 +396,7 @@ async def test_method_retrieve(self, async_client: AsyncDedalus) -> None:
@parametrize
async def test_raw_response_retrieve(self, async_client: AsyncDedalus) -> None:
response = await async_client.machines.executions.with_raw_response.retrieve(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="execution_id",
)
@@ -408,7 +408,7 @@ async def test_raw_response_retrieve(self, async_client: AsyncDedalus) -> None:
@parametrize
async def test_streaming_response_retrieve(self, async_client: AsyncDedalus) -> None:
async with async_client.machines.executions.with_streaming_response.retrieve(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="execution_id",
) as response:
assert not response.is_closed
@@ -429,21 +429,21 @@ async def test_path_params_retrieve(self, async_client: AsyncDedalus) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `execution_id` but received ''"):
await async_client.machines.executions.with_raw_response.retrieve(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="",
)
@parametrize
async def test_method_list(self, async_client: AsyncDedalus) -> None:
execution = await async_client.machines.executions.list(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
)
assert_matches_type(AsyncCursorPage[Execution], execution, path=["response"])
@parametrize
async def test_method_list_with_all_params(self, async_client: AsyncDedalus) -> None:
execution = await async_client.machines.executions.list(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
cursor="cursor",
limit=0,
)
@@ -452,7 +452,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncDedalus) ->
@parametrize
async def test_raw_response_list(self, async_client: AsyncDedalus) -> None:
response = await async_client.machines.executions.with_raw_response.list(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
)
assert response.is_closed is True
@@ -463,7 +463,7 @@ async def test_raw_response_list(self, async_client: AsyncDedalus) -> None:
@parametrize
async def test_streaming_response_list(self, async_client: AsyncDedalus) -> None:
async with async_client.machines.executions.with_streaming_response.list(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -483,7 +483,7 @@ async def test_path_params_list(self, async_client: AsyncDedalus) -> None:
@parametrize
async def test_method_delete(self, async_client: AsyncDedalus) -> None:
execution = await async_client.machines.executions.delete(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="execution_id",
)
assert_matches_type(Execution, execution, path=["response"])
@@ -491,7 +491,7 @@ async def test_method_delete(self, async_client: AsyncDedalus) -> None:
@parametrize
async def test_raw_response_delete(self, async_client: AsyncDedalus) -> None:
response = await async_client.machines.executions.with_raw_response.delete(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="execution_id",
)
@@ -503,7 +503,7 @@ async def test_raw_response_delete(self, async_client: AsyncDedalus) -> None:
@parametrize
async def test_streaming_response_delete(self, async_client: AsyncDedalus) -> None:
async with async_client.machines.executions.with_streaming_response.delete(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="execution_id",
) as response:
assert not response.is_closed
@@ -524,14 +524,14 @@ async def test_path_params_delete(self, async_client: AsyncDedalus) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `execution_id` but received ''"):
await async_client.machines.executions.with_raw_response.delete(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="",
)
@parametrize
async def test_method_events(self, async_client: AsyncDedalus) -> None:
execution = await async_client.machines.executions.events(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="execution_id",
)
assert_matches_type(AsyncCursorPage[ExecutionEvent], execution, path=["response"])
@@ -539,7 +539,7 @@ async def test_method_events(self, async_client: AsyncDedalus) -> None:
@parametrize
async def test_method_events_with_all_params(self, async_client: AsyncDedalus) -> None:
execution = await async_client.machines.executions.events(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="execution_id",
cursor="cursor",
limit=0,
@@ -549,7 +549,7 @@ async def test_method_events_with_all_params(self, async_client: AsyncDedalus) -
@parametrize
async def test_raw_response_events(self, async_client: AsyncDedalus) -> None:
response = await async_client.machines.executions.with_raw_response.events(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="execution_id",
)
@@ -561,7 +561,7 @@ async def test_raw_response_events(self, async_client: AsyncDedalus) -> None:
@parametrize
async def test_streaming_response_events(self, async_client: AsyncDedalus) -> None:
async with async_client.machines.executions.with_streaming_response.events(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="execution_id",
) as response:
assert not response.is_closed
@@ -582,14 +582,14 @@ async def test_path_params_events(self, async_client: AsyncDedalus) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `execution_id` but received ''"):
await async_client.machines.executions.with_raw_response.events(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="",
)
@parametrize
async def test_method_output(self, async_client: AsyncDedalus) -> None:
execution = await async_client.machines.executions.output(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="execution_id",
)
assert_matches_type(ExecutionOutput, execution, path=["response"])
@@ -597,7 +597,7 @@ async def test_method_output(self, async_client: AsyncDedalus) -> None:
@parametrize
async def test_raw_response_output(self, async_client: AsyncDedalus) -> None:
response = await async_client.machines.executions.with_raw_response.output(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="execution_id",
)
@@ -609,7 +609,7 @@ async def test_raw_response_output(self, async_client: AsyncDedalus) -> None:
@parametrize
async def test_streaming_response_output(self, async_client: AsyncDedalus) -> None:
async with async_client.machines.executions.with_streaming_response.output(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="execution_id",
) as response:
assert not response.is_closed
@@ -630,6 +630,6 @@ async def test_path_params_output(self, async_client: AsyncDedalus) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `execution_id` but received ''"):
await async_client.machines.executions.with_raw_response.output(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
execution_id="",
)
diff --git a/tests/api_resources/machines/test_previews.py b/tests/api_resources/machines/test_previews.py
deleted file mode 100644
index 271bac0..0000000
--- a/tests/api_resources/machines/test_previews.py
+++ /dev/null
@@ -1,415 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import os
-from typing import Any, cast
-
-import pytest
-
-from dedalus_sdk import Dedalus, AsyncDedalus
-from tests.utils import assert_matches_type
-from dedalus_sdk.pagination import SyncCursorPage, AsyncCursorPage
-from dedalus_sdk.types.machines import Preview
-
-base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
-
-
-class TestPreviews:
- parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
-
- @parametrize
- def test_method_create(self, client: Dedalus) -> None:
- preview = client.machines.previews.create(
- machine_id="dm-3",
- port=0,
- )
- assert_matches_type(Preview, preview, path=["response"])
-
- @parametrize
- def test_method_create_with_all_params(self, client: Dedalus) -> None:
- preview = client.machines.previews.create(
- machine_id="dm-3",
- port=0,
- protocol="http",
- visibility="public",
- )
- assert_matches_type(Preview, preview, path=["response"])
-
- @parametrize
- def test_raw_response_create(self, client: Dedalus) -> None:
- response = client.machines.previews.with_raw_response.create(
- machine_id="dm-3",
- port=0,
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- preview = response.parse()
- assert_matches_type(Preview, preview, path=["response"])
-
- @parametrize
- def test_streaming_response_create(self, client: Dedalus) -> None:
- with client.machines.previews.with_streaming_response.create(
- machine_id="dm-3",
- port=0,
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- preview = response.parse()
- assert_matches_type(Preview, preview, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_create(self, client: Dedalus) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `machine_id` but received ''"):
- client.machines.previews.with_raw_response.create(
- machine_id="",
- port=0,
- )
-
- @parametrize
- def test_method_retrieve(self, client: Dedalus) -> None:
- preview = client.machines.previews.retrieve(
- machine_id="dm-3",
- preview_id="preview_id",
- )
- assert_matches_type(Preview, preview, path=["response"])
-
- @parametrize
- def test_raw_response_retrieve(self, client: Dedalus) -> None:
- response = client.machines.previews.with_raw_response.retrieve(
- machine_id="dm-3",
- preview_id="preview_id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- preview = response.parse()
- assert_matches_type(Preview, preview, path=["response"])
-
- @parametrize
- def test_streaming_response_retrieve(self, client: Dedalus) -> None:
- with client.machines.previews.with_streaming_response.retrieve(
- machine_id="dm-3",
- preview_id="preview_id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- preview = response.parse()
- assert_matches_type(Preview, preview, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_retrieve(self, client: Dedalus) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `machine_id` but received ''"):
- client.machines.previews.with_raw_response.retrieve(
- machine_id="",
- preview_id="preview_id",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `preview_id` but received ''"):
- client.machines.previews.with_raw_response.retrieve(
- machine_id="dm-3",
- preview_id="",
- )
-
- @parametrize
- def test_method_list(self, client: Dedalus) -> None:
- preview = client.machines.previews.list(
- machine_id="dm-3",
- )
- assert_matches_type(SyncCursorPage[Preview], preview, path=["response"])
-
- @parametrize
- def test_method_list_with_all_params(self, client: Dedalus) -> None:
- preview = client.machines.previews.list(
- machine_id="dm-3",
- cursor="cursor",
- limit=0,
- )
- assert_matches_type(SyncCursorPage[Preview], preview, path=["response"])
-
- @parametrize
- def test_raw_response_list(self, client: Dedalus) -> None:
- response = client.machines.previews.with_raw_response.list(
- machine_id="dm-3",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- preview = response.parse()
- assert_matches_type(SyncCursorPage[Preview], preview, path=["response"])
-
- @parametrize
- def test_streaming_response_list(self, client: Dedalus) -> None:
- with client.machines.previews.with_streaming_response.list(
- machine_id="dm-3",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- preview = response.parse()
- assert_matches_type(SyncCursorPage[Preview], preview, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_list(self, client: Dedalus) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `machine_id` but received ''"):
- client.machines.previews.with_raw_response.list(
- machine_id="",
- )
-
- @parametrize
- def test_method_delete(self, client: Dedalus) -> None:
- preview = client.machines.previews.delete(
- machine_id="dm-3",
- preview_id="preview_id",
- )
- assert_matches_type(Preview, preview, path=["response"])
-
- @parametrize
- def test_raw_response_delete(self, client: Dedalus) -> None:
- response = client.machines.previews.with_raw_response.delete(
- machine_id="dm-3",
- preview_id="preview_id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- preview = response.parse()
- assert_matches_type(Preview, preview, path=["response"])
-
- @parametrize
- def test_streaming_response_delete(self, client: Dedalus) -> None:
- with client.machines.previews.with_streaming_response.delete(
- machine_id="dm-3",
- preview_id="preview_id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- preview = response.parse()
- assert_matches_type(Preview, preview, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_delete(self, client: Dedalus) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `machine_id` but received ''"):
- client.machines.previews.with_raw_response.delete(
- machine_id="",
- preview_id="preview_id",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `preview_id` but received ''"):
- client.machines.previews.with_raw_response.delete(
- machine_id="dm-3",
- preview_id="",
- )
-
-
-class TestAsyncPreviews:
- 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: AsyncDedalus) -> None:
- preview = await async_client.machines.previews.create(
- machine_id="dm-3",
- port=0,
- )
- assert_matches_type(Preview, preview, path=["response"])
-
- @parametrize
- async def test_method_create_with_all_params(self, async_client: AsyncDedalus) -> None:
- preview = await async_client.machines.previews.create(
- machine_id="dm-3",
- port=0,
- protocol="http",
- visibility="public",
- )
- assert_matches_type(Preview, preview, path=["response"])
-
- @parametrize
- async def test_raw_response_create(self, async_client: AsyncDedalus) -> None:
- response = await async_client.machines.previews.with_raw_response.create(
- machine_id="dm-3",
- port=0,
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- preview = await response.parse()
- assert_matches_type(Preview, preview, path=["response"])
-
- @parametrize
- async def test_streaming_response_create(self, async_client: AsyncDedalus) -> None:
- async with async_client.machines.previews.with_streaming_response.create(
- machine_id="dm-3",
- port=0,
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- preview = await response.parse()
- assert_matches_type(Preview, preview, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_create(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.previews.with_raw_response.create(
- machine_id="",
- port=0,
- )
-
- @parametrize
- async def test_method_retrieve(self, async_client: AsyncDedalus) -> None:
- preview = await async_client.machines.previews.retrieve(
- machine_id="dm-3",
- preview_id="preview_id",
- )
- assert_matches_type(Preview, preview, path=["response"])
-
- @parametrize
- async def test_raw_response_retrieve(self, async_client: AsyncDedalus) -> None:
- response = await async_client.machines.previews.with_raw_response.retrieve(
- machine_id="dm-3",
- preview_id="preview_id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- preview = await response.parse()
- assert_matches_type(Preview, preview, path=["response"])
-
- @parametrize
- async def test_streaming_response_retrieve(self, async_client: AsyncDedalus) -> None:
- async with async_client.machines.previews.with_streaming_response.retrieve(
- machine_id="dm-3",
- preview_id="preview_id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- preview = await response.parse()
- assert_matches_type(Preview, preview, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_retrieve(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.previews.with_raw_response.retrieve(
- machine_id="",
- preview_id="preview_id",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `preview_id` but received ''"):
- await async_client.machines.previews.with_raw_response.retrieve(
- machine_id="dm-3",
- preview_id="",
- )
-
- @parametrize
- async def test_method_list(self, async_client: AsyncDedalus) -> None:
- preview = await async_client.machines.previews.list(
- machine_id="dm-3",
- )
- assert_matches_type(AsyncCursorPage[Preview], preview, path=["response"])
-
- @parametrize
- async def test_method_list_with_all_params(self, async_client: AsyncDedalus) -> None:
- preview = await async_client.machines.previews.list(
- machine_id="dm-3",
- cursor="cursor",
- limit=0,
- )
- assert_matches_type(AsyncCursorPage[Preview], preview, path=["response"])
-
- @parametrize
- async def test_raw_response_list(self, async_client: AsyncDedalus) -> None:
- response = await async_client.machines.previews.with_raw_response.list(
- machine_id="dm-3",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- preview = await response.parse()
- assert_matches_type(AsyncCursorPage[Preview], preview, path=["response"])
-
- @parametrize
- async def test_streaming_response_list(self, async_client: AsyncDedalus) -> None:
- async with async_client.machines.previews.with_streaming_response.list(
- machine_id="dm-3",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- preview = await response.parse()
- assert_matches_type(AsyncCursorPage[Preview], preview, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_list(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.previews.with_raw_response.list(
- machine_id="",
- )
-
- @parametrize
- async def test_method_delete(self, async_client: AsyncDedalus) -> None:
- preview = await async_client.machines.previews.delete(
- machine_id="dm-3",
- preview_id="preview_id",
- )
- assert_matches_type(Preview, preview, path=["response"])
-
- @parametrize
- async def test_raw_response_delete(self, async_client: AsyncDedalus) -> None:
- response = await async_client.machines.previews.with_raw_response.delete(
- machine_id="dm-3",
- preview_id="preview_id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- preview = await response.parse()
- assert_matches_type(Preview, preview, path=["response"])
-
- @parametrize
- async def test_streaming_response_delete(self, async_client: AsyncDedalus) -> None:
- async with async_client.machines.previews.with_streaming_response.delete(
- machine_id="dm-3",
- preview_id="preview_id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- preview = await response.parse()
- assert_matches_type(Preview, preview, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_delete(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.previews.with_raw_response.delete(
- machine_id="",
- preview_id="preview_id",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `preview_id` but received ''"):
- await async_client.machines.previews.with_raw_response.delete(
- machine_id="dm-3",
- preview_id="",
- )
diff --git a/tests/api_resources/machines/test_ssh.py b/tests/api_resources/machines/test_ssh.py
index fc6e80c..65ba42c 100644
--- a/tests/api_resources/machines/test_ssh.py
+++ b/tests/api_resources/machines/test_ssh.py
@@ -21,7 +21,7 @@ class TestSSH:
@parametrize
def test_method_create(self, client: Dedalus) -> None:
ssh = client.machines.ssh.create(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
public_key="public_key",
)
assert_matches_type(SSHSession, ssh, path=["response"])
@@ -29,7 +29,7 @@ def test_method_create(self, client: Dedalus) -> None:
@parametrize
def test_raw_response_create(self, client: Dedalus) -> None:
response = client.machines.ssh.with_raw_response.create(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
public_key="public_key",
)
@@ -41,7 +41,7 @@ def test_raw_response_create(self, client: Dedalus) -> None:
@parametrize
def test_streaming_response_create(self, client: Dedalus) -> None:
with client.machines.ssh.with_streaming_response.create(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
public_key="public_key",
) as response:
assert not response.is_closed
@@ -63,7 +63,7 @@ def test_path_params_create(self, client: Dedalus) -> None:
@parametrize
def test_method_retrieve(self, client: Dedalus) -> None:
ssh = client.machines.ssh.retrieve(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
session_id="session_id",
)
assert_matches_type(SSHSession, ssh, path=["response"])
@@ -71,7 +71,7 @@ def test_method_retrieve(self, client: Dedalus) -> None:
@parametrize
def test_raw_response_retrieve(self, client: Dedalus) -> None:
response = client.machines.ssh.with_raw_response.retrieve(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
session_id="session_id",
)
@@ -83,7 +83,7 @@ def test_raw_response_retrieve(self, client: Dedalus) -> None:
@parametrize
def test_streaming_response_retrieve(self, client: Dedalus) -> None:
with client.machines.ssh.with_streaming_response.retrieve(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
session_id="session_id",
) as response:
assert not response.is_closed
@@ -104,21 +104,21 @@ def test_path_params_retrieve(self, client: Dedalus) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
client.machines.ssh.with_raw_response.retrieve(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
session_id="",
)
@parametrize
def test_method_list(self, client: Dedalus) -> None:
ssh = client.machines.ssh.list(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
)
assert_matches_type(SyncCursorPage[SSHSession], ssh, path=["response"])
@parametrize
def test_method_list_with_all_params(self, client: Dedalus) -> None:
ssh = client.machines.ssh.list(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
cursor="cursor",
limit=0,
)
@@ -127,7 +127,7 @@ def test_method_list_with_all_params(self, client: Dedalus) -> None:
@parametrize
def test_raw_response_list(self, client: Dedalus) -> None:
response = client.machines.ssh.with_raw_response.list(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
)
assert response.is_closed is True
@@ -138,7 +138,7 @@ def test_raw_response_list(self, client: Dedalus) -> None:
@parametrize
def test_streaming_response_list(self, client: Dedalus) -> None:
with client.machines.ssh.with_streaming_response.list(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -158,7 +158,7 @@ def test_path_params_list(self, client: Dedalus) -> None:
@parametrize
def test_method_delete(self, client: Dedalus) -> None:
ssh = client.machines.ssh.delete(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
session_id="session_id",
)
assert_matches_type(SSHSession, ssh, path=["response"])
@@ -166,7 +166,7 @@ def test_method_delete(self, client: Dedalus) -> None:
@parametrize
def test_raw_response_delete(self, client: Dedalus) -> None:
response = client.machines.ssh.with_raw_response.delete(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
session_id="session_id",
)
@@ -178,7 +178,7 @@ def test_raw_response_delete(self, client: Dedalus) -> None:
@parametrize
def test_streaming_response_delete(self, client: Dedalus) -> None:
with client.machines.ssh.with_streaming_response.delete(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
session_id="session_id",
) as response:
assert not response.is_closed
@@ -199,7 +199,7 @@ def test_path_params_delete(self, client: Dedalus) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
client.machines.ssh.with_raw_response.delete(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
session_id="",
)
@@ -212,7 +212,7 @@ class TestAsyncSSH:
@parametrize
async def test_method_create(self, async_client: AsyncDedalus) -> None:
ssh = await async_client.machines.ssh.create(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
public_key="public_key",
)
assert_matches_type(SSHSession, ssh, path=["response"])
@@ -220,7 +220,7 @@ async def test_method_create(self, async_client: AsyncDedalus) -> None:
@parametrize
async def test_raw_response_create(self, async_client: AsyncDedalus) -> None:
response = await async_client.machines.ssh.with_raw_response.create(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
public_key="public_key",
)
@@ -232,7 +232,7 @@ async def test_raw_response_create(self, async_client: AsyncDedalus) -> None:
@parametrize
async def test_streaming_response_create(self, async_client: AsyncDedalus) -> None:
async with async_client.machines.ssh.with_streaming_response.create(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
public_key="public_key",
) as response:
assert not response.is_closed
@@ -254,7 +254,7 @@ async def test_path_params_create(self, async_client: AsyncDedalus) -> None:
@parametrize
async def test_method_retrieve(self, async_client: AsyncDedalus) -> None:
ssh = await async_client.machines.ssh.retrieve(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
session_id="session_id",
)
assert_matches_type(SSHSession, ssh, path=["response"])
@@ -262,7 +262,7 @@ async def test_method_retrieve(self, async_client: AsyncDedalus) -> None:
@parametrize
async def test_raw_response_retrieve(self, async_client: AsyncDedalus) -> None:
response = await async_client.machines.ssh.with_raw_response.retrieve(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
session_id="session_id",
)
@@ -274,7 +274,7 @@ async def test_raw_response_retrieve(self, async_client: AsyncDedalus) -> None:
@parametrize
async def test_streaming_response_retrieve(self, async_client: AsyncDedalus) -> None:
async with async_client.machines.ssh.with_streaming_response.retrieve(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
session_id="session_id",
) as response:
assert not response.is_closed
@@ -295,21 +295,21 @@ async def test_path_params_retrieve(self, async_client: AsyncDedalus) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
await async_client.machines.ssh.with_raw_response.retrieve(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
session_id="",
)
@parametrize
async def test_method_list(self, async_client: AsyncDedalus) -> None:
ssh = await async_client.machines.ssh.list(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
)
assert_matches_type(AsyncCursorPage[SSHSession], ssh, path=["response"])
@parametrize
async def test_method_list_with_all_params(self, async_client: AsyncDedalus) -> None:
ssh = await async_client.machines.ssh.list(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
cursor="cursor",
limit=0,
)
@@ -318,7 +318,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncDedalus) ->
@parametrize
async def test_raw_response_list(self, async_client: AsyncDedalus) -> None:
response = await async_client.machines.ssh.with_raw_response.list(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
)
assert response.is_closed is True
@@ -329,7 +329,7 @@ async def test_raw_response_list(self, async_client: AsyncDedalus) -> None:
@parametrize
async def test_streaming_response_list(self, async_client: AsyncDedalus) -> None:
async with async_client.machines.ssh.with_streaming_response.list(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -349,7 +349,7 @@ async def test_path_params_list(self, async_client: AsyncDedalus) -> None:
@parametrize
async def test_method_delete(self, async_client: AsyncDedalus) -> None:
ssh = await async_client.machines.ssh.delete(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
session_id="session_id",
)
assert_matches_type(SSHSession, ssh, path=["response"])
@@ -357,7 +357,7 @@ async def test_method_delete(self, async_client: AsyncDedalus) -> None:
@parametrize
async def test_raw_response_delete(self, async_client: AsyncDedalus) -> None:
response = await async_client.machines.ssh.with_raw_response.delete(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
session_id="session_id",
)
@@ -369,7 +369,7 @@ async def test_raw_response_delete(self, async_client: AsyncDedalus) -> None:
@parametrize
async def test_streaming_response_delete(self, async_client: AsyncDedalus) -> None:
async with async_client.machines.ssh.with_streaming_response.delete(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
session_id="session_id",
) as response:
assert not response.is_closed
@@ -390,6 +390,6 @@ async def test_path_params_delete(self, async_client: AsyncDedalus) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `session_id` but received ''"):
await async_client.machines.ssh.with_raw_response.delete(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
session_id="",
)
diff --git a/tests/api_resources/machines/test_terminals.py b/tests/api_resources/machines/test_terminals.py
deleted file mode 100644
index ceacabc..0000000
--- a/tests/api_resources/machines/test_terminals.py
+++ /dev/null
@@ -1,427 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import os
-from typing import Any, cast
-
-import pytest
-
-from dedalus_sdk import Dedalus, AsyncDedalus
-from tests.utils import assert_matches_type
-from dedalus_sdk.pagination import SyncCursorPage, AsyncCursorPage
-from dedalus_sdk.types.machines import Terminal
-
-base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
-
-
-class TestTerminals:
- parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
-
- @parametrize
- def test_method_create(self, client: Dedalus) -> None:
- terminal = client.machines.terminals.create(
- machine_id="dm-3",
- height=0,
- width=0,
- )
- assert_matches_type(Terminal, terminal, path=["response"])
-
- @parametrize
- def test_method_create_with_all_params(self, client: Dedalus) -> None:
- terminal = client.machines.terminals.create(
- machine_id="dm-3",
- height=0,
- width=0,
- cwd="cwd",
- env={"foo": "string"},
- shell="shell",
- )
- assert_matches_type(Terminal, terminal, path=["response"])
-
- @parametrize
- def test_raw_response_create(self, client: Dedalus) -> None:
- response = client.machines.terminals.with_raw_response.create(
- machine_id="dm-3",
- height=0,
- width=0,
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- terminal = response.parse()
- assert_matches_type(Terminal, terminal, path=["response"])
-
- @parametrize
- def test_streaming_response_create(self, client: Dedalus) -> None:
- with client.machines.terminals.with_streaming_response.create(
- machine_id="dm-3",
- height=0,
- width=0,
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- terminal = response.parse()
- assert_matches_type(Terminal, terminal, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_create(self, client: Dedalus) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `machine_id` but received ''"):
- client.machines.terminals.with_raw_response.create(
- machine_id="",
- height=0,
- width=0,
- )
-
- @parametrize
- def test_method_retrieve(self, client: Dedalus) -> None:
- terminal = client.machines.terminals.retrieve(
- machine_id="dm-3",
- terminal_id="terminal_id",
- )
- assert_matches_type(Terminal, terminal, path=["response"])
-
- @parametrize
- def test_raw_response_retrieve(self, client: Dedalus) -> None:
- response = client.machines.terminals.with_raw_response.retrieve(
- machine_id="dm-3",
- terminal_id="terminal_id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- terminal = response.parse()
- assert_matches_type(Terminal, terminal, path=["response"])
-
- @parametrize
- def test_streaming_response_retrieve(self, client: Dedalus) -> None:
- with client.machines.terminals.with_streaming_response.retrieve(
- machine_id="dm-3",
- terminal_id="terminal_id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- terminal = response.parse()
- assert_matches_type(Terminal, terminal, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_retrieve(self, client: Dedalus) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `machine_id` but received ''"):
- client.machines.terminals.with_raw_response.retrieve(
- machine_id="",
- terminal_id="terminal_id",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `terminal_id` but received ''"):
- client.machines.terminals.with_raw_response.retrieve(
- machine_id="dm-3",
- terminal_id="",
- )
-
- @parametrize
- def test_method_list(self, client: Dedalus) -> None:
- terminal = client.machines.terminals.list(
- machine_id="dm-3",
- )
- assert_matches_type(SyncCursorPage[Terminal], terminal, path=["response"])
-
- @parametrize
- def test_method_list_with_all_params(self, client: Dedalus) -> None:
- terminal = client.machines.terminals.list(
- machine_id="dm-3",
- cursor="cursor",
- limit=0,
- )
- assert_matches_type(SyncCursorPage[Terminal], terminal, path=["response"])
-
- @parametrize
- def test_raw_response_list(self, client: Dedalus) -> None:
- response = client.machines.terminals.with_raw_response.list(
- machine_id="dm-3",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- terminal = response.parse()
- assert_matches_type(SyncCursorPage[Terminal], terminal, path=["response"])
-
- @parametrize
- def test_streaming_response_list(self, client: Dedalus) -> None:
- with client.machines.terminals.with_streaming_response.list(
- machine_id="dm-3",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- terminal = response.parse()
- assert_matches_type(SyncCursorPage[Terminal], terminal, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_list(self, client: Dedalus) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `machine_id` but received ''"):
- client.machines.terminals.with_raw_response.list(
- machine_id="",
- )
-
- @parametrize
- def test_method_delete(self, client: Dedalus) -> None:
- terminal = client.machines.terminals.delete(
- machine_id="dm-3",
- terminal_id="terminal_id",
- )
- assert_matches_type(Terminal, terminal, path=["response"])
-
- @parametrize
- def test_raw_response_delete(self, client: Dedalus) -> None:
- response = client.machines.terminals.with_raw_response.delete(
- machine_id="dm-3",
- terminal_id="terminal_id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- terminal = response.parse()
- assert_matches_type(Terminal, terminal, path=["response"])
-
- @parametrize
- def test_streaming_response_delete(self, client: Dedalus) -> None:
- with client.machines.terminals.with_streaming_response.delete(
- machine_id="dm-3",
- terminal_id="terminal_id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- terminal = response.parse()
- assert_matches_type(Terminal, terminal, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_delete(self, client: Dedalus) -> None:
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `machine_id` but received ''"):
- client.machines.terminals.with_raw_response.delete(
- machine_id="",
- terminal_id="terminal_id",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `terminal_id` but received ''"):
- client.machines.terminals.with_raw_response.delete(
- machine_id="dm-3",
- terminal_id="",
- )
-
-
-class TestAsyncTerminals:
- 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: AsyncDedalus) -> None:
- terminal = await async_client.machines.terminals.create(
- machine_id="dm-3",
- height=0,
- width=0,
- )
- assert_matches_type(Terminal, terminal, path=["response"])
-
- @parametrize
- async def test_method_create_with_all_params(self, async_client: AsyncDedalus) -> None:
- terminal = await async_client.machines.terminals.create(
- machine_id="dm-3",
- height=0,
- width=0,
- cwd="cwd",
- env={"foo": "string"},
- shell="shell",
- )
- assert_matches_type(Terminal, terminal, path=["response"])
-
- @parametrize
- async def test_raw_response_create(self, async_client: AsyncDedalus) -> None:
- response = await async_client.machines.terminals.with_raw_response.create(
- machine_id="dm-3",
- height=0,
- width=0,
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- terminal = await response.parse()
- assert_matches_type(Terminal, terminal, path=["response"])
-
- @parametrize
- async def test_streaming_response_create(self, async_client: AsyncDedalus) -> None:
- async with async_client.machines.terminals.with_streaming_response.create(
- machine_id="dm-3",
- height=0,
- width=0,
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- terminal = await response.parse()
- assert_matches_type(Terminal, terminal, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_create(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.terminals.with_raw_response.create(
- machine_id="",
- height=0,
- width=0,
- )
-
- @parametrize
- async def test_method_retrieve(self, async_client: AsyncDedalus) -> None:
- terminal = await async_client.machines.terminals.retrieve(
- machine_id="dm-3",
- terminal_id="terminal_id",
- )
- assert_matches_type(Terminal, terminal, path=["response"])
-
- @parametrize
- async def test_raw_response_retrieve(self, async_client: AsyncDedalus) -> None:
- response = await async_client.machines.terminals.with_raw_response.retrieve(
- machine_id="dm-3",
- terminal_id="terminal_id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- terminal = await response.parse()
- assert_matches_type(Terminal, terminal, path=["response"])
-
- @parametrize
- async def test_streaming_response_retrieve(self, async_client: AsyncDedalus) -> None:
- async with async_client.machines.terminals.with_streaming_response.retrieve(
- machine_id="dm-3",
- terminal_id="terminal_id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- terminal = await response.parse()
- assert_matches_type(Terminal, terminal, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_retrieve(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.terminals.with_raw_response.retrieve(
- machine_id="",
- terminal_id="terminal_id",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `terminal_id` but received ''"):
- await async_client.machines.terminals.with_raw_response.retrieve(
- machine_id="dm-3",
- terminal_id="",
- )
-
- @parametrize
- async def test_method_list(self, async_client: AsyncDedalus) -> None:
- terminal = await async_client.machines.terminals.list(
- machine_id="dm-3",
- )
- assert_matches_type(AsyncCursorPage[Terminal], terminal, path=["response"])
-
- @parametrize
- async def test_method_list_with_all_params(self, async_client: AsyncDedalus) -> None:
- terminal = await async_client.machines.terminals.list(
- machine_id="dm-3",
- cursor="cursor",
- limit=0,
- )
- assert_matches_type(AsyncCursorPage[Terminal], terminal, path=["response"])
-
- @parametrize
- async def test_raw_response_list(self, async_client: AsyncDedalus) -> None:
- response = await async_client.machines.terminals.with_raw_response.list(
- machine_id="dm-3",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- terminal = await response.parse()
- assert_matches_type(AsyncCursorPage[Terminal], terminal, path=["response"])
-
- @parametrize
- async def test_streaming_response_list(self, async_client: AsyncDedalus) -> None:
- async with async_client.machines.terminals.with_streaming_response.list(
- machine_id="dm-3",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- terminal = await response.parse()
- assert_matches_type(AsyncCursorPage[Terminal], terminal, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_list(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.terminals.with_raw_response.list(
- machine_id="",
- )
-
- @parametrize
- async def test_method_delete(self, async_client: AsyncDedalus) -> None:
- terminal = await async_client.machines.terminals.delete(
- machine_id="dm-3",
- terminal_id="terminal_id",
- )
- assert_matches_type(Terminal, terminal, path=["response"])
-
- @parametrize
- async def test_raw_response_delete(self, async_client: AsyncDedalus) -> None:
- response = await async_client.machines.terminals.with_raw_response.delete(
- machine_id="dm-3",
- terminal_id="terminal_id",
- )
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- terminal = await response.parse()
- assert_matches_type(Terminal, terminal, path=["response"])
-
- @parametrize
- async def test_streaming_response_delete(self, async_client: AsyncDedalus) -> None:
- async with async_client.machines.terminals.with_streaming_response.delete(
- machine_id="dm-3",
- terminal_id="terminal_id",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- terminal = await response.parse()
- assert_matches_type(Terminal, terminal, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_delete(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.terminals.with_raw_response.delete(
- machine_id="",
- terminal_id="terminal_id",
- )
-
- with pytest.raises(ValueError, match=r"Expected a non-empty value for `terminal_id` but received ''"):
- await async_client.machines.terminals.with_raw_response.delete(
- machine_id="dm-3",
- terminal_id="",
- )
diff --git a/tests/api_resources/test_machines.py b/tests/api_resources/test_machines.py
index 5e706dd..dbdfeef 100644
--- a/tests/api_resources/test_machines.py
+++ b/tests/api_resources/test_machines.py
@@ -12,6 +12,7 @@
from dedalus_sdk.types import (
Machine,
MachineListItem,
+ MachineRetrieveResponse,
)
from dedalus_sdk.pagination import SyncCursorPage, AsyncCursorPage
@@ -23,30 +24,22 @@ class TestMachines:
@parametrize
def test_method_create(self, client: Dedalus) -> None:
- machine = client.machines.create(
- memory_mib=0,
- storage_gib=0,
- vcpu=0,
- )
+ machine = client.machines.create()
assert_matches_type(Machine, machine, path=["response"])
@parametrize
def test_method_create_with_all_params(self, client: Dedalus) -> None:
machine = client.machines.create(
- memory_mib=0,
- storage_gib=0,
- vcpu=0,
autosleep="autosleep",
+ memory_mib=1,
+ storage_gib=1,
+ vcpu=1,
)
assert_matches_type(Machine, machine, path=["response"])
@parametrize
def test_raw_response_create(self, client: Dedalus) -> None:
- response = client.machines.with_raw_response.create(
- memory_mib=0,
- storage_gib=0,
- vcpu=0,
- )
+ response = client.machines.with_raw_response.create()
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -55,11 +48,7 @@ def test_raw_response_create(self, client: Dedalus) -> None:
@parametrize
def test_streaming_response_create(self, client: Dedalus) -> None:
- with client.machines.with_streaming_response.create(
- memory_mib=0,
- storage_gib=0,
- vcpu=0,
- ) as response:
+ with client.machines.with_streaming_response.create() as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -71,31 +60,31 @@ def test_streaming_response_create(self, client: Dedalus) -> None:
@parametrize
def test_method_retrieve(self, client: Dedalus) -> None:
machine = client.machines.retrieve(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
)
- assert_matches_type(Machine, machine, path=["response"])
+ assert_matches_type(MachineRetrieveResponse, machine, path=["response"])
@parametrize
def test_raw_response_retrieve(self, client: Dedalus) -> None:
response = client.machines.with_raw_response.retrieve(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
)
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"])
+ assert_matches_type(MachineRetrieveResponse, machine, path=["response"])
@parametrize
def test_streaming_response_retrieve(self, client: Dedalus) -> None:
with client.machines.with_streaming_response.retrieve(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
) 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_matches_type(MachineRetrieveResponse, machine, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -109,14 +98,14 @@ def test_path_params_retrieve(self, client: Dedalus) -> None:
@parametrize
def test_method_update(self, client: Dedalus) -> None:
machine = client.machines.update(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
)
assert_matches_type(Machine, machine, path=["response"])
@parametrize
def test_method_update_with_all_params(self, client: Dedalus) -> None:
machine = client.machines.update(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
autosleep="autosleep",
memory_mib=0,
storage_gib=0,
@@ -127,7 +116,7 @@ def test_method_update_with_all_params(self, client: Dedalus) -> None:
@parametrize
def test_raw_response_update(self, client: Dedalus) -> None:
response = client.machines.with_raw_response.update(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
)
assert response.is_closed is True
@@ -138,7 +127,7 @@ def test_raw_response_update(self, client: Dedalus) -> None:
@parametrize
def test_streaming_response_update(self, client: Dedalus) -> None:
with client.machines.with_streaming_response.update(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -191,14 +180,14 @@ def test_streaming_response_list(self, client: Dedalus) -> None:
@parametrize
def test_method_delete(self, client: Dedalus) -> None:
machine = client.machines.delete(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
)
assert_matches_type(Machine, machine, path=["response"])
@parametrize
def test_raw_response_delete(self, client: Dedalus) -> None:
response = client.machines.with_raw_response.delete(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
)
assert response.is_closed is True
@@ -209,7 +198,7 @@ def test_raw_response_delete(self, client: Dedalus) -> None:
@parametrize
def test_streaming_response_delete(self, client: Dedalus) -> None:
with client.machines.with_streaming_response.delete(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -229,14 +218,14 @@ def test_path_params_delete(self, client: Dedalus) -> None:
@parametrize
def test_method_sleep(self, client: Dedalus) -> None:
machine = client.machines.sleep(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
)
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="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
)
assert response.is_closed is True
@@ -247,7 +236,7 @@ def test_raw_response_sleep(self, client: Dedalus) -> None:
@parametrize
def test_streaming_response_sleep(self, client: Dedalus) -> None:
with client.machines.with_streaming_response.sleep(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -267,14 +256,14 @@ def test_path_params_sleep(self, client: Dedalus) -> None:
@parametrize
def test_method_wake(self, client: Dedalus) -> None:
machine = client.machines.wake(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
)
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="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
)
assert response.is_closed is True
@@ -285,7 +274,7 @@ def test_raw_response_wake(self, client: Dedalus) -> None:
@parametrize
def test_streaming_response_wake(self, client: Dedalus) -> None:
with client.machines.with_streaming_response.wake(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -302,51 +291,6 @@ def test_path_params_wake(self, client: Dedalus) -> None:
machine_id="",
)
- @parametrize
- def test_method_watch(self, client: Dedalus) -> None:
- machine_stream = client.machines.watch(
- machine_id="dm-3",
- )
- machine_stream.response.close()
-
- @parametrize
- def test_method_watch_with_all_params(self, client: Dedalus) -> None:
- machine_stream = client.machines.watch(
- machine_id="dm-3",
- last_event_id="Last-Event-ID",
- )
- machine_stream.response.close()
-
- @parametrize
- def test_raw_response_watch(self, client: Dedalus) -> None:
- response = client.machines.with_raw_response.watch(
- machine_id="dm-3",
- )
-
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- stream = response.parse()
- stream.close()
-
- @parametrize
- def test_streaming_response_watch(self, client: Dedalus) -> None:
- with client.machines.with_streaming_response.watch(
- machine_id="dm-3",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- stream = response.parse()
- stream.close()
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_path_params_watch(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.watch(
- machine_id="",
- )
-
class TestAsyncMachines:
parametrize = pytest.mark.parametrize(
@@ -355,30 +299,22 @@ class TestAsyncMachines:
@parametrize
async def test_method_create(self, async_client: AsyncDedalus) -> None:
- machine = await async_client.machines.create(
- memory_mib=0,
- storage_gib=0,
- vcpu=0,
- )
+ machine = await async_client.machines.create()
assert_matches_type(Machine, machine, path=["response"])
@parametrize
async def test_method_create_with_all_params(self, async_client: AsyncDedalus) -> None:
machine = await async_client.machines.create(
- memory_mib=0,
- storage_gib=0,
- vcpu=0,
autosleep="autosleep",
+ memory_mib=1,
+ storage_gib=1,
+ vcpu=1,
)
assert_matches_type(Machine, machine, path=["response"])
@parametrize
async def test_raw_response_create(self, async_client: AsyncDedalus) -> None:
- response = await async_client.machines.with_raw_response.create(
- memory_mib=0,
- storage_gib=0,
- vcpu=0,
- )
+ response = await async_client.machines.with_raw_response.create()
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -387,11 +323,7 @@ async def test_raw_response_create(self, async_client: AsyncDedalus) -> None:
@parametrize
async def test_streaming_response_create(self, async_client: AsyncDedalus) -> None:
- async with async_client.machines.with_streaming_response.create(
- memory_mib=0,
- storage_gib=0,
- vcpu=0,
- ) as response:
+ async with async_client.machines.with_streaming_response.create() as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -403,31 +335,31 @@ async def test_streaming_response_create(self, async_client: AsyncDedalus) -> No
@parametrize
async def test_method_retrieve(self, async_client: AsyncDedalus) -> None:
machine = await async_client.machines.retrieve(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
)
- assert_matches_type(Machine, machine, path=["response"])
+ assert_matches_type(MachineRetrieveResponse, machine, path=["response"])
@parametrize
async def test_raw_response_retrieve(self, async_client: AsyncDedalus) -> None:
response = await async_client.machines.with_raw_response.retrieve(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
)
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"])
+ assert_matches_type(MachineRetrieveResponse, machine, path=["response"])
@parametrize
async def test_streaming_response_retrieve(self, async_client: AsyncDedalus) -> None:
async with async_client.machines.with_streaming_response.retrieve(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
) 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_matches_type(MachineRetrieveResponse, machine, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -441,14 +373,14 @@ async def test_path_params_retrieve(self, async_client: AsyncDedalus) -> None:
@parametrize
async def test_method_update(self, async_client: AsyncDedalus) -> None:
machine = await async_client.machines.update(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
)
assert_matches_type(Machine, machine, path=["response"])
@parametrize
async def test_method_update_with_all_params(self, async_client: AsyncDedalus) -> None:
machine = await async_client.machines.update(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
autosleep="autosleep",
memory_mib=0,
storage_gib=0,
@@ -459,7 +391,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncDedalus) -
@parametrize
async def test_raw_response_update(self, async_client: AsyncDedalus) -> None:
response = await async_client.machines.with_raw_response.update(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
)
assert response.is_closed is True
@@ -470,7 +402,7 @@ async def test_raw_response_update(self, async_client: AsyncDedalus) -> None:
@parametrize
async def test_streaming_response_update(self, async_client: AsyncDedalus) -> None:
async with async_client.machines.with_streaming_response.update(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -523,14 +455,14 @@ async def test_streaming_response_list(self, async_client: AsyncDedalus) -> None
@parametrize
async def test_method_delete(self, async_client: AsyncDedalus) -> None:
machine = await async_client.machines.delete(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
)
assert_matches_type(Machine, machine, path=["response"])
@parametrize
async def test_raw_response_delete(self, async_client: AsyncDedalus) -> None:
response = await async_client.machines.with_raw_response.delete(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
)
assert response.is_closed is True
@@ -541,7 +473,7 @@ async def test_raw_response_delete(self, async_client: AsyncDedalus) -> None:
@parametrize
async def test_streaming_response_delete(self, async_client: AsyncDedalus) -> None:
async with async_client.machines.with_streaming_response.delete(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -561,14 +493,14 @@ async def test_path_params_delete(self, async_client: AsyncDedalus) -> None:
@parametrize
async def test_method_sleep(self, async_client: AsyncDedalus) -> None:
machine = await async_client.machines.sleep(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
)
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="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
)
assert response.is_closed is True
@@ -579,7 +511,7 @@ async def test_raw_response_sleep(self, async_client: AsyncDedalus) -> None:
@parametrize
async def test_streaming_response_sleep(self, async_client: AsyncDedalus) -> None:
async with async_client.machines.with_streaming_response.sleep(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -599,14 +531,14 @@ async def test_path_params_sleep(self, async_client: AsyncDedalus) -> None:
@parametrize
async def test_method_wake(self, async_client: AsyncDedalus) -> None:
machine = await async_client.machines.wake(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
)
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="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
)
assert response.is_closed is True
@@ -617,7 +549,7 @@ async def test_raw_response_wake(self, async_client: AsyncDedalus) -> None:
@parametrize
async def test_streaming_response_wake(self, async_client: AsyncDedalus) -> None:
async with async_client.machines.with_streaming_response.wake(
- machine_id="dm-3",
+ machine_id="dm-ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -633,48 +565,3 @@ async def test_path_params_wake(self, async_client: AsyncDedalus) -> None:
await async_client.machines.with_raw_response.wake(
machine_id="",
)
-
- @parametrize
- async def test_method_watch(self, async_client: AsyncDedalus) -> None:
- machine_stream = await async_client.machines.watch(
- machine_id="dm-3",
- )
- await machine_stream.response.aclose()
-
- @parametrize
- async def test_method_watch_with_all_params(self, async_client: AsyncDedalus) -> None:
- machine_stream = await async_client.machines.watch(
- machine_id="dm-3",
- last_event_id="Last-Event-ID",
- )
- await machine_stream.response.aclose()
-
- @parametrize
- async def test_raw_response_watch(self, async_client: AsyncDedalus) -> None:
- response = await async_client.machines.with_raw_response.watch(
- machine_id="dm-3",
- )
-
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- stream = await response.parse()
- await stream.close()
-
- @parametrize
- async def test_streaming_response_watch(self, async_client: AsyncDedalus) -> None:
- async with async_client.machines.with_streaming_response.watch(
- machine_id="dm-3",
- ) as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- stream = await response.parse()
- await stream.close()
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_path_params_watch(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.watch(
- machine_id="",
- )
diff --git a/tests/api_resources/test_usage.py b/tests/api_resources/test_usage.py
deleted file mode 100644
index ca8aa7e..0000000
--- a/tests/api_resources/test_usage.py
+++ /dev/null
@@ -1,230 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import os
-from typing import Any, cast
-
-import pytest
-
-from dedalus_sdk import Dedalus, AsyncDedalus
-from tests.utils import assert_matches_type
-from dedalus_sdk.types import (
- OrgUsage,
- MachineComputeUsage,
- MachineStorageUsage,
-)
-
-base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
-
-
-class TestUsage:
- parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
-
- @parametrize
- def test_method_retrieve(self, client: Dedalus) -> None:
- usage = client.usage.retrieve()
- assert_matches_type(OrgUsage, usage, path=["response"])
-
- @parametrize
- def test_method_retrieve_with_all_params(self, client: Dedalus) -> None:
- usage = client.usage.retrieve(
- period_start="period_start",
- )
- assert_matches_type(OrgUsage, usage, path=["response"])
-
- @parametrize
- def test_raw_response_retrieve(self, client: Dedalus) -> None:
- response = client.usage.with_raw_response.retrieve()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- usage = response.parse()
- assert_matches_type(OrgUsage, usage, path=["response"])
-
- @parametrize
- def test_streaming_response_retrieve(self, client: Dedalus) -> None:
- with client.usage.with_streaming_response.retrieve() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- usage = response.parse()
- assert_matches_type(OrgUsage, usage, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_method_machine_compute(self, client: Dedalus) -> None:
- usage = client.usage.machine_compute()
- assert_matches_type(MachineComputeUsage, usage, path=["response"])
-
- @parametrize
- def test_method_machine_compute_with_all_params(self, client: Dedalus) -> None:
- usage = client.usage.machine_compute(
- granularity="granularity",
- machine_id="machine_id",
- period_end="period_end",
- period_start="period_start",
- )
- assert_matches_type(MachineComputeUsage, usage, path=["response"])
-
- @parametrize
- def test_raw_response_machine_compute(self, client: Dedalus) -> None:
- response = client.usage.with_raw_response.machine_compute()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- usage = response.parse()
- assert_matches_type(MachineComputeUsage, usage, path=["response"])
-
- @parametrize
- def test_streaming_response_machine_compute(self, client: Dedalus) -> None:
- with client.usage.with_streaming_response.machine_compute() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- usage = response.parse()
- assert_matches_type(MachineComputeUsage, usage, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- def test_method_machine_storage(self, client: Dedalus) -> None:
- usage = client.usage.machine_storage()
- assert_matches_type(MachineStorageUsage, usage, path=["response"])
-
- @parametrize
- def test_method_machine_storage_with_all_params(self, client: Dedalus) -> None:
- usage = client.usage.machine_storage(
- machine_id="machine_id",
- period_end="period_end",
- period_start="period_start",
- )
- assert_matches_type(MachineStorageUsage, usage, path=["response"])
-
- @parametrize
- def test_raw_response_machine_storage(self, client: Dedalus) -> None:
- response = client.usage.with_raw_response.machine_storage()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- usage = response.parse()
- assert_matches_type(MachineStorageUsage, usage, path=["response"])
-
- @parametrize
- def test_streaming_response_machine_storage(self, client: Dedalus) -> None:
- with client.usage.with_streaming_response.machine_storage() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- usage = response.parse()
- assert_matches_type(MachineStorageUsage, usage, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
-
-class TestAsyncUsage:
- parametrize = pytest.mark.parametrize(
- "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
- )
-
- @parametrize
- async def test_method_retrieve(self, async_client: AsyncDedalus) -> None:
- usage = await async_client.usage.retrieve()
- assert_matches_type(OrgUsage, usage, path=["response"])
-
- @parametrize
- async def test_method_retrieve_with_all_params(self, async_client: AsyncDedalus) -> None:
- usage = await async_client.usage.retrieve(
- period_start="period_start",
- )
- assert_matches_type(OrgUsage, usage, path=["response"])
-
- @parametrize
- async def test_raw_response_retrieve(self, async_client: AsyncDedalus) -> None:
- response = await async_client.usage.with_raw_response.retrieve()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- usage = await response.parse()
- assert_matches_type(OrgUsage, usage, path=["response"])
-
- @parametrize
- async def test_streaming_response_retrieve(self, async_client: AsyncDedalus) -> None:
- async with async_client.usage.with_streaming_response.retrieve() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- usage = await response.parse()
- assert_matches_type(OrgUsage, usage, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_method_machine_compute(self, async_client: AsyncDedalus) -> None:
- usage = await async_client.usage.machine_compute()
- assert_matches_type(MachineComputeUsage, usage, path=["response"])
-
- @parametrize
- async def test_method_machine_compute_with_all_params(self, async_client: AsyncDedalus) -> None:
- usage = await async_client.usage.machine_compute(
- granularity="granularity",
- machine_id="machine_id",
- period_end="period_end",
- period_start="period_start",
- )
- assert_matches_type(MachineComputeUsage, usage, path=["response"])
-
- @parametrize
- async def test_raw_response_machine_compute(self, async_client: AsyncDedalus) -> None:
- response = await async_client.usage.with_raw_response.machine_compute()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- usage = await response.parse()
- assert_matches_type(MachineComputeUsage, usage, path=["response"])
-
- @parametrize
- async def test_streaming_response_machine_compute(self, async_client: AsyncDedalus) -> None:
- async with async_client.usage.with_streaming_response.machine_compute() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- usage = await response.parse()
- assert_matches_type(MachineComputeUsage, usage, path=["response"])
-
- assert cast(Any, response.is_closed) is True
-
- @parametrize
- async def test_method_machine_storage(self, async_client: AsyncDedalus) -> None:
- usage = await async_client.usage.machine_storage()
- assert_matches_type(MachineStorageUsage, usage, path=["response"])
-
- @parametrize
- async def test_method_machine_storage_with_all_params(self, async_client: AsyncDedalus) -> None:
- usage = await async_client.usage.machine_storage(
- machine_id="machine_id",
- period_end="period_end",
- period_start="period_start",
- )
- assert_matches_type(MachineStorageUsage, usage, path=["response"])
-
- @parametrize
- async def test_raw_response_machine_storage(self, async_client: AsyncDedalus) -> None:
- response = await async_client.usage.with_raw_response.machine_storage()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- usage = await response.parse()
- assert_matches_type(MachineStorageUsage, usage, path=["response"])
-
- @parametrize
- async def test_streaming_response_machine_storage(self, async_client: AsyncDedalus) -> None:
- async with async_client.usage.with_streaming_response.machine_storage() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- usage = await response.parse()
- assert_matches_type(MachineStorageUsage, usage, path=["response"])
-
- assert cast(Any, response.is_closed) is True
diff --git a/tests/test_client.py b/tests/test_client.py
index 63f5c33..c230dbd 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -23,7 +23,6 @@
from dedalus_sdk._types import Omit
from dedalus_sdk._utils import asyncify
from dedalus_sdk._models import BaseModel, FinalRequestOptions
-from dedalus_sdk._streaming import Stream, AsyncStream
from dedalus_sdk._exceptions import APIStatusError, APITimeoutError, APIResponseValidationError
from dedalus_sdk._base_client import (
DEFAULT_TIMEOUT,
@@ -861,17 +860,6 @@ def test_client_max_retries_validation(self) -> None:
with pytest.raises(TypeError, match=r"max_retries cannot be None"):
Dedalus(base_url=base_url, api_key=api_key, _strict_response_validation=True, max_retries=cast(Any, None))
- @pytest.mark.respx(base_url=base_url)
- def test_default_stream_cls(self, respx_mock: MockRouter, client: Dedalus) -> None:
- class Model(BaseModel):
- name: str
-
- respx_mock.post("/foo").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
-
- stream = client.post("/foo", cast_to=Model, stream=True, stream_cls=Stream[Model])
- assert isinstance(stream, Stream)
- stream.response.close()
-
@pytest.mark.respx(base_url=base_url)
def test_received_text_for_expected_json(self, respx_mock: MockRouter) -> None:
class Model(BaseModel):
@@ -928,7 +916,7 @@ def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter, clien
respx_mock.post("/v1/machines").mock(side_effect=httpx.TimeoutException("Test timeout error"))
with pytest.raises(APITimeoutError):
- client.machines.with_streaming_response.create(memory_mib=0, storage_gib=0, vcpu=0).__enter__()
+ client.machines.with_streaming_response.create().__enter__()
assert _get_open_connections(client) == 0
@@ -938,7 +926,7 @@ def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter, client
respx_mock.post("/v1/machines").mock(return_value=httpx.Response(500))
with pytest.raises(APIStatusError):
- client.machines.with_streaming_response.create(memory_mib=0, storage_gib=0, vcpu=0).__enter__()
+ client.machines.with_streaming_response.create().__enter__()
assert _get_open_connections(client) == 0
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
@@ -967,7 +955,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
respx_mock.post("/v1/machines").mock(side_effect=retry_handler)
- response = client.machines.with_raw_response.create(memory_mib=0, storage_gib=0, vcpu=0)
+ response = client.machines.with_raw_response.create()
assert response.retries_taken == failures_before_success
assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success
@@ -991,9 +979,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
respx_mock.post("/v1/machines").mock(side_effect=retry_handler)
- response = client.machines.with_raw_response.create(
- memory_mib=0, storage_gib=0, vcpu=0, extra_headers={"x-stainless-retry-count": Omit()}
- )
+ response = client.machines.with_raw_response.create(extra_headers={"x-stainless-retry-count": Omit()})
assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0
@@ -1016,9 +1002,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
respx_mock.post("/v1/machines").mock(side_effect=retry_handler)
- response = client.machines.with_raw_response.create(
- memory_mib=0, storage_gib=0, vcpu=0, extra_headers={"x-stainless-retry-count": "42"}
- )
+ response = client.machines.with_raw_response.create(extra_headers={"x-stainless-retry-count": "42"})
assert response.http_request.headers.get("x-stainless-retry-count") == "42"
@@ -1846,17 +1830,6 @@ async def test_client_max_retries_validation(self) -> None:
base_url=base_url, api_key=api_key, _strict_response_validation=True, max_retries=cast(Any, None)
)
- @pytest.mark.respx(base_url=base_url)
- async def test_default_stream_cls(self, respx_mock: MockRouter, async_client: AsyncDedalus) -> None:
- class Model(BaseModel):
- name: str
-
- respx_mock.post("/foo").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
-
- stream = await async_client.post("/foo", cast_to=Model, stream=True, stream_cls=AsyncStream[Model])
- assert isinstance(stream, AsyncStream)
- await stream.response.aclose()
-
@pytest.mark.respx(base_url=base_url)
async def test_received_text_for_expected_json(self, respx_mock: MockRouter) -> None:
class Model(BaseModel):
@@ -1915,7 +1888,7 @@ async def test_retrying_timeout_errors_doesnt_leak(
respx_mock.post("/v1/machines").mock(side_effect=httpx.TimeoutException("Test timeout error"))
with pytest.raises(APITimeoutError):
- await async_client.machines.with_streaming_response.create(memory_mib=0, storage_gib=0, vcpu=0).__aenter__()
+ await async_client.machines.with_streaming_response.create().__aenter__()
assert _get_open_connections(async_client) == 0
@@ -1925,7 +1898,7 @@ async def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter,
respx_mock.post("/v1/machines").mock(return_value=httpx.Response(500))
with pytest.raises(APIStatusError):
- await async_client.machines.with_streaming_response.create(memory_mib=0, storage_gib=0, vcpu=0).__aenter__()
+ await async_client.machines.with_streaming_response.create().__aenter__()
assert _get_open_connections(async_client) == 0
@pytest.mark.parametrize("failures_before_success", [0, 2, 4])
@@ -1954,7 +1927,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
respx_mock.post("/v1/machines").mock(side_effect=retry_handler)
- response = await client.machines.with_raw_response.create(memory_mib=0, storage_gib=0, vcpu=0)
+ response = await client.machines.with_raw_response.create()
assert response.retries_taken == failures_before_success
assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success
@@ -1978,9 +1951,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
respx_mock.post("/v1/machines").mock(side_effect=retry_handler)
- response = await client.machines.with_raw_response.create(
- memory_mib=0, storage_gib=0, vcpu=0, extra_headers={"x-stainless-retry-count": Omit()}
- )
+ response = await client.machines.with_raw_response.create(extra_headers={"x-stainless-retry-count": Omit()})
assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0
@@ -2003,9 +1974,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
respx_mock.post("/v1/machines").mock(side_effect=retry_handler)
- response = await client.machines.with_raw_response.create(
- memory_mib=0, storage_gib=0, vcpu=0, extra_headers={"x-stainless-retry-count": "42"}
- )
+ response = await client.machines.with_raw_response.create(extra_headers={"x-stainless-retry-count": "42"})
assert response.http_request.headers.get("x-stainless-retry-count") == "42"
diff --git a/tests/test_send_queue.py b/tests/test_send_queue.py
deleted file mode 100644
index 196d78d..0000000
--- a/tests/test_send_queue.py
+++ /dev/null
@@ -1,128 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-import pytest
-
-from dedalus_sdk._exceptions import WebSocketQueueFullError
-from dedalus_sdk._send_queue import SendQueue
-
-
-class TestSendQueue:
- def test_enqueue_and_drain(self) -> None:
- q = SendQueue()
- q.enqueue('{"type": "session.update"}')
- q.enqueue('{"type": "response.create"}')
- assert len(q) == 2
-
- items = q.drain()
- assert items == ['{"type": "session.update"}', '{"type": "response.create"}']
- assert len(q) == 0
-
- def test_enqueue_respects_byte_limit(self) -> None:
- q = SendQueue(max_bytes=10)
- q.enqueue("12345") # 5 bytes, fits
- with pytest.raises(WebSocketQueueFullError):
- q.enqueue("123456") # 6 bytes, would exceed 10
- assert len(q) == 1
-
- def test_drain_empties_queue(self) -> None:
- q = SendQueue()
- q.enqueue("hello")
- q.drain()
- assert len(q) == 0
- assert not q
-
- def test_bool(self) -> None:
- q = SendQueue()
- assert not q
- q.enqueue("x")
- assert q
-
- def test_flush_sync(self) -> None:
- q = SendQueue()
- q.enqueue("a")
- q.enqueue("b")
- q.enqueue("c")
-
- sent: list[str] = []
- q.flush_sync(sent.append)
- assert sent == ["a", "b", "c"]
- assert len(q) == 0
-
- def test_flush_sync_requeues_on_failure(self) -> None:
- q = SendQueue()
- q.enqueue("a")
- q.enqueue("b")
- q.enqueue("c")
-
- sent: list[str] = []
-
- def failing_send(data: str) -> None:
- if data == "b":
- raise RuntimeError("send failed")
- sent.append(data)
-
- with pytest.raises(RuntimeError, match="send failed"):
- q.flush_sync(failing_send)
-
- assert sent == ["a"]
- # b and c should be re-queued
- remaining = q.drain()
- assert remaining == ["b", "c"]
-
- @pytest.mark.asyncio
- async def test_flush_async(self) -> None:
- q = SendQueue()
- q.enqueue("a")
- q.enqueue("b")
-
- sent: list[str] = []
-
- async def async_send(data: str) -> None:
- sent.append(data)
-
- await q.flush_async(async_send)
- assert sent == ["a", "b"]
- assert len(q) == 0
-
- @pytest.mark.asyncio
- async def test_flush_async_requeues_on_failure(self) -> None:
- q = SendQueue()
- q.enqueue("a")
- q.enqueue("b")
- q.enqueue("c")
-
- sent: list[str] = []
-
- async def failing_send(data: str) -> None:
- if data == "b":
- raise RuntimeError("send failed")
- sent.append(data)
-
- with pytest.raises(RuntimeError, match="send failed"):
- await q.flush_async(failing_send)
-
- assert sent == ["a"]
- remaining = q.drain()
- assert remaining == ["b", "c"]
-
- def test_flush_sync_preserves_new_items_on_failure(self) -> None:
- """If items are enqueued after flush starts and flush fails,
- the re-queued items should come before the new items."""
- q = SendQueue()
- q.enqueue("a")
- q.enqueue("b")
-
- def failing_send(data: str) -> None:
- if data == "b":
- # Simulate another thread enqueuing during flush
- q.enqueue("new")
- raise RuntimeError("fail")
-
- with pytest.raises(RuntimeError):
- q.flush_sync(failing_send)
-
- # "b" (failed) should come before "new" (added during flush)
- remaining = q.drain()
- assert remaining == ["b", "new"]
diff --git a/uv.lock b/uv.lock
index c06f3a3..2facb36 100644
--- a/uv.lock
+++ b/uv.lock
@@ -261,9 +261,6 @@ aiohttp = [
{ name = "aiohttp" },
{ name = "httpx-aiohttp" },
]
-websockets = [
- { name = "websockets" },
-]
[package.dev-dependencies]
dev = [
@@ -299,9 +296,8 @@ requires-dist = [
{ name = "pydantic", specifier = ">=1.9.0,<3" },
{ name = "sniffio" },
{ name = "typing-extensions", specifier = ">=4.14,<5" },
- { name = "websockets", marker = "extra == 'websockets'", specifier = ">=13,<16" },
]
-provides-extras = ["aiohttp", "websockets"]
+provides-extras = ["aiohttp"]
[package.metadata.requires-dev]
dev = [
@@ -1681,82 +1677,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" },
]
-[[package]]
-name = "websockets"
-version = "15.0.1"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/21/e6/26d09fab466b7ca9c7737474c52be4f76a40301b08362eb2dbc19dcc16c1/websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee", size = 177016, upload-time = "2025-03-05T20:03:41.606Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/1e/da/6462a9f510c0c49837bbc9345aca92d767a56c1fb2939e1579df1e1cdcf7/websockets-15.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d63efaa0cd96cf0c5fe4d581521d9fa87744540d4bc999ae6e08595a1014b45b", size = 175423, upload-time = "2025-03-05T20:01:35.363Z" },
- { url = "https://files.pythonhosted.org/packages/1c/9f/9d11c1a4eb046a9e106483b9ff69bce7ac880443f00e5ce64261b47b07e7/websockets-15.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ac60e3b188ec7574cb761b08d50fcedf9d77f1530352db4eef1707fe9dee7205", size = 173080, upload-time = "2025-03-05T20:01:37.304Z" },
- { url = "https://files.pythonhosted.org/packages/d5/4f/b462242432d93ea45f297b6179c7333dd0402b855a912a04e7fc61c0d71f/websockets-15.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5756779642579d902eed757b21b0164cd6fe338506a8083eb58af5c372e39d9a", size = 173329, upload-time = "2025-03-05T20:01:39.668Z" },
- { url = "https://files.pythonhosted.org/packages/6e/0c/6afa1f4644d7ed50284ac59cc70ef8abd44ccf7d45850d989ea7310538d0/websockets-15.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fdfe3e2a29e4db3659dbd5bbf04560cea53dd9610273917799f1cde46aa725e", size = 182312, upload-time = "2025-03-05T20:01:41.815Z" },
- { url = "https://files.pythonhosted.org/packages/dd/d4/ffc8bd1350b229ca7a4db2a3e1c482cf87cea1baccd0ef3e72bc720caeec/websockets-15.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c2529b320eb9e35af0fa3016c187dffb84a3ecc572bcee7c3ce302bfeba52bf", size = 181319, upload-time = "2025-03-05T20:01:43.967Z" },
- { url = "https://files.pythonhosted.org/packages/97/3a/5323a6bb94917af13bbb34009fac01e55c51dfde354f63692bf2533ffbc2/websockets-15.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac1e5c9054fe23226fb11e05a6e630837f074174c4c2f0fe442996112a6de4fb", size = 181631, upload-time = "2025-03-05T20:01:46.104Z" },
- { url = "https://files.pythonhosted.org/packages/a6/cc/1aeb0f7cee59ef065724041bb7ed667b6ab1eeffe5141696cccec2687b66/websockets-15.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5df592cd503496351d6dc14f7cdad49f268d8e618f80dce0cd5a36b93c3fc08d", size = 182016, upload-time = "2025-03-05T20:01:47.603Z" },
- { url = "https://files.pythonhosted.org/packages/79/f9/c86f8f7af208e4161a7f7e02774e9d0a81c632ae76db2ff22549e1718a51/websockets-15.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0a34631031a8f05657e8e90903e656959234f3a04552259458aac0b0f9ae6fd9", size = 181426, upload-time = "2025-03-05T20:01:48.949Z" },
- { url = "https://files.pythonhosted.org/packages/c7/b9/828b0bc6753db905b91df6ae477c0b14a141090df64fb17f8a9d7e3516cf/websockets-15.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3d00075aa65772e7ce9e990cab3ff1de702aa09be3940d1dc88d5abf1ab8a09c", size = 181360, upload-time = "2025-03-05T20:01:50.938Z" },
- { url = "https://files.pythonhosted.org/packages/89/fb/250f5533ec468ba6327055b7d98b9df056fb1ce623b8b6aaafb30b55d02e/websockets-15.0.1-cp310-cp310-win32.whl", hash = "sha256:1234d4ef35db82f5446dca8e35a7da7964d02c127b095e172e54397fb6a6c256", size = 176388, upload-time = "2025-03-05T20:01:52.213Z" },
- { url = "https://files.pythonhosted.org/packages/1c/46/aca7082012768bb98e5608f01658ff3ac8437e563eca41cf068bd5849a5e/websockets-15.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:39c1fec2c11dc8d89bba6b2bf1556af381611a173ac2b511cf7231622058af41", size = 176830, upload-time = "2025-03-05T20:01:53.922Z" },
- { url = "https://files.pythonhosted.org/packages/9f/32/18fcd5919c293a398db67443acd33fde142f283853076049824fc58e6f75/websockets-15.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:823c248b690b2fd9303ba00c4f66cd5e2d8c3ba4aa968b2779be9532a4dad431", size = 175423, upload-time = "2025-03-05T20:01:56.276Z" },
- { url = "https://files.pythonhosted.org/packages/76/70/ba1ad96b07869275ef42e2ce21f07a5b0148936688c2baf7e4a1f60d5058/websockets-15.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678999709e68425ae2593acf2e3ebcbcf2e69885a5ee78f9eb80e6e371f1bf57", size = 173082, upload-time = "2025-03-05T20:01:57.563Z" },
- { url = "https://files.pythonhosted.org/packages/86/f2/10b55821dd40eb696ce4704a87d57774696f9451108cff0d2824c97e0f97/websockets-15.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d50fd1ee42388dcfb2b3676132c78116490976f1300da28eb629272d5d93e905", size = 173330, upload-time = "2025-03-05T20:01:59.063Z" },
- { url = "https://files.pythonhosted.org/packages/a5/90/1c37ae8b8a113d3daf1065222b6af61cc44102da95388ac0018fcb7d93d9/websockets-15.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d99e5546bf73dbad5bf3547174cd6cb8ba7273062a23808ffea025ecb1cf8562", size = 182878, upload-time = "2025-03-05T20:02:00.305Z" },
- { url = "https://files.pythonhosted.org/packages/8e/8d/96e8e288b2a41dffafb78e8904ea7367ee4f891dafc2ab8d87e2124cb3d3/websockets-15.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66dd88c918e3287efc22409d426c8f729688d89a0c587c88971a0faa2c2f3792", size = 181883, upload-time = "2025-03-05T20:02:03.148Z" },
- { url = "https://files.pythonhosted.org/packages/93/1f/5d6dbf551766308f6f50f8baf8e9860be6182911e8106da7a7f73785f4c4/websockets-15.0.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8dd8327c795b3e3f219760fa603dcae1dcc148172290a8ab15158cf85a953413", size = 182252, upload-time = "2025-03-05T20:02:05.29Z" },
- { url = "https://files.pythonhosted.org/packages/d4/78/2d4fed9123e6620cbf1706c0de8a1632e1a28e7774d94346d7de1bba2ca3/websockets-15.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8fdc51055e6ff4adeb88d58a11042ec9a5eae317a0a53d12c062c8a8865909e8", size = 182521, upload-time = "2025-03-05T20:02:07.458Z" },
- { url = "https://files.pythonhosted.org/packages/e7/3b/66d4c1b444dd1a9823c4a81f50231b921bab54eee2f69e70319b4e21f1ca/websockets-15.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:693f0192126df6c2327cce3baa7c06f2a117575e32ab2308f7f8216c29d9e2e3", size = 181958, upload-time = "2025-03-05T20:02:09.842Z" },
- { url = "https://files.pythonhosted.org/packages/08/ff/e9eed2ee5fed6f76fdd6032ca5cd38c57ca9661430bb3d5fb2872dc8703c/websockets-15.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:54479983bd5fb469c38f2f5c7e3a24f9a4e70594cd68cd1fa6b9340dadaff7cf", size = 181918, upload-time = "2025-03-05T20:02:11.968Z" },
- { url = "https://files.pythonhosted.org/packages/d8/75/994634a49b7e12532be6a42103597b71098fd25900f7437d6055ed39930a/websockets-15.0.1-cp311-cp311-win32.whl", hash = "sha256:16b6c1b3e57799b9d38427dda63edcbe4926352c47cf88588c0be4ace18dac85", size = 176388, upload-time = "2025-03-05T20:02:13.32Z" },
- { url = "https://files.pythonhosted.org/packages/98/93/e36c73f78400a65f5e236cd376713c34182e6663f6889cd45a4a04d8f203/websockets-15.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:27ccee0071a0e75d22cb35849b1db43f2ecd3e161041ac1ee9d2352ddf72f065", size = 176828, upload-time = "2025-03-05T20:02:14.585Z" },
- { url = "https://files.pythonhosted.org/packages/51/6b/4545a0d843594f5d0771e86463606a3988b5a09ca5123136f8a76580dd63/websockets-15.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3e90baa811a5d73f3ca0bcbf32064d663ed81318ab225ee4f427ad4e26e5aff3", size = 175437, upload-time = "2025-03-05T20:02:16.706Z" },
- { url = "https://files.pythonhosted.org/packages/f4/71/809a0f5f6a06522af902e0f2ea2757f71ead94610010cf570ab5c98e99ed/websockets-15.0.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:592f1a9fe869c778694f0aa806ba0374e97648ab57936f092fd9d87f8bc03665", size = 173096, upload-time = "2025-03-05T20:02:18.832Z" },
- { url = "https://files.pythonhosted.org/packages/3d/69/1a681dd6f02180916f116894181eab8b2e25b31e484c5d0eae637ec01f7c/websockets-15.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0701bc3cfcb9164d04a14b149fd74be7347a530ad3bbf15ab2c678a2cd3dd9a2", size = 173332, upload-time = "2025-03-05T20:02:20.187Z" },
- { url = "https://files.pythonhosted.org/packages/a6/02/0073b3952f5bce97eafbb35757f8d0d54812b6174ed8dd952aa08429bcc3/websockets-15.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8b56bdcdb4505c8078cb6c7157d9811a85790f2f2b3632c7d1462ab5783d215", size = 183152, upload-time = "2025-03-05T20:02:22.286Z" },
- { url = "https://files.pythonhosted.org/packages/74/45/c205c8480eafd114b428284840da0b1be9ffd0e4f87338dc95dc6ff961a1/websockets-15.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0af68c55afbd5f07986df82831c7bff04846928ea8d1fd7f30052638788bc9b5", size = 182096, upload-time = "2025-03-05T20:02:24.368Z" },
- { url = "https://files.pythonhosted.org/packages/14/8f/aa61f528fba38578ec553c145857a181384c72b98156f858ca5c8e82d9d3/websockets-15.0.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64dee438fed052b52e4f98f76c5790513235efaa1ef7f3f2192c392cd7c91b65", size = 182523, upload-time = "2025-03-05T20:02:25.669Z" },
- { url = "https://files.pythonhosted.org/packages/ec/6d/0267396610add5bc0d0d3e77f546d4cd287200804fe02323797de77dbce9/websockets-15.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d5f6b181bb38171a8ad1d6aa58a67a6aa9d4b38d0f8c5f496b9e42561dfc62fe", size = 182790, upload-time = "2025-03-05T20:02:26.99Z" },
- { url = "https://files.pythonhosted.org/packages/02/05/c68c5adbf679cf610ae2f74a9b871ae84564462955d991178f95a1ddb7dd/websockets-15.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5d54b09eba2bada6011aea5375542a157637b91029687eb4fdb2dab11059c1b4", size = 182165, upload-time = "2025-03-05T20:02:30.291Z" },
- { url = "https://files.pythonhosted.org/packages/29/93/bb672df7b2f5faac89761cb5fa34f5cec45a4026c383a4b5761c6cea5c16/websockets-15.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3be571a8b5afed347da347bfcf27ba12b069d9d7f42cb8c7028b5e98bbb12597", size = 182160, upload-time = "2025-03-05T20:02:31.634Z" },
- { url = "https://files.pythonhosted.org/packages/ff/83/de1f7709376dc3ca9b7eeb4b9a07b4526b14876b6d372a4dc62312bebee0/websockets-15.0.1-cp312-cp312-win32.whl", hash = "sha256:c338ffa0520bdb12fbc527265235639fb76e7bc7faafbb93f6ba80d9c06578a9", size = 176395, upload-time = "2025-03-05T20:02:33.017Z" },
- { url = "https://files.pythonhosted.org/packages/7d/71/abf2ebc3bbfa40f391ce1428c7168fb20582d0ff57019b69ea20fa698043/websockets-15.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:fcd5cf9e305d7b8338754470cf69cf81f420459dbae8a3b40cee57417f4614a7", size = 176841, upload-time = "2025-03-05T20:02:34.498Z" },
- { url = "https://files.pythonhosted.org/packages/cb/9f/51f0cf64471a9d2b4d0fc6c534f323b664e7095640c34562f5182e5a7195/websockets-15.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee443ef070bb3b6ed74514f5efaa37a252af57c90eb33b956d35c8e9c10a1931", size = 175440, upload-time = "2025-03-05T20:02:36.695Z" },
- { url = "https://files.pythonhosted.org/packages/8a/05/aa116ec9943c718905997412c5989f7ed671bc0188ee2ba89520e8765d7b/websockets-15.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5a939de6b7b4e18ca683218320fc67ea886038265fd1ed30173f5ce3f8e85675", size = 173098, upload-time = "2025-03-05T20:02:37.985Z" },
- { url = "https://files.pythonhosted.org/packages/ff/0b/33cef55ff24f2d92924923c99926dcce78e7bd922d649467f0eda8368923/websockets-15.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:746ee8dba912cd6fc889a8147168991d50ed70447bf18bcda7039f7d2e3d9151", size = 173329, upload-time = "2025-03-05T20:02:39.298Z" },
- { url = "https://files.pythonhosted.org/packages/31/1d/063b25dcc01faa8fada1469bdf769de3768b7044eac9d41f734fd7b6ad6d/websockets-15.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:595b6c3969023ecf9041b2936ac3827e4623bfa3ccf007575f04c5a6aa318c22", size = 183111, upload-time = "2025-03-05T20:02:40.595Z" },
- { url = "https://files.pythonhosted.org/packages/93/53/9a87ee494a51bf63e4ec9241c1ccc4f7c2f45fff85d5bde2ff74fcb68b9e/websockets-15.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c714d2fc58b5ca3e285461a4cc0c9a66bd0e24c5da9911e30158286c9b5be7f", size = 182054, upload-time = "2025-03-05T20:02:41.926Z" },
- { url = "https://files.pythonhosted.org/packages/ff/b2/83a6ddf56cdcbad4e3d841fcc55d6ba7d19aeb89c50f24dd7e859ec0805f/websockets-15.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f3c1e2ab208db911594ae5b4f79addeb3501604a165019dd221c0bdcabe4db8", size = 182496, upload-time = "2025-03-05T20:02:43.304Z" },
- { url = "https://files.pythonhosted.org/packages/98/41/e7038944ed0abf34c45aa4635ba28136f06052e08fc2168520bb8b25149f/websockets-15.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:229cf1d3ca6c1804400b0a9790dc66528e08a6a1feec0d5040e8b9eb14422375", size = 182829, upload-time = "2025-03-05T20:02:48.812Z" },
- { url = "https://files.pythonhosted.org/packages/e0/17/de15b6158680c7623c6ef0db361da965ab25d813ae54fcfeae2e5b9ef910/websockets-15.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:756c56e867a90fb00177d530dca4b097dd753cde348448a1012ed6c5131f8b7d", size = 182217, upload-time = "2025-03-05T20:02:50.14Z" },
- { url = "https://files.pythonhosted.org/packages/33/2b/1f168cb6041853eef0362fb9554c3824367c5560cbdaad89ac40f8c2edfc/websockets-15.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4", size = 182195, upload-time = "2025-03-05T20:02:51.561Z" },
- { url = "https://files.pythonhosted.org/packages/86/eb/20b6cdf273913d0ad05a6a14aed4b9a85591c18a987a3d47f20fa13dcc47/websockets-15.0.1-cp313-cp313-win32.whl", hash = "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa", size = 176393, upload-time = "2025-03-05T20:02:53.814Z" },
- { url = "https://files.pythonhosted.org/packages/1b/6c/c65773d6cab416a64d191d6ee8a8b1c68a09970ea6909d16965d26bfed1e/websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561", size = 176837, upload-time = "2025-03-05T20:02:55.237Z" },
- { url = "https://files.pythonhosted.org/packages/36/db/3fff0bcbe339a6fa6a3b9e3fbc2bfb321ec2f4cd233692272c5a8d6cf801/websockets-15.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5f4c04ead5aed67c8a1a20491d54cdfba5884507a48dd798ecaf13c74c4489f5", size = 175424, upload-time = "2025-03-05T20:02:56.505Z" },
- { url = "https://files.pythonhosted.org/packages/46/e6/519054c2f477def4165b0ec060ad664ed174e140b0d1cbb9fafa4a54f6db/websockets-15.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:abdc0c6c8c648b4805c5eacd131910d2a7f6455dfd3becab248ef108e89ab16a", size = 173077, upload-time = "2025-03-05T20:02:58.37Z" },
- { url = "https://files.pythonhosted.org/packages/1a/21/c0712e382df64c93a0d16449ecbf87b647163485ca1cc3f6cbadb36d2b03/websockets-15.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a625e06551975f4b7ea7102bc43895b90742746797e2e14b70ed61c43a90f09b", size = 173324, upload-time = "2025-03-05T20:02:59.773Z" },
- { url = "https://files.pythonhosted.org/packages/1c/cb/51ba82e59b3a664df54beed8ad95517c1b4dc1a913730e7a7db778f21291/websockets-15.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d591f8de75824cbb7acad4e05d2d710484f15f29d4a915092675ad3456f11770", size = 182094, upload-time = "2025-03-05T20:03:01.827Z" },
- { url = "https://files.pythonhosted.org/packages/fb/0f/bf3788c03fec679bcdaef787518dbe60d12fe5615a544a6d4cf82f045193/websockets-15.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47819cea040f31d670cc8d324bb6435c6f133b8c7a19ec3d61634e62f8d8f9eb", size = 181094, upload-time = "2025-03-05T20:03:03.123Z" },
- { url = "https://files.pythonhosted.org/packages/5e/da/9fb8c21edbc719b66763a571afbaf206cb6d3736d28255a46fc2fe20f902/websockets-15.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac017dd64572e5c3bd01939121e4d16cf30e5d7e110a119399cf3133b63ad054", size = 181397, upload-time = "2025-03-05T20:03:04.443Z" },
- { url = "https://files.pythonhosted.org/packages/2e/65/65f379525a2719e91d9d90c38fe8b8bc62bd3c702ac651b7278609b696c4/websockets-15.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4a9fac8e469d04ce6c25bb2610dc535235bd4aa14996b4e6dbebf5e007eba5ee", size = 181794, upload-time = "2025-03-05T20:03:06.708Z" },
- { url = "https://files.pythonhosted.org/packages/d9/26/31ac2d08f8e9304d81a1a7ed2851c0300f636019a57cbaa91342015c72cc/websockets-15.0.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363c6f671b761efcb30608d24925a382497c12c506b51661883c3e22337265ed", size = 181194, upload-time = "2025-03-05T20:03:08.844Z" },
- { url = "https://files.pythonhosted.org/packages/98/72/1090de20d6c91994cd4b357c3f75a4f25ee231b63e03adea89671cc12a3f/websockets-15.0.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2034693ad3097d5355bfdacfffcbd3ef5694f9718ab7f29c29689a9eae841880", size = 181164, upload-time = "2025-03-05T20:03:10.242Z" },
- { url = "https://files.pythonhosted.org/packages/2d/37/098f2e1c103ae8ed79b0e77f08d83b0ec0b241cf4b7f2f10edd0126472e1/websockets-15.0.1-cp39-cp39-win32.whl", hash = "sha256:3b1ac0d3e594bf121308112697cf4b32be538fb1444468fb0a6ae4feebc83411", size = 176381, upload-time = "2025-03-05T20:03:12.77Z" },
- { url = "https://files.pythonhosted.org/packages/75/8b/a32978a3ab42cebb2ebdd5b05df0696a09f4d436ce69def11893afa301f0/websockets-15.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:b7643a03db5c95c799b89b31c036d5f27eeb4d259c798e878d6937d71832b1e4", size = 176841, upload-time = "2025-03-05T20:03:14.367Z" },
- { url = "https://files.pythonhosted.org/packages/02/9e/d40f779fa16f74d3468357197af8d6ad07e7c5a27ea1ca74ceb38986f77a/websockets-15.0.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0c9e74d766f2818bb95f84c25be4dea09841ac0f734d1966f415e4edfc4ef1c3", size = 173109, upload-time = "2025-03-05T20:03:17.769Z" },
- { url = "https://files.pythonhosted.org/packages/bc/cd/5b887b8585a593073fd92f7c23ecd3985cd2c3175025a91b0d69b0551372/websockets-15.0.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1009ee0c7739c08a0cd59de430d6de452a55e42d6b522de7aa15e6f67db0b8e1", size = 173343, upload-time = "2025-03-05T20:03:19.094Z" },
- { url = "https://files.pythonhosted.org/packages/fe/ae/d34f7556890341e900a95acf4886833646306269f899d58ad62f588bf410/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76d1f20b1c7a2fa82367e04982e708723ba0e7b8d43aa643d3dcd404d74f1475", size = 174599, upload-time = "2025-03-05T20:03:21.1Z" },
- { url = "https://files.pythonhosted.org/packages/71/e6/5fd43993a87db364ec60fc1d608273a1a465c0caba69176dd160e197ce42/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f29d80eb9a9263b8d109135351caf568cc3f80b9928bccde535c235de55c22d9", size = 174207, upload-time = "2025-03-05T20:03:23.221Z" },
- { url = "https://files.pythonhosted.org/packages/2b/fb/c492d6daa5ec067c2988ac80c61359ace5c4c674c532985ac5a123436cec/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b359ed09954d7c18bbc1680f380c7301f92c60bf924171629c5db97febb12f04", size = 174155, upload-time = "2025-03-05T20:03:25.321Z" },
- { url = "https://files.pythonhosted.org/packages/68/a1/dcb68430b1d00b698ae7a7e0194433bce4f07ded185f0ee5fb21e2a2e91e/websockets-15.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:cad21560da69f4ce7658ca2cb83138fb4cf695a2ba3e475e0559e05991aa8122", size = 176884, upload-time = "2025-03-05T20:03:27.934Z" },
- { url = "https://files.pythonhosted.org/packages/b7/48/4b67623bac4d79beb3a6bb27b803ba75c1bdedc06bd827e465803690a4b2/websockets-15.0.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7f493881579c90fc262d9cdbaa05a6b54b3811c2f300766748db79f098db9940", size = 173106, upload-time = "2025-03-05T20:03:29.404Z" },
- { url = "https://files.pythonhosted.org/packages/ed/f0/adb07514a49fe5728192764e04295be78859e4a537ab8fcc518a3dbb3281/websockets-15.0.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:47b099e1f4fbc95b701b6e85768e1fcdaf1630f3cbe4765fa216596f12310e2e", size = 173339, upload-time = "2025-03-05T20:03:30.755Z" },
- { url = "https://files.pythonhosted.org/packages/87/28/bd23c6344b18fb43df40d0700f6d3fffcd7cef14a6995b4f976978b52e62/websockets-15.0.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67f2b6de947f8c757db2db9c71527933ad0019737ec374a8a6be9a956786aaf9", size = 174597, upload-time = "2025-03-05T20:03:32.247Z" },
- { url = "https://files.pythonhosted.org/packages/6d/79/ca288495863d0f23a60f546f0905ae8f3ed467ad87f8b6aceb65f4c013e4/websockets-15.0.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d08eb4c2b7d6c41da6ca0600c077e93f5adcfd979cd777d747e9ee624556da4b", size = 174205, upload-time = "2025-03-05T20:03:33.731Z" },
- { url = "https://files.pythonhosted.org/packages/04/e4/120ff3180b0872b1fe6637f6f995bcb009fb5c87d597c1fc21456f50c848/websockets-15.0.1-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b826973a4a2ae47ba357e4e82fa44a463b8f168e1ca775ac64521442b19e87f", size = 174150, upload-time = "2025-03-05T20:03:35.757Z" },
- { url = "https://files.pythonhosted.org/packages/cb/c3/30e2f9c539b8da8b1d76f64012f3b19253271a63413b2d3adb94b143407f/websockets-15.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:21c1fa28a6a7e3cbdc171c694398b6df4744613ce9b36b1a498e816787e28123", size = 176877, upload-time = "2025-03-05T20:03:37.199Z" },
- { url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743, upload-time = "2025-03-05T20:03:39.41Z" },
-]
-
[[package]]
name = "yarl"
version = "1.22.0"
From d5da50918b753f6c76387a077a7b17dc1efd4f26 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 1 Sep 2026 23:01:46 +0000
Subject: [PATCH 18/18] release: 0.5.0
---
.release-please-manifest.json | 2 +-
CHANGELOG.md | 24 ++++++++++++++++++++++++
pyproject.toml | 2 +-
src/dedalus_sdk/_version.py | 2 +-
4 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index da59f99..2aca35a 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.4.0"
+ ".": "0.5.0"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f7ec47b..6df1404 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,29 @@
# Changelog
+## 0.5.0 (2026-09-01)
+
+Full Changelog: [v0.4.0...v0.5.0](https://github.com/dedalus-labs/dedalus-python/compare/v0.4.0...v0.5.0)
+
+### ⚠ BREAKING CHANGES
+
+* **api:** regenerate SDKs from the current public DCS contract
+
+### Features
+
+* **api:** regenerate SDKs from the current public DCS contract ([04208ef](https://github.com/dedalus-labs/dedalus-python/commit/04208ef05cb07426d68717abb57835e089b76205))
+* **stlc:** configurable CI runner and private-production-repo support in workflow templates ([6acb1d3](https://github.com/dedalus-labs/dedalus-python/commit/6acb1d303d2a07cf6c01f63005a4f98541c47f40))
+
+
+### Bug Fixes
+
+* **auth:** prioritize first auth header ([81f3c28](https://github.com/dedalus-labs/dedalus-python/commit/81f3c288b2ae2e97046344177500714e1e4ce6be))
+* **internal:** resolve build failures ([c10ce00](https://github.com/dedalus-labs/dedalus-python/commit/c10ce00180c146772ec9f390e3d058a1d9462082))
+
+
+### Chores
+
+* **internal:** allow the mock server port to be set with STAINLESS_MOCK_PORT ([aa8a0ee](https://github.com/dedalus-labs/dedalus-python/commit/aa8a0ee9f29ad6fa93a917baba1ab0ffaebb6959))
+
## 0.4.0 (2026-05-12)
Full Changelog: [v0.3.0...v0.4.0](https://github.com/dedalus-labs/dedalus-python/compare/v0.3.0...v0.4.0)
diff --git a/pyproject.toml b/pyproject.toml
index 16fdcbd..5e91b1b 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "dedalus-sdk"
-version = "0.4.0"
+version = "0.5.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 ff44f48..2e5e834 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.4.0" # x-release-please-version
+__version__ = "0.5.0" # x-release-please-version