drukbox-python-sdk 0.0.3__py3-none-any.whl → 0.0.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: drukbox-python-sdk
3
- Version: 0.0.3
3
+ Version: 0.0.4
4
4
  Summary: Async Python client for Drukbox.
5
5
  Requires-Python: >=3.11
6
6
  Requires-Dist: httpx>=0.28
@@ -65,6 +65,7 @@ Public exports live in `drukbox_sdk`:
65
65
 
66
66
  - `SandboxAPI`
67
67
  - `SandboxHost`
68
+ - `DoctorReport` and `DoctorCheck`
68
69
  - `SandboxAPIError` and typed subclasses for auth, not found, conflict,
69
70
  unavailable, and unclassified response errors
70
71
 
@@ -75,11 +76,18 @@ Supported host operations:
75
76
  - `attach`
76
77
  - `list_hosts`
77
78
  - `delete_host`
79
+ - `doctor`
78
80
  - `aclose`
79
81
 
80
82
  `create_host` supports the service's optional `image`, `env`, `expires_at`,
81
83
  and `Idempotency-Key` inputs.
82
84
 
85
+ `doctor` fetches `GET /doctor` — read-only dependency health. The service
86
+ runs one cheap, non-mutating probe per dependency (database, active VM
87
+ provider, Tailscale when enabled) and always responds 200, so callers branch
88
+ on `DoctorReport.ok` rather than the HTTP status. A failed `DoctorCheck`
89
+ carries a stable `hint` slug for remediation.
90
+
83
91
  The SDK does not mint Tailscale auth keys, manage ACLs, establish SSH,
84
92
  provision Linux users, transfer files, or run remote commands.
85
93
 
@@ -0,0 +1,6 @@
1
+ drukbox_sdk/__init__.py,sha256=mYIclrOsTbsz9I-0J7eTizXg9s95dGker9SQppmVmrI,732
2
+ drukbox_sdk/api.py,sha256=rZ1MI4zKMiqGNOtAzcPM10Y-Q7ZW3Ly_ZP9cgVqhcDc,13953
3
+ drukbox_sdk/exceptions.py,sha256=eGtoDqmyt5vF0f4AJ4XmOatEe1vVl9KDOfI2YygdA2k,1811
4
+ drukbox_python_sdk-0.0.4.dist-info/METADATA,sha256=aAGDQPkXP6ktJ_yKYbOAaooAmDbqS0lq4fckWJqKgu8,3191
5
+ drukbox_python_sdk-0.0.4.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
6
+ drukbox_python_sdk-0.0.4.dist-info/RECORD,,
drukbox_sdk/__init__.py CHANGED
@@ -5,6 +5,8 @@ detail and may change without notice.
5
5
  """
6
6
 
7
7
  from .api import (
8
+ DoctorCheck,
9
+ DoctorReport,
8
10
  SandboxAPI,
9
11
  SandboxHost,
10
12
  )
@@ -19,6 +21,8 @@ from .exceptions import (
19
21
  )
20
22
 
21
23
  __all__ = [
24
+ "DoctorCheck",
25
+ "DoctorReport",
22
26
  "SandboxAPI",
23
27
  "SandboxAPIError",
24
28
  "SandboxAuthError",
drukbox_sdk/api.py CHANGED
@@ -112,6 +112,46 @@ def _parse_sandbox_host(data: dict[str, Any]) -> SandboxHost:
112
112
  return SandboxHost(**{key: data[key] for key in _SANDBOX_HOST_FIELDS})
113
113
 
114
114
 
115
+ @dataclass(frozen=True)
116
+ class DoctorCheck:
117
+ """One dependency probe. ``hint`` is a remediation slug, set only on failures."""
118
+
119
+ name: str
120
+ status: str
121
+ detail: str | None
122
+ latency_ms: int | None
123
+ hint: str | None
124
+
125
+
126
+ @dataclass(frozen=True)
127
+ class DoctorReport:
128
+ """Health snapshot. The HTTP status is always 200 — branch on ``ok``."""
129
+
130
+ ok: bool
131
+ active_provider: str
132
+ tailscale_enabled: bool
133
+ checks: list[DoctorCheck]
134
+
135
+
136
+ def _parse_doctor_check(data: dict[str, Any]) -> DoctorCheck:
137
+ return DoctorCheck(
138
+ name=data["name"],
139
+ status=data["status"],
140
+ detail=data["detail"],
141
+ latency_ms=data["latency_ms"],
142
+ hint=data["hint"],
143
+ )
144
+
145
+
146
+ def _parse_doctor_report(data: dict[str, Any]) -> DoctorReport:
147
+ return DoctorReport(
148
+ ok=data["ok"],
149
+ active_provider=data["active_provider"],
150
+ tailscale_enabled=data["tailscale_enabled"],
151
+ checks=[_parse_doctor_check(check) for check in data["checks"]],
152
+ )
153
+
154
+
115
155
  class SandboxAPI:
116
156
  """Async client for Drukbox.
117
157
 
@@ -231,6 +271,17 @@ class SandboxAPI:
231
271
  async def delete_host(self, host_id: uuid.UUID | str) -> None:
232
272
  await self._request("DELETE", f"/hosts/{host_id}")
233
273
 
274
+ async def doctor(self) -> DoctorReport:
275
+ """Fetch ``GET /doctor`` — read-only dependency health.
276
+
277
+ Always responds 200; inspect :attr:`DoctorReport.ok`, not the HTTP
278
+ status. Auth failures raise :class:`SandboxAuthError`.
279
+ """
280
+
281
+ data = await self._request("GET", "/doctor")
282
+ assert isinstance(data, dict)
283
+ return _parse_doctor_report(data)
284
+
234
285
  async def aclose(self) -> None:
235
286
  if self._client is None:
236
287
  return
@@ -1,6 +0,0 @@
1
- drukbox_sdk/__init__.py,sha256=KJmc7_s4WLMBbD_IlMoILfGvfFNcaR8cu7TbPeKHDs4,658
2
- drukbox_sdk/api.py,sha256=s4aHpSKq8xgS3xM37XpyaykSvfgfMLzwI95CgmieAG0,12558
3
- drukbox_sdk/exceptions.py,sha256=eGtoDqmyt5vF0f4AJ4XmOatEe1vVl9KDOfI2YygdA2k,1811
4
- drukbox_python_sdk-0.0.3.dist-info/METADATA,sha256=BoCz8UDnDrlA7QobAxSoCTegk2nGEodYDIv87OVRGF4,2801
5
- drukbox_python_sdk-0.0.3.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
6
- drukbox_python_sdk-0.0.3.dist-info/RECORD,,