code-sandboxes 1.9.6__tar.gz → 1.9.8__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.6 → code_sandboxes-1.9.8}/CHANGELOG.md +24 -0
  2. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/PKG-INFO +1 -1
  3. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/__version__.py +1 -1
  4. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/attest.py +69 -20
  5. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_environment_attest.py +47 -1
  6. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/.github/workflows/build.yml +0 -0
  7. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/.github/workflows/environments-live.yml +0 -0
  8. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/.github/workflows/py-code-style.yml +0 -0
  9. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/.github/workflows/py-tests.yml +0 -0
  10. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/.github/workflows/py-typing.yml +0 -0
  11. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/.github/workflows/reusable-python.yml +0 -0
  12. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/.gitignore +0 -0
  13. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/.licenserc.yaml +0 -0
  14. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/.pre-commit-config.yaml +0 -0
  15. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/.vscode/settings.json +0 -0
  16. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/Dockerfile +0 -0
  17. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/LICENSE +0 -0
  18. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/Makefile +0 -0
  19. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/README.md +0 -0
  20. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/build.log +0 -0
  21. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/__init__.py +0 -0
  22. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/base.py +0 -0
  23. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/bridge_mount.py +0 -0
  24. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/builds.py +0 -0
  25. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/cli.py +0 -0
  26. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/client.py +0 -0
  27. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/cloudflare_sandbox.py +0 -0
  28. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/commands.py +0 -0
  29. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/console.py +0 -0
  30. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/contents.py +0 -0
  31. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/coreweave_sandbox.py +0 -0
  32. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/datalayer_sandbox.py +0 -0
  33. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/daytona_sandbox.py +0 -0
  34. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/docker_sandbox.py +0 -0
  35. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/e2b_sandbox.py +0 -0
  36. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/__init__.py +0 -0
  37. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/__main__.py +0 -0
  38. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/accounts.py +0 -0
  39. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/adapters/__init__.py +0 -0
  40. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/adapters/datalayer.py +0 -0
  41. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/adapters/daytona.py +0 -0
  42. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/adapters/e2b.py +0 -0
  43. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/adapters/managed.py +0 -0
  44. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/adapters/modal.py +0 -0
  45. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/bases.py +0 -0
  46. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/breaker.py +0 -0
  47. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/build_secrets.py +0 -0
  48. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/builders.py +0 -0
  49. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/canonical.py +0 -0
  50. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/conformance.py +0 -0
  51. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/constraints/sandbox-contract-v1.txt +0 -0
  52. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/constraints/wheelhouse/README.md +0 -0
  53. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/constraints/wheelhouse/jupyter_server-2.21.0+datalayer.1-py3-none-any.whl +0 -0
  54. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/contract.py +0 -0
  55. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/doctor/__init__.py +0 -0
  56. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/doctor/build.py +0 -0
  57. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/doctor/datalayer_sandbox.py +0 -0
  58. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/doctor/report.schema.json +0 -0
  59. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/errors.py +0 -0
  60. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/files.py +0 -0
  61. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/image_import.py +0 -0
  62. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/lifecycle.py +0 -0
  63. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/policy.py +0 -0
  64. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/redact.py +0 -0
  65. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/resolve.py +0 -0
  66. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/schema.py +0 -0
  67. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/environments/spec.py +0 -0
  68. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/eval_sandbox.py +0 -0
  69. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/exceptions.py +0 -0
  70. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/filesystem.py +0 -0
  71. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/google_colab.py +0 -0
  72. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/google_colab_sandbox.py +0 -0
  73. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/interfaces.py +0 -0
  74. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/jupyter_ingress.py +0 -0
  75. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/jupyter_server_sandbox.py +0 -0
  76. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/kaggle.py +0 -0
  77. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/kaggle_execute.py +0 -0
  78. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/kaggle_live.py +0 -0
  79. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/kaggle_sandbox.py +0 -0
  80. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/lifecycle.py +0 -0
  81. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/manage.py +0 -0
  82. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/modal_sandbox.py +0 -0
  83. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/models.py +0 -0
  84. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/monty_sandbox.py +0 -0
  85. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/provider_ingress.py +0 -0
  86. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/code_sandboxes/providers.py +0 -0
  87. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docker/Dockerfile +0 -0
  88. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/.gitignore +0 -0
  89. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/LICENSE +0 -0
  90. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/Makefile +0 -0
  91. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/README.md +0 -0
  92. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/babel.config.js +0 -0
  93. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/api-reference/_category_.yml +0 -0
  94. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/api-reference/index.mdx +0 -0
  95. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/cli/_category_.yml +0 -0
  96. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/cli/index.mdx +0 -0
  97. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/contribute/_category_.yml +0 -0
  98. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/contribute/index.mdx +0 -0
  99. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/environments/_category_.yml +0 -0
  100. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/environments/contract.mdx +0 -0
  101. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/environments/index.mdx +0 -0
  102. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/environments/specification.mdx +0 -0
  103. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/environments/spike-2026-09.mdx +0 -0
  104. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/examples/_category_.yml +0 -0
  105. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/examples/index.mdx +0 -0
  106. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/guide/_category_.yml +0 -0
  107. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/guide/index.mdx +0 -0
  108. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/index.mdx +0 -0
  109. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/install/_category_.yml +0 -0
  110. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/install/index.mdx +0 -0
  111. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/provider-ingress.mdx +0 -0
  112. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/providers/_category_.yml +0 -0
  113. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/providers/cloudflare.mdx +0 -0
  114. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/providers/coreweave.mdx +0 -0
  115. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/providers/datalayer.mdx +0 -0
  116. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/providers/daytona.mdx +0 -0
  117. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/providers/docker.mdx +0 -0
  118. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/providers/e2b.mdx +0 -0
  119. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/providers/eval.mdx +0 -0
  120. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/providers/google-colab.mdx +0 -0
  121. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/providers/index.mdx +0 -0
  122. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/providers/jupyter-server.mdx +0 -0
  123. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/providers/kaggle.mdx +0 -0
  124. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/providers/modal.mdx +0 -0
  125. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docs/providers/monty.mdx +0 -0
  126. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/docusaurus.config.js +0 -0
  127. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/package.json +0 -0
  128. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/sidebars.js +0 -0
  129. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/src/components/HomepageRow1.js +0 -0
  130. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/src/components/HomepageRow1.module.css +0 -0
  131. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/src/components/HomepageRow2.js +0 -0
  132. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/src/components/HomepageRow2.module.css +0 -0
  133. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/src/components/HomepageRow3.js +0 -0
  134. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/src/components/HomepageRow3.module.css +0 -0
  135. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/src/css/custom.css +0 -0
  136. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/src/pages/index.module.css +0 -0
  137. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/src/pages/markdown-page.md +0 -0
  138. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/src/theme/CustomDocItem.tsx +0 -0
  139. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/src/theme/IconsTitle.tsx +0 -0
  140. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/static/img/bricks.svg +0 -0
  141. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/static/img/building-construction.svg +0 -0
  142. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/static/img/cloud-sun.svg +0 -0
  143. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/static/img/cloud.svg +0 -0
  144. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/static/img/collaboration.svg +0 -0
  145. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/static/img/copy-left.svg +0 -0
  146. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/static/img/datalayer/logo.png +0 -0
  147. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/static/img/datalayer/logo.svg +0 -0
  148. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/static/img/datalayer/personas/business.svg +0 -0
  149. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/static/img/datalayer/personas/data-scientist.svg +0 -0
  150. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/static/img/datalayer/personas/devops.svg +0 -0
  151. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/static/img/datalayer/project/project-line.svg +0 -0
  152. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/static/img/favicon.ico +0 -0
  153. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/static/img/jupyter.svg +0 -0
  154. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/static/img/open-source.svg +0 -0
  155. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/static/img/react-js.svg +0 -0
  156. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/static/img/react-js2.svg +0 -0
  157. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/static/img/ringed-planet.svg +0 -0
  158. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/static/img/robot.svg +0 -0
  159. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/static/img/rocket.svg +0 -0
  160. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/static/img/shield.svg +0 -0
  161. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/static/img/sparkles.svg +0 -0
  162. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/static/img/streamlit.gif +0 -0
  163. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/static/img/super-hero.svg +0 -0
  164. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/static/img/target.svg +0 -0
  165. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/docs/static/img/thumbs-up.svg +0 -0
  166. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/examples/README.md +0 -0
  167. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/examples/exec/Makefile +0 -0
  168. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/examples/exec/cloudflare_sandbox_example.py +0 -0
  169. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/examples/exec/coreweave_sandbox_example.py +0 -0
  170. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/examples/exec/datalayer_sandbox_example.py +0 -0
  171. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/examples/exec/daytona_sandbox_example.py +0 -0
  172. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/examples/exec/docker_sandbox_example.py +0 -0
  173. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/examples/exec/e2b_sandbox_example.py +0 -0
  174. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/examples/exec/eval_sandbox_example.py +0 -0
  175. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/examples/exec/google_colab_sandbox_example.py +0 -0
  176. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/examples/exec/jupyter_server_sandbox_example.py +0 -0
  177. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/examples/exec/kaggle_sandbox_example.py +0 -0
  178. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/examples/exec/modal_sandbox_example.py +0 -0
  179. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/examples/exec/monty_sandbox_example.py +0 -0
  180. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/examples/repl/Makefile +0 -0
  181. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/examples/repl/cloudflare_sandbox_example.py +0 -0
  182. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/examples/repl/coreweave_sandbox_example.py +0 -0
  183. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/examples/repl/datalayer_sandbox_example.py +0 -0
  184. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/examples/repl/daytona_sandbox_example.py +0 -0
  185. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/examples/repl/docker_sandbox_example.py +0 -0
  186. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/examples/repl/e2b_sandbox_example.py +0 -0
  187. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/examples/repl/eval_sandbox_example.py +0 -0
  188. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/examples/repl/google_colab_sandbox_example.py +0 -0
  189. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/examples/repl/jupyter_server_sandbox_example.py +0 -0
  190. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/examples/repl/kaggle_sandbox_example.py +0 -0
  191. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/examples/repl/modal_sandbox_example.py +0 -0
  192. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/examples/repl/monty_sandbox_example.py +0 -0
  193. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/pyproject.toml +0 -0
  194. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/schemas/environment-v1alpha1.json +0 -0
  195. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/__init__.py +0 -0
  196. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/conftest.py +0 -0
  197. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_a_datalayer_sandbox_can_be_interrupted.py +0 -0
  198. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_bridge_mount.py +0 -0
  199. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_builds.py +0 -0
  200. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_cli_exec.py +0 -0
  201. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_cli_repl.py +0 -0
  202. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_client.py +0 -0
  203. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_client_contents.py +0 -0
  204. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_client_files.py +0 -0
  205. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_client_outcome_error_output.py +0 -0
  206. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_cloudflare.py +0 -0
  207. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_commands_envelope.py +0 -0
  208. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_console.py +0 -0
  209. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_contents_contract.py +0 -0
  210. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_contents_live_matrix.py +0 -0
  211. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_coreweave.py +0 -0
  212. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_datalayer_sandbox.py +0 -0
  213. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_daytona.py +0 -0
  214. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_e2b.py +0 -0
  215. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_environment_accounts.py +0 -0
  216. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_environment_bases.py +0 -0
  217. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_environment_breaker.py +0 -0
  218. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_environment_build_secrets.py +0 -0
  219. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_environment_builders.py +0 -0
  220. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_environment_canonical.py +0 -0
  221. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_environment_conformance.py +0 -0
  222. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_environment_constraints.py +0 -0
  223. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_environment_contract.py +0 -0
  224. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_environment_cross_variant_report.py +0 -0
  225. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_environment_datalayer_builder.py +0 -0
  226. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_environment_daytona_builder.py +0 -0
  227. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_environment_doctor.py +0 -0
  228. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_environment_e2b_builder.py +0 -0
  229. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_environment_errors.py +0 -0
  230. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_environment_image_import.py +0 -0
  231. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_environment_lifecycle.py +0 -0
  232. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_environment_live_matrix.py +0 -0
  233. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_environment_managed_builders.py +0 -0
  234. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_environment_modal_builder.py +0 -0
  235. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_environment_redact.py +0 -0
  236. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_environment_resolve.py +0 -0
  237. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_environment_spec.py +0 -0
  238. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_eval.py +0 -0
  239. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_every_variant_has_a_real_interrupt.py +0 -0
  240. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_factory.py +0 -0
  241. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_google_colab.py +0 -0
  242. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_integration.py +0 -0
  243. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_jupyter_ingress.py +0 -0
  244. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_jupyter_server.py +0 -0
  245. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_jupyter_server_streaming.py +0 -0
  246. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_kaggle.py +0 -0
  247. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_kaggle_execute.py +0 -0
  248. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_kaggle_live.py +0 -0
  249. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_kaggle_session.py +0 -0
  250. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_kernel_client_compatibility.py +0 -0
  251. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_lifecycle_vocabulary.py +0 -0
  252. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_manage.py +0 -0
  253. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_manage_datalayer.py +0 -0
  254. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_modal_google_colab_sandbox.py +0 -0
  255. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_modal_session.py +0 -0
  256. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_models.py +0 -0
  257. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_output_line_fidelity.py +0 -0
  258. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_provider_catalog_names.py +0 -0
  259. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_provider_ingress.py +0 -0
  260. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_providers.py +0 -0
  261. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_sandboxes.py +0 -0
  262. {code_sandboxes-1.9.6 → code_sandboxes-1.9.8}/tests/test_the_kill_relaunch_drill.py +0 -0
@@ -8,6 +8,30 @@
8
8
 
9
9
  ## Unreleased
10
10
 
11
+ ## 1.9.8
12
+
13
+ - **Every page of a scan's findings is read before deciding**
14
+ (`environments.attest`; PLAN_ENV.md E1-08, D-11). `describe_image_scan_
15
+ findings` paginates, and the attestor called it exactly once. Found live
16
+ on r1, 2026-09-14: the first real image with more findings than one page
17
+ had 1,547 enhanced findings, 31 of them critical, and the single-page read
18
+ saw a small enough slice that the decision passed — an image with real,
19
+ unreviewed critical vulnerabilities would have been signed and started. A
20
+ hard cap of 50 pages keeps a pathological registry from paginating
21
+ forever; hitting it logs that more findings went unread rather than
22
+ pretending the scan was complete.
23
+
24
+ ## 1.9.7
25
+
26
+ - **cosign signs again under `--use-signing-config=false`** (`environments
27
+ .attest`; PLAN_ENV.md E1-09). cosign 3.1.3 defaults `--use-signing-config`
28
+ to `true`: a TUF-provided signing config now names the service URLs,
29
+ including a transparency log, and `--tlog-upload=false` alone no longer
30
+ overrides that — cosign refused the combination outright (found live on
31
+ r1, 2026-09-14, the first real signature this pipeline ever attempted).
32
+ Turning the signing config off restores the plain, flag-driven behavior
33
+ `--tlog-upload=false` already asks for.
34
+
11
35
  ## 1.9.6
12
36
 
13
37
  - **`datalayer/python-cpu`'s `2026.09` channel points at the patched base**
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: code_sandboxes
3
- Version: 1.9.6
3
+ Version: 1.9.8
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.6"
6
+ __version__ = "1.9.8"
@@ -289,32 +289,70 @@ class Attestor:
289
289
  detail={"repository": repository, "digest": digest},
290
290
  )
291
291
 
292
+ #: A hard cap on pages read, so a registry that never stops paginating
293
+ #: cannot wedge a build forever — this many pages is already far past any
294
+ #: real image's own finding count (E1-08, found live 2026-09-14: see
295
+ #: `_describe`'s own docstring for why a page limit is not optional).
296
+ _MAX_FINDING_PAGES = 50
297
+
292
298
  def _describe(self, *, repository: str, digest: str) -> tuple[str, dict[str, Any]]:
293
- """One `DescribeImageScanFindings`, as a status and what it answered."""
294
- try:
295
- answer = self._client().describe_image_scan_findings(
296
- repositoryName=repository, imageId={"imageDigest": digest}
297
- )
298
- except Exception as error:
299
- if _is_in_progress(error):
300
- return "IN_PROGRESS", {}
301
- if _is_missing(error):
299
+ """Every `DescribeImageScanFindings` page, as one status and one answer.
300
+
301
+ ECR paginates enhanced findings — `nextToken`, not a field this call
302
+ can ask to skip — and a single unpaginated call answers only its first
303
+ page. Found live, 2026-09-14: the first real artifact this pipeline
304
+ scanned had 1,547 enhanced findings across many pages and 31 of them
305
+ critical, and a single-page read passed a decision that should have
306
+ blocked, because none of those 31 were in the one page it happened to
307
+ see. Every page is read and merged before `decide` ever runs.
308
+ """
309
+ pages = 0
310
+ status = ""
311
+ enhanced: list[Any] = []
312
+ basic: list[Any] = []
313
+ completed_at: Any = None
314
+ token: str | None = None
315
+ while True:
316
+ try:
317
+ kwargs: dict[str, Any] = {
318
+ "repositoryName": repository,
319
+ "imageId": {"imageDigest": digest},
320
+ }
321
+ if token:
322
+ kwargs["nextToken"] = token
323
+ answer = self._client().describe_image_scan_findings(**kwargs)
324
+ except Exception as error:
325
+ if _is_in_progress(error):
326
+ return "IN_PROGRESS", {}
327
+ if _is_missing(error):
328
+ raise EnvironmentsError(
329
+ PROVIDER_ERROR,
330
+ f"The registry has no scan for {digest}: {error}",
331
+ detail={"repository": repository, "digest": digest},
332
+ ) from error
302
333
  raise EnvironmentsError(
303
334
  PROVIDER_ERROR,
304
- f"The registry has no scan for {digest}: {error}",
335
+ f"The scan of {digest} could not be read: {error}",
305
336
  detail={"repository": repository, "digest": digest},
306
337
  ) from error
307
- raise EnvironmentsError(
308
- PROVIDER_ERROR,
309
- f"The scan of {digest} could not be read: {error}",
310
- detail={"repository": repository, "digest": digest},
311
- ) from error
312
- status = str(((answer.get("imageScanStatus") or {}).get("status")) or "")
313
- findings = answer.get("imageScanFindings") or {}
338
+ status = str(((answer.get("imageScanStatus") or {}).get("status")) or "")
339
+ findings = answer.get("imageScanFindings") or {}
340
+ enhanced.extend(findings.get("enhancedFindings") or [])
341
+ basic.extend(findings.get("findings") or [])
342
+ completed_at = findings.get("imageScanCompletedAt") or completed_at
343
+ pages += 1
344
+ token = answer.get("nextToken")
345
+ if not token or pages >= self._MAX_FINDING_PAGES:
346
+ if token:
347
+ self._log(
348
+ f"Stopped reading {digest}'s scan after {pages} pages, "
349
+ "with more findings still unread"
350
+ )
351
+ break
314
352
  return status, {
315
- "findings": findings,
316
- "completed_at": findings.get("imageScanCompletedAt"),
317
- "scanner": "ECR enhanced" if findings.get("enhancedFindings") else "ECR basic",
353
+ "findings": {"enhancedFindings": enhanced, "findings": basic},
354
+ "completed_at": completed_at,
355
+ "scanner": "ECR enhanced" if enhanced else "ECR basic",
318
356
  }
319
357
 
320
358
  @staticmethod
@@ -380,6 +418,17 @@ class Attestor:
380
418
  # even answer. The matching verify-side omission is fixed in
381
419
  # `datalayer_operator.services.environment_signatures`.
382
420
  "--tlog-upload=false",
421
+ # cosign 3.1.3 defaults `--use-signing-config` to `true`: a
422
+ # TUF-provided signing config now names the service URLs,
423
+ # including a transparency log, and `--tlog-upload=false` alone
424
+ # no longer overrides that — cosign refuses the combination
425
+ # outright, "not supported with --signing-config or
426
+ # --use-signing-config" (found live, 2026-09-14, the first real
427
+ # sign this worker's own pinned cosign ever ran). Turning the
428
+ # signing config off restores the plain, flag-driven behavior
429
+ # `--tlog-upload=false` already asks for, and needs no network
430
+ # call of its own to fetch one.
431
+ "--use-signing-config=false",
383
432
  "--key",
384
433
  self._key,
385
434
  reference,
@@ -90,9 +90,14 @@ class FakeEcr:
90
90
  enhanced_findings=True,
91
91
  signed: set[str] | None = None,
92
92
  manifest: dict | None = None,
93
+ pages: list[list[dict]] | None = None,
93
94
  ) -> None:
94
95
  self.statuses = list(statuses)
95
96
  self.findings = list(findings)
97
+ #: Each entry is one `describe_image_scan_findings` page's own
98
+ #: findings, read in order and merged by `_describe` — overrides
99
+ #: `findings` when given, to test reading more than one page.
100
+ self.pages = pages
96
101
  self.enhanced_findings = enhanced_findings
97
102
  self.signed = set(signed or set())
98
103
  self.manifest = manifest
@@ -115,7 +120,7 @@ class FakeEcr:
115
120
  ]
116
121
  }
117
122
 
118
- def describe_image_scan_findings(self, repositoryName, imageId): # noqa: N803 - boto3's spelling
123
+ def describe_image_scan_findings(self, repositoryName, imageId, nextToken=None): # noqa: N803 - boto3's spelling
119
124
  self.asked += 1
120
125
  self.scanned.append(imageId["imageDigest"])
121
126
  status = self.statuses[min(self.asked, len(self.statuses)) - 1]
@@ -132,6 +137,18 @@ class FakeEcr:
132
137
  error.response = {"Error": {"Code": "ImageNotFoundException"}}
133
138
  raise error
134
139
  key = "enhancedFindings" if self.enhanced_findings else "findings"
140
+ if self.pages is not None:
141
+ index = int(nextToken or "0")
142
+ answer = {
143
+ "imageScanStatus": {"status": status},
144
+ "imageScanFindings": {
145
+ key: list(self.pages[index]),
146
+ "imageScanCompletedAt": "2026-09-12T09:00:00Z",
147
+ },
148
+ }
149
+ if index + 1 < len(self.pages):
150
+ answer["nextToken"] = str(index + 1)
151
+ return answer
135
152
  return {
136
153
  "imageScanStatus": {"status": status},
137
154
  "imageScanFindings": {
@@ -327,6 +344,31 @@ class TestTheScan:
327
344
  assert raised.value.code.code == "DL_ENV_PROVIDER_ERROR"
328
345
  assert raised.value.detail["digest"] == DIGEST
329
346
 
347
+ def test_every_page_of_findings_is_read_before_deciding(self) -> None:
348
+ """Found live, 2026-09-14: a single unpaginated call answered only its
349
+ first page, and a real image with 1,547 findings across many pages
350
+ passed a decision that should have blocked — none of its 31 critical
351
+ findings were on the one page a single call happened to see. Every
352
+ page is now read and merged before `decide` runs."""
353
+ page_1 = [enhanced("CVE-2026-1111", "LOW")]
354
+ page_2 = [enhanced("CVE-2026-1234", "CRITICAL", fixed="2.9.15")]
355
+ page_3 = [enhanced("CVE-2026-2222", "MEDIUM")]
356
+ ecr = FakeEcr(pages=[page_1, page_2, page_3])
357
+ decision = an_attestor(ecr=ecr).scan(repository=REPOSITORY, digest=DIGEST)
358
+ assert decision.decision == "blocked"
359
+ assert [finding.id for finding in decision.blocking] == ["CVE-2026-1234"]
360
+ assert decision.body()["counts"] == {"LOW": 1, "CRITICAL": 1, "MEDIUM": 1}
361
+ assert ecr.asked == 3
362
+
363
+ def test_reading_pages_stops_at_the_cap_rather_than_paginating_forever(self) -> None:
364
+ pages = [
365
+ [enhanced(f"CVE-2026-{n:04d}", "LOW")] for n in range(Attestor._MAX_FINDING_PAGES + 5)
366
+ ]
367
+ ecr = FakeEcr(pages=pages)
368
+ decision = an_attestor(ecr=ecr).scan(repository=REPOSITORY, digest=DIGEST)
369
+ assert decision.decision == "pass"
370
+ assert ecr.asked == Attestor._MAX_FINDING_PAGES
371
+
330
372
  IMAGE = "sha256:" + "bb" * 32
331
373
  ATTESTATION = "sha256:" + "cc" * 32
332
374
 
@@ -418,6 +460,10 @@ class TestTheSignature:
418
460
  # default and prompts for consent to publish an immutable
419
461
  # record — the wrong default for a private environment.
420
462
  "--tlog-upload=false",
463
+ # cosign 3.1.3 defaults to a TUF-provided signing config that
464
+ # `--tlog-upload=false` alone can no longer override (found live
465
+ # 2026-09-14): turned off so the plain flag is honored again.
466
+ "--use-signing-config=false",
421
467
  "--key",
422
468
  KEY,
423
469
  f"{REGISTRY}/{REPOSITORY}@{DIGEST}",
File without changes
File without changes
File without changes
File without changes