Metadata-Version: 2.5
Name: daytona
Version: 2.0.0rc1
Summary: Daytona V2 Python SDK.
Project-URL: Homepage, https://github.com/daytona/rlp
Project-URL: Repository, https://github.com/daytona/rlp
Project-URL: Issues, https://github.com/daytona/rlp/issues
Author-email: Vedran Jukic <vedran.jukic@gmail.com>
License: Apache-2.0
Keywords: agents,daytona,sandbox,sdk
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: httpx>=0.24
Provides-Extra: dev
Requires-Dist: mypy>=1.8; extra == 'dev'
Requires-Dist: pytest-cov>=5; extra == 'dev'
Requires-Dist: pytest>=7; extra == 'dev'
Requires-Dist: respx>=0.20; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Description-Content-Type: text/markdown

# Daytona Python SDK

The Daytona interface is defined in [`../../internal-docs/PLAN-SDK-V2.md`](../../internal-docs/PLAN-SDK-V2.md). The
import module and package name are `daytona`.

```python
from daytona import Daytona, DaytonaConfig

daytona = Daytona(DaytonaConfig(
    api_url="https://api.example",
    api_key="dtn_...",  # mint a project API key from the dashboard
    toolbox_url="https://toolbox.example/toolbox",
))

sandbox = daytona.create(image="python:3.12", cpu=1.0, memory=1)
result = sandbox.process.run("python -V")
print(result.exit_code, result.output)
daytona.delete(sandbox)
```

## Surface

- `Daytona` client.
- Sandbox lifecycle: `create`, lazy `sandbox(id)`, `get`, `list`, `start`,
  `pause`, `resume`, `fork`, `delete`.
- Platform namespaces: `images`, `snapshots`, `volumes`, `object_stores`,
  `secrets`, `functions`.
- Sandbox namespaces: `process`, `fs`, `git`, `interpreter`, `pty`, `ports`,
  `lsp`, `computer_use`.
- Process V2: detached `start()`, awaited `run()`, serializable
  `ProcessHandle(sandbox_id, process_id)`, `logs()`, `stream_logs()`, `wait()`,
  `stdin()`, `stdin_eof()`, signal-aware `kill()`, `resize()`, and optional
  `attach()`.
- Filesystem conventions: `read_text`, `write_text`, `read_bytes`,
  `write_bytes`, `read_many`, `write_many`, `watch_dir`,
  `presigned_download_url`, `presigned_upload_url`, and sandbox-level
  `rotate_signing_key()`; list-like APIs return `{items, next_cursor}`
  objects, watch handles drain queued SSE events via `get_new_events()`, and
  `watch_dir(..., on_exit=...)` reports a single exit notification that
  callers can also observe through `wait_for_exit()` / `exit_error`. Pre-signed
  file URLs stay proxy-backed: linux uses `/vms/:id/signing-key`, GPU uses
  `/gpu/vms/:id/signing-key`, windows raises `UNSUPPORTED_OPERATION` because it
  has no toolbox, and a direct daemon `toolbox_url` override is rejected here
  because only the proxy can verify and strip `signature` / `expires` before
  forwarding to the daemon.
- Typed errors: status-level base classes and daemon code-specific subclasses;
  every SDK error exposes `code` and `source`.

The `ports` namespace surfaces in-guest listener discovery (`list()`,
`is_in_use(port)`). `lsp` exposes daemon-managed language-server lifecycle,
document/workspace symbol lookup, and completions. `computer_use` targets the
lazy addon routes for screenshots, mouse/keyboard control, display/window
metadata, accessibility inspection/actions, and recording download.

The interpreter namespace runs code through the V2 wire shape
`POST /processes {kind:"code", code, language, sessionId?}` — Jupyter kernels
behind the daemon's kernel seam (python via ipykernel, TS/JS via deno).
`timeout_ms` is client-side: code executions carry no server deadline, so on
expiry the SDK interrupts the kernel (^C semantics) and returns the
interrupted result. Environments that cannot provision a kernel raise
`KernelUnavailableError`; the live test skips there.

Git `clone()`, `pull()`, and `push()` use a 30-minute client deadline by
default so long-running repo operations can finish without falling back to an
unbounded read timeout. Pass `timeout=` (seconds) to override it per call.

## Local verification

```bash
nix develop .#python --command bash -c \
  "cd clients/python && \
   uv venv && uv pip install -e '.[dev]' && .venv/bin/python -m pytest -x -q"
```

The live e2e now picks ephemeral toolbox/control ports by default (override
with `RLP_SDKPY_TOOLBOX_PORT` / `RLP_SDKPY_CONTROL_PORT`) and waits for a real
`GET /version` 200 before running. It still must launch the daemon with a
system PATH (a dev-shell PATH would build the kernel venv on nix python, whose
manylinux-wheel story is broken).
