jupyverse 0.10.1__tar.gz → 0.10.3__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 (257) hide show
  1. {jupyverse-0.10.1 → jupyverse-0.10.3}/.pre-commit-config.yaml +1 -1
  2. {jupyverse-0.10.1 → jupyverse-0.10.3}/CHANGELOG.md +8 -0
  3. {jupyverse-0.10.1 → jupyverse-0.10.3}/PKG-INFO +3 -3
  4. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/kernels/fps_kernels/kernel_server/server.py +2 -2
  5. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/kernels/pyproject.toml +1 -1
  6. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/yjs/fps_yjs/main.py +1 -1
  7. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/yjs/fps_yjs/routes.py +9 -6
  8. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/yjs/pyproject.toml +1 -1
  9. {jupyverse-0.10.1 → jupyverse-0.10.3}/pyproject.toml +3 -3
  10. {jupyverse-0.10.1 → jupyverse-0.10.3}/tests/test_kernels.py +82 -75
  11. jupyverse-0.10.3/tests/utils.py +385 -0
  12. jupyverse-0.10.1/tests/utils.py +0 -141
  13. {jupyverse-0.10.1 → jupyverse-0.10.3}/.devcontainer/devcontainer.json +0 -0
  14. {jupyverse-0.10.1 → jupyverse-0.10.3}/.devcontainer/requirements.txt +0 -0
  15. {jupyverse-0.10.1 → jupyverse-0.10.3}/.github/workflows/publish-release.yml +0 -0
  16. {jupyverse-0.10.1 → jupyverse-0.10.3}/.github/workflows/test.yml +0 -0
  17. {jupyverse-0.10.1 → jupyverse-0.10.3}/.gitignore +0 -0
  18. {jupyverse-0.10.1 → jupyverse-0.10.3}/COPYING.md +0 -0
  19. {jupyverse-0.10.1 → jupyverse-0.10.3}/README.md +0 -0
  20. {jupyverse-0.10.1 → jupyverse-0.10.3}/binder/environment.yml +0 -0
  21. {jupyverse-0.10.1 → jupyverse-0.10.3}/binder/jupyter_notebook_config.py +0 -0
  22. {jupyverse-0.10.1 → jupyverse-0.10.3}/binder/postBuild +0 -0
  23. {jupyverse-0.10.1 → jupyverse-0.10.3}/binder/start +0 -0
  24. {jupyverse-0.10.1 → jupyverse-0.10.3}/docs/index.md +0 -0
  25. {jupyverse-0.10.1 → jupyverse-0.10.3}/docs/install.md +0 -0
  26. {jupyverse-0.10.1 → jupyverse-0.10.3}/docs/jupyter.svg +0 -0
  27. {jupyverse-0.10.1 → jupyverse-0.10.3}/docs/plugins/auth.md +0 -0
  28. {jupyverse-0.10.1 → jupyverse-0.10.3}/docs/plugins/contents.md +0 -0
  29. {jupyverse-0.10.1 → jupyverse-0.10.3}/docs/plugins/frontend.md +0 -0
  30. {jupyverse-0.10.1 → jupyverse-0.10.3}/docs/plugins/jupyterlab.md +0 -0
  31. {jupyverse-0.10.1 → jupyverse-0.10.3}/docs/plugins/kernels.md +0 -0
  32. {jupyverse-0.10.1 → jupyverse-0.10.3}/docs/plugins/lab.md +0 -0
  33. {jupyverse-0.10.1 → jupyverse-0.10.3}/docs/plugins/login.md +0 -0
  34. {jupyverse-0.10.1 → jupyverse-0.10.3}/docs/plugins/nbconvert.md +0 -0
  35. {jupyverse-0.10.1 → jupyverse-0.10.3}/docs/plugins/notebook.md +0 -0
  36. {jupyverse-0.10.1 → jupyverse-0.10.3}/docs/plugins/resource_usage.md +0 -0
  37. {jupyverse-0.10.1 → jupyverse-0.10.3}/docs/plugins/terminals.md +0 -0
  38. {jupyverse-0.10.1 → jupyverse-0.10.3}/docs/plugins/yjs.md +0 -0
  39. {jupyverse-0.10.1 → jupyverse-0.10.3}/docs/tutorials/jupyterhub_jupyverse_deployment.md +0 -0
  40. {jupyverse-0.10.1 → jupyverse-0.10.3}/docs/tutorials/standalone_jupyverse_deployment.md +0 -0
  41. {jupyverse-0.10.1 → jupyverse-0.10.3}/docs/usage/microservices.md +0 -0
  42. {jupyverse-0.10.1 → jupyverse-0.10.3}/docs/usage/multi_user.md +0 -0
  43. {jupyverse-0.10.1 → jupyverse-0.10.3}/docs/usage/single_user.md +0 -0
  44. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse/__init__.py +0 -0
  45. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse/py.typed +0 -0
  46. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse_api/COPYING.md +0 -0
  47. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse_api/README.md +0 -0
  48. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse_api/jupyverse_api/__init__.py +0 -0
  49. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse_api/jupyverse_api/app/__init__.py +0 -0
  50. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse_api/jupyverse_api/auth/__init__.py +0 -0
  51. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse_api/jupyverse_api/auth/models.py +0 -0
  52. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse_api/jupyverse_api/cli.py +0 -0
  53. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse_api/jupyverse_api/contents/__init__.py +0 -0
  54. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse_api/jupyverse_api/contents/models.py +0 -0
  55. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse_api/jupyverse_api/exceptions.py +0 -0
  56. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse_api/jupyverse_api/file_id/__init__.py +0 -0
  57. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse_api/jupyverse_api/frontend/__init__.py +0 -0
  58. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse_api/jupyverse_api/jupyterlab/__init__.py +0 -0
  59. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse_api/jupyverse_api/kernel/__init__.py +0 -0
  60. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse_api/jupyverse_api/kernels/__init__.py +0 -0
  61. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse_api/jupyverse_api/kernels/models.py +0 -0
  62. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse_api/jupyverse_api/lab/__init__.py +0 -0
  63. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse_api/jupyverse_api/login/__init__.py +0 -0
  64. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse_api/jupyverse_api/main/__init__.py +0 -0
  65. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse_api/jupyverse_api/nbconvert/__init__.py +0 -0
  66. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse_api/jupyverse_api/notebook/__init__.py +0 -0
  67. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse_api/jupyverse_api/py.typed +0 -0
  68. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse_api/jupyverse_api/resource_usage/__init__.py +0 -0
  69. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse_api/jupyverse_api/terminals/__init__.py +0 -0
  70. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse_api/jupyverse_api/terminals/models.py +0 -0
  71. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse_api/jupyverse_api/yjs/__init__.py +0 -0
  72. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse_api/jupyverse_api/yjs/models.py +0 -0
  73. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse_api/pyproject.toml +0 -0
  74. {jupyverse-0.10.1 → jupyverse-0.10.3}/jupyverse_api/tests/test_resource_lock.py +0 -0
  75. {jupyverse-0.10.1 → jupyverse-0.10.3}/mkdocs.yml +0 -0
  76. {jupyverse-0.10.1 → jupyverse-0.10.3}/notebooks/admin_users.ipynb +0 -0
  77. {jupyverse-0.10.1 → jupyverse-0.10.3}/notebooks/admin_users.py +0 -0
  78. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth/COPYING.md +0 -0
  79. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth/README.md +0 -0
  80. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth/fps_auth/__init__.py +0 -0
  81. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth/fps_auth/backends.py +0 -0
  82. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth/fps_auth/config.py +0 -0
  83. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth/fps_auth/db.py +0 -0
  84. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth/fps_auth/main.py +0 -0
  85. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth/fps_auth/models.py +0 -0
  86. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth/fps_auth/py.typed +0 -0
  87. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth/fps_auth/routes.py +0 -0
  88. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth/pyproject.toml +0 -0
  89. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth_fief/COPYING.md +0 -0
  90. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth_fief/README.md +0 -0
  91. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth_fief/fps_auth_fief/__init__.py +0 -0
  92. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth_fief/fps_auth_fief/backend.py +0 -0
  93. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth_fief/fps_auth_fief/config.py +0 -0
  94. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth_fief/fps_auth_fief/main.py +0 -0
  95. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth_fief/fps_auth_fief/py.typed +0 -0
  96. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth_fief/fps_auth_fief/routes.py +0 -0
  97. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth_fief/pyproject.toml +0 -0
  98. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth_jupyterhub/COPYING.md +0 -0
  99. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth_jupyterhub/README.md +0 -0
  100. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth_jupyterhub/fps_auth_jupyterhub/__init__.py +0 -0
  101. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth_jupyterhub/fps_auth_jupyterhub/config.py +0 -0
  102. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth_jupyterhub/fps_auth_jupyterhub/db.py +0 -0
  103. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth_jupyterhub/fps_auth_jupyterhub/launch.py +0 -0
  104. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth_jupyterhub/fps_auth_jupyterhub/main.py +0 -0
  105. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth_jupyterhub/fps_auth_jupyterhub/models.py +0 -0
  106. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth_jupyterhub/fps_auth_jupyterhub/py.typed +0 -0
  107. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth_jupyterhub/fps_auth_jupyterhub/routes.py +0 -0
  108. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/auth_jupyterhub/pyproject.toml +0 -0
  109. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/contents/COPYING.md +0 -0
  110. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/contents/README.md +0 -0
  111. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/contents/fps_contents/__init__.py +0 -0
  112. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/contents/fps_contents/main.py +0 -0
  113. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/contents/fps_contents/py.typed +0 -0
  114. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/contents/fps_contents/routes.py +0 -0
  115. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/contents/pyproject.toml +0 -0
  116. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/file_id/COPYING.md +0 -0
  117. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/file_id/README.md +0 -0
  118. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/file_id/fps_file_id/__init__.py +0 -0
  119. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/file_id/fps_file_id/file_id.py +0 -0
  120. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/file_id/fps_file_id/main.py +0 -0
  121. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/file_id/fps_file_id/py.typed +0 -0
  122. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/file_id/pyproject.toml +0 -0
  123. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/frontend/COPYING.md +0 -0
  124. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/frontend/README.md +0 -0
  125. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/frontend/fps_frontend/__init__.py +0 -0
  126. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/frontend/fps_frontend/main.py +0 -0
  127. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/frontend/fps_frontend/py.typed +0 -0
  128. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/frontend/pyproject.toml +0 -0
  129. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/jupyterlab/COPYING.md +0 -0
  130. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/jupyterlab/README.md +0 -0
  131. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/jupyterlab/fps_jupyterlab/__init__.py +0 -0
  132. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/jupyterlab/fps_jupyterlab/index.py +0 -0
  133. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/jupyterlab/fps_jupyterlab/main.py +0 -0
  134. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/jupyterlab/fps_jupyterlab/py.typed +0 -0
  135. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/jupyterlab/fps_jupyterlab/routes.py +0 -0
  136. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/jupyterlab/pyproject.toml +0 -0
  137. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/kernel_subprocess/COPYING.md +0 -0
  138. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/kernel_subprocess/README.md +0 -0
  139. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/kernel_subprocess/fps_kernel_subprocess/__init__.py +0 -0
  140. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/kernel_subprocess/fps_kernel_subprocess/connect.py +0 -0
  141. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/kernel_subprocess/fps_kernel_subprocess/kernel_subprocess.py +0 -0
  142. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/kernel_subprocess/fps_kernel_subprocess/main.py +0 -0
  143. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/kernel_subprocess/fps_kernel_subprocess/py.typed +0 -0
  144. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/kernel_subprocess/pyproject.toml +0 -0
  145. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/kernels/COPYING.md +0 -0
  146. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/kernels/README.md +0 -0
  147. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/kernels/fps_kernels/__init__.py +0 -0
  148. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/kernels/fps_kernels/kernel_driver/__init__.py +0 -0
  149. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/kernels/fps_kernels/kernel_driver/driver.py +0 -0
  150. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/kernels/fps_kernels/kernel_driver/kernelspec.py +0 -0
  151. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/kernels/fps_kernels/kernel_driver/message.py +0 -0
  152. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/kernels/fps_kernels/kernel_driver/paths.py +0 -0
  153. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/kernels/fps_kernels/kernel_server/__init__.py +0 -0
  154. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/kernels/fps_kernels/kernel_server/message.py +0 -0
  155. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/kernels/fps_kernels/main.py +0 -0
  156. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/kernels/fps_kernels/py.typed +0 -0
  157. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/kernels/fps_kernels/routes.py +0 -0
  158. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/kernels/tests/test_kernel_launcher.py +0 -0
  159. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/lab/COPYING.md +0 -0
  160. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/lab/README.md +0 -0
  161. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/lab/fps_lab/__init__.py +0 -0
  162. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/lab/fps_lab/main.py +0 -0
  163. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/lab/fps_lab/py.typed +0 -0
  164. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/lab/fps_lab/routes.py +0 -0
  165. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/lab/fps_lab/static/favicon.ico +0 -0
  166. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/lab/pyproject.toml +0 -0
  167. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/login/COPYING.md +0 -0
  168. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/login/README.md +0 -0
  169. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/login/fps_login/__init__.py +0 -0
  170. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/login/fps_login/main.py +0 -0
  171. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/login/fps_login/py.typed +0 -0
  172. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/login/fps_login/routes.py +0 -0
  173. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/login/fps_login/static/favicons/favicon-busy-1.ico +0 -0
  174. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/login/fps_login/static/favicons/favicon-busy-2.ico +0 -0
  175. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/login/fps_login/static/favicons/favicon-busy-3.ico +0 -0
  176. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/login/fps_login/static/favicons/favicon-file.ico +0 -0
  177. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/login/fps_login/static/favicons/favicon-notebook.ico +0 -0
  178. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/login/fps_login/static/favicons/favicon-terminal.ico +0 -0
  179. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/login/fps_login/static/favicons/favicon.ico +0 -0
  180. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/login/fps_login/static/index.html +0 -0
  181. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/login/fps_login/static/logo/github.svg +0 -0
  182. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/login/fps_login/static/logo/logo.png +0 -0
  183. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/login/fps_login/static/style/index.css +0 -0
  184. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/login/pyproject.toml +0 -0
  185. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/nbconvert/COPYING.md +0 -0
  186. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/nbconvert/README.md +0 -0
  187. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/nbconvert/fps_nbconvert/__init__.py +0 -0
  188. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/nbconvert/fps_nbconvert/main.py +0 -0
  189. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/nbconvert/fps_nbconvert/py.typed +0 -0
  190. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/nbconvert/fps_nbconvert/routes.py +0 -0
  191. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/nbconvert/pyproject.toml +0 -0
  192. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/noauth/COPYING.md +0 -0
  193. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/noauth/README.md +0 -0
  194. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/noauth/fps_noauth/__init__.py +0 -0
  195. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/noauth/fps_noauth/backends.py +0 -0
  196. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/noauth/fps_noauth/main.py +0 -0
  197. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/noauth/fps_noauth/py.typed +0 -0
  198. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/noauth/pyproject.toml +0 -0
  199. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/notebook/COPYING.md +0 -0
  200. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/notebook/README.md +0 -0
  201. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/notebook/fps_notebook/__init__.py +0 -0
  202. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/notebook/fps_notebook/main.py +0 -0
  203. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/notebook/fps_notebook/py.typed +0 -0
  204. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/notebook/fps_notebook/routes.py +0 -0
  205. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/notebook/pyproject.toml +0 -0
  206. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/resource_usage/COPYING.md +0 -0
  207. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/resource_usage/README.md +0 -0
  208. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/resource_usage/fps_resource_usage/__init__.py +0 -0
  209. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/resource_usage/fps_resource_usage/main.py +0 -0
  210. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/resource_usage/fps_resource_usage/py.typed +0 -0
  211. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/resource_usage/fps_resource_usage/routes.py +0 -0
  212. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/resource_usage/pyproject.toml +0 -0
  213. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/terminals/COPYING.md +0 -0
  214. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/terminals/README.md +0 -0
  215. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/terminals/fps_terminals/__init__.py +0 -0
  216. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/terminals/fps_terminals/main.py +0 -0
  217. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/terminals/fps_terminals/py.typed +0 -0
  218. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/terminals/fps_terminals/routes.py +0 -0
  219. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/terminals/fps_terminals/server.py +0 -0
  220. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/terminals/fps_terminals/win_server.py +0 -0
  221. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/terminals/pyproject.toml +0 -0
  222. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/webdav/COPYING.md +0 -0
  223. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/webdav/README.md +0 -0
  224. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/webdav/fps_webdav/__init__.py +0 -0
  225. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/webdav/fps_webdav/config.py +0 -0
  226. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/webdav/fps_webdav/main.py +0 -0
  227. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/webdav/fps_webdav/py.typed +0 -0
  228. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/webdav/fps_webdav/routes.py +0 -0
  229. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/webdav/pyproject.toml +0 -0
  230. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/webdav/tests/conftest.py +0 -0
  231. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/webdav/tests/test_webdav.py +0 -0
  232. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/yjs/COPYING.md +0 -0
  233. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/yjs/README.md +0 -0
  234. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/yjs/fps_yjs/__init__.py +0 -0
  235. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/yjs/fps_yjs/py.typed +0 -0
  236. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/yjs/fps_yjs/ywebsocket/__init__.py +0 -0
  237. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/yjs/fps_yjs/ywebsocket/asgi_server.py +0 -0
  238. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/yjs/fps_yjs/ywebsocket/awareness.py +0 -0
  239. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/yjs/fps_yjs/ywebsocket/django_channels_consumer.py +0 -0
  240. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/yjs/fps_yjs/ywebsocket/websocket.py +0 -0
  241. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/yjs/fps_yjs/ywebsocket/websocket_provider.py +0 -0
  242. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/yjs/fps_yjs/ywebsocket/websocket_server.py +0 -0
  243. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/yjs/fps_yjs/ywebsocket/yroom.py +0 -0
  244. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/yjs/fps_yjs/ywebsocket/ystore.py +0 -0
  245. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/yjs/fps_yjs/ywebsocket/yutils.py +0 -0
  246. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/yjs/fps_yjs/ywidgets/__init__.py +0 -0
  247. {jupyverse-0.10.1 → jupyverse-0.10.3}/plugins/yjs/fps_yjs/ywidgets/widgets.py +0 -0
  248. {jupyverse-0.10.1 → jupyverse-0.10.3}/pytest.ini +0 -0
  249. {jupyverse-0.10.1 → jupyverse-0.10.3}/tests/conftest.py +0 -0
  250. {jupyverse-0.10.1 → jupyverse-0.10.3}/tests/data/notebook0.ipynb +0 -0
  251. {jupyverse-0.10.1 → jupyverse-0.10.3}/tests/data/notebook1.ipynb +0 -0
  252. {jupyverse-0.10.1 → jupyverse-0.10.3}/tests/test_app.py +0 -0
  253. {jupyverse-0.10.1 → jupyverse-0.10.3}/tests/test_auth.py +0 -0
  254. {jupyverse-0.10.1 → jupyverse-0.10.3}/tests/test_contents.py +0 -0
  255. {jupyverse-0.10.1 → jupyverse-0.10.3}/tests/test_execute.py +0 -0
  256. {jupyverse-0.10.1 → jupyverse-0.10.3}/tests/test_server.py +0 -0
  257. {jupyverse-0.10.1 → jupyverse-0.10.3}/tests/test_settings.py +0 -0
@@ -16,7 +16,7 @@ repos:
16
16
  - id: trailing-whitespace
17
17
 
18
18
  - repo: https://github.com/astral-sh/ruff-pre-commit
19
- rev: v0.12.2
19
+ rev: v0.12.3
20
20
  hooks:
21
21
  - id: ruff
22
22
  args: ["--fix"]
@@ -1,5 +1,13 @@
1
1
  # Version history
2
2
 
3
+ ## 0.10.3
4
+
5
+ - Propagate `yjs` settings.
6
+
7
+ ## 0.10.2
8
+
9
+ - Rework `test_kernels.py` to use ASGI transport.
10
+
3
11
  ## 0.10.1
4
12
 
5
13
  - Fix optional dependencies pinning.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jupyverse
3
- Version: 0.10.1
3
+ Version: 0.10.3
4
4
  Summary: A set of FPS plugins implementing a Jupyter server
5
5
  Project-URL: Homepage, https://jupyter.org
6
6
  Author-email: Jupyter Development Team <jupyter@googlegroups.com>
@@ -13,11 +13,11 @@ Requires-Dist: fps-contents<0.11.0,>=0.10.0
13
13
  Requires-Dist: fps-file-id<0.3.0,>=0.2.0
14
14
  Requires-Dist: fps-frontend<0.10.0,>=0.9.0
15
15
  Requires-Dist: fps-kernel-subprocess<0.2.0,>=0.1.0
16
- Requires-Dist: fps-kernels<0.10.0,>=0.9.0
16
+ Requires-Dist: fps-kernels<0.10.0,>=0.9.1
17
17
  Requires-Dist: fps-lab<0.10.0,>=0.9.0
18
18
  Requires-Dist: fps-nbconvert<0.10.0,>=0.9.0
19
19
  Requires-Dist: fps-terminals<0.10.0,>=0.9.0
20
- Requires-Dist: fps-yjs<0.11.0,>=0.10.0
20
+ Requires-Dist: fps-yjs<0.11.0,>=0.10.1
21
21
  Requires-Dist: fps[anycorn,click,fastapi]<0.5.0,>=0.4.0
22
22
  Requires-Dist: jupyverse-api<0.11.0,>=0.10.0
23
23
  Requires-Dist: rich-click<2,>=1.6.1
@@ -6,7 +6,7 @@ from datetime import datetime, timezone
6
6
 
7
7
  from anyio import TASK_STATUS_IGNORED, Event, create_task_group, move_on_after
8
8
  from anyio.abc import TaskStatus
9
- from fastapi import WebSocket, WebSocketDisconnect
9
+ from fastapi import WebSocket
10
10
  from starlette.websockets import WebSocketState
11
11
 
12
12
  from jupyverse_api.kernel import DefaultKernelFactory, KernelFactory
@@ -160,7 +160,7 @@ class KernelServer:
160
160
  async def listen_web(self, websocket: AcceptedWebSocket, stop_event: Event):
161
161
  try:
162
162
  await self.send_to_kernel(websocket)
163
- except WebSocketDisconnect:
163
+ except BaseException:
164
164
  pass
165
165
  finally:
166
166
  stop_event.set()
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "fps_kernels"
7
- version = "0.9.0"
7
+ version = "0.9.1"
8
8
  description = "An FPS plugin for the kernels API"
9
9
  keywords = ["jupyter", "server", "fastapi", "plugins"]
10
10
  requires-python = ">=3.9"
@@ -27,7 +27,7 @@ class YjsModule(Module):
27
27
  file_id = await self.get(FileId) # type: ignore[type-abstract]
28
28
  lifespan = await self.get(Lifespan)
29
29
 
30
- self.yjs = _Yjs(app, auth, contents, file_id, lifespan)
30
+ self.yjs = _Yjs(app, auth, contents, file_id, lifespan, self.config)
31
31
 
32
32
  async with create_task_group() as tg:
33
33
  await tg.start(self.yjs.start)
@@ -25,7 +25,7 @@ from jupyverse_api.auth import Auth, User
25
25
  from jupyverse_api.contents import Contents
26
26
  from jupyverse_api.file_id import FileId
27
27
  from jupyverse_api.main import Lifespan
28
- from jupyverse_api.yjs import Yjs
28
+ from jupyverse_api.yjs import Yjs, YjsConfig
29
29
  from jupyverse_api.yjs.models import CreateDocumentSession
30
30
 
31
31
  from .ywebsocket.websocket import Websocket
@@ -51,11 +51,13 @@ class _Yjs(Yjs):
51
51
  contents: Contents,
52
52
  file_id: FileId,
53
53
  lifespan: Lifespan,
54
+ config: YjsConfig,
54
55
  ) -> None:
55
56
  super().__init__(app=app, auth=auth)
56
57
  self.contents = contents
57
58
  self.file_id = file_id
58
59
  self.lifespan = lifespan
60
+ self.config = config
59
61
  if Widgets is None:
60
62
  self.widgets = None
61
63
  else:
@@ -63,7 +65,7 @@ class _Yjs(Yjs):
63
65
 
64
66
  async def start(self, *, task_status: TaskStatus[None] = TASK_STATUS_IGNORED) -> None:
65
67
  async with create_task_group() as tg:
66
- self.room_manager = RoomManager(self.contents, self.file_id, self.lifespan)
68
+ self.room_manager = RoomManager(self.contents, self.file_id, self.lifespan, self.config)
67
69
  tg.start_soon(self.room_manager.start)
68
70
  task_status.started()
69
71
 
@@ -166,7 +168,7 @@ class RoomManager:
166
168
  room_write_permissions: dict[str, set[YWebsocket]]
167
169
  room_lock: ResourceLock
168
170
 
169
- def __init__(self, contents: Contents, file_id: FileId, lifespan: Lifespan):
171
+ def __init__(self, contents: Contents, file_id: FileId, lifespan: Lifespan, config: YjsConfig):
170
172
  self.contents = contents
171
173
  self.file_id = file_id
172
174
  self.lifespan = lifespan
@@ -178,6 +180,7 @@ class RoomManager:
178
180
  self.room_write_permissions = {} # a dictionary of room_name:websockets that can write
179
181
  self.websocket_server = JupyterWebsocketServer(rooms_ready=False, auto_clean_rooms=False)
180
182
  self.room_lock = ResourceLock()
183
+ self.config = config
181
184
 
182
185
  async def start(self):
183
186
  async with create_task_group() as self.task_group:
@@ -364,8 +367,8 @@ class RoomManager:
364
367
  async def maybe_save_document(
365
368
  self, file_id: str, file_type: str, file_format: str, document: YBaseDoc
366
369
  ) -> None:
367
- # save after 1 second of inactivity to prevent too frequent saving
368
- await sleep(1) # FIXME: pass in config
370
+ # save after configured delay to prevent too frequent saving
371
+ await sleep(self.config.document_save_delay)
369
372
  # if the room cannot be found, don't save
370
373
  try:
371
374
  file_path = await self.get_file_path(file_id, document)
@@ -401,7 +404,7 @@ class RoomManager:
401
404
  async def maybe_clean_room(self, room, ws_path: str) -> None:
402
405
  file_id = ws_path.split(":", 2)[2]
403
406
  # keep the document for a while in case someone reconnects
404
- await sleep(60) # FIXME: pass in config
407
+ await sleep(self.config.document_cleanup_delay)
405
408
  document = self.documents[ws_path]
406
409
  document.unobserve()
407
410
  del self.documents[ws_path]
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "fps_yjs"
7
- version = "0.10.0"
7
+ version = "0.10.1"
8
8
  description = "An FPS plugin for the Yjs API"
9
9
  keywords = [ "jupyter", "server", "fastapi", "plugins" ]
10
10
  requires-python = ">=3.9"
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "jupyverse"
7
- version = "0.10.1"
7
+ version = "0.10.3"
8
8
  description = "A set of FPS plugins implementing a Jupyter server"
9
9
  keywords = ["jupyter", "server", "fastapi", "plugins"]
10
10
  requires-python = ">=3.9"
@@ -13,10 +13,10 @@ dependencies = [
13
13
  "fps-contents >=0.10.0,<0.11.0",
14
14
  "fps-file-id >=0.2.0,<0.3.0",
15
15
  "fps-kernel-subprocess >=0.1.0,<0.2.0",
16
- "fps-kernels >=0.9.0,<0.10.0",
16
+ "fps-kernels >=0.9.1,<0.10.0",
17
17
  "fps-terminals >=0.9.0,<0.10.0",
18
18
  "fps-nbconvert >=0.9.0,<0.10.0",
19
- "fps-yjs >=0.10.0,<0.11.0",
19
+ "fps-yjs >=0.10.1,<0.11.0",
20
20
  "fps-lab >=0.9.0,<0.10.0",
21
21
  "fps-frontend >=0.9.0,<0.10.0",
22
22
  "jupyverse-api >=0.10.0,<0.11.0",
@@ -8,6 +8,7 @@ from fps import get_root_module, merge_config
8
8
  from fps_kernels.kernel_server.server import KernelServer, kernels
9
9
  from httpx import AsyncClient
10
10
  from httpx_ws import aconnect_ws
11
+ from utils import ASGIWebSocketTransport
11
12
 
12
13
  from jupyverse_api.kernel import Kernel
13
14
 
@@ -16,6 +17,9 @@ os.environ["PYDEVD_DISABLE_FILE_VALIDATION"] = "1"
16
17
  CONFIG = {
17
18
  "jupyverse": {
18
19
  "type": "jupyverse",
20
+ "config": {
21
+ "start_server": False,
22
+ },
19
23
  "modules": {
20
24
  "app": {
21
25
  "type": "app",
@@ -29,9 +33,6 @@ CONFIG = {
29
33
  "contents": {
30
34
  "type": "contents",
31
35
  },
32
- "file_id": {
33
- "type": "file_id",
34
- },
35
36
  "frontend": {
36
37
  "type": "frontend",
37
38
  },
@@ -47,9 +48,6 @@ CONFIG = {
47
48
  "kernels": {
48
49
  "type": "kernels",
49
50
  },
50
- "yjs": {
51
- "type": "yjs",
52
- },
53
51
  },
54
52
  }
55
53
  }
@@ -57,87 +55,96 @@ CONFIG = {
57
55
 
58
56
  @pytest.mark.anyio
59
57
  @pytest.mark.parametrize("auth_mode", ("noauth",))
60
- async def test_kernel_messages(auth_mode, capfd, unused_tcp_port):
58
+ async def test_kernel_messages(auth_mode, capfd):
61
59
  kernel_id = "kernel_id_0"
62
60
  kernel_name = "python3"
63
61
  kernelspec_path = (
64
62
  Path(sys.prefix) / "share" / "jupyter" / "kernels" / kernel_name / "kernel.json"
65
63
  )
66
64
  assert kernelspec_path.exists()
67
- async with create_task_group() as tg:
68
- msg = {
69
- "channel": "shell",
70
- "parent_header": None,
71
- "content": None,
72
- "metadata": None,
73
- "header": {
74
- "msg_type": "msg_type_0",
75
- "msg_id": "0",
76
- },
77
- }
78
-
79
- config = merge_config(
80
- CONFIG,
81
- {
82
- "jupyverse": {
83
- "config": {"port": unused_tcp_port},
84
- "modules": {
85
- "auth": {
86
- "config": {
87
- "mode": auth_mode,
88
- }
65
+ msg = {
66
+ "channel": "shell",
67
+ "parent_header": None,
68
+ "content": None,
69
+ "metadata": None,
70
+ "header": {
71
+ "msg_type": "msg_type_0",
72
+ "msg_id": "0",
73
+ },
74
+ }
75
+
76
+ config = merge_config(
77
+ CONFIG,
78
+ {
79
+ "jupyverse": {
80
+ "modules": {
81
+ "auth": {
82
+ "config": {
83
+ "mode": auth_mode,
89
84
  }
90
- },
91
- }
92
- },
93
- )
94
- async with get_root_module(config), AsyncClient():
85
+ }
86
+ },
87
+ }
88
+ },
89
+ )
90
+ async with get_root_module(config) as root_module:
91
+ app = root_module.app
92
+ transport = ASGIWebSocketTransport(app=app)
93
+ async with AsyncClient(transport=transport, base_url="http://testserver") as client:
95
94
  kernel_server = KernelServer(
96
95
  kernelspec_path=kernelspec_path,
97
96
  capture_kernel_output=False,
98
97
  default_kernel_factory=KernelFactory(),
99
98
  )
100
- await tg.start(kernel_server.start)
101
- kernels[kernel_id] = {"server": kernel_server, "driver": None}
102
- # block msg_type_0
103
- kernel_server.block_messages("msg_type_0")
104
- async with aconnect_ws(
105
- f"http://127.0.0.1:{unused_tcp_port}/api/kernels/{kernel_id}/channels?session_id=session_id_0",
106
- ) as websocket:
107
- await websocket.send_json(msg)
108
- await sleep(0.1)
109
- out, err = capfd.readouterr()
110
- assert not err
111
-
112
- # allow only msg_type_0
113
- kernel_server.allow_messages("msg_type_0")
114
- async with aconnect_ws(
115
- f"http://127.0.0.1:{unused_tcp_port}/api/kernels/{kernel_id}/channels?session_id=session_id_0",
116
- ) as websocket:
117
- await websocket.send_json(msg)
118
- await sleep(0.1)
119
- out, err = capfd.readouterr()
120
- assert err.count("msg_type_0") == 1
121
-
122
- # block all messages
123
- kernel_server.allow_messages([])
124
- async with aconnect_ws(
125
- f"http://127.0.0.1:{unused_tcp_port}/api/kernels/{kernel_id}/channels?session_id=session_id_0",
126
- ) as websocket:
127
- await websocket.send_json(msg)
128
- await sleep(0.1)
129
- out, err = capfd.readouterr()
130
- assert not err
131
-
132
- # allow all messages
133
- kernel_server.allow_messages()
134
- async with aconnect_ws(
135
- f"http://127.0.0.1:{unused_tcp_port}/api/kernels/{kernel_id}/channels?session_id=session_id_0",
136
- ) as websocket:
137
- await websocket.send_json(msg)
138
- await sleep(0.1)
139
- out, err = capfd.readouterr()
140
- assert err.count("msg_type_0") >= 1
99
+ async with create_task_group() as tg:
100
+ await tg.start(kernel_server.start)
101
+ kernels[kernel_id] = {"server": kernel_server, "driver": None}
102
+
103
+ # block msg_type_0
104
+ kernel_server.block_messages("msg_type_0")
105
+ async with aconnect_ws(
106
+ f"http://testserver/api/kernels/{kernel_id}/channels?session_id=session_id_0",
107
+ client,
108
+ ) as websocket:
109
+ await websocket.send_json(msg)
110
+ await sleep(0.1)
111
+ out, err = capfd.readouterr()
112
+ assert not err
113
+
114
+ # allow only msg_type_0
115
+ kernel_server.allow_messages("msg_type_0")
116
+ async with aconnect_ws(
117
+ f"http://testserver/api/kernels/{kernel_id}/channels?session_id=session_id_0",
118
+ client,
119
+ ) as websocket:
120
+ await websocket.send_json(msg)
121
+ await sleep(0.1)
122
+ out, err = capfd.readouterr()
123
+ assert err.count("msg_type_0") == 1
124
+
125
+ # block all messages
126
+ kernel_server.allow_messages([])
127
+ async with aconnect_ws(
128
+ f"http://testserver/api/kernels/{kernel_id}/channels?session_id=session_id_0",
129
+ client,
130
+ ) as websocket:
131
+ await websocket.send_json(msg)
132
+ await sleep(0.1)
133
+ out, err = capfd.readouterr()
134
+ assert not err
135
+
136
+ # allow all messages
137
+ kernel_server.allow_messages()
138
+ async with aconnect_ws(
139
+ f"http://testserver/api/kernels/{kernel_id}/channels?session_id=session_id_0",
140
+ client,
141
+ ) as websocket:
142
+ await websocket.send_json(msg)
143
+ await sleep(0.1)
144
+ out, err = capfd.readouterr()
145
+ assert err.count("msg_type_0") >= 1
146
+
147
+ await kernel_server.stop()
141
148
 
142
149
 
143
150
  class KernelFactory: