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.
Files changed (194) hide show
  1. code_sandboxes-1.4.4/.github/workflows/build.yml +24 -0
  2. code_sandboxes-1.4.4/.github/workflows/py-code-style.yml +44 -0
  3. code_sandboxes-1.4.4/.github/workflows/py-tests.yml +43 -0
  4. code_sandboxes-1.4.4/.github/workflows/py-typing.yml +44 -0
  5. code_sandboxes-1.4.4/.github/workflows/reusable-python.yml +100 -0
  6. code_sandboxes-1.4.4/.gitignore +129 -0
  7. code_sandboxes-1.4.4/.licenserc.yaml +18 -0
  8. code_sandboxes-1.4.4/.pre-commit-config.yaml +38 -0
  9. code_sandboxes-1.4.4/.vscode/settings.json +9 -0
  10. code_sandboxes-1.4.4/CHANGELOG.md +223 -0
  11. code_sandboxes-1.4.4/Dockerfile +19 -0
  12. code_sandboxes-1.4.4/LICENSE +29 -0
  13. code_sandboxes-1.4.4/Makefile +83 -0
  14. code_sandboxes-1.4.4/PKG-INFO +372 -0
  15. code_sandboxes-1.4.4/README.md +276 -0
  16. code_sandboxes-1.4.4/code_sandboxes/__init__.py +309 -0
  17. code_sandboxes-1.4.4/code_sandboxes/__version__.py +6 -0
  18. code_sandboxes-1.4.4/code_sandboxes/base.py +1143 -0
  19. code_sandboxes-1.4.4/code_sandboxes/bridge_mount.py +1071 -0
  20. code_sandboxes-1.4.4/code_sandboxes/builds.py +348 -0
  21. code_sandboxes-1.4.4/code_sandboxes/cli.py +677 -0
  22. code_sandboxes-1.4.4/code_sandboxes/client.py +718 -0
  23. code_sandboxes-1.4.4/code_sandboxes/cloudflare_sandbox.py +660 -0
  24. code_sandboxes-1.4.4/code_sandboxes/commands.py +475 -0
  25. code_sandboxes-1.4.4/code_sandboxes/console.py +355 -0
  26. code_sandboxes-1.4.4/code_sandboxes/contents.py +1483 -0
  27. code_sandboxes-1.4.4/code_sandboxes/coreweave_sandbox.py +754 -0
  28. code_sandboxes-1.4.4/code_sandboxes/datalayer_sandbox.py +1112 -0
  29. code_sandboxes-1.4.4/code_sandboxes/daytona_sandbox.py +877 -0
  30. code_sandboxes-1.4.4/code_sandboxes/docker_sandbox.py +334 -0
  31. code_sandboxes-1.4.4/code_sandboxes/e2b_sandbox.py +663 -0
  32. code_sandboxes-1.4.4/code_sandboxes/eval_sandbox.py +525 -0
  33. code_sandboxes-1.4.4/code_sandboxes/exceptions.py +118 -0
  34. code_sandboxes-1.4.4/code_sandboxes/filesystem.py +495 -0
  35. code_sandboxes-1.4.4/code_sandboxes/google_colab.py +208 -0
  36. code_sandboxes-1.4.4/code_sandboxes/google_colab_sandbox.py +271 -0
  37. code_sandboxes-1.4.4/code_sandboxes/interfaces.py +34 -0
  38. code_sandboxes-1.4.4/code_sandboxes/jupyter_ingress.py +74 -0
  39. code_sandboxes-1.4.4/code_sandboxes/jupyter_server_sandbox.py +813 -0
  40. code_sandboxes-1.4.4/code_sandboxes/kaggle.py +162 -0
  41. code_sandboxes-1.4.4/code_sandboxes/kaggle_execute.py +597 -0
  42. code_sandboxes-1.4.4/code_sandboxes/kaggle_live.py +474 -0
  43. code_sandboxes-1.4.4/code_sandboxes/kaggle_sandbox.py +818 -0
  44. code_sandboxes-1.4.4/code_sandboxes/lifecycle.py +208 -0
  45. code_sandboxes-1.4.4/code_sandboxes/manage.py +1148 -0
  46. code_sandboxes-1.4.4/code_sandboxes/modal_sandbox.py +628 -0
  47. code_sandboxes-1.4.4/code_sandboxes/models.py +700 -0
  48. code_sandboxes-1.4.4/code_sandboxes/monty_sandbox.py +235 -0
  49. code_sandboxes-1.4.4/code_sandboxes/provider_ingress.py +50 -0
  50. code_sandboxes-1.4.4/code_sandboxes/providers.py +436 -0
  51. code_sandboxes-1.4.4/docker/Dockerfile +20 -0
  52. code_sandboxes-1.4.4/docs/.gitignore +23 -0
  53. code_sandboxes-1.4.4/docs/LICENSE +21 -0
  54. code_sandboxes-1.4.4/docs/Makefile +65 -0
  55. code_sandboxes-1.4.4/docs/README.md +37 -0
  56. code_sandboxes-1.4.4/docs/babel.config.js +8 -0
  57. code_sandboxes-1.4.4/docs/docs/api-reference/_category_.yml +2 -0
  58. code_sandboxes-1.4.4/docs/docs/api-reference/index.mdx +923 -0
  59. code_sandboxes-1.4.4/docs/docs/cli/_category_.yml +2 -0
  60. code_sandboxes-1.4.4/docs/docs/cli/index.mdx +319 -0
  61. code_sandboxes-1.4.4/docs/docs/contribute/_category_.yml +2 -0
  62. code_sandboxes-1.4.4/docs/docs/contribute/index.mdx +106 -0
  63. code_sandboxes-1.4.4/docs/docs/examples/_category_.yml +2 -0
  64. code_sandboxes-1.4.4/docs/docs/examples/index.mdx +111 -0
  65. code_sandboxes-1.4.4/docs/docs/guide/_category_.yml +2 -0
  66. code_sandboxes-1.4.4/docs/docs/guide/index.mdx +218 -0
  67. code_sandboxes-1.4.4/docs/docs/index.mdx +158 -0
  68. code_sandboxes-1.4.4/docs/docs/install/_category_.yml +2 -0
  69. code_sandboxes-1.4.4/docs/docs/install/index.mdx +122 -0
  70. code_sandboxes-1.4.4/docs/docs/provider-ingress.mdx +91 -0
  71. code_sandboxes-1.4.4/docs/docs/providers/_category_.yml +2 -0
  72. code_sandboxes-1.4.4/docs/docs/providers/cloudflare.mdx +157 -0
  73. code_sandboxes-1.4.4/docs/docs/providers/coreweave.mdx +189 -0
  74. code_sandboxes-1.4.4/docs/docs/providers/datalayer.mdx +67 -0
  75. code_sandboxes-1.4.4/docs/docs/providers/daytona.mdx +228 -0
  76. code_sandboxes-1.4.4/docs/docs/providers/docker.mdx +39 -0
  77. code_sandboxes-1.4.4/docs/docs/providers/e2b.mdx +189 -0
  78. code_sandboxes-1.4.4/docs/docs/providers/eval.mdx +29 -0
  79. code_sandboxes-1.4.4/docs/docs/providers/google-colab.mdx +141 -0
  80. code_sandboxes-1.4.4/docs/docs/providers/index.mdx +323 -0
  81. code_sandboxes-1.4.4/docs/docs/providers/jupyter-server.mdx +56 -0
  82. code_sandboxes-1.4.4/docs/docs/providers/kaggle.mdx +258 -0
  83. code_sandboxes-1.4.4/docs/docs/providers/modal.mdx +73 -0
  84. code_sandboxes-1.4.4/docs/docs/providers/monty.mdx +48 -0
  85. code_sandboxes-1.4.4/docs/docusaurus.config.js +201 -0
  86. code_sandboxes-1.4.4/docs/package.json +50 -0
  87. code_sandboxes-1.4.4/docs/sidebars.js +36 -0
  88. code_sandboxes-1.4.4/docs/src/components/HomepageRow1.js +66 -0
  89. code_sandboxes-1.4.4/docs/src/components/HomepageRow1.module.css +18 -0
  90. code_sandboxes-1.4.4/docs/src/components/HomepageRow2.js +66 -0
  91. code_sandboxes-1.4.4/docs/src/components/HomepageRow2.module.css +18 -0
  92. code_sandboxes-1.4.4/docs/src/components/HomepageRow3.js +67 -0
  93. code_sandboxes-1.4.4/docs/src/components/HomepageRow3.module.css +18 -0
  94. code_sandboxes-1.4.4/docs/src/css/custom.css +189 -0
  95. code_sandboxes-1.4.4/docs/src/pages/index.module.css +39 -0
  96. code_sandboxes-1.4.4/docs/src/pages/markdown-page.md +7 -0
  97. code_sandboxes-1.4.4/docs/src/theme/CustomDocItem.tsx +22 -0
  98. code_sandboxes-1.4.4/docs/src/theme/IconsTitle.tsx +36 -0
  99. code_sandboxes-1.4.4/docs/static/img/bricks.svg +32 -0
  100. code_sandboxes-1.4.4/docs/static/img/building-construction.svg +22 -0
  101. code_sandboxes-1.4.4/docs/static/img/cloud-sun.svg +14 -0
  102. code_sandboxes-1.4.4/docs/static/img/cloud.svg +125 -0
  103. code_sandboxes-1.4.4/docs/static/img/collaboration.svg +1676 -0
  104. code_sandboxes-1.4.4/docs/static/img/copy-left.svg +9 -0
  105. code_sandboxes-1.4.4/docs/static/img/datalayer/logo.png +0 -0
  106. code_sandboxes-1.4.4/docs/static/img/datalayer/logo.svg +158 -0
  107. code_sandboxes-1.4.4/docs/static/img/datalayer/personas/business.svg +527 -0
  108. code_sandboxes-1.4.4/docs/static/img/datalayer/personas/data-scientist.svg +486 -0
  109. code_sandboxes-1.4.4/docs/static/img/datalayer/personas/devops.svg +463 -0
  110. code_sandboxes-1.4.4/docs/static/img/datalayer/project/project-line.svg +564 -0
  111. code_sandboxes-1.4.4/docs/static/img/favicon.ico +0 -0
  112. code_sandboxes-1.4.4/docs/static/img/jupyter.svg +260 -0
  113. code_sandboxes-1.4.4/docs/static/img/open-source.svg +1 -0
  114. code_sandboxes-1.4.4/docs/static/img/react-js.svg +4 -0
  115. code_sandboxes-1.4.4/docs/static/img/react-js2.svg +46 -0
  116. code_sandboxes-1.4.4/docs/static/img/ringed-planet.svg +13 -0
  117. code_sandboxes-1.4.4/docs/static/img/robot.svg +28 -0
  118. code_sandboxes-1.4.4/docs/static/img/rocket.svg +20 -0
  119. code_sandboxes-1.4.4/docs/static/img/shield.svg +14 -0
  120. code_sandboxes-1.4.4/docs/static/img/sparkles.svg +18 -0
  121. code_sandboxes-1.4.4/docs/static/img/streamlit.gif +0 -0
  122. code_sandboxes-1.4.4/docs/static/img/super-hero.svg +32 -0
  123. code_sandboxes-1.4.4/docs/static/img/target.svg +134 -0
  124. code_sandboxes-1.4.4/docs/static/img/thumbs-up.svg +17 -0
  125. code_sandboxes-1.4.4/examples/README.md +138 -0
  126. code_sandboxes-1.4.4/examples/exec/Makefile +92 -0
  127. code_sandboxes-1.4.4/examples/exec/cloudflare_sandbox_example.py +100 -0
  128. code_sandboxes-1.4.4/examples/exec/coreweave_sandbox_example.py +140 -0
  129. code_sandboxes-1.4.4/examples/exec/datalayer_sandbox_example.py +41 -0
  130. code_sandboxes-1.4.4/examples/exec/daytona_sandbox_example.py +166 -0
  131. code_sandboxes-1.4.4/examples/exec/docker_sandbox_example.py +39 -0
  132. code_sandboxes-1.4.4/examples/exec/e2b_sandbox_example.py +121 -0
  133. code_sandboxes-1.4.4/examples/exec/eval_sandbox_example.py +40 -0
  134. code_sandboxes-1.4.4/examples/exec/google_colab_sandbox_example.py +49 -0
  135. code_sandboxes-1.4.4/examples/exec/jupyter_server_sandbox_example.py +40 -0
  136. code_sandboxes-1.4.4/examples/exec/kaggle_sandbox_example.py +189 -0
  137. code_sandboxes-1.4.4/examples/exec/modal_sandbox_example.py +137 -0
  138. code_sandboxes-1.4.4/examples/exec/monty_sandbox_example.py +36 -0
  139. code_sandboxes-1.4.4/examples/repl/Makefile +97 -0
  140. code_sandboxes-1.4.4/examples/repl/cloudflare_sandbox_example.py +102 -0
  141. code_sandboxes-1.4.4/examples/repl/coreweave_sandbox_example.py +160 -0
  142. code_sandboxes-1.4.4/examples/repl/datalayer_sandbox_example.py +66 -0
  143. code_sandboxes-1.4.4/examples/repl/daytona_sandbox_example.py +192 -0
  144. code_sandboxes-1.4.4/examples/repl/docker_sandbox_example.py +69 -0
  145. code_sandboxes-1.4.4/examples/repl/e2b_sandbox_example.py +130 -0
  146. code_sandboxes-1.4.4/examples/repl/eval_sandbox_example.py +43 -0
  147. code_sandboxes-1.4.4/examples/repl/google_colab_sandbox_example.py +78 -0
  148. code_sandboxes-1.4.4/examples/repl/jupyter_server_sandbox_example.py +60 -0
  149. code_sandboxes-1.4.4/examples/repl/kaggle_sandbox_example.py +119 -0
  150. code_sandboxes-1.4.4/examples/repl/modal_sandbox_example.py +148 -0
  151. code_sandboxes-1.4.4/examples/repl/monty_sandbox_example.py +50 -0
  152. code_sandboxes-1.4.4/pyproject.toml +170 -0
  153. code_sandboxes-1.4.4/tests/__init__.py +5 -0
  154. code_sandboxes-1.4.4/tests/conftest.py +39 -0
  155. code_sandboxes-1.4.4/tests/test_a_datalayer_sandbox_can_be_interrupted.py +162 -0
  156. code_sandboxes-1.4.4/tests/test_bridge_mount.py +1028 -0
  157. code_sandboxes-1.4.4/tests/test_builds.py +365 -0
  158. code_sandboxes-1.4.4/tests/test_cli_exec.py +124 -0
  159. code_sandboxes-1.4.4/tests/test_cli_repl.py +187 -0
  160. code_sandboxes-1.4.4/tests/test_client.py +276 -0
  161. code_sandboxes-1.4.4/tests/test_client_contents.py +312 -0
  162. code_sandboxes-1.4.4/tests/test_client_files.py +127 -0
  163. code_sandboxes-1.4.4/tests/test_client_outcome_error_output.py +68 -0
  164. code_sandboxes-1.4.4/tests/test_cloudflare.py +471 -0
  165. code_sandboxes-1.4.4/tests/test_commands_envelope.py +92 -0
  166. code_sandboxes-1.4.4/tests/test_console.py +424 -0
  167. code_sandboxes-1.4.4/tests/test_contents_contract.py +1825 -0
  168. code_sandboxes-1.4.4/tests/test_contents_live_matrix.py +160 -0
  169. code_sandboxes-1.4.4/tests/test_coreweave.py +467 -0
  170. code_sandboxes-1.4.4/tests/test_datalayer_sandbox.py +439 -0
  171. code_sandboxes-1.4.4/tests/test_daytona.py +650 -0
  172. code_sandboxes-1.4.4/tests/test_e2b.py +398 -0
  173. code_sandboxes-1.4.4/tests/test_eval.py +515 -0
  174. code_sandboxes-1.4.4/tests/test_factory.py +184 -0
  175. code_sandboxes-1.4.4/tests/test_google_colab.py +125 -0
  176. code_sandboxes-1.4.4/tests/test_integration.py +144 -0
  177. code_sandboxes-1.4.4/tests/test_jupyter_ingress.py +97 -0
  178. code_sandboxes-1.4.4/tests/test_jupyter_server.py +355 -0
  179. code_sandboxes-1.4.4/tests/test_jupyter_server_streaming.py +117 -0
  180. code_sandboxes-1.4.4/tests/test_kaggle.py +127 -0
  181. code_sandboxes-1.4.4/tests/test_kaggle_execute.py +265 -0
  182. code_sandboxes-1.4.4/tests/test_kaggle_live.py +133 -0
  183. code_sandboxes-1.4.4/tests/test_kaggle_session.py +121 -0
  184. code_sandboxes-1.4.4/tests/test_kernel_client_compatibility.py +166 -0
  185. code_sandboxes-1.4.4/tests/test_lifecycle_vocabulary.py +204 -0
  186. code_sandboxes-1.4.4/tests/test_manage.py +261 -0
  187. code_sandboxes-1.4.4/tests/test_modal_google_colab_sandbox.py +493 -0
  188. code_sandboxes-1.4.4/tests/test_modal_session.py +60 -0
  189. code_sandboxes-1.4.4/tests/test_models.py +247 -0
  190. code_sandboxes-1.4.4/tests/test_output_line_fidelity.py +41 -0
  191. code_sandboxes-1.4.4/tests/test_provider_catalog_names.py +103 -0
  192. code_sandboxes-1.4.4/tests/test_provider_ingress.py +62 -0
  193. code_sandboxes-1.4.4/tests/test_providers.py +149 -0
  194. 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,9 @@
1
+ {
2
+ "python-envs.pythonProjects": [
3
+ {
4
+ "path": "",
5
+ "envManager": "ms-python.python:conda",
6
+ "packageManager": "ms-python.python:conda"
7
+ }
8
+ ]
9
+ }
@@ -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`.