jupyverse 0.6.4__tar.gz → 0.7.1__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 (303) hide show
  1. {jupyverse-0.6.4 → jupyverse-0.7.1}/.devcontainer/requirements.txt +1 -2
  2. {jupyverse-0.6.4 → jupyverse-0.7.1}/.github/workflows/test.yml +4 -4
  3. {jupyverse-0.6.4 → jupyverse-0.7.1}/.pre-commit-config.yaml +1 -1
  4. {jupyverse-0.6.4 → jupyverse-0.7.1}/CHANGELOG.md +34 -2
  5. {jupyverse-0.6.4 → jupyverse-0.7.1}/PKG-INFO +20 -21
  6. {jupyverse-0.6.4 → jupyverse-0.7.1}/README.md +1 -1
  7. {jupyverse-0.6.4 → jupyverse-0.7.1}/binder/environment.yml +1 -1
  8. jupyverse-0.7.1/jupyverse/__init__.py +1 -0
  9. {jupyverse-0.6.4 → jupyverse-0.7.1}/jupyverse_api/jupyverse_api/__init__.py +36 -2
  10. {jupyverse-0.6.4 → jupyverse-0.7.1}/jupyverse_api/jupyverse_api/app/__init__.py +4 -4
  11. {jupyverse-0.6.4 → jupyverse-0.7.1}/jupyverse_api/jupyverse_api/auth/__init__.py +2 -2
  12. jupyverse-0.7.1/jupyverse_api/jupyverse_api/cli.py +115 -0
  13. {jupyverse-0.6.4 → jupyverse-0.7.1}/jupyverse_api/jupyverse_api/contents/__init__.py +13 -5
  14. jupyverse-0.7.1/jupyverse_api/jupyverse_api/main/__init__.py +110 -0
  15. {jupyverse-0.6.4 → jupyverse-0.7.1}/jupyverse_api/jupyverse_api/terminals/__init__.py +1 -1
  16. {jupyverse-0.6.4 → jupyverse-0.7.1}/jupyverse_api/pyproject.toml +9 -9
  17. jupyverse-0.7.1/jupyverse_api/tests/test_resource_lock.py +57 -0
  18. {jupyverse-0.6.4 → jupyverse-0.7.1}/mkdocs.yml +1 -1
  19. jupyverse-0.7.1/plugins/auth/fps_auth/__init__.py +1 -0
  20. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/auth/fps_auth/backends.py +0 -3
  21. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/auth/fps_auth/db.py +0 -3
  22. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/auth/fps_auth/main.py +13 -22
  23. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/auth/fps_auth/routes.py +2 -5
  24. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/auth/pyproject.toml +4 -4
  25. jupyverse-0.7.1/plugins/auth_fief/fps_auth_fief/__init__.py +1 -0
  26. jupyverse-0.7.1/plugins/auth_fief/fps_auth_fief/main.py +20 -0
  27. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/auth_fief/fps_auth_fief/routes.py +2 -2
  28. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/auth_fief/pyproject.toml +2 -2
  29. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/auth_jupyterhub/fps_auth_jupyterhub/__init__.py +1 -1
  30. jupyverse-0.7.1/plugins/auth_jupyterhub/fps_auth_jupyterhub/main.py +34 -0
  31. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/auth_jupyterhub/fps_auth_jupyterhub/routes.py +24 -13
  32. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/auth_jupyterhub/pyproject.toml +5 -4
  33. jupyverse-0.7.1/plugins/contents/fps_contents/__init__.py +1 -0
  34. jupyverse-0.7.1/plugins/contents/fps_contents/fileid.py +224 -0
  35. jupyverse-0.7.1/plugins/contents/fps_contents/main.py +16 -0
  36. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/contents/fps_contents/routes.py +111 -97
  37. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/contents/pyproject.toml +6 -6
  38. jupyverse-0.7.1/plugins/frontend/fps_frontend/__init__.py +1 -0
  39. jupyverse-0.7.1/plugins/frontend/fps_frontend/main.py +12 -0
  40. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/frontend/pyproject.toml +4 -4
  41. jupyverse-0.7.1/plugins/jupyterlab/fps_jupyterlab/__init__.py +1 -0
  42. jupyverse-0.7.1/plugins/jupyterlab/fps_jupyterlab/main.py +26 -0
  43. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/jupyterlab/fps_jupyterlab/routes.py +1 -1
  44. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/jupyterlab/pyproject.toml +4 -4
  45. jupyverse-0.7.1/plugins/kernels/fps_kernels/__init__.py +1 -0
  46. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/kernels/fps_kernels/kernel_driver/connect.py +15 -14
  47. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/kernels/fps_kernels/kernel_driver/driver.py +108 -77
  48. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/kernels/fps_kernels/kernel_driver/message.py +1 -1
  49. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/kernels/fps_kernels/kernel_server/server.py +58 -47
  50. jupyverse-0.7.1/plugins/kernels/fps_kernels/main.py +45 -0
  51. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/kernels/fps_kernels/routes.py +51 -9
  52. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/kernels/pyproject.toml +7 -5
  53. jupyverse-0.7.1/plugins/lab/fps_lab/__init__.py +1 -0
  54. jupyverse-0.7.1/plugins/lab/fps_lab/main.py +20 -0
  55. jupyverse-0.7.1/plugins/lab/fps_lab/py.typed +0 -0
  56. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/lab/fps_lab/routes.py +0 -3
  57. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/lab/pyproject.toml +4 -4
  58. jupyverse-0.7.1/plugins/login/fps_login/__init__.py +1 -0
  59. jupyverse-0.7.1/plugins/login/fps_login/main.py +16 -0
  60. jupyverse-0.7.1/plugins/login/fps_login/py.typed +0 -0
  61. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/login/pyproject.toml +4 -4
  62. jupyverse-0.7.1/plugins/nbconvert/fps_nbconvert/__init__.py +1 -0
  63. jupyverse-0.7.1/plugins/nbconvert/fps_nbconvert/main.py +15 -0
  64. jupyverse-0.7.1/plugins/nbconvert/fps_nbconvert/py.typed +0 -0
  65. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/nbconvert/pyproject.toml +4 -4
  66. jupyverse-0.7.1/plugins/noauth/fps_noauth/__init__.py +1 -0
  67. jupyverse-0.7.1/plugins/noauth/fps_noauth/main.py +12 -0
  68. jupyverse-0.7.1/plugins/noauth/fps_noauth/py.typed +0 -0
  69. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/noauth/pyproject.toml +4 -4
  70. jupyverse-0.7.1/plugins/notebook/fps_notebook/__init__.py +1 -0
  71. jupyverse-0.7.1/plugins/notebook/fps_notebook/main.py +25 -0
  72. jupyverse-0.7.1/plugins/notebook/fps_notebook/py.typed +0 -0
  73. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/notebook/fps_notebook/routes.py +32 -25
  74. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/notebook/pyproject.toml +4 -4
  75. jupyverse-0.7.1/plugins/resource_usage/fps_resource_usage/__init__.py +1 -0
  76. jupyverse-0.7.1/plugins/resource_usage/fps_resource_usage/main.py +20 -0
  77. jupyverse-0.7.1/plugins/resource_usage/fps_resource_usage/py.typed +0 -0
  78. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/resource_usage/pyproject.toml +4 -4
  79. jupyverse-0.7.1/plugins/terminals/fps_terminals/__init__.py +1 -0
  80. jupyverse-0.7.1/plugins/terminals/fps_terminals/main.py +32 -0
  81. jupyverse-0.7.1/plugins/terminals/fps_terminals/py.typed +0 -0
  82. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/terminals/fps_terminals/routes.py +32 -4
  83. jupyverse-0.7.1/plugins/terminals/fps_terminals/server.py +150 -0
  84. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/terminals/fps_terminals/win_server.py +22 -16
  85. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/terminals/pyproject.toml +4 -4
  86. jupyverse-0.7.1/plugins/webdav/fps_webdav/__init__.py +1 -0
  87. jupyverse-0.7.1/plugins/webdav/fps_webdav/main.py +18 -0
  88. jupyverse-0.7.1/plugins/webdav/fps_webdav/py.typed +0 -0
  89. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/webdav/fps_webdav/routes.py +10 -6
  90. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/webdav/pyproject.toml +5 -5
  91. jupyverse-0.7.1/plugins/webdav/tests/conftest.py +15 -0
  92. jupyverse-0.7.1/plugins/webdav/tests/test_webdav.py +54 -0
  93. jupyverse-0.7.1/plugins/yjs/fps_yjs/__init__.py +1 -0
  94. jupyverse-0.7.1/plugins/yjs/fps_yjs/main.py +38 -0
  95. jupyverse-0.7.1/plugins/yjs/fps_yjs/py.typed +0 -0
  96. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/yjs/fps_yjs/routes.py +145 -108
  97. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/yjs/fps_yjs/ydocs/ybasedoc.py +3 -0
  98. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/yjs/fps_yjs/ydocs/yblob.py +2 -0
  99. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/yjs/fps_yjs/ydocs/ynotebook.py +3 -0
  100. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/yjs/fps_yjs/ywebsocket/__init__.py +0 -1
  101. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/yjs/fps_yjs/ywebsocket/awareness.py +1 -1
  102. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/yjs/fps_yjs/ywebsocket/django_channels_consumer.py +18 -6
  103. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/yjs/fps_yjs/ywebsocket/websocket_provider.py +31 -41
  104. jupyverse-0.7.1/plugins/yjs/fps_yjs/ywebsocket/websocket_server.py +88 -0
  105. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/yjs/fps_yjs/ywebsocket/yroom.py +42 -29
  106. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/yjs/fps_yjs/ywebsocket/ystore.py +97 -103
  107. jupyverse-0.7.1/plugins/yjs/fps_yjs/ywebsocket/yutils.py +29 -0
  108. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/yjs/fps_yjs/ywidgets/widgets.py +3 -3
  109. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/yjs/pyproject.toml +6 -5
  110. {jupyverse-0.6.4 → jupyverse-0.7.1}/pyproject.toml +16 -20
  111. {jupyverse-0.6.4 → jupyverse-0.7.1}/tests/conftest.py +23 -9
  112. {jupyverse-0.6.4 → jupyverse-0.7.1}/tests/test_app.py +21 -13
  113. jupyverse-0.7.1/tests/test_auth.py +182 -0
  114. {jupyverse-0.6.4 → jupyverse-0.7.1}/tests/test_contents.py +40 -17
  115. {jupyverse-0.6.4 → jupyverse-0.7.1}/tests/test_execute.py +70 -38
  116. jupyverse-0.7.1/tests/test_kernels.py +136 -0
  117. {jupyverse-0.6.4 → jupyverse-0.7.1}/tests/test_server.py +33 -34
  118. {jupyverse-0.6.4 → jupyverse-0.7.1}/tests/test_settings.py +51 -21
  119. {jupyverse-0.6.4 → jupyverse-0.7.1}/tests/utils.py +31 -10
  120. jupyverse-0.6.4/MANIFEST.in +0 -2
  121. jupyverse-0.6.4/config.yaml +0 -52
  122. jupyverse-0.6.4/jupyverse/__init__.py +0 -1
  123. jupyverse-0.6.4/jupyverse_api/jupyverse_api/cli.py +0 -110
  124. jupyverse-0.6.4/jupyverse_api/jupyverse_api/main/__init__.py +0 -99
  125. jupyverse-0.6.4/plugins/auth/MANIFEST.in +0 -1
  126. jupyverse-0.6.4/plugins/auth/fps_auth/__init__.py +0 -1
  127. jupyverse-0.6.4/plugins/auth_fief/MANIFEST.in +0 -1
  128. jupyverse-0.6.4/plugins/auth_fief/fps_auth_fief/__init__.py +0 -1
  129. jupyverse-0.6.4/plugins/auth_fief/fps_auth_fief/main.py +0 -23
  130. jupyverse-0.6.4/plugins/auth_jupyterhub/fps_auth_jupyterhub/main.py +0 -50
  131. jupyverse-0.6.4/plugins/contents/MANIFEST.in +0 -1
  132. jupyverse-0.6.4/plugins/contents/fps_contents/__init__.py +0 -1
  133. jupyverse-0.6.4/plugins/contents/fps_contents/fileid.py +0 -212
  134. jupyverse-0.6.4/plugins/contents/fps_contents/main.py +0 -19
  135. jupyverse-0.6.4/plugins/frontend/MANIFEST.in +0 -1
  136. jupyverse-0.6.4/plugins/frontend/fps_frontend/__init__.py +0 -1
  137. jupyverse-0.6.4/plugins/frontend/fps_frontend/main.py +0 -14
  138. jupyverse-0.6.4/plugins/jupyterlab/MANIFEST.in +0 -1
  139. jupyverse-0.6.4/plugins/jupyterlab/fps_jupyterlab/__init__.py +0 -1
  140. jupyverse-0.6.4/plugins/jupyterlab/fps_jupyterlab/main.py +0 -28
  141. jupyverse-0.6.4/plugins/kernels/MANIFEST.in +0 -1
  142. jupyverse-0.6.4/plugins/kernels/fps_kernels/__init__.py +0 -1
  143. jupyverse-0.6.4/plugins/kernels/fps_kernels/main.py +0 -56
  144. jupyverse-0.6.4/plugins/lab/MANIFEST.in +0 -1
  145. jupyverse-0.6.4/plugins/lab/fps_lab/__init__.py +0 -1
  146. jupyverse-0.6.4/plugins/lab/fps_lab/main.py +0 -23
  147. jupyverse-0.6.4/plugins/login/MANIFEST.in +0 -2
  148. jupyverse-0.6.4/plugins/login/fps_login/__init__.py +0 -1
  149. jupyverse-0.6.4/plugins/login/fps_login/main.py +0 -19
  150. jupyverse-0.6.4/plugins/nbconvert/MANIFEST.in +0 -1
  151. jupyverse-0.6.4/plugins/nbconvert/fps_nbconvert/__init__.py +0 -1
  152. jupyverse-0.6.4/plugins/nbconvert/fps_nbconvert/main.py +0 -19
  153. jupyverse-0.6.4/plugins/noauth/MANIFEST.in +0 -1
  154. jupyverse-0.6.4/plugins/noauth/fps_noauth/__init__.py +0 -1
  155. jupyverse-0.6.4/plugins/noauth/fps_noauth/main.py +0 -14
  156. jupyverse-0.6.4/plugins/notebook/MANIFEST.in +0 -1
  157. jupyverse-0.6.4/plugins/notebook/fps_notebook/__init__.py +0 -1
  158. jupyverse-0.6.4/plugins/notebook/fps_notebook/main.py +0 -23
  159. jupyverse-0.6.4/plugins/resource_usage/fps_resource_usage/__init__.py +0 -1
  160. jupyverse-0.6.4/plugins/resource_usage/fps_resource_usage/main.py +0 -22
  161. jupyverse-0.6.4/plugins/terminals/MANIFEST.in +0 -1
  162. jupyverse-0.6.4/plugins/terminals/fps_terminals/__init__.py +0 -1
  163. jupyverse-0.6.4/plugins/terminals/fps_terminals/main.py +0 -28
  164. jupyverse-0.6.4/plugins/terminals/fps_terminals/server.py +0 -82
  165. jupyverse-0.6.4/plugins/webdav/fps_webdav/__init__.py +0 -1
  166. jupyverse-0.6.4/plugins/webdav/fps_webdav/main.py +0 -20
  167. jupyverse-0.6.4/plugins/webdav/tests/test_webdav.py +0 -47
  168. jupyverse-0.6.4/plugins/yjs/MANIFEST.in +0 -1
  169. jupyverse-0.6.4/plugins/yjs/fps_yjs/__init__.py +0 -1
  170. jupyverse-0.6.4/plugins/yjs/fps_yjs/main.py +0 -41
  171. jupyverse-0.6.4/plugins/yjs/fps_yjs/ywebsocket/websocket_server.py +0 -205
  172. jupyverse-0.6.4/plugins/yjs/fps_yjs/ywebsocket/yutils.py +0 -155
  173. jupyverse-0.6.4/tests/test_auth.py +0 -131
  174. jupyverse-0.6.4/tests/test_kernels.py +0 -102
  175. {jupyverse-0.6.4 → jupyverse-0.7.1}/.devcontainer/devcontainer.json +0 -0
  176. {jupyverse-0.6.4 → jupyverse-0.7.1}/.github/workflows/check-release.yml +0 -0
  177. {jupyverse-0.6.4 → jupyverse-0.7.1}/.gitignore +0 -0
  178. {jupyverse-0.6.4 → jupyverse-0.7.1}/CONTRIBUTING.md +0 -0
  179. {jupyverse-0.6.4 → jupyverse-0.7.1}/COPYING.md +0 -0
  180. {jupyverse-0.6.4 → jupyverse-0.7.1}/binder/jupyter_notebook_config.py +0 -0
  181. {jupyverse-0.6.4 → jupyverse-0.7.1}/binder/postBuild +0 -0
  182. {jupyverse-0.6.4 → jupyverse-0.7.1}/binder/start +0 -0
  183. {jupyverse-0.6.4 → jupyverse-0.7.1}/docs/index.md +0 -0
  184. {jupyverse-0.6.4 → jupyverse-0.7.1}/docs/install.md +0 -0
  185. {jupyverse-0.6.4 → jupyverse-0.7.1}/docs/jupyter.svg +0 -0
  186. {jupyverse-0.6.4 → jupyverse-0.7.1}/docs/plugins/auth.md +0 -0
  187. {jupyverse-0.6.4 → jupyverse-0.7.1}/docs/plugins/contents.md +0 -0
  188. {jupyverse-0.6.4 → jupyverse-0.7.1}/docs/plugins/frontend.md +0 -0
  189. {jupyverse-0.6.4 → jupyverse-0.7.1}/docs/plugins/jupyterlab.md +0 -0
  190. {jupyverse-0.6.4 → jupyverse-0.7.1}/docs/plugins/kernels.md +0 -0
  191. {jupyverse-0.6.4 → jupyverse-0.7.1}/docs/plugins/lab.md +0 -0
  192. {jupyverse-0.6.4 → jupyverse-0.7.1}/docs/plugins/login.md +0 -0
  193. {jupyverse-0.6.4 → jupyverse-0.7.1}/docs/plugins/nbconvert.md +0 -0
  194. {jupyverse-0.6.4 → jupyverse-0.7.1}/docs/plugins/notebook.md +0 -0
  195. {jupyverse-0.6.4 → jupyverse-0.7.1}/docs/plugins/resource_usage.md +0 -0
  196. {jupyverse-0.6.4 → jupyverse-0.7.1}/docs/plugins/terminals.md +0 -0
  197. {jupyverse-0.6.4 → jupyverse-0.7.1}/docs/plugins/yjs.md +0 -0
  198. {jupyverse-0.6.4 → jupyverse-0.7.1}/docs/tutorials/jupyterhub_jupyverse_deployment.md +0 -0
  199. {jupyverse-0.6.4 → jupyverse-0.7.1}/docs/tutorials/standalone_jupyverse_deployment.md +0 -0
  200. {jupyverse-0.6.4 → jupyverse-0.7.1}/docs/usage/microservices.md +0 -0
  201. {jupyverse-0.6.4 → jupyverse-0.7.1}/docs/usage/multi_user.md +0 -0
  202. {jupyverse-0.6.4 → jupyverse-0.7.1}/docs/usage/single_user.md +0 -0
  203. {jupyverse-0.6.4 → jupyverse-0.7.1}/jupyverse/py.typed +0 -0
  204. {jupyverse-0.6.4 → jupyverse-0.7.1}/jupyverse_api/COPYING.md +0 -0
  205. {jupyverse-0.6.4 → jupyverse-0.7.1}/jupyverse_api/README.md +0 -0
  206. {jupyverse-0.6.4 → jupyverse-0.7.1}/jupyverse_api/jupyverse_api/auth/models.py +0 -0
  207. {jupyverse-0.6.4 → jupyverse-0.7.1}/jupyverse_api/jupyverse_api/contents/models.py +0 -0
  208. {jupyverse-0.6.4 → jupyverse-0.7.1}/jupyverse_api/jupyverse_api/exceptions.py +0 -0
  209. {jupyverse-0.6.4 → jupyverse-0.7.1}/jupyverse_api/jupyverse_api/frontend/__init__.py +0 -0
  210. {jupyverse-0.6.4 → jupyverse-0.7.1}/jupyverse_api/jupyverse_api/jupyterlab/__init__.py +0 -0
  211. {jupyverse-0.6.4 → jupyverse-0.7.1}/jupyverse_api/jupyverse_api/kernels/__init__.py +0 -0
  212. {jupyverse-0.6.4 → jupyverse-0.7.1}/jupyverse_api/jupyverse_api/kernels/models.py +0 -0
  213. {jupyverse-0.6.4 → jupyverse-0.7.1}/jupyverse_api/jupyverse_api/lab/__init__.py +0 -0
  214. {jupyverse-0.6.4 → jupyverse-0.7.1}/jupyverse_api/jupyverse_api/login/__init__.py +0 -0
  215. {jupyverse-0.6.4 → jupyverse-0.7.1}/jupyverse_api/jupyverse_api/nbconvert/__init__.py +0 -0
  216. {jupyverse-0.6.4 → jupyverse-0.7.1}/jupyverse_api/jupyverse_api/notebook/__init__.py +0 -0
  217. {jupyverse-0.6.4 → jupyverse-0.7.1}/jupyverse_api/jupyverse_api/py.typed +0 -0
  218. {jupyverse-0.6.4 → jupyverse-0.7.1}/jupyverse_api/jupyverse_api/resource_usage/__init__.py +0 -0
  219. {jupyverse-0.6.4 → jupyverse-0.7.1}/jupyverse_api/jupyverse_api/terminals/models.py +0 -0
  220. {jupyverse-0.6.4 → jupyverse-0.7.1}/jupyverse_api/jupyverse_api/yjs/__init__.py +0 -0
  221. {jupyverse-0.6.4 → jupyverse-0.7.1}/jupyverse_api/jupyverse_api/yjs/models.py +0 -0
  222. {jupyverse-0.6.4 → jupyverse-0.7.1}/notebooks/admin_users.ipynb +0 -0
  223. {jupyverse-0.6.4 → jupyverse-0.7.1}/notebooks/admin_users.py +0 -0
  224. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/auth/COPYING.md +0 -0
  225. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/auth/README.md +0 -0
  226. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/auth/fps_auth/config.py +0 -0
  227. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/auth/fps_auth/models.py +0 -0
  228. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/auth/fps_auth/py.typed +0 -0
  229. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/auth_fief/COPYING.md +0 -0
  230. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/auth_fief/README.md +0 -0
  231. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/auth_fief/fps_auth_fief/backend.py +0 -0
  232. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/auth_fief/fps_auth_fief/config.py +0 -0
  233. {jupyverse-0.6.4/plugins/contents/fps_contents → jupyverse-0.7.1/plugins/auth_fief/fps_auth_fief}/py.typed +0 -0
  234. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/auth_jupyterhub/COPYING.md +0 -0
  235. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/auth_jupyterhub/README.md +0 -0
  236. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/auth_jupyterhub/fps_auth_jupyterhub/config.py +0 -0
  237. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/auth_jupyterhub/fps_auth_jupyterhub/db.py +0 -0
  238. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/auth_jupyterhub/fps_auth_jupyterhub/launch.py +0 -0
  239. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/auth_jupyterhub/fps_auth_jupyterhub/models.py +0 -0
  240. {jupyverse-0.6.4/plugins/frontend/fps_frontend → jupyverse-0.7.1/plugins/auth_jupyterhub/fps_auth_jupyterhub}/py.typed +0 -0
  241. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/contents/COPYING.md +0 -0
  242. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/contents/README.md +0 -0
  243. {jupyverse-0.6.4/plugins/jupyterlab/fps_jupyterlab → jupyverse-0.7.1/plugins/contents/fps_contents}/py.typed +0 -0
  244. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/frontend/COPYING.md +0 -0
  245. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/frontend/README.md +0 -0
  246. {jupyverse-0.6.4/plugins/noauth/fps_noauth → jupyverse-0.7.1/plugins/frontend/fps_frontend}/py.typed +0 -0
  247. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/jupyterlab/COPYING.md +0 -0
  248. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/jupyterlab/README.md +0 -0
  249. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/jupyterlab/fps_jupyterlab/index.py +0 -0
  250. {jupyverse-0.6.4/plugins/webdav/fps_webdav → jupyverse-0.7.1/plugins/jupyterlab/fps_jupyterlab}/py.typed +0 -0
  251. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/kernels/COPYING.md +0 -0
  252. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/kernels/README.md +0 -0
  253. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/kernels/fps_kernels/kernel_driver/__init__.py +0 -0
  254. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/kernels/fps_kernels/kernel_driver/kernelspec.py +0 -0
  255. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/kernels/fps_kernels/kernel_driver/paths.py +0 -0
  256. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/kernels/fps_kernels/kernel_server/__init__.py +0 -0
  257. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/kernels/fps_kernels/kernel_server/message.py +0 -0
  258. {jupyverse-0.6.4/plugins/yjs/fps_yjs → jupyverse-0.7.1/plugins/kernels/fps_kernels}/py.typed +0 -0
  259. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/lab/COPYING.md +0 -0
  260. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/lab/README.md +0 -0
  261. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/lab/fps_lab/static/favicon.ico +0 -0
  262. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/login/COPYING.md +0 -0
  263. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/login/README.md +0 -0
  264. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/login/fps_login/routes.py +0 -0
  265. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/login/fps_login/static/favicons/favicon-busy-1.ico +0 -0
  266. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/login/fps_login/static/favicons/favicon-busy-2.ico +0 -0
  267. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/login/fps_login/static/favicons/favicon-busy-3.ico +0 -0
  268. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/login/fps_login/static/favicons/favicon-file.ico +0 -0
  269. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/login/fps_login/static/favicons/favicon-notebook.ico +0 -0
  270. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/login/fps_login/static/favicons/favicon-terminal.ico +0 -0
  271. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/login/fps_login/static/favicons/favicon.ico +0 -0
  272. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/login/fps_login/static/index.html +0 -0
  273. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/login/fps_login/static/logo/github.svg +0 -0
  274. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/login/fps_login/static/logo/logo.png +0 -0
  275. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/login/fps_login/static/style/index.css +0 -0
  276. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/nbconvert/COPYING.md +0 -0
  277. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/nbconvert/README.md +0 -0
  278. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/nbconvert/fps_nbconvert/routes.py +0 -0
  279. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/noauth/COPYING.md +0 -0
  280. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/noauth/README.md +0 -0
  281. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/noauth/fps_noauth/backends.py +0 -0
  282. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/notebook/COPYING.md +0 -0
  283. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/notebook/README.md +0 -0
  284. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/resource_usage/COPYING.md +0 -0
  285. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/resource_usage/README.md +0 -0
  286. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/resource_usage/fps_resource_usage/routes.py +0 -0
  287. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/terminals/COPYING.md +0 -0
  288. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/terminals/README.md +0 -0
  289. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/webdav/COPYING.md +0 -0
  290. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/webdav/README.md +0 -0
  291. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/webdav/fps_webdav/config.py +0 -0
  292. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/yjs/COPYING.md +0 -0
  293. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/yjs/README.md +0 -0
  294. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/yjs/fps_yjs/ydocs/__init__.py +0 -0
  295. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/yjs/fps_yjs/ydocs/utils.py +0 -0
  296. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/yjs/fps_yjs/ydocs/yfile.py +0 -0
  297. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/yjs/fps_yjs/ydocs/yunicode.py +0 -0
  298. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/yjs/fps_yjs/ywebsocket/asgi_server.py +0 -0
  299. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/yjs/fps_yjs/ywebsocket/websocket.py +0 -0
  300. {jupyverse-0.6.4 → jupyverse-0.7.1}/plugins/yjs/fps_yjs/ywidgets/__init__.py +0 -0
  301. {jupyverse-0.6.4 → jupyverse-0.7.1}/pytest.ini +0 -0
  302. {jupyverse-0.6.4 → jupyverse-0.7.1}/tests/data/notebook0.ipynb +0 -0
  303. {jupyverse-0.6.4 → jupyverse-0.7.1}/tests/data/notebook1.ipynb +0 -0
@@ -7,7 +7,6 @@
7
7
  ./plugins/nbconvert
8
8
  ./plugins/terminals
9
9
  ./plugins/yjs
10
- fps[unicorn] >=0.0.10
10
+ fps >=0.1.1
11
11
  mypy
12
12
  pytest
13
- pytest-asyncio
@@ -21,7 +21,7 @@ jobs:
21
21
  uses: actions/checkout@v3
22
22
  - uses: actions/setup-python@v4
23
23
  with:
24
- python-version: '3.12'
24
+ python-version: '3.13'
25
25
  cache: 'pip'
26
26
  - name: Install hatch
27
27
  run: |
@@ -43,13 +43,13 @@ jobs:
43
43
  fail-fast: false
44
44
  matrix:
45
45
  os: [ubuntu-latest, macos-latest, windows-latest]
46
- python-version: [ '3.8', '3.9', '3.10', '3.11', '3.12' ]
46
+ python-version: [ '3.9', '3.10', '3.11', '3.12', '3.13' ]
47
47
 
48
48
  steps:
49
49
  - name: Checkout
50
- uses: actions/checkout@v3
50
+ uses: actions/checkout@v4
51
51
 
52
- - uses: actions/setup-python@v4
52
+ - uses: actions/setup-python@v5
53
53
  with:
54
54
  python-version: ${{ matrix.python-version }}
55
55
  cache: 'pip'
@@ -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.6.9
19
+ rev: v0.7.1
20
20
  hooks:
21
21
  - id: ruff
22
22
  args: ["--fix"]
@@ -2,6 +2,40 @@
2
2
 
3
3
  <!-- <START NEW CHANGELOG ENTRY> -->
4
4
 
5
+ ## 0.7.1
6
+
7
+ ([Full Changelog](https://github.com/jupyter-server/jupyverse/compare/v0.7.0...96cb8831e330527089ebbf41d649cbe9c8b32053))
8
+
9
+ ### Merged PRs
10
+
11
+ - Require versions >=0.7.0 [#457](https://github.com/jupyter-server/jupyverse/pull/457) ([@davidbrochart](https://github.com/davidbrochart))
12
+ - Unpin Python version in Binder [#456](https://github.com/jupyter-server/jupyverse/pull/456) ([@davidbrochart](https://github.com/davidbrochart))
13
+ - Fix fps-notebook base URL [#455](https://github.com/jupyter-server/jupyverse/pull/455) ([@davidbrochart](https://github.com/davidbrochart))
14
+ - Update README [#454](https://github.com/jupyter-server/jupyverse/pull/454) ([@davidbrochart](https://github.com/davidbrochart))
15
+
16
+ ### Contributors to this release
17
+
18
+ ([GitHub contributors page for this release](https://github.com/jupyter-server/jupyverse/graphs/contributors?from=2025-02-14&to=2025-02-14&type=c))
19
+
20
+ [@davidbrochart](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyverse+involves%3Adavidbrochart+updated%3A2025-02-14..2025-02-14&type=Issues)
21
+
22
+ <!-- <END NEW CHANGELOG ENTRY> -->
23
+
24
+ ## 0.7.0
25
+
26
+ ([Full Changelog](https://github.com/jupyter-server/jupyverse/compare/v0.6.4...6fe98eab9ef0cef9d77a49bed92829ae3fb3538c))
27
+
28
+ ### Merged PRs
29
+
30
+ - Switch to FPS [#453](https://github.com/jupyter-server/jupyverse/pull/453) ([@davidbrochart](https://github.com/davidbrochart))
31
+ - Fixing typo in the documentation [#452](https://github.com/jupyter-server/jupyverse/pull/452) ([@ThePavolC](https://github.com/ThePavolC))
32
+
33
+ ### Contributors to this release
34
+
35
+ ([GitHub contributors page for this release](https://github.com/jupyter-server/jupyverse/graphs/contributors?from=2024-10-15&to=2025-02-14&type=c))
36
+
37
+ [@davidbrochart](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyverse+involves%3Adavidbrochart+updated%3A2024-10-15..2025-02-14&type=Issues) | [@pre-commit-ci](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyverse+involves%3Apre-commit-ci+updated%3A2024-10-15..2025-02-14&type=Issues) | [@ThePavolC](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyverse+involves%3AThePavolC+updated%3A2024-10-15..2025-02-14&type=Issues)
38
+
5
39
  ## 0.6.4
6
40
 
7
41
  ([Full Changelog](https://github.com/jupyter-server/jupyverse/compare/v0.6.3...69394c087d0645c784ff14e3cb71557c7a0d5cfa))
@@ -16,8 +50,6 @@
16
50
 
17
51
  [@davidbrochart](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyverse+involves%3Adavidbrochart+updated%3A2024-10-02..2024-10-15&type=Issues) | [@pre-commit-ci](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyverse+involves%3Apre-commit-ci+updated%3A2024-10-02..2024-10-15&type=Issues)
18
52
 
19
- <!-- <END NEW CHANGELOG ENTRY> -->
20
-
21
53
  ## 0.6.3
22
54
 
23
55
  ([Full Changelog](https://github.com/jupyter-server/jupyverse/compare/v0.6.2...aa6854a51665d95216340d7fda1ba111af6aef74))
@@ -1,51 +1,50 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: jupyverse
3
- Version: 0.6.4
3
+ Version: 0.7.1
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>
7
7
  License: BSD 3-Clause License
8
8
  License-File: COPYING.md
9
9
  Keywords: fastapi,jupyter,plugins,server
10
- Requires-Python: >=3.8
11
- Requires-Dist: fps-contents<1,>=0.1.2
12
- Requires-Dist: fps-frontend<1,>=0.1.2
13
- Requires-Dist: fps-kernels<1,>=0.1.2
14
- Requires-Dist: fps-lab<1,>=0.1.2
15
- Requires-Dist: fps-nbconvert<1,>=0.1.2
16
- Requires-Dist: fps-terminals<1,>=0.1.2
17
- Requires-Dist: fps-yjs<1,>=0.1.2
18
- Requires-Dist: jupyverse-api<1,>=0.1.2
10
+ Requires-Python: >=3.9
11
+ Requires-Dist: fps-contents<1,>=0.7.0
12
+ Requires-Dist: fps-frontend<1,>=0.7.0
13
+ Requires-Dist: fps-kernels<1,>=0.7.0
14
+ Requires-Dist: fps-lab<1,>=0.7.0
15
+ Requires-Dist: fps-nbconvert<1,>=0.7.0
16
+ Requires-Dist: fps-terminals<1,>=0.7.0
17
+ Requires-Dist: fps-yjs<1,>=0.7.0
18
+ Requires-Dist: jupyverse-api<1,>=0.7.0
19
19
  Provides-Extra: auth
20
- Requires-Dist: fps-auth<1,>=0.1.2; extra == 'auth'
21
- Requires-Dist: fps-login<1,>=0.1.2; extra == 'auth'
20
+ Requires-Dist: fps-auth<1,>=0.7.0; extra == 'auth'
21
+ Requires-Dist: fps-login<1,>=0.7.0; extra == 'auth'
22
22
  Provides-Extra: auth-fief
23
- Requires-Dist: fps-auth-fief<1,>=0.1.2; extra == 'auth-fief'
23
+ Requires-Dist: fps-auth-fief<1,>=0.7.0; extra == 'auth-fief'
24
24
  Provides-Extra: auth-jupyterhub
25
- Requires-Dist: fps-auth-jupyterhub<1,>=0.1.2; extra == 'auth-jupyterhub'
25
+ Requires-Dist: fps-auth-jupyterhub<1,>=0.7.0; extra == 'auth-jupyterhub'
26
26
  Provides-Extra: docs
27
27
  Requires-Dist: mkdocs; extra == 'docs'
28
28
  Requires-Dist: mkdocs-material; extra == 'docs'
29
29
  Provides-Extra: jupyterlab
30
- Requires-Dist: fps-jupyterlab<1,>=0.1.2; extra == 'jupyterlab'
30
+ Requires-Dist: fps-jupyterlab<1,>=0.7.0; extra == 'jupyterlab'
31
31
  Provides-Extra: noauth
32
- Requires-Dist: fps-noauth<1,>=0.1.2; extra == 'noauth'
32
+ Requires-Dist: fps-noauth<1,>=0.7.0; extra == 'noauth'
33
33
  Provides-Extra: notebook
34
- Requires-Dist: fps-notebook<1,>=0.1.2; extra == 'notebook'
34
+ Requires-Dist: fps-notebook<1,>=0.7.0; extra == 'notebook'
35
35
  Provides-Extra: test
36
36
  Requires-Dist: httpx; extra == 'test'
37
37
  Requires-Dist: httpx-ws>=0.4.1; extra == 'test'
38
38
  Requires-Dist: ipykernel; extra == 'test'
39
39
  Requires-Dist: mypy; extra == 'test'
40
40
  Requires-Dist: pytest; extra == 'test'
41
- Requires-Dist: pytest-asyncio; extra == 'test'
42
41
  Requires-Dist: pytest-env; extra == 'test'
43
42
  Requires-Dist: pytest-rerunfailures; extra == 'test'
44
43
  Requires-Dist: pytest-timeout; extra == 'test'
45
44
  Requires-Dist: requests; extra == 'test'
46
45
  Requires-Dist: ruff>=0.1.2; extra == 'test'
46
+ Requires-Dist: trio; extra == 'test'
47
47
  Requires-Dist: types-setuptools; extra == 'test'
48
- Requires-Dist: websockets; extra == 'test'
49
48
  Requires-Dist: ypywidgets-textual<0.6.0,>=0.5.0; extra == 'test'
50
49
  Requires-Dist: ypywidgets<0.10.0,>=0.9.3; extra == 'test'
51
50
  Description-Content-Type: text/markdown
@@ -54,7 +53,7 @@ Description-Content-Type: text/markdown
54
53
 
55
54
  # jupyverse
56
55
 
57
- A set of [Asphalt](https://asphalt.readthedocs.io) components implementing a Jupyter server.
56
+ A set of [FPS](https://github.com/jupyter-server/fps) modules implementing a Jupyter server.
58
57
 
59
58
  Try it online:
60
59
  - JupyterLab frontend: [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/jupyter-server/jupyverse/HEAD?urlpath=jupyverse-jupyterlab)
@@ -2,7 +2,7 @@
2
2
 
3
3
  # jupyverse
4
4
 
5
- A set of [Asphalt](https://asphalt.readthedocs.io) components implementing a Jupyter server.
5
+ A set of [FPS](https://github.com/jupyter-server/fps) modules implementing a Jupyter server.
6
6
 
7
7
  Try it online:
8
8
  - JupyterLab frontend: [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/jupyter-server/jupyverse/HEAD?urlpath=jupyverse-jupyterlab)
@@ -2,7 +2,7 @@ name: jupyverse
2
2
  channels:
3
3
  - conda-forge
4
4
  dependencies:
5
- - python =3.9
5
+ - python
6
6
  - jupyter-server-proxy
7
7
  - jupyterlab-language-pack-fr-FR
8
8
  - pip
@@ -0,0 +1 @@
1
+ __version__ = "0.7.1"
@@ -1,10 +1,11 @@
1
- from typing import Dict
1
+ from typing import Any, Dict
2
2
 
3
+ from anyio import Event
3
4
  from pydantic import BaseModel
4
5
 
5
6
  from .app import App
6
7
 
7
- __version__ = "0.6.4"
8
+ __version__ = "0.7.1"
8
9
 
9
10
 
10
11
  class Singleton(type):
@@ -41,3 +42,36 @@ class Router:
41
42
 
42
43
  def add_middleware(self, middleware, *args, **kwargs) -> None:
43
44
  self._app.add_middleware(middleware, *args, **kwargs)
45
+
46
+
47
+ class ResourceLock:
48
+ """ResourceLock ensures that accesses cannot be done concurrently on the same resource.
49
+ """
50
+ _locks: Dict[Any, Event]
51
+
52
+ def __init__(self):
53
+ self._locks = {}
54
+
55
+ def __call__(self, idx: Any):
56
+ return _ResourceLock(idx, self._locks)
57
+
58
+
59
+ class _ResourceLock:
60
+ _idx: Any
61
+ _locks: Dict[Any, Event]
62
+ _lock: Event
63
+
64
+ def __init__(self, idx: Any, locks: Dict[Any, Event]):
65
+ self._idx = idx
66
+ self._locks = locks
67
+
68
+ async def __aenter__(self):
69
+ while True:
70
+ if self._idx not in self._locks:
71
+ break
72
+ await self._locks[self._idx].wait()
73
+ self._locks[self._idx] = self._lock = Event()
74
+
75
+ async def __aexit__(self, exc_type, exc_value, exc_tb):
76
+ self._lock.set()
77
+ del self._locks[self._idx]
@@ -1,15 +1,15 @@
1
1
  from __future__ import annotations
2
2
 
3
- import logging
4
3
  from collections import defaultdict
5
4
  from datetime import datetime, timezone
6
5
  from typing import Dict, List
7
6
 
7
+ import structlog
8
8
  from fastapi import FastAPI, Request
9
9
 
10
10
  from ..exceptions import RedirectException, _redirect_exception_handler
11
11
 
12
- logger = logging.getLogger("app")
12
+ logger = structlog.get_logger()
13
13
 
14
14
 
15
15
  class App:
@@ -57,7 +57,7 @@ class App:
57
57
  f"{_type} adds a handler for a path that is already defined in "
58
58
  f"{_router}: {path}"
59
59
  )
60
- logger.debug("%s added handler for path: %s", _type, path)
60
+ logger.debug("Handler added", type=_type, path=path)
61
61
  new_paths.append(path)
62
62
  self._router_paths[_type].extend(new_paths)
63
63
  self._app.include_router(router, **kwargs)
@@ -69,7 +69,7 @@ class App:
69
69
  f"{_type } mounts a path that is already defined in {_router}: {path}"
70
70
  )
71
71
  self._router_paths[_type].append(path)
72
- logger.debug("%s mounted path: %s", _type, path)
72
+ logger.debug("Path mounted", type=_type, path=path)
73
73
  self._app.mount(path, *args, **kwargs)
74
74
 
75
75
  def add_middleware(self, middleware, *args, **kwargs) -> None:
@@ -1,5 +1,5 @@
1
1
  from abc import ABC, abstractmethod
2
- from typing import Any, Callable, Dict, List, Optional, Tuple
2
+ from typing import Any, Awaitable, Callable, Dict, List, Optional, Tuple
3
3
 
4
4
  from jupyverse_api import Config
5
5
 
@@ -19,7 +19,7 @@ class Auth(ABC):
19
19
  def websocket_auth(
20
20
  self,
21
21
  permissions: Optional[Dict[str, List[str]]] = None,
22
- ) -> Callable[[], Tuple[Any, Dict[str, List[str]]]]:
22
+ ) -> Callable[[Any], Awaitable[Optional[Tuple[Any, Optional[Dict[str, List[str]]]]]]]:
23
23
  ...
24
24
 
25
25
 
@@ -0,0 +1,115 @@
1
+ import io
2
+ import json
3
+ import sys
4
+ from typing import Any, List, Tuple
5
+
6
+ import rich_click as click
7
+ from fps import main as fps_main
8
+
9
+ if sys.version_info < (3, 10):
10
+ from importlib_metadata import entry_points
11
+ else:
12
+ from importlib.metadata import entry_points
13
+
14
+
15
+ @click.command() # type: ignore
16
+ @click.option(
17
+ "--debug",
18
+ is_flag=True,
19
+ show_default=True,
20
+ default=False,
21
+ help="Enable debug mode.",
22
+ )
23
+ @click.option(
24
+ "--open-browser",
25
+ is_flag=True,
26
+ show_default=True,
27
+ default=False,
28
+ help="Open a browser window.",
29
+ )
30
+ @click.option(
31
+ "--host",
32
+ type=str,
33
+ default="127.0.0.1",
34
+ help="The host URL.",
35
+ )
36
+ @click.option(
37
+ "--port",
38
+ type=int,
39
+ default=8000,
40
+ help="The host port.",
41
+ )
42
+ @click.option(
43
+ "--query-param",
44
+ multiple=True,
45
+ type=str,
46
+ help='The query parameter key and value, separated by "=".',
47
+ )
48
+ @click.option(
49
+ "--allow-origin",
50
+ multiple=True,
51
+ type=str,
52
+ help="The origin to allow.",
53
+ )
54
+ @click.option(
55
+ "--set",
56
+ "set_",
57
+ multiple=True,
58
+ type=str,
59
+ help="Set configuration.",
60
+ )
61
+ @click.option(
62
+ "--disable",
63
+ multiple=True,
64
+ type=str,
65
+ help="Disable plugin.",
66
+ )
67
+ def main(
68
+ debug: bool = False,
69
+ open_browser: bool = False,
70
+ host: str = "127.0.0.1",
71
+ port: int = 8000,
72
+ set_: Tuple[str, ...] = (),
73
+ disable: Tuple[str, ...] = (),
74
+ allow_origin: Tuple[str, ...] = (),
75
+ query_param: Tuple[str, ...] = (),
76
+ ) -> None:
77
+ query_params_dict = {}
78
+ for qp in query_param:
79
+ key, _, value = qp.partition("=")
80
+ query_params_dict[key] = value
81
+ query_params_str = json.dumps(query_params_dict)
82
+ allow_origins_str = json.dumps(allow_origin)
83
+ set_list: List[str] = list(set_)
84
+ set_list.append(f"debug={debug}")
85
+ set_list.append(f"open_browser={open_browser}")
86
+ set_list.append(f"host={host}")
87
+ set_list.append(f"port={port}")
88
+ set_list.append(f"allow_origins={allow_origins_str}")
89
+ set_list.append(f"query_params={query_params_str}")
90
+ pluggin_config = io.StringIO(json.dumps(get_pluggin_config(disable)))
91
+ fps_main.callback(
92
+ "",
93
+ set_=set_list,
94
+ config=pluggin_config,
95
+ ) # type: ignore
96
+
97
+
98
+ def get_pluggin_config(disable: Tuple[str, ...]) -> dict[str, Any]:
99
+ jupyverse_modules = [
100
+ ep.name
101
+ for ep in entry_points(group="jupyverse.modules")
102
+ if ep.name not in disable
103
+ ]
104
+ config = {
105
+ "jupyverse": {
106
+ "type":"jupyverse_api.main:JupyverseModule",
107
+ "modules": {
108
+ module: {
109
+ "type": module
110
+ }
111
+ for module in jupyverse_modules
112
+ }
113
+ }
114
+ }
115
+ return config
@@ -1,11 +1,12 @@
1
- import asyncio
1
+ from __future__ import annotations
2
+
2
3
  from abc import ABC, abstractmethod
3
4
  from pathlib import Path
4
5
  from typing import Dict, List, Optional, Union
5
6
 
6
7
  from fastapi import APIRouter, Depends, Request, Response
7
8
 
8
- from jupyverse_api import Router
9
+ from jupyverse_api import ResourceLock, Router
9
10
 
10
11
  from ..app import App
11
12
  from ..auth import Auth, User
@@ -13,8 +14,13 @@ from .models import Checkpoint, Content, SaveContent
13
14
 
14
15
 
15
16
  class FileIdManager(ABC):
16
- stop_watching_files: asyncio.Event
17
- stopped_watching_files: asyncio.Event
17
+ @abstractmethod
18
+ async def start(self) -> None:
19
+ ...
20
+
21
+ @abstractmethod
22
+ async def stop(self) -> None:
23
+ ...
18
24
 
19
25
  @abstractmethod
20
26
  async def get_path(self, file_id: str) -> str:
@@ -32,9 +38,11 @@ class FileIdManager(ABC):
32
38
 
33
39
 
34
40
  class Contents(Router, ABC):
41
+ file_lock: ResourceLock
42
+
35
43
  def __init__(self, app: App, auth: Auth):
36
44
  super().__init__(app=app)
37
-
45
+ self.file_lock = ResourceLock()
38
46
  router = APIRouter()
39
47
 
40
48
  @router.post(
@@ -0,0 +1,110 @@
1
+ from __future__ import annotations
2
+
3
+ import logging
4
+ import webbrowser
5
+ from typing import Dict, List
6
+
7
+ import structlog
8
+ from anyio import Event, create_task_group
9
+ from fastapi import FastAPI
10
+ from fastapi.middleware.cors import CORSMiddleware
11
+ from fps import Module
12
+ from fps.web.fastapi import FastAPIModule
13
+ from pydantic import BaseModel, Json
14
+
15
+ from jupyverse_api import Config
16
+
17
+ from ..app import App
18
+
19
+ logger = structlog.get_logger()
20
+
21
+
22
+ class AppModule(Module):
23
+ def __init__(
24
+ self,
25
+ name: str,
26
+ *,
27
+ mount_path: str | None = None,
28
+ ) -> None:
29
+ super().__init__(name)
30
+ self.mount_path = mount_path
31
+
32
+ async def prepare(self) -> None:
33
+ app = await self.get(FastAPI)
34
+ _app = App(app, mount_path=self.mount_path)
35
+ self.put(_app)
36
+
37
+
38
+ class JupyverseModule(FastAPIModule):
39
+ def __init__(self, name: str, **kwargs) -> None:
40
+ self.jupyverse_config = JupyverseConfig(**kwargs)
41
+ if self.jupyverse_config.debug:
42
+ structlog.stdlib.recreate_defaults(log_level=logging.DEBUG)
43
+ super().__init__(
44
+ name,
45
+ host=self.jupyverse_config.host,
46
+ port=self.jupyverse_config.port,
47
+ debug=self.jupyverse_config.debug,
48
+ )
49
+ self.lifespan = Lifespan()
50
+
51
+ async def prepare(self) -> None:
52
+ await super().prepare()
53
+ app = await self.get(App)
54
+ if self.jupyverse_config.allow_origins:
55
+ app.add_middleware(
56
+ CORSMiddleware,
57
+ allow_origins=self.jupyverse_config.allow_origins,
58
+ allow_credentials=True,
59
+ allow_methods=["*"],
60
+ allow_headers=["*"],
61
+ )
62
+ self._query_params = QueryParams(d={})
63
+ self._host = self.jupyverse_config.host
64
+ if not self._host.startswith("http"):
65
+ self._host = f"http://{self._host}"
66
+ self._port = self.jupyverse_config.port
67
+ host_url = Host(url=f"{self._host}:{self._port}/")
68
+ self.put(self._query_params)
69
+ self.put(host_url)
70
+ self.put(self.lifespan)
71
+
72
+ async def start(self) -> None:
73
+ async with create_task_group() as tg:
74
+ tg.start_soon(super().start)
75
+ await self.started.wait()
76
+
77
+ # at this point, the server has started
78
+ qp = self._query_params.d
79
+ if self.jupyverse_config.query_params:
80
+ qp.update(**self.jupyverse_config.query_params)
81
+ query_params_str = "?" + "&".join([f"{k}={v}" for k, v in qp.items()]) if qp else ""
82
+ url = f"{self._host}:{self._port}{query_params_str}"
83
+ logger.info("Server running", url=url)
84
+ if self.jupyverse_config.open_browser:
85
+ webbrowser.open_new_tab(url)
86
+
87
+ async def stop(self) -> None:
88
+ self.lifespan.shutdown_request.set()
89
+
90
+
91
+ class QueryParams(BaseModel):
92
+ d: Dict[str, str]
93
+
94
+
95
+ class Host(BaseModel):
96
+ url: str
97
+
98
+
99
+ class Lifespan:
100
+ def __init__(self):
101
+ self.shutdown_request = Event()
102
+
103
+
104
+ class JupyverseConfig(Config):
105
+ host: str = "127.0.0.1"
106
+ port: int = 8000
107
+ allow_origins: Json[List[str]] = []
108
+ open_browser: bool = False
109
+ query_params: Json[Dict[str, str]] = {}
110
+ debug: bool = False
@@ -83,5 +83,5 @@ class TerminalServer(ABC):
83
83
  ...
84
84
 
85
85
  @abstractmethod
86
- async def exit(self):
86
+ def quit(self, websocket):
87
87
  ...
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
6
6
  name = "jupyverse_api"
7
7
  description = "The public API for Jupyverse"
8
8
  readme = "README.md"
9
- requires-python = ">=3.8"
9
+ requires-python = ">=3.9"
10
10
  keywords = [
11
11
  "jupyverse", "api",
12
12
  ]
@@ -16,10 +16,11 @@ authors = [
16
16
  classifiers = [
17
17
  "Development Status :: 4 - Beta",
18
18
  "Programming Language :: Python",
19
- "Programming Language :: Python :: 3.8",
20
19
  "Programming Language :: Python :: 3.9",
21
20
  "Programming Language :: Python :: 3.10",
22
21
  "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Programming Language :: Python :: 3.13",
23
24
  "Programming Language :: Python :: Implementation :: CPython",
24
25
  "Programming Language :: Python :: Implementation :: PyPy",
25
26
  ]
@@ -28,8 +29,7 @@ dependencies = [
28
29
  "pydantic >=2,<3",
29
30
  "fastapi >=0.95.0,<1",
30
31
  "rich-click >=1.6.1,<2",
31
- "asphalt >=4.11.0,<5",
32
- "asphalt-web[fastapi] >=1.1.0,<2",
32
+ "fps[web] >=0.1.1,<0.2.0",
33
33
  ]
34
34
  dynamic = ["version"]
35
35
 
@@ -42,12 +42,12 @@ Source = "https://github.com/jupyter-server/jupyverse/jupyverse_api"
42
42
  [project.scripts]
43
43
  jupyverse = "jupyverse_api.cli:main"
44
44
 
45
- [project.entry-points."asphalt.components"]
46
- app = "jupyverse_api.main:AppComponent"
47
- jupyverse = "jupyverse_api.main:JupyverseComponent"
45
+ [project.entry-points."fps.modules"]
46
+ app = "jupyverse_api.main:AppModule"
47
+ jupyverse = "jupyverse_api.main:JupyverseModule"
48
48
 
49
- [project.entry-points."jupyverse.components"]
50
- app = "jupyverse_api.main:AppComponent"
49
+ [project.entry-points."jupyverse.modules"]
50
+ app = "jupyverse_api.main:AppModule"
51
51
 
52
52
  [tool.hatch.version]
53
53
  path = "jupyverse_api/__init__.py"