code-sandboxes 1.9.10__tar.gz → 1.9.11__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 (262) hide show
  1. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/CHANGELOG.md +18 -0
  2. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/PKG-INFO +1 -1
  3. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/__version__.py +1 -1
  4. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/attest.py +33 -30
  5. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_environment_attest.py +51 -28
  6. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/.github/workflows/build.yml +0 -0
  7. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/.github/workflows/environments-live.yml +0 -0
  8. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/.github/workflows/py-code-style.yml +0 -0
  9. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/.github/workflows/py-tests.yml +0 -0
  10. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/.github/workflows/py-typing.yml +0 -0
  11. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/.github/workflows/reusable-python.yml +0 -0
  12. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/.gitignore +0 -0
  13. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/.licenserc.yaml +0 -0
  14. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/.pre-commit-config.yaml +0 -0
  15. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/.vscode/settings.json +0 -0
  16. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/Dockerfile +0 -0
  17. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/LICENSE +0 -0
  18. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/Makefile +0 -0
  19. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/README.md +0 -0
  20. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/build.log +0 -0
  21. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/__init__.py +0 -0
  22. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/base.py +0 -0
  23. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/bridge_mount.py +0 -0
  24. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/builds.py +0 -0
  25. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/cli.py +0 -0
  26. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/client.py +0 -0
  27. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/cloudflare_sandbox.py +0 -0
  28. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/commands.py +0 -0
  29. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/console.py +0 -0
  30. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/contents.py +0 -0
  31. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/coreweave_sandbox.py +0 -0
  32. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/datalayer_sandbox.py +0 -0
  33. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/daytona_sandbox.py +0 -0
  34. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/docker_sandbox.py +0 -0
  35. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/e2b_sandbox.py +0 -0
  36. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/__init__.py +0 -0
  37. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/__main__.py +0 -0
  38. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/accounts.py +0 -0
  39. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/adapters/__init__.py +0 -0
  40. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/adapters/datalayer.py +0 -0
  41. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/adapters/daytona.py +0 -0
  42. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/adapters/e2b.py +0 -0
  43. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/adapters/managed.py +0 -0
  44. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/adapters/modal.py +0 -0
  45. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/bases.py +0 -0
  46. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/breaker.py +0 -0
  47. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/build_secrets.py +0 -0
  48. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/builders.py +0 -0
  49. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/canonical.py +0 -0
  50. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/conformance.py +0 -0
  51. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/constraints/sandbox-contract-v1.txt +0 -0
  52. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/constraints/wheelhouse/README.md +0 -0
  53. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/constraints/wheelhouse/jupyter_server-2.21.0+datalayer.1-py3-none-any.whl +0 -0
  54. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/contract.py +0 -0
  55. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/doctor/__init__.py +0 -0
  56. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/doctor/build.py +0 -0
  57. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/doctor/datalayer_sandbox.py +0 -0
  58. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/doctor/report.schema.json +0 -0
  59. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/errors.py +0 -0
  60. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/files.py +0 -0
  61. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/image_import.py +0 -0
  62. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/lifecycle.py +0 -0
  63. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/policy.py +0 -0
  64. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/redact.py +0 -0
  65. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/resolve.py +0 -0
  66. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/schema.py +0 -0
  67. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/environments/spec.py +0 -0
  68. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/eval_sandbox.py +0 -0
  69. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/exceptions.py +0 -0
  70. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/filesystem.py +0 -0
  71. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/google_colab.py +0 -0
  72. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/google_colab_sandbox.py +0 -0
  73. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/interfaces.py +0 -0
  74. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/jupyter_ingress.py +0 -0
  75. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/jupyter_server_sandbox.py +0 -0
  76. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/kaggle.py +0 -0
  77. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/kaggle_execute.py +0 -0
  78. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/kaggle_live.py +0 -0
  79. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/kaggle_sandbox.py +0 -0
  80. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/lifecycle.py +0 -0
  81. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/manage.py +0 -0
  82. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/modal_sandbox.py +0 -0
  83. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/models.py +0 -0
  84. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/monty_sandbox.py +0 -0
  85. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/provider_ingress.py +0 -0
  86. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/code_sandboxes/providers.py +0 -0
  87. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docker/Dockerfile +0 -0
  88. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/.gitignore +0 -0
  89. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/LICENSE +0 -0
  90. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/Makefile +0 -0
  91. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/README.md +0 -0
  92. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/babel.config.js +0 -0
  93. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/api-reference/_category_.yml +0 -0
  94. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/api-reference/index.mdx +0 -0
  95. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/cli/_category_.yml +0 -0
  96. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/cli/index.mdx +0 -0
  97. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/contribute/_category_.yml +0 -0
  98. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/contribute/index.mdx +0 -0
  99. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/environments/_category_.yml +0 -0
  100. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/environments/contract.mdx +0 -0
  101. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/environments/index.mdx +0 -0
  102. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/environments/specification.mdx +0 -0
  103. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/environments/spike-2026-09.mdx +0 -0
  104. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/examples/_category_.yml +0 -0
  105. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/examples/index.mdx +0 -0
  106. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/guide/_category_.yml +0 -0
  107. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/guide/index.mdx +0 -0
  108. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/index.mdx +0 -0
  109. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/install/_category_.yml +0 -0
  110. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/install/index.mdx +0 -0
  111. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/provider-ingress.mdx +0 -0
  112. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/providers/_category_.yml +0 -0
  113. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/providers/cloudflare.mdx +0 -0
  114. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/providers/coreweave.mdx +0 -0
  115. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/providers/datalayer.mdx +0 -0
  116. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/providers/daytona.mdx +0 -0
  117. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/providers/docker.mdx +0 -0
  118. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/providers/e2b.mdx +0 -0
  119. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/providers/eval.mdx +0 -0
  120. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/providers/google-colab.mdx +0 -0
  121. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/providers/index.mdx +0 -0
  122. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/providers/jupyter-server.mdx +0 -0
  123. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/providers/kaggle.mdx +0 -0
  124. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/providers/modal.mdx +0 -0
  125. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docs/providers/monty.mdx +0 -0
  126. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/docusaurus.config.js +0 -0
  127. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/package.json +0 -0
  128. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/sidebars.js +0 -0
  129. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/src/components/HomepageRow1.js +0 -0
  130. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/src/components/HomepageRow1.module.css +0 -0
  131. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/src/components/HomepageRow2.js +0 -0
  132. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/src/components/HomepageRow2.module.css +0 -0
  133. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/src/components/HomepageRow3.js +0 -0
  134. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/src/components/HomepageRow3.module.css +0 -0
  135. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/src/css/custom.css +0 -0
  136. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/src/pages/index.module.css +0 -0
  137. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/src/pages/markdown-page.md +0 -0
  138. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/src/theme/CustomDocItem.tsx +0 -0
  139. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/src/theme/IconsTitle.tsx +0 -0
  140. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/static/img/bricks.svg +0 -0
  141. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/static/img/building-construction.svg +0 -0
  142. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/static/img/cloud-sun.svg +0 -0
  143. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/static/img/cloud.svg +0 -0
  144. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/static/img/collaboration.svg +0 -0
  145. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/static/img/copy-left.svg +0 -0
  146. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/static/img/datalayer/logo.png +0 -0
  147. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/static/img/datalayer/logo.svg +0 -0
  148. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/static/img/datalayer/personas/business.svg +0 -0
  149. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/static/img/datalayer/personas/data-scientist.svg +0 -0
  150. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/static/img/datalayer/personas/devops.svg +0 -0
  151. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/static/img/datalayer/project/project-line.svg +0 -0
  152. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/static/img/favicon.ico +0 -0
  153. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/static/img/jupyter.svg +0 -0
  154. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/static/img/open-source.svg +0 -0
  155. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/static/img/react-js.svg +0 -0
  156. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/static/img/react-js2.svg +0 -0
  157. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/static/img/ringed-planet.svg +0 -0
  158. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/static/img/robot.svg +0 -0
  159. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/static/img/rocket.svg +0 -0
  160. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/static/img/shield.svg +0 -0
  161. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/static/img/sparkles.svg +0 -0
  162. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/static/img/streamlit.gif +0 -0
  163. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/static/img/super-hero.svg +0 -0
  164. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/static/img/target.svg +0 -0
  165. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/docs/static/img/thumbs-up.svg +0 -0
  166. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/examples/README.md +0 -0
  167. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/examples/exec/Makefile +0 -0
  168. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/examples/exec/cloudflare_sandbox_example.py +0 -0
  169. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/examples/exec/coreweave_sandbox_example.py +0 -0
  170. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/examples/exec/datalayer_sandbox_example.py +0 -0
  171. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/examples/exec/daytona_sandbox_example.py +0 -0
  172. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/examples/exec/docker_sandbox_example.py +0 -0
  173. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/examples/exec/e2b_sandbox_example.py +0 -0
  174. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/examples/exec/eval_sandbox_example.py +0 -0
  175. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/examples/exec/google_colab_sandbox_example.py +0 -0
  176. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/examples/exec/jupyter_server_sandbox_example.py +0 -0
  177. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/examples/exec/kaggle_sandbox_example.py +0 -0
  178. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/examples/exec/modal_sandbox_example.py +0 -0
  179. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/examples/exec/monty_sandbox_example.py +0 -0
  180. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/examples/repl/Makefile +0 -0
  181. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/examples/repl/cloudflare_sandbox_example.py +0 -0
  182. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/examples/repl/coreweave_sandbox_example.py +0 -0
  183. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/examples/repl/datalayer_sandbox_example.py +0 -0
  184. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/examples/repl/daytona_sandbox_example.py +0 -0
  185. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/examples/repl/docker_sandbox_example.py +0 -0
  186. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/examples/repl/e2b_sandbox_example.py +0 -0
  187. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/examples/repl/eval_sandbox_example.py +0 -0
  188. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/examples/repl/google_colab_sandbox_example.py +0 -0
  189. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/examples/repl/jupyter_server_sandbox_example.py +0 -0
  190. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/examples/repl/kaggle_sandbox_example.py +0 -0
  191. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/examples/repl/modal_sandbox_example.py +0 -0
  192. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/examples/repl/monty_sandbox_example.py +0 -0
  193. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/pyproject.toml +0 -0
  194. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/schemas/environment-v1alpha1.json +0 -0
  195. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/__init__.py +0 -0
  196. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/conftest.py +0 -0
  197. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_a_datalayer_sandbox_can_be_interrupted.py +0 -0
  198. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_bridge_mount.py +0 -0
  199. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_builds.py +0 -0
  200. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_cli_exec.py +0 -0
  201. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_cli_repl.py +0 -0
  202. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_client.py +0 -0
  203. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_client_contents.py +0 -0
  204. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_client_files.py +0 -0
  205. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_client_outcome_error_output.py +0 -0
  206. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_cloudflare.py +0 -0
  207. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_commands_envelope.py +0 -0
  208. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_console.py +0 -0
  209. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_contents_contract.py +0 -0
  210. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_contents_live_matrix.py +0 -0
  211. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_coreweave.py +0 -0
  212. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_datalayer_sandbox.py +0 -0
  213. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_daytona.py +0 -0
  214. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_e2b.py +0 -0
  215. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_environment_accounts.py +0 -0
  216. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_environment_bases.py +0 -0
  217. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_environment_breaker.py +0 -0
  218. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_environment_build_secrets.py +0 -0
  219. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_environment_builders.py +0 -0
  220. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_environment_canonical.py +0 -0
  221. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_environment_conformance.py +0 -0
  222. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_environment_constraints.py +0 -0
  223. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_environment_contract.py +0 -0
  224. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_environment_cross_variant_report.py +0 -0
  225. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_environment_datalayer_builder.py +0 -0
  226. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_environment_daytona_builder.py +0 -0
  227. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_environment_doctor.py +0 -0
  228. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_environment_e2b_builder.py +0 -0
  229. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_environment_errors.py +0 -0
  230. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_environment_image_import.py +0 -0
  231. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_environment_lifecycle.py +0 -0
  232. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_environment_live_matrix.py +0 -0
  233. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_environment_managed_builders.py +0 -0
  234. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_environment_modal_builder.py +0 -0
  235. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_environment_redact.py +0 -0
  236. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_environment_resolve.py +0 -0
  237. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_environment_spec.py +0 -0
  238. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_eval.py +0 -0
  239. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_every_variant_has_a_real_interrupt.py +0 -0
  240. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_factory.py +0 -0
  241. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_google_colab.py +0 -0
  242. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_integration.py +0 -0
  243. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_jupyter_ingress.py +0 -0
  244. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_jupyter_server.py +0 -0
  245. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_jupyter_server_streaming.py +0 -0
  246. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_kaggle.py +0 -0
  247. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_kaggle_execute.py +0 -0
  248. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_kaggle_live.py +0 -0
  249. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_kaggle_session.py +0 -0
  250. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_kernel_client_compatibility.py +0 -0
  251. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_lifecycle_vocabulary.py +0 -0
  252. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_manage.py +0 -0
  253. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_manage_datalayer.py +0 -0
  254. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_modal_google_colab_sandbox.py +0 -0
  255. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_modal_session.py +0 -0
  256. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_models.py +0 -0
  257. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_output_line_fidelity.py +0 -0
  258. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_provider_catalog_names.py +0 -0
  259. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_provider_ingress.py +0 -0
  260. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_providers.py +0 -0
  261. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_sandboxes.py +0 -0
  262. {code_sandboxes-1.9.10 → code_sandboxes-1.9.11}/tests/test_the_kill_relaunch_drill.py +0 -0
@@ -8,6 +8,24 @@
8
8
 
9
9
  ## Unreleased
10
10
 
11
+ ## 1.9.11
12
+
13
+ - **1.9.10's own fix did not work: `--registry-referrers-mode` only ever
14
+ governs *reading* referrers, never where `sign` writes one** —
15
+ `sign --help` says so outright ("mode for fetching references"), and a
16
+ second live sign on r1, 2026-09-14, confirmed it: the signature still
17
+ landed as an OCI 1.1 referrer, no legacy tag. `Attestor` no longer tries
18
+ to force cosign's own storage choice. Its replay check and its own
19
+ `signature_ref` now ask cosign directly, the same way the Operator's own
20
+ verify will: `can_verify(reference)` runs `cosign verify --key <key>
21
+ --insecure-ignore-tlog=true <reference>` and answers its exit code, and
22
+ `signature_ref` is the digest reference itself — what `cosign verify`
23
+ takes, not a tag it may or may not have written. Signing the same digest
24
+ twice no longer errors the way a second push under the old immutable tag
25
+ once would have, but `can_verify` still avoids it, since two valid
26
+ signatures claiming to be Datalayer's own word on one artifact is not
27
+ the design either.
28
+
11
29
  ## 1.9.10
12
30
 
13
31
  - **cosign signs the legacy tag again, not just an OCI referrer**
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: code_sandboxes
3
- Version: 1.9.10
3
+ Version: 1.9.11
4
4
  Project-URL: Home, https://github.com/datalayer/code-sandboxes
5
5
  Author-email: Datalayer <info@datalayer.io>
6
6
  License: BSD 3-Clause License
@@ -3,4 +3,4 @@
3
3
 
4
4
  """Code Sandboxes."""
5
5
 
6
- __version__ = "1.9.10"
6
+ __version__ = "1.9.11"
@@ -403,17 +403,28 @@ class Attestor:
403
403
  def sign(self, *, registry: str, repository: str, digest: str) -> tuple[str, bool]:
404
404
  """Sign the digest with the KMS key, unless it is signed already (E1-09).
405
405
 
406
- Answers the signature's reference and whether this call made it. A
407
- replay finds the existing signature: pushing a second one under the
408
- same tag is what immutable tags refuse, and it would be a second thing
409
- claiming to be Datalayer's word on the same artifact.
406
+ Answers the signature's own reference — the digest itself, which is
407
+ what `cosign verify --key <key>` takes, resolving the signature's
408
+ real location on its own — and whether this call made it.
409
+
410
+ A replay finds the existing signature by asking cosign whether *this*
411
+ key has already signed it, the same check the Operator itself will
412
+ make before starting a pod (`can_verify`): cosign 3.1.3 stores a
413
+ signature as an OCI 1.1 referrer, not the classic `sha256-<hex>.sig`
414
+ sidecar tag a first version of this method assumed (found live,
415
+ 2026-09-14, twice — `--registry-referrers-mode` only ever governed
416
+ *reading* referrers, never where `sign` writes one, so it changed
417
+ nothing the first time either). Signing twice would not error the way
418
+ it would have under the old tag (an OCI referrer is not an immutable
419
+ tag to collide with), but it would leave two things claiming to be
420
+ Datalayer's word on the same artifact, which `can_verify` first
421
+ avoids.
410
422
  """
411
423
  self.can_sign()
412
- tag = signature_tag(digest)
413
424
  reference = f"{registry}/{repository}@{digest}"
414
- if self._signature_exists(repository=repository, tag=tag):
415
- self._log(f"{digest} is signed already, under {tag}")
416
- return f"{registry}/{repository}:{tag}", False
425
+ if self.can_verify(reference):
426
+ self._log(f"{digest} is signed already")
427
+ return reference, False
417
428
  command = [
418
429
  self._cosign,
419
430
  "sign",
@@ -440,13 +451,6 @@ class Attestor:
440
451
  # `--tlog-upload=false` already asks for, and needs no network
441
452
  # call of its own to fetch one.
442
453
  "--use-signing-config=false",
443
- # cosign 3.1.3 defaults to the OCI 1.1 referrers API instead of
444
- # the classic `sha256-<hex>.sig` sidecar tag — found live,
445
- # 2026-09-14: `cosign sign` reported success, but no such tag
446
- # ever existed, so `_signature_exists`'s own replay check (below)
447
- # never found it and `signature_ref` named a tag nothing could
448
- # pull. `legacy` restores the tag both of those already assume.
449
- "--registry-referrers-mode=legacy",
450
454
  "--key",
451
455
  self._key,
452
456
  reference,
@@ -459,22 +463,21 @@ class Attestor:
459
463
  "cosign did not sign the artifact; its output says why",
460
464
  detail={"digest": digest, "exit": finished.returncode},
461
465
  )
462
- return f"{registry}/{repository}:{tag}", True
466
+ return reference, True
463
467
 
464
- def _signature_exists(self, *, repository: str, tag: str) -> bool:
465
- try:
466
- answer = self._client().describe_images(
467
- repositoryName=repository, imageIds=[{"imageTag": tag}]
468
- )
469
- except Exception as error:
470
- if _is_missing(error):
471
- return False
472
- raise EnvironmentsError(
473
- PROVIDER_ERROR,
474
- f"Whether {tag} is already signed could not be read: {error}",
475
- detail={"repository": repository, "tag": tag},
476
- ) from error
477
- return bool(answer.get("imageDetails"))
468
+ def can_verify(self, reference: str) -> bool:
469
+ """Whether cosign already finds a signature by this key on `reference`.
470
+
471
+ Wherever cosign itself keeps a signature — the OCI 1.1 referrer it
472
+ defaults to, or the legacy sidecar tag an older registry might still
473
+ need — is cosign's own business to resolve; asking it directly, the
474
+ same check the Operator makes before starting a pod, is simpler and
475
+ more honest than tracking cosign's own storage choices here too.
476
+ """
477
+ finished = self._invoke(
478
+ [self._cosign, "verify", "--insecure-ignore-tlog=true", "--key", self._key, reference]
479
+ )
480
+ return finished.returncode == 0
478
481
 
479
482
  def _invoke(self, command: Sequence[str]) -> subprocess.CompletedProcess[str]:
480
483
  # `registry_auth` — same shape as the resolver's own — puts cosign's
@@ -88,7 +88,6 @@ class FakeEcr:
88
88
  statuses=("ACTIVE",),
89
89
  findings=(),
90
90
  enhanced_findings=True,
91
- signed: set[str] | None = None,
92
91
  manifest: dict | None = None,
93
92
  pages: list[list[dict]] | None = None,
94
93
  ) -> None:
@@ -99,11 +98,9 @@ class FakeEcr:
99
98
  #: `findings` when given, to test reading more than one page.
100
99
  self.pages = pages
101
100
  self.enhanced_findings = enhanced_findings
102
- self.signed = set(signed or set())
103
101
  self.manifest = manifest
104
102
  self.asked = 0
105
103
  self.scanned: list[str] = []
106
- self.described_tags: list[str] = []
107
104
 
108
105
  def batch_get_image(self, repositoryName, imageIds, acceptedMediaTypes): # noqa: N803 - boto3's spelling
109
106
  manifest = self.manifest or {
@@ -157,28 +154,29 @@ class FakeEcr:
157
154
  },
158
155
  }
159
156
 
160
- def describe_images(self, repositoryName, imageIds): # noqa: N803 - boto3's spelling
161
- tag = imageIds[0].get("imageTag") or ""
162
- self.described_tags.append(tag)
163
- if tag in self.signed:
164
- return {"imageDetails": [{"imageTags": [tag]}]}
165
- error = Exception("ImageNotFoundException")
166
- error.response = {"Error": {"Code": "ImageNotFoundException"}}
167
- raise error
168
-
169
157
 
170
158
  class Cosign:
171
- """A cosign whose argv and env are read, and which can refuse."""
159
+ """Every cosign invocation, in order; `argv`/`env` are the last call's own.
160
+
161
+ `verify_returncode` is `sign`'s own upfront replay check (E1-09): 1 (not
162
+ signed yet) unless a test says otherwise, so the ordinary path — verify,
163
+ then sign — still leaves `argv`/`env` as the `sign` call a test written
164
+ against the single-call fake already expects.
165
+ """
172
166
 
173
- def __init__(self, returncode: int = 0) -> None:
167
+ def __init__(self, returncode: int = 0, *, verify_returncode: int = 1) -> None:
174
168
  self.returncode = returncode
169
+ self.verify_returncode = verify_returncode
170
+ self.calls: list[tuple[list[str], dict[str, str] | None]] = []
175
171
  self.argv: list[str] = []
176
172
  self.env: dict[str, str] | None = None
177
173
 
178
174
  def __call__(self, argv, *, env=None, **_kwargs) -> subprocess.CompletedProcess[str]:
179
175
  self.argv = list(argv)
180
176
  self.env = env
181
- return subprocess.CompletedProcess(self.argv, self.returncode, "", "Pushing signature\n")
177
+ self.calls.append((self.argv, self.env))
178
+ code = self.verify_returncode if "verify" in argv else self.returncode
179
+ return subprocess.CompletedProcess(self.argv, code, "", "Pushing signature\n")
182
180
 
183
181
 
184
182
  def an_attestor(**changes) -> Attestor:
@@ -466,17 +464,21 @@ class TestTheSignature:
466
464
  # `--tlog-upload=false` alone can no longer override (found live
467
465
  # 2026-09-14): turned off so the plain flag is honored again.
468
466
  "--use-signing-config=false",
469
- # cosign 3.1.3 defaults to the OCI 1.1 referrers API rather than
470
- # the classic sidecar tag: found live 2026-09-14, `cosign sign`
471
- # reported success but pushed no tag `_signature_exists` or
472
- # `signature_ref` could ever find. `legacy` restores it.
473
- "--registry-referrers-mode=legacy",
474
467
  "--key",
475
468
  KEY,
476
469
  f"{REGISTRY}/{REPOSITORY}@{DIGEST}",
477
470
  ]
478
- assert reference == f"{REGISTRY}/{REPOSITORY}:{signature_tag(DIGEST)}"
471
+ # The digest itself: what `cosign verify --key <key>` takes, not a
472
+ # tag — cosign 3.1.3 defaults to storing a signature as an OCI 1.1
473
+ # referrer, not the classic `sha256-<hex>.sig` sidecar tag (found
474
+ # live 2026-09-14, twice: `--registry-referrers-mode` only ever
475
+ # governed *reading* referrers, never where `sign` writes one).
476
+ assert reference == f"{REGISTRY}/{REPOSITORY}@{DIGEST}"
479
477
  assert signed_now is True
478
+ # The upfront replay check, cosign's own answer for whether this key
479
+ # already signed it — not yet, here, so `sign` ran right after.
480
+ subcommands = [call[0][1] for call in cosign.calls]
481
+ assert subcommands == ["verify", "sign"]
480
482
 
481
483
  def test_no_registry_auth_leaves_cosigns_own_environment_untouched(self) -> None:
482
484
  """The common case — nothing to add — inherits this process's own
@@ -508,15 +510,19 @@ class TestTheSignature:
508
510
  assert cosign.env[name] == os.environ[name]
509
511
 
510
512
  def test_a_replay_finds_the_signature_instead_of_pushing_a_second(self) -> None:
511
- """Immutable tags would refuse the second, and two signatures are two words."""
512
- ecr = FakeEcr(signed={signature_tag(DIGEST)})
513
- cosign = Cosign()
514
- reference, signed_now = an_attestor(ecr=ecr, run=cosign).sign(
513
+ """A second signature would not error the way a second push under the
514
+ old immutable tag once did, but it would still be two things claiming
515
+ to be Datalayer's word on the same artifact — cosign's own answer to
516
+ `verify` is asked first, and `sign` never runs when it says yes."""
517
+ cosign = Cosign(verify_returncode=0)
518
+ reference, signed_now = an_attestor(run=cosign).sign(
515
519
  registry=REGISTRY, repository=REPOSITORY, digest=DIGEST
516
520
  )
517
521
  assert signed_now is False
518
- assert cosign.argv == []
519
- assert reference.endswith(signature_tag(DIGEST))
522
+ assert len(cosign.calls) == 1
523
+ assert "verify" in cosign.argv
524
+ assert "sign" not in cosign.argv
525
+ assert reference == f"{REGISTRY}/{REPOSITORY}@{DIGEST}"
520
526
 
521
527
  def test_cosign_refusing_is_a_provider_error(self) -> None:
522
528
  with pytest.raises(EnvironmentsError) as raised:
@@ -535,6 +541,23 @@ class TestTheSignature:
535
541
  an_attestor(cosign="").sign(registry=REGISTRY, repository=REPOSITORY, digest=DIGEST)
536
542
  assert raised.value.detail["missing"] == "cosign"
537
543
 
544
+ def test_can_verify_asks_cosign_and_answers_its_exit_code(self) -> None:
545
+ reference = f"{REGISTRY}/{REPOSITORY}@{DIGEST}"
546
+ assert an_attestor(run=Cosign(verify_returncode=0)).can_verify(reference) is True
547
+ assert an_attestor(run=Cosign(verify_returncode=1)).can_verify(reference) is False
548
+
549
+ def test_can_verify_names_the_key_and_ignores_the_transparency_log(self) -> None:
550
+ cosign = Cosign(verify_returncode=0)
551
+ an_attestor(run=cosign, key=KEY).can_verify(f"{REGISTRY}/{REPOSITORY}@{DIGEST}")
552
+ assert cosign.argv == [
553
+ "/usr/bin/cosign",
554
+ "verify",
555
+ "--insecure-ignore-tlog=true",
556
+ "--key",
557
+ KEY,
558
+ f"{REGISTRY}/{REPOSITORY}@{DIGEST}",
559
+ ]
560
+
538
561
  def test_the_signature_sits_beside_the_image_at_cosigns_own_tag(self) -> None:
539
562
  assert signature_tag(DIGEST) == "sha256-" + "aa" * 32 + ".sig"
540
563
  with pytest.raises(ValueError):
@@ -560,7 +583,7 @@ class TestAttestingAnArtifact:
560
583
  artifact=self.an_artifact(), size_bytes=116_183_040, attestor=attestor
561
584
  )
562
585
  assert answer["scan_summary"]["decision"] == "pass"
563
- assert answer["signature_ref"].endswith(signature_tag(DIGEST))
586
+ assert answer["signature_ref"] == f"{REGISTRY}/{REPOSITORY}@{DIGEST}"
564
587
  assert answer["sbom_ref"].endswith(".sbom")
565
588
  assert answer["provenance_ref"].endswith(".att")
566
589
  assert answer["size_bytes"] == 116_183_040
File without changes