code-sandboxes 1.4.4__tar.gz
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.
- code_sandboxes-1.4.4/.github/workflows/build.yml +24 -0
- code_sandboxes-1.4.4/.github/workflows/py-code-style.yml +44 -0
- code_sandboxes-1.4.4/.github/workflows/py-tests.yml +43 -0
- code_sandboxes-1.4.4/.github/workflows/py-typing.yml +44 -0
- code_sandboxes-1.4.4/.github/workflows/reusable-python.yml +100 -0
- code_sandboxes-1.4.4/.gitignore +129 -0
- code_sandboxes-1.4.4/.licenserc.yaml +18 -0
- code_sandboxes-1.4.4/.pre-commit-config.yaml +38 -0
- code_sandboxes-1.4.4/.vscode/settings.json +9 -0
- code_sandboxes-1.4.4/CHANGELOG.md +223 -0
- code_sandboxes-1.4.4/Dockerfile +19 -0
- code_sandboxes-1.4.4/LICENSE +29 -0
- code_sandboxes-1.4.4/Makefile +83 -0
- code_sandboxes-1.4.4/PKG-INFO +372 -0
- code_sandboxes-1.4.4/README.md +276 -0
- code_sandboxes-1.4.4/code_sandboxes/__init__.py +309 -0
- code_sandboxes-1.4.4/code_sandboxes/__version__.py +6 -0
- code_sandboxes-1.4.4/code_sandboxes/base.py +1143 -0
- code_sandboxes-1.4.4/code_sandboxes/bridge_mount.py +1071 -0
- code_sandboxes-1.4.4/code_sandboxes/builds.py +348 -0
- code_sandboxes-1.4.4/code_sandboxes/cli.py +677 -0
- code_sandboxes-1.4.4/code_sandboxes/client.py +718 -0
- code_sandboxes-1.4.4/code_sandboxes/cloudflare_sandbox.py +660 -0
- code_sandboxes-1.4.4/code_sandboxes/commands.py +475 -0
- code_sandboxes-1.4.4/code_sandboxes/console.py +355 -0
- code_sandboxes-1.4.4/code_sandboxes/contents.py +1483 -0
- code_sandboxes-1.4.4/code_sandboxes/coreweave_sandbox.py +754 -0
- code_sandboxes-1.4.4/code_sandboxes/datalayer_sandbox.py +1112 -0
- code_sandboxes-1.4.4/code_sandboxes/daytona_sandbox.py +877 -0
- code_sandboxes-1.4.4/code_sandboxes/docker_sandbox.py +334 -0
- code_sandboxes-1.4.4/code_sandboxes/e2b_sandbox.py +663 -0
- code_sandboxes-1.4.4/code_sandboxes/eval_sandbox.py +525 -0
- code_sandboxes-1.4.4/code_sandboxes/exceptions.py +118 -0
- code_sandboxes-1.4.4/code_sandboxes/filesystem.py +495 -0
- code_sandboxes-1.4.4/code_sandboxes/google_colab.py +208 -0
- code_sandboxes-1.4.4/code_sandboxes/google_colab_sandbox.py +271 -0
- code_sandboxes-1.4.4/code_sandboxes/interfaces.py +34 -0
- code_sandboxes-1.4.4/code_sandboxes/jupyter_ingress.py +74 -0
- code_sandboxes-1.4.4/code_sandboxes/jupyter_server_sandbox.py +813 -0
- code_sandboxes-1.4.4/code_sandboxes/kaggle.py +162 -0
- code_sandboxes-1.4.4/code_sandboxes/kaggle_execute.py +597 -0
- code_sandboxes-1.4.4/code_sandboxes/kaggle_live.py +474 -0
- code_sandboxes-1.4.4/code_sandboxes/kaggle_sandbox.py +818 -0
- code_sandboxes-1.4.4/code_sandboxes/lifecycle.py +208 -0
- code_sandboxes-1.4.4/code_sandboxes/manage.py +1148 -0
- code_sandboxes-1.4.4/code_sandboxes/modal_sandbox.py +628 -0
- code_sandboxes-1.4.4/code_sandboxes/models.py +700 -0
- code_sandboxes-1.4.4/code_sandboxes/monty_sandbox.py +235 -0
- code_sandboxes-1.4.4/code_sandboxes/provider_ingress.py +50 -0
- code_sandboxes-1.4.4/code_sandboxes/providers.py +436 -0
- code_sandboxes-1.4.4/docker/Dockerfile +20 -0
- code_sandboxes-1.4.4/docs/.gitignore +23 -0
- code_sandboxes-1.4.4/docs/LICENSE +21 -0
- code_sandboxes-1.4.4/docs/Makefile +65 -0
- code_sandboxes-1.4.4/docs/README.md +37 -0
- code_sandboxes-1.4.4/docs/babel.config.js +8 -0
- code_sandboxes-1.4.4/docs/docs/api-reference/_category_.yml +2 -0
- code_sandboxes-1.4.4/docs/docs/api-reference/index.mdx +923 -0
- code_sandboxes-1.4.4/docs/docs/cli/_category_.yml +2 -0
- code_sandboxes-1.4.4/docs/docs/cli/index.mdx +319 -0
- code_sandboxes-1.4.4/docs/docs/contribute/_category_.yml +2 -0
- code_sandboxes-1.4.4/docs/docs/contribute/index.mdx +106 -0
- code_sandboxes-1.4.4/docs/docs/examples/_category_.yml +2 -0
- code_sandboxes-1.4.4/docs/docs/examples/index.mdx +111 -0
- code_sandboxes-1.4.4/docs/docs/guide/_category_.yml +2 -0
- code_sandboxes-1.4.4/docs/docs/guide/index.mdx +218 -0
- code_sandboxes-1.4.4/docs/docs/index.mdx +158 -0
- code_sandboxes-1.4.4/docs/docs/install/_category_.yml +2 -0
- code_sandboxes-1.4.4/docs/docs/install/index.mdx +122 -0
- code_sandboxes-1.4.4/docs/docs/provider-ingress.mdx +91 -0
- code_sandboxes-1.4.4/docs/docs/providers/_category_.yml +2 -0
- code_sandboxes-1.4.4/docs/docs/providers/cloudflare.mdx +157 -0
- code_sandboxes-1.4.4/docs/docs/providers/coreweave.mdx +189 -0
- code_sandboxes-1.4.4/docs/docs/providers/datalayer.mdx +67 -0
- code_sandboxes-1.4.4/docs/docs/providers/daytona.mdx +228 -0
- code_sandboxes-1.4.4/docs/docs/providers/docker.mdx +39 -0
- code_sandboxes-1.4.4/docs/docs/providers/e2b.mdx +189 -0
- code_sandboxes-1.4.4/docs/docs/providers/eval.mdx +29 -0
- code_sandboxes-1.4.4/docs/docs/providers/google-colab.mdx +141 -0
- code_sandboxes-1.4.4/docs/docs/providers/index.mdx +323 -0
- code_sandboxes-1.4.4/docs/docs/providers/jupyter-server.mdx +56 -0
- code_sandboxes-1.4.4/docs/docs/providers/kaggle.mdx +258 -0
- code_sandboxes-1.4.4/docs/docs/providers/modal.mdx +73 -0
- code_sandboxes-1.4.4/docs/docs/providers/monty.mdx +48 -0
- code_sandboxes-1.4.4/docs/docusaurus.config.js +201 -0
- code_sandboxes-1.4.4/docs/package.json +50 -0
- code_sandboxes-1.4.4/docs/sidebars.js +36 -0
- code_sandboxes-1.4.4/docs/src/components/HomepageRow1.js +66 -0
- code_sandboxes-1.4.4/docs/src/components/HomepageRow1.module.css +18 -0
- code_sandboxes-1.4.4/docs/src/components/HomepageRow2.js +66 -0
- code_sandboxes-1.4.4/docs/src/components/HomepageRow2.module.css +18 -0
- code_sandboxes-1.4.4/docs/src/components/HomepageRow3.js +67 -0
- code_sandboxes-1.4.4/docs/src/components/HomepageRow3.module.css +18 -0
- code_sandboxes-1.4.4/docs/src/css/custom.css +189 -0
- code_sandboxes-1.4.4/docs/src/pages/index.module.css +39 -0
- code_sandboxes-1.4.4/docs/src/pages/markdown-page.md +7 -0
- code_sandboxes-1.4.4/docs/src/theme/CustomDocItem.tsx +22 -0
- code_sandboxes-1.4.4/docs/src/theme/IconsTitle.tsx +36 -0
- code_sandboxes-1.4.4/docs/static/img/bricks.svg +32 -0
- code_sandboxes-1.4.4/docs/static/img/building-construction.svg +22 -0
- code_sandboxes-1.4.4/docs/static/img/cloud-sun.svg +14 -0
- code_sandboxes-1.4.4/docs/static/img/cloud.svg +125 -0
- code_sandboxes-1.4.4/docs/static/img/collaboration.svg +1676 -0
- code_sandboxes-1.4.4/docs/static/img/copy-left.svg +9 -0
- code_sandboxes-1.4.4/docs/static/img/datalayer/logo.png +0 -0
- code_sandboxes-1.4.4/docs/static/img/datalayer/logo.svg +158 -0
- code_sandboxes-1.4.4/docs/static/img/datalayer/personas/business.svg +527 -0
- code_sandboxes-1.4.4/docs/static/img/datalayer/personas/data-scientist.svg +486 -0
- code_sandboxes-1.4.4/docs/static/img/datalayer/personas/devops.svg +463 -0
- code_sandboxes-1.4.4/docs/static/img/datalayer/project/project-line.svg +564 -0
- code_sandboxes-1.4.4/docs/static/img/favicon.ico +0 -0
- code_sandboxes-1.4.4/docs/static/img/jupyter.svg +260 -0
- code_sandboxes-1.4.4/docs/static/img/open-source.svg +1 -0
- code_sandboxes-1.4.4/docs/static/img/react-js.svg +4 -0
- code_sandboxes-1.4.4/docs/static/img/react-js2.svg +46 -0
- code_sandboxes-1.4.4/docs/static/img/ringed-planet.svg +13 -0
- code_sandboxes-1.4.4/docs/static/img/robot.svg +28 -0
- code_sandboxes-1.4.4/docs/static/img/rocket.svg +20 -0
- code_sandboxes-1.4.4/docs/static/img/shield.svg +14 -0
- code_sandboxes-1.4.4/docs/static/img/sparkles.svg +18 -0
- code_sandboxes-1.4.4/docs/static/img/streamlit.gif +0 -0
- code_sandboxes-1.4.4/docs/static/img/super-hero.svg +32 -0
- code_sandboxes-1.4.4/docs/static/img/target.svg +134 -0
- code_sandboxes-1.4.4/docs/static/img/thumbs-up.svg +17 -0
- code_sandboxes-1.4.4/examples/README.md +138 -0
- code_sandboxes-1.4.4/examples/exec/Makefile +92 -0
- code_sandboxes-1.4.4/examples/exec/cloudflare_sandbox_example.py +100 -0
- code_sandboxes-1.4.4/examples/exec/coreweave_sandbox_example.py +140 -0
- code_sandboxes-1.4.4/examples/exec/datalayer_sandbox_example.py +41 -0
- code_sandboxes-1.4.4/examples/exec/daytona_sandbox_example.py +166 -0
- code_sandboxes-1.4.4/examples/exec/docker_sandbox_example.py +39 -0
- code_sandboxes-1.4.4/examples/exec/e2b_sandbox_example.py +121 -0
- code_sandboxes-1.4.4/examples/exec/eval_sandbox_example.py +40 -0
- code_sandboxes-1.4.4/examples/exec/google_colab_sandbox_example.py +49 -0
- code_sandboxes-1.4.4/examples/exec/jupyter_server_sandbox_example.py +40 -0
- code_sandboxes-1.4.4/examples/exec/kaggle_sandbox_example.py +189 -0
- code_sandboxes-1.4.4/examples/exec/modal_sandbox_example.py +137 -0
- code_sandboxes-1.4.4/examples/exec/monty_sandbox_example.py +36 -0
- code_sandboxes-1.4.4/examples/repl/Makefile +97 -0
- code_sandboxes-1.4.4/examples/repl/cloudflare_sandbox_example.py +102 -0
- code_sandboxes-1.4.4/examples/repl/coreweave_sandbox_example.py +160 -0
- code_sandboxes-1.4.4/examples/repl/datalayer_sandbox_example.py +66 -0
- code_sandboxes-1.4.4/examples/repl/daytona_sandbox_example.py +192 -0
- code_sandboxes-1.4.4/examples/repl/docker_sandbox_example.py +69 -0
- code_sandboxes-1.4.4/examples/repl/e2b_sandbox_example.py +130 -0
- code_sandboxes-1.4.4/examples/repl/eval_sandbox_example.py +43 -0
- code_sandboxes-1.4.4/examples/repl/google_colab_sandbox_example.py +78 -0
- code_sandboxes-1.4.4/examples/repl/jupyter_server_sandbox_example.py +60 -0
- code_sandboxes-1.4.4/examples/repl/kaggle_sandbox_example.py +119 -0
- code_sandboxes-1.4.4/examples/repl/modal_sandbox_example.py +148 -0
- code_sandboxes-1.4.4/examples/repl/monty_sandbox_example.py +50 -0
- code_sandboxes-1.4.4/pyproject.toml +170 -0
- code_sandboxes-1.4.4/tests/__init__.py +5 -0
- code_sandboxes-1.4.4/tests/conftest.py +39 -0
- code_sandboxes-1.4.4/tests/test_a_datalayer_sandbox_can_be_interrupted.py +162 -0
- code_sandboxes-1.4.4/tests/test_bridge_mount.py +1028 -0
- code_sandboxes-1.4.4/tests/test_builds.py +365 -0
- code_sandboxes-1.4.4/tests/test_cli_exec.py +124 -0
- code_sandboxes-1.4.4/tests/test_cli_repl.py +187 -0
- code_sandboxes-1.4.4/tests/test_client.py +276 -0
- code_sandboxes-1.4.4/tests/test_client_contents.py +312 -0
- code_sandboxes-1.4.4/tests/test_client_files.py +127 -0
- code_sandboxes-1.4.4/tests/test_client_outcome_error_output.py +68 -0
- code_sandboxes-1.4.4/tests/test_cloudflare.py +471 -0
- code_sandboxes-1.4.4/tests/test_commands_envelope.py +92 -0
- code_sandboxes-1.4.4/tests/test_console.py +424 -0
- code_sandboxes-1.4.4/tests/test_contents_contract.py +1825 -0
- code_sandboxes-1.4.4/tests/test_contents_live_matrix.py +160 -0
- code_sandboxes-1.4.4/tests/test_coreweave.py +467 -0
- code_sandboxes-1.4.4/tests/test_datalayer_sandbox.py +439 -0
- code_sandboxes-1.4.4/tests/test_daytona.py +650 -0
- code_sandboxes-1.4.4/tests/test_e2b.py +398 -0
- code_sandboxes-1.4.4/tests/test_eval.py +515 -0
- code_sandboxes-1.4.4/tests/test_factory.py +184 -0
- code_sandboxes-1.4.4/tests/test_google_colab.py +125 -0
- code_sandboxes-1.4.4/tests/test_integration.py +144 -0
- code_sandboxes-1.4.4/tests/test_jupyter_ingress.py +97 -0
- code_sandboxes-1.4.4/tests/test_jupyter_server.py +355 -0
- code_sandboxes-1.4.4/tests/test_jupyter_server_streaming.py +117 -0
- code_sandboxes-1.4.4/tests/test_kaggle.py +127 -0
- code_sandboxes-1.4.4/tests/test_kaggle_execute.py +265 -0
- code_sandboxes-1.4.4/tests/test_kaggle_live.py +133 -0
- code_sandboxes-1.4.4/tests/test_kaggle_session.py +121 -0
- code_sandboxes-1.4.4/tests/test_kernel_client_compatibility.py +166 -0
- code_sandboxes-1.4.4/tests/test_lifecycle_vocabulary.py +204 -0
- code_sandboxes-1.4.4/tests/test_manage.py +261 -0
- code_sandboxes-1.4.4/tests/test_modal_google_colab_sandbox.py +493 -0
- code_sandboxes-1.4.4/tests/test_modal_session.py +60 -0
- code_sandboxes-1.4.4/tests/test_models.py +247 -0
- code_sandboxes-1.4.4/tests/test_output_line_fidelity.py +41 -0
- code_sandboxes-1.4.4/tests/test_provider_catalog_names.py +103 -0
- code_sandboxes-1.4.4/tests/test_provider_ingress.py +62 -0
- code_sandboxes-1.4.4/tests/test_providers.py +149 -0
- code_sandboxes-1.4.4/tests/test_sandboxes.py +883 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: Build
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main, develop ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ main, develop ]
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
python-build:
|
|
12
|
+
name: Python Build & Test (${{ matrix.python-version }})
|
|
13
|
+
strategy:
|
|
14
|
+
matrix:
|
|
15
|
+
python-version: ['3.11', '3.12']
|
|
16
|
+
uses: ./.github/workflows/reusable-python.yml
|
|
17
|
+
with:
|
|
18
|
+
python-version: ${{ matrix.python-version }}
|
|
19
|
+
install-extras: test,typing
|
|
20
|
+
extra-packages: dbus-python keyring secretstorage
|
|
21
|
+
run-tests: true
|
|
22
|
+
test-command: pytest tests/ --cov=code_sandboxes --cov-report term-missing
|
|
23
|
+
run-mypy: true
|
|
24
|
+
mypy-target: code_sandboxes
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
name: Py Code Style
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
- develop
|
|
8
|
+
paths:
|
|
9
|
+
- 'code_sandboxes/**/*.py'
|
|
10
|
+
- 'tests/**/*.py'
|
|
11
|
+
- 'pyproject.toml'
|
|
12
|
+
- 'setup.py'
|
|
13
|
+
- '.pre-commit-config.yaml'
|
|
14
|
+
- 'ruff.toml'
|
|
15
|
+
- '.ruff.toml'
|
|
16
|
+
- '.github/workflows/py-code-style.yml'
|
|
17
|
+
- '.github/workflows/reusable-python.yml'
|
|
18
|
+
pull_request:
|
|
19
|
+
branches:
|
|
20
|
+
- main
|
|
21
|
+
- develop
|
|
22
|
+
paths:
|
|
23
|
+
- 'code_sandboxes/**/*.py'
|
|
24
|
+
- 'tests/**/*.py'
|
|
25
|
+
- 'pyproject.toml'
|
|
26
|
+
- 'setup.py'
|
|
27
|
+
- '.pre-commit-config.yaml'
|
|
28
|
+
- 'ruff.toml'
|
|
29
|
+
- '.ruff.toml'
|
|
30
|
+
- '.github/workflows/py-code-style.yml'
|
|
31
|
+
- '.github/workflows/reusable-python.yml'
|
|
32
|
+
workflow_dispatch:
|
|
33
|
+
|
|
34
|
+
concurrency:
|
|
35
|
+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
|
36
|
+
cancel-in-progress: true
|
|
37
|
+
|
|
38
|
+
jobs:
|
|
39
|
+
check-code-style:
|
|
40
|
+
uses: ./.github/workflows/reusable-python.yml
|
|
41
|
+
with:
|
|
42
|
+
python-version: '3.11'
|
|
43
|
+
extra-packages: pre-commit
|
|
44
|
+
run-pre-commit: true
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
name: Py Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
paths:
|
|
8
|
+
- 'code_sandboxes/**'
|
|
9
|
+
- 'tests/**'
|
|
10
|
+
- 'pyproject.toml'
|
|
11
|
+
- 'setup.py'
|
|
12
|
+
- 'requirements*.txt'
|
|
13
|
+
- '**/*.py'
|
|
14
|
+
- '.github/workflows/py-tests.yml'
|
|
15
|
+
- '.github/workflows/reusable-python.yml'
|
|
16
|
+
pull_request:
|
|
17
|
+
branches:
|
|
18
|
+
- main
|
|
19
|
+
paths:
|
|
20
|
+
- 'code_sandboxes/**'
|
|
21
|
+
- 'tests/**'
|
|
22
|
+
- 'pyproject.toml'
|
|
23
|
+
- 'setup.py'
|
|
24
|
+
- 'requirements*.txt'
|
|
25
|
+
- '**/*.py'
|
|
26
|
+
- '.github/workflows/py-tests.yml'
|
|
27
|
+
- '.github/workflows/reusable-python.yml'
|
|
28
|
+
|
|
29
|
+
workflow_dispatch:
|
|
30
|
+
|
|
31
|
+
jobs:
|
|
32
|
+
tests:
|
|
33
|
+
strategy:
|
|
34
|
+
max-parallel: 1
|
|
35
|
+
matrix:
|
|
36
|
+
python-version: ['3.10', '3.11', '3.12', '3.13']
|
|
37
|
+
uses: ./.github/workflows/reusable-python.yml
|
|
38
|
+
with:
|
|
39
|
+
python-version: ${{ matrix.python-version }}
|
|
40
|
+
install-extras: test
|
|
41
|
+
extra-packages: dbus-python keyring secretstorage
|
|
42
|
+
run-tests: true
|
|
43
|
+
test-command: pytest tests/ --cov=code_sandboxes --cov-report term-missing
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
name: Py Type Checking
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
- develop
|
|
8
|
+
paths:
|
|
9
|
+
- 'code_sandboxes/**/*.py'
|
|
10
|
+
- 'tests/**/*.py'
|
|
11
|
+
- 'pyproject.toml'
|
|
12
|
+
- 'setup.py'
|
|
13
|
+
- 'mypy.ini'
|
|
14
|
+
- '.mypy.ini'
|
|
15
|
+
- '.github/workflows/py-typing.yml'
|
|
16
|
+
- '.github/workflows/reusable-python.yml'
|
|
17
|
+
pull_request:
|
|
18
|
+
branches:
|
|
19
|
+
- main
|
|
20
|
+
- develop
|
|
21
|
+
paths:
|
|
22
|
+
- 'code_sandboxes/**/*.py'
|
|
23
|
+
- 'tests/**/*.py'
|
|
24
|
+
- 'pyproject.toml'
|
|
25
|
+
- 'setup.py'
|
|
26
|
+
- 'mypy.ini'
|
|
27
|
+
- '.mypy.ini'
|
|
28
|
+
- '.github/workflows/py-typing.yml'
|
|
29
|
+
- '.github/workflows/reusable-python.yml'
|
|
30
|
+
workflow_dispatch:
|
|
31
|
+
|
|
32
|
+
concurrency:
|
|
33
|
+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
|
34
|
+
cancel-in-progress: true
|
|
35
|
+
|
|
36
|
+
jobs:
|
|
37
|
+
type-check:
|
|
38
|
+
uses: ./.github/workflows/reusable-python.yml
|
|
39
|
+
with:
|
|
40
|
+
python-version: '3.12'
|
|
41
|
+
install-extras: typing
|
|
42
|
+
extra-packages: types-requests
|
|
43
|
+
run-mypy: true
|
|
44
|
+
mypy-target: code_sandboxes
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
name: Reusable Python Workflow
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_call:
|
|
5
|
+
inputs:
|
|
6
|
+
python-version:
|
|
7
|
+
description: Python version to use
|
|
8
|
+
required: false
|
|
9
|
+
type: string
|
|
10
|
+
default: '3.11'
|
|
11
|
+
install-system-deps:
|
|
12
|
+
description: Install Linux system dependencies and unlock keyring
|
|
13
|
+
required: false
|
|
14
|
+
type: boolean
|
|
15
|
+
default: true
|
|
16
|
+
install-extras:
|
|
17
|
+
description: Optional extras to install from pyproject (for example test,typing)
|
|
18
|
+
required: false
|
|
19
|
+
type: string
|
|
20
|
+
default: ''
|
|
21
|
+
extra-packages:
|
|
22
|
+
description: Optional extra packages to install with uv pip
|
|
23
|
+
required: false
|
|
24
|
+
type: string
|
|
25
|
+
default: ''
|
|
26
|
+
run-tests:
|
|
27
|
+
description: Run tests
|
|
28
|
+
required: false
|
|
29
|
+
type: boolean
|
|
30
|
+
default: false
|
|
31
|
+
test-command:
|
|
32
|
+
description: Test command to run when run-tests=true
|
|
33
|
+
required: false
|
|
34
|
+
type: string
|
|
35
|
+
default: 'pytest -q'
|
|
36
|
+
run-mypy:
|
|
37
|
+
description: Run mypy
|
|
38
|
+
required: false
|
|
39
|
+
type: boolean
|
|
40
|
+
default: false
|
|
41
|
+
mypy-target:
|
|
42
|
+
description: Package/module path to type-check
|
|
43
|
+
required: false
|
|
44
|
+
type: string
|
|
45
|
+
default: ''
|
|
46
|
+
run-pre-commit:
|
|
47
|
+
description: Run pre-commit
|
|
48
|
+
required: false
|
|
49
|
+
type: boolean
|
|
50
|
+
default: false
|
|
51
|
+
|
|
52
|
+
jobs:
|
|
53
|
+
python-checks:
|
|
54
|
+
runs-on: ubuntu-latest
|
|
55
|
+
|
|
56
|
+
steps:
|
|
57
|
+
- name: Install system dependencies
|
|
58
|
+
if: inputs.install-system-deps
|
|
59
|
+
run: |
|
|
60
|
+
sudo apt-get update
|
|
61
|
+
sudo apt-get install -y libdbus-1-3 libdbus-1-dev libglib2.0-dev
|
|
62
|
+
|
|
63
|
+
- name: Checkout
|
|
64
|
+
uses: actions/checkout@v6
|
|
65
|
+
|
|
66
|
+
- name: Setup UV
|
|
67
|
+
uses: astral-sh/setup-uv@v7
|
|
68
|
+
with:
|
|
69
|
+
version: latest
|
|
70
|
+
python-version: ${{ inputs.python-version }}
|
|
71
|
+
activate-environment: true
|
|
72
|
+
|
|
73
|
+
- name: Install dependencies
|
|
74
|
+
run: |
|
|
75
|
+
uv pip install .
|
|
76
|
+
if [[ -n "${{ inputs.install-extras }}" ]]; then
|
|
77
|
+
uv pip install ".[${{ inputs.install-extras }}]"
|
|
78
|
+
fi
|
|
79
|
+
if [[ -n "${{ inputs.extra-packages }}" ]]; then
|
|
80
|
+
uv pip install ${{ inputs.extra-packages }}
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
- name: Unlock keyring
|
|
84
|
+
if: inputs.install-system-deps
|
|
85
|
+
uses: t1m0thyj/unlock-keyring@v1
|
|
86
|
+
|
|
87
|
+
- name: Configure git to use https
|
|
88
|
+
run: git config --global hub.protocol https
|
|
89
|
+
|
|
90
|
+
- name: Run tests
|
|
91
|
+
if: inputs.run-tests
|
|
92
|
+
run: ${{ inputs.test-command }}
|
|
93
|
+
|
|
94
|
+
- name: Run mypy
|
|
95
|
+
if: inputs.run-mypy
|
|
96
|
+
run: mypy ${{ inputs.mypy-target }}
|
|
97
|
+
|
|
98
|
+
- name: Run pre-commit
|
|
99
|
+
if: inputs.run-pre-commit
|
|
100
|
+
run: pre-commit run --all-files
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
*.egg-info/
|
|
2
|
+
.ipynb_checkpoints
|
|
3
|
+
|
|
4
|
+
# Created by https://www.gitignore.io/api/python
|
|
5
|
+
# Edit at https://www.gitignore.io/?templates=python
|
|
6
|
+
|
|
7
|
+
### Python ###
|
|
8
|
+
# Byte-compiled / optimized / DLL files
|
|
9
|
+
__pycache__/
|
|
10
|
+
*.py[cod]
|
|
11
|
+
*$py.class
|
|
12
|
+
|
|
13
|
+
# C extensions
|
|
14
|
+
*.so
|
|
15
|
+
|
|
16
|
+
# Distribution / packaging
|
|
17
|
+
.Python
|
|
18
|
+
build/
|
|
19
|
+
dist/
|
|
20
|
+
downloads/
|
|
21
|
+
lib/
|
|
22
|
+
lib64/
|
|
23
|
+
parts/
|
|
24
|
+
sdist/
|
|
25
|
+
var/
|
|
26
|
+
wheels/
|
|
27
|
+
pip-wheel-metadata/
|
|
28
|
+
share/python-wheels/
|
|
29
|
+
.installed.cfg
|
|
30
|
+
|
|
31
|
+
# PyInstaller
|
|
32
|
+
# Usually these files are written by a python script from a template
|
|
33
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
34
|
+
*.manifest
|
|
35
|
+
*.spec
|
|
36
|
+
|
|
37
|
+
# Installer logs
|
|
38
|
+
pip-log.txt
|
|
39
|
+
pip-delete-this-directory.txt
|
|
40
|
+
|
|
41
|
+
# Unit test / coverage reports
|
|
42
|
+
htmlcov/
|
|
43
|
+
.tox/
|
|
44
|
+
.nox/
|
|
45
|
+
.coverage
|
|
46
|
+
.coverage.*
|
|
47
|
+
.cache
|
|
48
|
+
nosetests.xml
|
|
49
|
+
coverage.xml
|
|
50
|
+
*.cover
|
|
51
|
+
.hypothesis/
|
|
52
|
+
.pytest_cache/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Environment variables:
|
|
59
|
+
.env
|
|
60
|
+
|
|
61
|
+
# Scrapy stuff:
|
|
62
|
+
.scrapy
|
|
63
|
+
|
|
64
|
+
# Sphinx documentation
|
|
65
|
+
docs/_build/
|
|
66
|
+
|
|
67
|
+
# PyBuilder
|
|
68
|
+
target/
|
|
69
|
+
|
|
70
|
+
# pyenv
|
|
71
|
+
.python-version
|
|
72
|
+
|
|
73
|
+
# celery beat schedule file
|
|
74
|
+
celerybeat-schedule
|
|
75
|
+
|
|
76
|
+
# SageMath parsed files
|
|
77
|
+
*.sage.py
|
|
78
|
+
|
|
79
|
+
# Spyder project settings
|
|
80
|
+
.spyderproject
|
|
81
|
+
.spyproject
|
|
82
|
+
|
|
83
|
+
# Rope project settings
|
|
84
|
+
.ropeproject
|
|
85
|
+
|
|
86
|
+
# Mr Developer
|
|
87
|
+
.mr.developer.cfg
|
|
88
|
+
.project
|
|
89
|
+
.pydevproject
|
|
90
|
+
|
|
91
|
+
# mkdocs documentation
|
|
92
|
+
/site
|
|
93
|
+
|
|
94
|
+
# mypy
|
|
95
|
+
.mypy_cache/
|
|
96
|
+
.dmypy.json
|
|
97
|
+
dmypy.json
|
|
98
|
+
|
|
99
|
+
# ruff
|
|
100
|
+
.ruff_cache
|
|
101
|
+
|
|
102
|
+
# Pyre type checker
|
|
103
|
+
.pyre/
|
|
104
|
+
|
|
105
|
+
# End of https://www.gitignore.io/api/python
|
|
106
|
+
|
|
107
|
+
# OSX files
|
|
108
|
+
.DS_Store
|
|
109
|
+
|
|
110
|
+
# Include
|
|
111
|
+
!**/.*ignore
|
|
112
|
+
!**/.*rc
|
|
113
|
+
!**/.*rc.js
|
|
114
|
+
!**/.*rc.json
|
|
115
|
+
!**/.*rc.yml
|
|
116
|
+
!**/.*config
|
|
117
|
+
!*.*rc.json
|
|
118
|
+
!.github
|
|
119
|
+
!.devcontainer
|
|
120
|
+
|
|
121
|
+
untracked_notebooks/*
|
|
122
|
+
.jupyter_ystore
|
|
123
|
+
.jupyter_ystore.db
|
|
124
|
+
docs/.yarn/*
|
|
125
|
+
|
|
126
|
+
uv.lock
|
|
127
|
+
|
|
128
|
+
generated
|
|
129
|
+
skills
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
header:
|
|
2
|
+
license:
|
|
3
|
+
content: |
|
|
4
|
+
Copyright (c) 2025-2026 Datalayer, Inc.
|
|
5
|
+
|
|
6
|
+
BSD 3-Clause License
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
paths-ignore:
|
|
10
|
+
- '**/*.ipynb'
|
|
11
|
+
- '**/*.json'
|
|
12
|
+
- '**/*.yaml'
|
|
13
|
+
- '**/*.yml'
|
|
14
|
+
- '**/.*'
|
|
15
|
+
- 'docs/**/*'
|
|
16
|
+
- 'LICENSE'
|
|
17
|
+
|
|
18
|
+
comment: on-failure
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
ci:
|
|
2
|
+
autoupdate_schedule: monthly
|
|
3
|
+
|
|
4
|
+
repos:
|
|
5
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
6
|
+
rev: v5.0.0
|
|
7
|
+
hooks:
|
|
8
|
+
- id: end-of-file-fixer
|
|
9
|
+
- id: check-case-conflict
|
|
10
|
+
- id: check-executables-have-shebangs
|
|
11
|
+
- id: requirements-txt-fixer
|
|
12
|
+
- id: check-added-large-files
|
|
13
|
+
- id: check-case-conflict
|
|
14
|
+
- id: check-toml
|
|
15
|
+
- id: check-yaml
|
|
16
|
+
- id: debug-statements
|
|
17
|
+
- id: forbid-new-submodules
|
|
18
|
+
- id: check-builtin-literals
|
|
19
|
+
- id: trailing-whitespace
|
|
20
|
+
|
|
21
|
+
- repo: https://github.com/python-jsonschema/check-jsonschema
|
|
22
|
+
rev: 0.29.4
|
|
23
|
+
hooks:
|
|
24
|
+
- id: check-github-workflows
|
|
25
|
+
|
|
26
|
+
- repo: https://github.com/executablebooks/mdformat
|
|
27
|
+
rev: 0.7.19
|
|
28
|
+
hooks:
|
|
29
|
+
- id: mdformat
|
|
30
|
+
additional_dependencies:
|
|
31
|
+
[mdformat-gfm, mdformat-frontmatter, mdformat-footnote]
|
|
32
|
+
|
|
33
|
+
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
|
34
|
+
rev: v0.8.0
|
|
35
|
+
hooks:
|
|
36
|
+
- id: ruff
|
|
37
|
+
args: ["--fix"]
|
|
38
|
+
- id: ruff-format
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
~ Copyright (c) 2025-2026 Datalayer, Inc.
|
|
3
|
+
~
|
|
4
|
+
~ BSD 3-Clause License
|
|
5
|
+
-->
|
|
6
|
+
|
|
7
|
+
# Changelog
|
|
8
|
+
|
|
9
|
+
## Unreleased
|
|
10
|
+
|
|
11
|
+
- `DatalayerSandbox` can be interrupted. It neither implemented `_do_interrupt`
|
|
12
|
+
nor read the flag the base class sets, so the default ran instead: it sets a
|
|
13
|
+
flag, returns `True`, and stops nothing. Everything above believed it —
|
|
14
|
+
`tasks/cancel` in the MCP gateway marks a task `cancelled` and calls the
|
|
15
|
+
interrupt `execute_cell` registered, which is this. Measured on prod1 on
|
|
16
|
+
2026-09-07: a two-minute cell cancelled ten seconds in answered `cancelled`
|
|
17
|
+
from both `tasks/cancel` and `tasks/get`, and the next `execute_code` on that
|
|
18
|
+
session took **60.8 seconds** and came back empty, where a free kernel answers
|
|
19
|
+
in about a second. The cell ran to completion on a runtime that went on being
|
|
20
|
+
billed. It now delegates to the runtime's own `sandbox_client` — the
|
|
21
|
+
jupyter-server client `run_code` already executes through, which interrupts
|
|
22
|
+
the kernel over the REST API — and answers whether the interrupt was
|
|
23
|
+
delivered, never raising: a cancel that cannot reach the kernel is a cancel
|
|
24
|
+
that failed, and the caller decides what that means.
|
|
25
|
+
|
|
26
|
+
`docker` and `monty` have the same hole and are pinned as known in
|
|
27
|
+
`tests/test_a_datalayer_sandbox_can_be_interrupted.py`, so the set cannot grow
|
|
28
|
+
quietly. (`google_colab` and `kaggle` are entitled to the default: they poll
|
|
29
|
+
`_interrupt_requested` and stop cooperatively.)
|
|
30
|
+
|
|
31
|
+
- `provider_catalog` takes a `names` argument, so a caller can describe the
|
|
32
|
+
providers it serves and pay for only those. Added under 1.3.1 without a
|
|
33
|
+
version bump, which is what broke the operator: its image installs this
|
|
34
|
+
package unpinned, PyPI's newest was 1.3.0, and the two-argument call landed
|
|
35
|
+
on a one-argument function — `TypeError: provider_catalog() takes from 0 to 1 positional arguments but 2 were given`, and `datalayer envs ls` answered 500.
|
|
36
|
+
A new public parameter is a feature; released as 1.4.0 so a dependant can ask
|
|
37
|
+
for it.
|
|
38
|
+
|
|
39
|
+
- `CodeExecutionOutcome` now carries `outputs`: the rich results as Jupyter
|
|
40
|
+
outputs, with their mime bundles intact. It called itself a faithful superset
|
|
41
|
+
of the raw `ExecutionResult` and was not — every representation but
|
|
42
|
+
`text/plain` was dropped on the way through, so a matplotlib figure reached
|
|
43
|
+
its callers as the string `<Figure size 640x480 with 1 Axes>` and anything
|
|
44
|
+
wanting to draw it had nothing to draw. `results` is unchanged, for callers
|
|
45
|
+
that only print.
|
|
46
|
+
|
|
47
|
+
- Exported the lifecycle vocabulary from the package root, so a consumer writes
|
|
48
|
+
`from code_sandboxes import SandboxLifecycle` rather than reaching into
|
|
49
|
+
`code_sandboxes.lifecycle` — the import path is the part that cannot be
|
|
50
|
+
changed afterwards, which is why it moved before anything depended on it.
|
|
51
|
+
|
|
52
|
+
The vocabulary gained `update` (the Runtimes API's `PUT`) and split in two.
|
|
53
|
+
`SandboxLifecycle` is one sandbox — `start`, `stop`, `pause`, `resume`,
|
|
54
|
+
`snapshot`, `run_code`; `SandboxManagerLifecycle` is whoever hands them out —
|
|
55
|
+
`create`, `list`, `get`, `update`. They were one protocol that quietly
|
|
56
|
+
disagreed with `LIFECYCLE_OPERATIONS`, because `Sandbox.create` is a
|
|
57
|
+
classmethod and a client's `create` is not; `INSTANCE_OPERATIONS` and
|
|
58
|
+
`MANAGER_OPERATIONS` now say which verb belongs to which shape, and a test
|
|
59
|
+
holds them to covering every verb exactly once.
|
|
60
|
+
|
|
61
|
+
It also gained the URL builders — `runtimes_url`, `runtime_url`,
|
|
62
|
+
`runtime_pause_url`, `runtime_resume_url`, `sandbox_snapshots_url`,
|
|
63
|
+
`sandbox_snapshot_url`, `runtime_checkpoints_url` — so every Python caller of
|
|
64
|
+
the Runtimes API builds a path from one place instead of its own f-string.
|
|
65
|
+
`snapshot` is recorded against `POST /sandbox-snapshots`, which is the route
|
|
66
|
+
that exists; it had been documented as a sub-path of the runtime, which was
|
|
67
|
+
not.
|
|
68
|
+
|
|
69
|
+
- Numbered the prompt's examples, and made one runnable by its number:
|
|
70
|
+
`:examples` lists them `1.`, `2.`, … and `:examples:2` prints the second and
|
|
71
|
+
then executes it, for a reader who wants the answer rather than the paste.
|
|
72
|
+
They are now declared where the sandbox is made —
|
|
73
|
+
`Sandbox.create(..., examples=[...])`, carried on `SandboxConfig` — so
|
|
74
|
+
`run_repl(sandbox)` finds them without being told twice; passing them to
|
|
75
|
+
`run_repl` still overrides for one prompt. Snippets are printed with Rich's
|
|
76
|
+
markup off, since `[...]` was being read as a style tag and a snippet
|
|
77
|
+
holding `list[str]` printed as `list = []`, wrong exactly where someone was
|
|
78
|
+
about to copy it.
|
|
79
|
+
|
|
80
|
+
- Added `:examples` to the sandbox prompt. `run_repl(sandbox, examples=[...])`
|
|
81
|
+
takes title-and-code pairs and prints them on request, for a reader to copy
|
|
82
|
+
into the prompt; every REPL example under `examples/repl` ships its own, and
|
|
83
|
+
the ones that can take a GPU offer device discovery and a timed matmul
|
|
84
|
+
instead of their general set when `--gpu` was asked for. The snippets avoid
|
|
85
|
+
blocks on purpose: the prompt reads one line at a time, so a pasted `for` or
|
|
86
|
+
`def` would arrive without its body.
|
|
87
|
+
|
|
88
|
+
- Fixed a `daytona` GPU sandbox failing to be created at all unless it was
|
|
89
|
+
also asking for preemptible capacity. Daytona requires every GPU sandbox to
|
|
90
|
+
be ephemeral — *"GPU sandboxes must be ephemeral; set autoDeleteInterval to
|
|
91
|
+
0"* — and `auto_delete_interval=0` was being set only on the `spot=True`
|
|
92
|
+
path, so a plain `gpu="H100"` was refused by the API. It now follows the GPU
|
|
93
|
+
itself, which is what Daytona ties it to.
|
|
94
|
+
|
|
95
|
+
- Added three cloud variants: `e2b`, `coreweave` and `cloudflare`.
|
|
96
|
+
|
|
97
|
+
`e2b` runs in a Firecracker microVM through E2B's code interpreter SDK, so it
|
|
98
|
+
holds a Jupyter kernel per context — `x = 1` in one call is still there in
|
|
99
|
+
the next — and answers with rich display data: a figure comes back as an
|
|
100
|
+
image, an HTML repr as HTML. It needs `E2B_API_KEY` and
|
|
101
|
+
`pip install code-sandboxes[e2b]`. `set_timeout()` extends the life of a
|
|
102
|
+
running sandbox and `get_host(port)` gives the public host of a port inside.
|
|
103
|
+
|
|
104
|
+
`coreweave` runs a container on CoreWeave's GPU cloud. What the SDK offers is
|
|
105
|
+
`exec` — a process at a time — so a namespace is held here instead: one
|
|
106
|
+
`python -u -c` session is started with the sandbox and fed JSON lines on
|
|
107
|
+
stdin, the same arrangement the `modal` variant uses, and snippets share a
|
|
108
|
+
namespace as they do everywhere else. A session that cannot start, or that
|
|
109
|
+
goes away, drops back to a process per snippet rather than failing. It needs
|
|
110
|
+
`CWSANDBOX_API_KEY` and `pip install code-sandboxes[coreweave]`.
|
|
111
|
+
|
|
112
|
+
`cloudflare` runs a container on Cloudflare's edge. Cloudflare's own SDK is a
|
|
113
|
+
Workers binding written in TypeScript, which a Python process cannot hold, so
|
|
114
|
+
this variant drives the SANDBOX BRIDGE — the Worker Cloudflare publishes to
|
|
115
|
+
expose the SDK over HTTP. Deploy it once with
|
|
116
|
+
`npm create cloudflare -- sandbox-bridge --template=cloudflare/sandbox-sdk/bridge/worker`,
|
|
117
|
+
then set `CLOUDFLARE_SANDBOX_API_URL` and `CLOUDFLARE_SANDBOX_API_KEY`. The
|
|
118
|
+
bridge gives a started process nothing to write to, so each snippet runs in
|
|
119
|
+
one of its own and state does not carry between calls — put what shares state
|
|
120
|
+
in one snippet, or keep it in a file, which does persist. Its manager creates,
|
|
121
|
+
gets and deletes; it cannot list, because the bridge has no endpoint that
|
|
122
|
+
enumerates sandboxes, and says so rather than answering with an empty list.
|
|
123
|
+
|
|
124
|
+
- Hardened the three new variants against silently doing something other than
|
|
125
|
+
what was asked. `cloudflare` now carries `SandboxConfig.env_vars` into every
|
|
126
|
+
snippet — the bridge takes no environment when it creates a sandbox, so they
|
|
127
|
+
had been accepted and dropped — refuses a `network_policy` it cannot apply
|
|
128
|
+
rather than leaving a sandbox believed to be cut off connected, refuses
|
|
129
|
+
`get_variable` with the reason instead of answering the misleading "no such
|
|
130
|
+
variable", and serves `files.read`/`files.write` through the bridge's own
|
|
131
|
+
file endpoints so they need no session at all. `coreweave` refuses the
|
|
132
|
+
variable APIs when there is no session process — under `stateful=False`, or
|
|
133
|
+
after one was lost — rather than reporting a successful set that vanishes
|
|
134
|
+
with the process, and a snippet that runs past its timeout now has its
|
|
135
|
+
session STOPPED rather than left running and changing the namespace behind a
|
|
136
|
+
call that already returned.
|
|
137
|
+
|
|
138
|
+
- A GPU asked of a variant that has none is now REFUSED rather than dropped.
|
|
139
|
+
`--gpu` reaches `coreweave`, `datalayer`, `daytona`, `kaggle` and `modal`,
|
|
140
|
+
and `code-sandboxes exec -v e2b --gpu H100` says which variants can give one
|
|
141
|
+
instead of running on a CPU as though nothing had been asked — a sandbox that
|
|
142
|
+
looks as though it asked for an H100 and did not is one whose timings mean
|
|
143
|
+
nothing. `--gpu` was previously accepted and silently ignored for every other
|
|
144
|
+
variant.
|
|
145
|
+
|
|
146
|
+
- Corrected the module docstring of the `modal` variant, which still described
|
|
147
|
+
the process-per-snippet behaviour that the session process replaced: `modal`
|
|
148
|
+
keeps a namespace between snippets, and falls back to a process per snippet
|
|
149
|
+
only when the session cannot be held.
|
|
150
|
+
|
|
151
|
+
- Added GPU support to the `daytona` variant. `gpu=` takes Daytona's own
|
|
152
|
+
flavors, `gpu_count=` how many, and several names comma-separated are an
|
|
153
|
+
ordered list of preferences Daytona falls back along — `gpu="H100,H200"`
|
|
154
|
+
takes an H200 when no H100 is free. `spot=True` runs on preemptible
|
|
155
|
+
capacity, which is far cheaper and outside the GPU quota; it is GPU-only and
|
|
156
|
+
built from an image with `auto_delete_interval=0`, both checked before the
|
|
157
|
+
request rather than left to come back as an API error.
|
|
158
|
+
`DaytonaSandbox.preempted_at()` answers when a spot sandbox was reclaimed,
|
|
159
|
+
and `run_code` asks on your behalf so that an eviction is not reported as a
|
|
160
|
+
dropped connection. `code-sandboxes exec/repl --spot` reaches it from the
|
|
161
|
+
CLI.
|
|
162
|
+
|
|
163
|
+
- Renamed the `google_colab` variant to `google-colab`, so every canonical
|
|
164
|
+
variant name is spelled the one way (`jupyter-server` already was). Any
|
|
165
|
+
spelling is still accepted everywhere a variant is named — `normalize_variant`
|
|
166
|
+
now folds to the canonical dashed form rather than to underscores, which is
|
|
167
|
+
what a dispatcher compares against, so the two can no longer drift apart.
|
|
168
|
+
|
|
169
|
+
- Added `code-sandboxes exec`, which runs one snippet in a fresh sandbox of any
|
|
170
|
+
variant and exits with the status the code earned — `0` when it ran cleanly,
|
|
171
|
+
`1` when it raised — so it composes in a shell. The code comes from an
|
|
172
|
+
argument, from `--file`, or from standard input; `--quiet` prints only what
|
|
173
|
+
the code produced. `exec` and `repl` take the same options.
|
|
174
|
+
|
|
175
|
+
- Moved the machinery for showing a run — `show_code`, `show_result`,
|
|
176
|
+
`show_and_run`, `run_repl`, `repl_prompt` — into `code_sandboxes.console`,
|
|
177
|
+
exported from the package. It existed three times over: in the CLI, in the
|
|
178
|
+
REPL examples and in the exec examples, disagreeing about whether the value
|
|
179
|
+
of a trailing expression is shown, whether stderr is told apart from stdout,
|
|
180
|
+
and which words end a session. The examples now import it like any other
|
|
181
|
+
consumer, and `examples/*/[exec|repl]_common.py` are gone.
|
|
182
|
+
|
|
183
|
+
- Added the `daytona` sandbox variant (`DaytonaSandbox`), running code in a
|
|
184
|
+
[Daytona](https://www.daytona.io/docs/) cloud sandbox. It drives the
|
|
185
|
+
sandbox's code interpreter rather than `process.code_run`, so state persists
|
|
186
|
+
between calls and `create_context()` gives a namespace Daytona keeps apart.
|
|
187
|
+
The value of a trailing expression is captured and returned as
|
|
188
|
+
`ExecutionResult.text`, which the interpreter itself does not report. GPUs,
|
|
189
|
+
cpu/memory and the network policy map onto Daytona's own settings; binary
|
|
190
|
+
files go through its filesystem API. Authenticate with `DAYTONA_API_KEY` (or
|
|
191
|
+
`DAYTONA_JWT_TOKEN` with `DAYTONA_ORGANIZATION_ID`) and install with
|
|
192
|
+
`pip install code-sandboxes[daytona]`. `get_manager("daytona")` answers the
|
|
193
|
+
CRUD verbs over an organization's sandboxes.
|
|
194
|
+
|
|
195
|
+
- Added the `kaggle` sandbox variant (`KaggleSandbox`) to connect to a Kaggle
|
|
196
|
+
interactive notebook runtime via `jupyter-kernel-client`'s
|
|
197
|
+
`KaggleKernelClient`. Authenticate with a Kaggle API token (`token` argument or
|
|
198
|
+
the `KAGGLE_API_TOKEN` environment variable) — omitting `kernel_id` then creates
|
|
199
|
+
a new kernel. Alternatively, connect to an existing session with a
|
|
200
|
+
`server_url`/`kernel_id` or a notebook session `channels_url` (the signed JWT in
|
|
201
|
+
the proxied URL provides the authentication). Install with
|
|
202
|
+
`pip install code-sandboxes[kaggle]`.
|
|
203
|
+
|
|
204
|
+
- Enhanced `KaggleSandbox` with a transparent batch primitive: when no runtime
|
|
205
|
+
connection details are provided, it automatically executes code through
|
|
206
|
+
`KaggleKernelExecutor` (submit/poll/download) so integrations like
|
|
207
|
+
`jupyter-mcp-server` can run on Kaggle without requiring interactive runtime
|
|
208
|
+
wiring.
|
|
209
|
+
|
|
210
|
+
- Added Kaggle accelerator forwarding in batch mode: `Sandbox.create(variant="kaggle", gpu=...)`
|
|
211
|
+
now passes the value to `KaggleKernelExecutor.execute(accelerator=...)`,
|
|
212
|
+
supporting both Kaggle API values (`NvidiaTeslaT4`, ...) and friendly aliases
|
|
213
|
+
(`T4`, `P100`, ...).
|
|
214
|
+
|
|
215
|
+
- Updated `ColabSandbox` to be reuse-only for existing Colab runtimes and added
|
|
216
|
+
`channels_url` parsing support for extracting `server_url` / `kernel_id` /
|
|
217
|
+
`proxy_token` directly from the Colab WebSocket channels URL.
|
|
218
|
+
|
|
219
|
+
- Breaking change: sandbox variant names are `eval`, `docker`, `jupyter`, and `datalayer`.
|
|
220
|
+
|
|
221
|
+
- Removed support for the older `local-*` variant names from the public API and documentation.
|
|
222
|
+
|
|
223
|
+
- Clarified in the documentation that `Sandbox.create()` defaults to `datalayer`.
|