beaker-notebook 2.0.0b1__py3-none-any.whl

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 (202) hide show
  1. beaker_kernel/__init__.py +37 -0
  2. beaker_notebook/__init__.py +172 -0
  3. beaker_notebook/app/__init__.py +13 -0
  4. beaker_notebook/app/api/__init__.py +0 -0
  5. beaker_notebook/app/api/handlers.py +84 -0
  6. beaker_notebook/app/api/integrations.py +299 -0
  7. beaker_notebook/app/api/notebook.py +118 -0
  8. beaker_notebook/app/api/subkernels.py +70 -0
  9. beaker_notebook/app/base.py +377 -0
  10. beaker_notebook/app/dev_app.py +145 -0
  11. beaker_notebook/app/handlers.py +607 -0
  12. beaker_notebook/app/notebook_app.py +13 -0
  13. beaker_notebook/app/server_app.py +16 -0
  14. beaker_notebook/app/ui/beaker.svg +101 -0
  15. beaker_notebook/app/ui/favicon.ico +0 -0
  16. beaker_notebook/app/ui/index.html +15 -0
  17. beaker_notebook/app/ui/static/BaseQueryCell-BkYxksI5.js +1 -0
  18. beaker_notebook/app/ui/static/BeakerAdmin-CmINXWMq.css +1 -0
  19. beaker_notebook/app/ui/static/BeakerAdmin-DZrn90Yo.js +531 -0
  20. beaker_notebook/app/ui/static/BeakerNotebookPanel-DlwDdhcR.css +1 -0
  21. beaker_notebook/app/ui/static/BeakerNotebookPanel.vue_vue_type_style_index_0_lang-DVEpDAgJ.js +2352 -0
  22. beaker_notebook/app/ui/static/BeakerQueryCell-CLP87HiT.css +1 -0
  23. beaker_notebook/app/ui/static/BeakerQueryCell.vue_vue_type_style_index_0_lang-CsPbh_vB.js +364 -0
  24. beaker_notebook/app/ui/static/BeakerRawCell-CYX7jUwf.css +1 -0
  25. beaker_notebook/app/ui/static/BeakerRawCell.vue_vue_type_style_index_0_lang-C0LQPDG_.js +845 -0
  26. beaker_notebook/app/ui/static/BrainIcon-Cu5xmR-n.js +1 -0
  27. beaker_notebook/app/ui/static/ChatInterface-CQS-IhF0.js +1065 -0
  28. beaker_notebook/app/ui/static/ChatInterface-DKDl_3ZW.css +1 -0
  29. beaker_notebook/app/ui/static/DevInterface-CX6JI9k4.css +1 -0
  30. beaker_notebook/app/ui/static/DevInterface-D89vpZ2M.js +1171 -0
  31. beaker_notebook/app/ui/static/IntegrationPanel-DKP_5B7W.css +1 -0
  32. beaker_notebook/app/ui/static/IntegrationPanel.vue_vue_type_style_index_0_lang-c-zr1Dig.js +762 -0
  33. beaker_notebook/app/ui/static/IntegrationsInterface-BlUeSxlA.js +1656 -0
  34. beaker_notebook/app/ui/static/IntegrationsInterface-BzFBE6eg.css +1 -0
  35. beaker_notebook/app/ui/static/MediaPanel-DNCoIEA4.css +1 -0
  36. beaker_notebook/app/ui/static/MediaPanel.vue_vue_type_style_index_0_lang-qeorC2Wr.js +709 -0
  37. beaker_notebook/app/ui/static/NextBeakerQueryCell-C426bZbZ.css +1 -0
  38. beaker_notebook/app/ui/static/NextBeakerQueryCell.vue_vue_type_style_index_0_lang-COubACPH.js +1 -0
  39. beaker_notebook/app/ui/static/NextNotebookInterface-CnSA3fCt.js +1090 -0
  40. beaker_notebook/app/ui/static/NextNotebookInterface-DxBYBP58.css +1 -0
  41. beaker_notebook/app/ui/static/NotebookInterface-B63z6cMq.js +597 -0
  42. beaker_notebook/app/ui/static/NotebookInterface-BdxzVo_D.css +1 -0
  43. beaker_notebook/app/ui/static/NotebookSvg-2w04pLXO.js +1 -0
  44. beaker_notebook/app/ui/static/PlaygroundInterface-BiWl-IG6.css +1 -0
  45. beaker_notebook/app/ui/static/PlaygroundInterface-CQXkNf61.js +1 -0
  46. beaker_notebook/app/ui/static/WorkflowOutputPanel-CLNRizln.css +1 -0
  47. beaker_notebook/app/ui/static/WorkflowOutputPanel.vue_vue_type_style_index_0_lang-CdsA6Nlb.js +20070 -0
  48. beaker_notebook/app/ui/static/_plugin-vue_export-helper-DlAUqK2U.js +1 -0
  49. beaker_notebook/app/ui/static/cellOperations-DiO7UBn1.css +1 -0
  50. beaker_notebook/app/ui/static/cellOperations-mmhE2rpR.js +296 -0
  51. beaker_notebook/app/ui/static/codemirror-CEJpu35t.js +12 -0
  52. beaker_notebook/app/ui/static/index-8H8ONTyz.js +7212 -0
  53. beaker_notebook/app/ui/static/index-CDHrXzwd.css +1 -0
  54. beaker_notebook/app/ui/static/jupyterlab-DCB4j3g5.js +89 -0
  55. beaker_notebook/app/ui/static/lato-v17-latin-ext_latin-300-CGqVYVBd.woff2 +0 -0
  56. beaker_notebook/app/ui/static/lato-v17-latin-ext_latin-300-D-Ix9km9.woff +0 -0
  57. beaker_notebook/app/ui/static/lato-v17-latin-ext_latin-700-CCBIyjkE.woff +0 -0
  58. beaker_notebook/app/ui/static/lato-v17-latin-ext_latin-700-C_mCopxe.woff2 +0 -0
  59. beaker_notebook/app/ui/static/lato-v17-latin-ext_latin-regular-Dz3ZLxjK.woff +0 -0
  60. beaker_notebook/app/ui/static/lato-v17-latin-ext_latin-regular-GAITDyQJ.woff2 +0 -0
  61. beaker_notebook/app/ui/static/pdf.worker-BQQyum15.mjs +58272 -0
  62. beaker_notebook/app/ui/static/pdfjs-B7zhfHd9.js +16052 -0
  63. beaker_notebook/app/ui/static/primeicons-C6QP2o4f.woff2 +0 -0
  64. beaker_notebook/app/ui/static/primeicons-DMOk5skT.eot +0 -0
  65. beaker_notebook/app/ui/static/primeicons-Dr5RGzOO.svg +345 -0
  66. beaker_notebook/app/ui/static/primeicons-MpK4pl85.ttf +0 -0
  67. beaker_notebook/app/ui/static/primeicons-WjwUDZjB.woff +0 -0
  68. beaker_notebook/app/ui/static/primevue-DXcp5I-A.js +5711 -0
  69. beaker_notebook/app/ui/static/renderers-D-ztt1K4.js +19617 -0
  70. beaker_notebook/app/ui/static/renderers-DTrMDJiK.css +1 -0
  71. beaker_notebook/app/ui/static/vue.esm-browser.prod.js +12 -0
  72. beaker_notebook/app/ui/static/xlsx-C3u7rb2R.js +63 -0
  73. beaker_notebook/builder/__init__.py +0 -0
  74. beaker_notebook/builder/beaker.py +210 -0
  75. beaker_notebook/builder/hooks.py +22 -0
  76. beaker_notebook/builder/templates.py +99 -0
  77. beaker_notebook/builder/utils.py +12 -0
  78. beaker_notebook/cli/__init__.py +0 -0
  79. beaker_notebook/cli/app.py +131 -0
  80. beaker_notebook/cli/config.py +270 -0
  81. beaker_notebook/cli/context.py +236 -0
  82. beaker_notebook/cli/helpers.py +77 -0
  83. beaker_notebook/cli/main.py +73 -0
  84. beaker_notebook/cli/project.py +340 -0
  85. beaker_notebook/cli/running.py +114 -0
  86. beaker_notebook/cli/server.py +210 -0
  87. beaker_notebook/cli/subkernel.py +499 -0
  88. beaker_notebook/contexts/__init__.py +0 -0
  89. beaker_notebook/contexts/default/__init__.py +0 -0
  90. beaker_notebook/contexts/default/agent.py +91 -0
  91. beaker_notebook/contexts/default/context.py +46 -0
  92. beaker_notebook/contexts/default/default_payload.json +1 -0
  93. beaker_notebook/kernel.json +9 -0
  94. beaker_notebook/kernel.py +900 -0
  95. beaker_notebook/lib/__init__.py +9 -0
  96. beaker_notebook/lib/admin.py +105 -0
  97. beaker_notebook/lib/agent.py +471 -0
  98. beaker_notebook/lib/agent_tasks.py +111 -0
  99. beaker_notebook/lib/app.py +458 -0
  100. beaker_notebook/lib/autodiscovery.py +198 -0
  101. beaker_notebook/lib/code_analysis/__init__.py +19 -0
  102. beaker_notebook/lib/code_analysis/analysis_agent.py +149 -0
  103. beaker_notebook/lib/code_analysis/analysis_types.py +144 -0
  104. beaker_notebook/lib/code_analysis/analyzer.py +74 -0
  105. beaker_notebook/lib/code_analysis/message_types.py +0 -0
  106. beaker_notebook/lib/code_analysis/rules/__init__.py +1 -0
  107. beaker_notebook/lib/code_analysis/rules/base.py +134 -0
  108. beaker_notebook/lib/code_analysis/rules/trust/__init__.py +6 -0
  109. beaker_notebook/lib/code_analysis/rules/trust/categories.py +103 -0
  110. beaker_notebook/lib/code_analysis/rules/trust/rules.py +138 -0
  111. beaker_notebook/lib/config.py +550 -0
  112. beaker_notebook/lib/context.py +1225 -0
  113. beaker_notebook/lib/context_dump.py +453 -0
  114. beaker_notebook/lib/exporters/__init__.py +0 -0
  115. beaker_notebook/lib/exporters/chat.py +349 -0
  116. beaker_notebook/lib/exporters/full_context_notebook.py +24 -0
  117. beaker_notebook/lib/exporters/streamline.py +223 -0
  118. beaker_notebook/lib/extension.py +53 -0
  119. beaker_notebook/lib/integrations/__init__.py +0 -0
  120. beaker_notebook/lib/integrations/adhoc.py +645 -0
  121. beaker_notebook/lib/integrations/base.py +203 -0
  122. beaker_notebook/lib/integrations/registry.py +52 -0
  123. beaker_notebook/lib/integrations/skill.py +746 -0
  124. beaker_notebook/lib/integrations/types.py +254 -0
  125. beaker_notebook/lib/jupyter_kernel_proxy.py +391 -0
  126. beaker_notebook/lib/kernel_state.py +131 -0
  127. beaker_notebook/lib/message_types.py +38 -0
  128. beaker_notebook/lib/notebook_state.py +236 -0
  129. beaker_notebook/lib/reflector.py +247 -0
  130. beaker_notebook/lib/subkernel.py +898 -0
  131. beaker_notebook/lib/templates/__init__.py +105 -0
  132. beaker_notebook/lib/templates/agent_file.py +70 -0
  133. beaker_notebook/lib/templates/context_file.py +57 -0
  134. beaker_notebook/lib/templates/paths.py +12 -0
  135. beaker_notebook/lib/templates/procedure_file.py +21 -0
  136. beaker_notebook/lib/templates/readme_file.py +74 -0
  137. beaker_notebook/lib/templates/subkernel_file.py +50 -0
  138. beaker_notebook/lib/types.py +327 -0
  139. beaker_notebook/lib/utils.py +400 -0
  140. beaker_notebook/lib/workflow.py +341 -0
  141. beaker_notebook/services/__init__.py +59 -0
  142. beaker_notebook/services/auth/__init__.py +185 -0
  143. beaker_notebook/services/auth/dummy.py +33 -0
  144. beaker_notebook/services/auth/notebook.py +22 -0
  145. beaker_notebook/services/context/__init__.py +0 -0
  146. beaker_notebook/services/context/discovery_service.py +78 -0
  147. beaker_notebook/services/context/handlers.py +36 -0
  148. beaker_notebook/services/context/manager.py +88 -0
  149. beaker_notebook/services/context/util.py +64 -0
  150. beaker_notebook/services/kernel/__init__.py +5 -0
  151. beaker_notebook/services/kernel/manager.py +158 -0
  152. beaker_notebook/services/kernel/mappingmanager.py +125 -0
  153. beaker_notebook/services/kernel/provisioner.py +60 -0
  154. beaker_notebook/services/kernel/spec.py +115 -0
  155. beaker_notebook/services/session/__init__.py +245 -0
  156. beaker_notebook/services/storage/__init__.py +0 -0
  157. beaker_notebook/services/storage/base.py +93 -0
  158. beaker_notebook/services/storage/notebook.py +361 -0
  159. beaker_notebook/subkernels/__init__.py +0 -0
  160. beaker_notebook/subkernels/julia/__init__.py +3 -0
  161. beaker_notebook/subkernels/julia/procedures/.gitkeep +0 -0
  162. beaker_notebook/subkernels/julia/procedures/fetch_state.jl +71 -0
  163. beaker_notebook/subkernels/julia/procedures/reflectors/array.jl +24 -0
  164. beaker_notebook/subkernels/julia/procedures/reflectors/default.jl +20 -0
  165. beaker_notebook/subkernels/julia/procedures/reflectors/dict.jl +34 -0
  166. beaker_notebook/subkernels/julia/procedures/reflectors/function.jl +7 -0
  167. beaker_notebook/subkernels/julia/procedures/reflectors/module.jl +7 -0
  168. beaker_notebook/subkernels/julia/procedures/reflectors/type.jl +7 -0
  169. beaker_notebook/subkernels/julia/subkernel.py +39 -0
  170. beaker_notebook/subkernels/python/__init__.py +3 -0
  171. beaker_notebook/subkernels/python/procedures/.gitkeep +0 -0
  172. beaker_notebook/subkernels/python/procedures/describe_variables.py +69 -0
  173. beaker_notebook/subkernels/python/procedures/fetch_state.py +59 -0
  174. beaker_notebook/subkernels/python/procedures/reflectors/class.py +14 -0
  175. beaker_notebook/subkernels/python/procedures/reflectors/dataframe.py +28 -0
  176. beaker_notebook/subkernels/python/procedures/reflectors/default.py +32 -0
  177. beaker_notebook/subkernels/python/procedures/reflectors/function.py +18 -0
  178. beaker_notebook/subkernels/python/procedures/reflectors/mapping.py +36 -0
  179. beaker_notebook/subkernels/python/procedures/reflectors/module.py +9 -0
  180. beaker_notebook/subkernels/python/procedures/reflectors/ndarray.py +27 -0
  181. beaker_notebook/subkernels/python/procedures/reflectors/primitive.py +22 -0
  182. beaker_notebook/subkernels/python/procedures/reflectors/sequence.py +32 -0
  183. beaker_notebook/subkernels/python/procedures/reflectors/series.py +26 -0
  184. beaker_notebook/subkernels/python/procedures/reflectors/string.py +21 -0
  185. beaker_notebook/subkernels/python/subkernel.py +165 -0
  186. beaker_notebook/subkernels/rlang/__init__.py +3 -0
  187. beaker_notebook/subkernels/rlang/procedures/.gitkeep +0 -0
  188. beaker_notebook/subkernels/rlang/procedures/fetch_state.r +55 -0
  189. beaker_notebook/subkernels/rlang/procedures/reflectors/data_frame.r +28 -0
  190. beaker_notebook/subkernels/rlang/procedures/reflectors/default.r +23 -0
  191. beaker_notebook/subkernels/rlang/procedures/reflectors/function.r +11 -0
  192. beaker_notebook/subkernels/rlang/procedures/reflectors/list.r +23 -0
  193. beaker_notebook/subkernels/rlang/procedures/reflectors/vector.r +25 -0
  194. beaker_notebook/subkernels/rlang/subkernel.py +38 -0
  195. beaker_notebook/util/__init__.py +0 -0
  196. beaker_notebook/util/refactor.py +52 -0
  197. beaker_notebook-2.0.0b1.data/data/share/jupyter/kernels/beaker_kernel/kernel.json +9 -0
  198. beaker_notebook-2.0.0b1.dist-info/METADATA +86 -0
  199. beaker_notebook-2.0.0b1.dist-info/RECORD +202 -0
  200. beaker_notebook-2.0.0b1.dist-info/WHEEL +4 -0
  201. beaker_notebook-2.0.0b1.dist-info/entry_points.txt +24 -0
  202. beaker_notebook-2.0.0b1.dist-info/licenses/LICENSE.txt +9 -0
@@ -0,0 +1,37 @@
1
+ """
2
+ Compatibility shim: redirects any `beaker_kernel[.X]` import to `beaker_notebook[.X]`.
3
+ """
4
+ import importlib
5
+ import sys
6
+ from importlib.abc import MetaPathFinder, Loader
7
+ from importlib.machinery import ModuleSpec
8
+
9
+ _OLD = "beaker_kernel"
10
+ _NEW = "beaker_notebook"
11
+
12
+
13
+ class _RenameLoader(Loader):
14
+ def create_module(self, spec):
15
+ target = _NEW + spec.name[len(_OLD):]
16
+ module = importlib.import_module(target)
17
+ sys.modules[spec.name] = module
18
+ return module
19
+
20
+ def exec_module(self, module):
21
+ pass
22
+
23
+
24
+ class _RenameFinder(MetaPathFinder):
25
+ def find_spec(self, fullname, path=None, target=None):
26
+ if fullname == _OLD or fullname.startswith(_OLD + "."):
27
+ return ModuleSpec(fullname, _RenameLoader(), is_package=True)
28
+ return None
29
+
30
+
31
+ # Install once.
32
+ if not any(isinstance(f, _RenameFinder) for f in sys.meta_path):
33
+ sys.meta_path.insert(0, _RenameFinder())
34
+
35
+ # Make `beaker_kernel` itself be `beaker_notebook`.
36
+ import beaker_notebook as _bn
37
+ sys.modules[__name__] = _bn
@@ -0,0 +1,172 @@
1
+ from beaker_notebook.util.refactor import redirect_imports, ImportRedirectMap
2
+
3
+ redirect_map: ImportRedirectMap = {
4
+ 'beaker_kernel.service.admin_utils': {
5
+ 'build_edges_map': 'beaker_kernel.lib.admin',
6
+ 'build_proc_info': 'beaker_kernel.lib.admin',
7
+ 'fetch_kernel_info': 'beaker_kernel.lib.admin',
8
+ 'fetch_system_stats': 'beaker_kernel.lib.admin',
9
+ },
10
+ 'beaker_kernel.service.api': {},
11
+ 'beaker_kernel.service.api.handlers': {
12
+ 'add_handler_prefix': 'beaker_kernel.app.api.handlers',
13
+ 'find_api_handlers': 'beaker_kernel.app.api.handlers',
14
+ 'register_api_handlers': 'beaker_kernel.app.api.handlers',
15
+ },
16
+ 'beaker_kernel.service.api.integrations': {
17
+ 'BeakerAPIMixin': 'beaker_kernel.app.api.integrations',
18
+ 'IntegrationHandler': 'beaker_kernel.app.api.integrations',
19
+ 'IntegrationResourceHandler': 'beaker_kernel.app.api.integrations',
20
+ 'get_context': 'beaker_kernel.app.api.integrations',
21
+ },
22
+ 'beaker_kernel.service.api.notebook': {
23
+ 'NotebookHandler': 'beaker_kernel.app.api.notebook'
24
+ },
25
+ 'beaker_kernel.service.auth': {
26
+ 'BeakerUser': 'beaker_kernel.services.auth',
27
+ 'current_request': 'beaker_kernel.services.auth',
28
+ 'current_user': 'beaker_kernel.services.auth',
29
+ 'BeakerAuthorizer': 'beaker_kernel.services.auth',
30
+ 'BeakerIdentityProvider': 'beaker_kernel.services.auth',
31
+ 'BeakerPermission': 'beaker_kernel.services.auth',
32
+ 'BeakerRole': 'beaker_kernel.services.auth',
33
+ 'RoleBasedUser': 'beaker_kernel.services.auth',
34
+ },
35
+ 'beaker_kernel.service.auth.dummy': {
36
+ 'DummyAuthorizer': 'beaker_kernel.services.auth.dummy',
37
+ 'DummyIdentityProvider': 'beaker_kernel.services.auth.dummy',
38
+ },
39
+ 'beaker_kernel.service.auth.notebook': {
40
+ 'NotebookAuthorizer': 'beaker_kernel.services.auth.notebook',
41
+ 'NotebookIdentityProvider': 'beaker_kernel.services.auth.notebook',
42
+ },
43
+ 'beaker_kernel.service.base': {
44
+ 'BaseBeakerApp': 'beaker_kernel.app.base',
45
+ 'BeakerKernelManager': 'beaker_kernel.services.kernel.manager',
46
+ 'BeakerKernelMappingManager': 'beaker_kernel.services.kernel.mappingmanager',
47
+ 'BeakerKernelSpecManager': 'beaker_kernel.services.kernel.spec',
48
+ 'BeakerSessionManager': 'beaker_kernel.services.session',
49
+ },
50
+ 'beaker_kernel.service.dev': {
51
+ 'BeakerWatchDog': 'beaker_kernel.app.dev_app',
52
+ 'DevBeakerJupyterApp': 'beaker_kernel.app.dev_app',
53
+ 'create_observer': 'beaker_kernel.app.dev_app',
54
+ },
55
+ 'beaker_kernel.service.handlers': {
56
+ 'ConfigController': 'beaker_kernel.app.handlers',
57
+ 'ConfigHandler': 'beaker_kernel.app.handlers',
58
+ 'ContextHandler': 'beaker_kernel.app.handlers',
59
+ 'ExportAsHandler': 'beaker_kernel.app.handlers',
60
+ 'PageHandler': 'beaker_kernel.app.handlers',
61
+ 'StatsHandler': 'beaker_kernel.app.handlers',
62
+ 'register_handlers': 'beaker_kernel.app.handlers',
63
+ 'request_log_handler': 'beaker_kernel.app.handlers',
64
+ 'sanitize_env': 'beaker_kernel.app.handlers',
65
+ },
66
+ 'beaker_kernel.service.notebook': {
67
+ 'BeakerNotebookApp': 'beaker_kernel.app.notebook_app'
68
+ },
69
+ 'beaker_kernel.service.server': {
70
+ 'BeakerServerApp': 'beaker_kernel.app.server_app'
71
+ },
72
+ 'beaker_kernel.service.storage': {},
73
+ 'beaker_kernel.service.storage.base': {
74
+ 'BaseBeakerContentsManager': 'beaker_kernel.services.storage.base',
75
+ 'BeakerLocalContentsHandler': 'beaker_kernel.services.storage.base',
76
+ 'BeakerLocalContentsManager': 'beaker_kernel.services.storage.base',
77
+ 'BeakerStorageManager': 'beaker_kernel.services.storage.base',
78
+ 'with_hidden_files': 'beaker_kernel.services.storage.base',
79
+ },
80
+ 'beaker_kernel.service.storage.notebook': {
81
+ 'BaseNotebookManager': 'beaker_kernel.services.storage.notebook',
82
+ 'BrowserLocalDataNotebookManager': 'beaker_kernel.services.storage.notebook',
83
+ 'FileNotebookManager': 'beaker_kernel.services.storage.notebook',
84
+ 'NotebookInfo': 'beaker_kernel.services.storage.notebook',
85
+ 'with_hidden_files': 'beaker_kernel.services.storage.notebook',
86
+ },
87
+ 'beaker_notebook.service.admin_utils': {
88
+ 'build_edges_map': 'beaker_notebook.lib.admin',
89
+ 'build_proc_info': 'beaker_notebook.lib.admin',
90
+ 'fetch_kernel_info': 'beaker_notebook.lib.admin',
91
+ 'fetch_system_stats': 'beaker_notebook.lib.admin',
92
+ },
93
+ 'beaker_notebook.service.api': {},
94
+ 'beaker_notebook.service.api.handlers': {
95
+ 'add_handler_prefix': 'beaker_notebook.app.api.handlers',
96
+ 'find_api_handlers': 'beaker_notebook.app.api.handlers',
97
+ 'register_api_handlers': 'beaker_notebook.app.api.handlers',
98
+ },
99
+ 'beaker_notebook.service.api.integrations': {
100
+ 'BeakerAPIMixin': 'beaker_notebook.app.api.integrations',
101
+ 'IntegrationHandler': 'beaker_notebook.app.api.integrations',
102
+ 'IntegrationResourceHandler': 'beaker_notebook.app.api.integrations',
103
+ 'get_context': 'beaker_notebook.app.api.integrations',
104
+ },
105
+ 'beaker_notebook.service.api.notebook': {
106
+ 'NotebookHandler': 'beaker_notebook.app.api.notebook'
107
+ },
108
+ 'beaker_notebook.service.auth': {
109
+ 'BeakerUser': 'beaker_notebook.services.auth',
110
+ 'current_request': 'beaker_notebook.services.auth',
111
+ 'current_user': 'beaker_notebook.services.auth',
112
+ 'BeakerAuthorizer': 'beaker_notebook.services.auth',
113
+ 'BeakerIdentityProvider': 'beaker_notebook.services.auth',
114
+ 'BeakerPermission': 'beaker_notebook.services.auth',
115
+ 'BeakerRole': 'beaker_notebook.services.auth',
116
+ 'RoleBasedUser': 'beaker_notebook.services.auth',
117
+ },
118
+ 'beaker_notebook.service.auth.dummy': {
119
+ 'DummyAuthorizer': 'beaker_notebook.services.auth.dummy',
120
+ 'DummyIdentityProvider': 'beaker_notebook.services.auth.dummy',
121
+ },
122
+ 'beaker_notebook.service.auth.notebook': {
123
+ 'NotebookAuthorizer': 'beaker_notebook.services.auth.notebook',
124
+ 'NotebookIdentityProvider': 'beaker_notebook.services.auth.notebook',
125
+ },
126
+ 'beaker_notebook.service.base': {
127
+ 'BaseBeakerApp': 'beaker_notebook.app.base',
128
+ 'BeakerKernelManager': 'beaker_notebook.services.kernel.manager',
129
+ 'BeakerKernelMappingManager': 'beaker_notebook.services.kernel.mappingmanager',
130
+ 'BeakerKernelSpecManager': 'beaker_notebook.services.kernel.spec',
131
+ 'BeakerSessionManager': 'beaker_notebook.services.session',
132
+ },
133
+ 'beaker_notebook.service.dev': {
134
+ 'BeakerWatchDog': 'beaker_notebook.app.dev_app',
135
+ 'DevBeakerJupyterApp': 'beaker_notebook.app.dev_app',
136
+ 'create_observer': 'beaker_notebook.app.dev_app',
137
+ },
138
+ 'beaker_notebook.service.handlers': {
139
+ 'ConfigController': 'beaker_notebook.app.handlers',
140
+ 'ConfigHandler': 'beaker_notebook.app.handlers',
141
+ 'ContextHandler': 'beaker_notebook.app.handlers',
142
+ 'ExportAsHandler': 'beaker_notebook.app.handlers',
143
+ 'PageHandler': 'beaker_notebook.app.handlers',
144
+ 'StatsHandler': 'beaker_notebook.app.handlers',
145
+ 'register_handlers': 'beaker_notebook.app.handlers',
146
+ 'request_log_handler': 'beaker_notebook.app.handlers',
147
+ 'sanitize_env': 'beaker_notebook.app.handlers',
148
+ },
149
+ 'beaker_notebook.service.notebook': {
150
+ 'BeakerNotebookApp': 'beaker_notebook.app.notebook_app'
151
+ },
152
+ 'beaker_notebook.service.server': {
153
+ 'BeakerServerApp': 'beaker_notebook.app.server_app'
154
+ },
155
+ 'beaker_notebook.service.storage': {},
156
+ 'beaker_notebook.service.storage.base': {
157
+ 'BaseBeakerContentsManager': 'beaker_notebook.services.storage.base',
158
+ 'BeakerLocalContentsHandler': 'beaker_notebook.services.storage.base',
159
+ 'BeakerLocalContentsManager': 'beaker_notebook.services.storage.base',
160
+ 'BeakerStorageManager': 'beaker_notebook.services.storage.base',
161
+ 'with_hidden_files': 'beaker_notebook.services.storage.base',
162
+ },
163
+ 'beaker_notebook.service.storage.notebook': {
164
+ 'BaseNotebookManager': 'beaker_notebook.services.storage.notebook',
165
+ 'BrowserLocalDataNotebookManager': 'beaker_notebook.services.storage.notebook',
166
+ 'FileNotebookManager': 'beaker_notebook.services.storage.notebook',
167
+ 'NotebookInfo': 'beaker_notebook.services.storage.notebook',
168
+ 'with_hidden_files': 'beaker_notebook.services.storage.notebook',
169
+ },
170
+ }
171
+
172
+ redirect_imports(redirect_map)
@@ -0,0 +1,13 @@
1
+ # Application interface layer
2
+
3
+ def __getattr__(name):
4
+ if name == "BaseBeakerApp":
5
+ from .base import BaseBeakerApp
6
+ return BaseBeakerApp
7
+ elif name == "BeakerServerApp":
8
+ from .server_app import BeakerServerApp
9
+ return BeakerServerApp
10
+ elif name == "BeakerNotebookApp":
11
+ from .notebook_app import BeakerNotebookApp
12
+ return BeakerNotebookApp
13
+ raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
File without changes
@@ -0,0 +1,84 @@
1
+ import importlib
2
+ import logging
3
+ import os
4
+ import sys
5
+ import urllib.parse
6
+ from typing import get_origin, get_args
7
+ from dataclasses import is_dataclass, asdict
8
+ from typing import TYPE_CHECKING, get_origin, get_args, GenericAlias, Union, Generic, Generator, Optional, Any
9
+
10
+
11
+ from beaker_notebook.lib.autodiscovery import autodiscover
12
+ from beaker_notebook.lib.app import BeakerApp
13
+ from beaker_notebook.lib.context import BeakerContext
14
+ from beaker_notebook.lib.subkernel import BeakerSubkernel
15
+ from beaker_notebook.lib.agent_tasks import summarize
16
+ from beaker_notebook.lib.config import config, locate_config, Config, Table, Choice, recursiveOptionalUpdate, reset_config
17
+ from beaker_notebook.lib import admin
18
+
19
+ if TYPE_CHECKING:
20
+ from beaker_notebook.app.base import BaseBeakerApp
21
+
22
+ logger = logging.getLogger(__name__)
23
+
24
+ PREFIX = '/beaker/'
25
+
26
+ def find_api_handlers(base=None) -> Generator[tuple[str, Any, str], None, None]:
27
+ """Discover and yield API handlers from registered Beaker extensions.
28
+
29
+ This function uses the Beaker extension autodiscovery mechanism to find
30
+ all extensions that may provide API handlers. It then iterates through
31
+ each extension's handlers and yields them one by one.
32
+
33
+ Yields
34
+ ------
35
+ tuple[str, Any, str]
36
+ A tuple containing the URL pattern, handler class, and optional name
37
+ for each discovered API handler.
38
+ """
39
+ if base is None:
40
+ package = __package__
41
+ base_dir = os.path.dirname(str(sys.modules[package].__file__))
42
+ else:
43
+ package = None
44
+ try:
45
+ mod = importlib.import_module(base)
46
+ base_dir = os.path.dirname(str(mod.__file__))
47
+ package = mod.__package__
48
+ except (ImportError, TypeError):
49
+ logger.error(f"Could not import module {base} for API handler discovery")
50
+ return
51
+
52
+ if base_dir is None or package is None:
53
+ logger.error(f"Invalid base parameter: {type(base)}: {base}")
54
+ return
55
+
56
+ for f in os.listdir(base_dir):
57
+ if f.endswith('.py') and f != '__init__.py' and f != 'handlers.py':
58
+ s = f'{package}.{f[:-3]}'
59
+ try:
60
+ mod = importlib.import_module(s)
61
+ if "handlers" in dir(mod):
62
+ logger.debug(f"Found handlers in {s}")
63
+ for handlers in getattr(mod, "handlers"):
64
+ yield handlers
65
+ except ImportError as e:
66
+ logger.warning(f"Failed to import API handler module '{s}': {e}")
67
+ logger.warning(f"Skipping API handler module '{s}' due to import error")
68
+ continue
69
+
70
+
71
+ def add_handler_prefix(prefix: str, handler_tuple: tuple[str, Any, str]):
72
+ path, rest = handler_tuple[0], handler_tuple[1:]
73
+ if not prefix.endswith('/'):
74
+ prefix = prefix + '/'
75
+ if path.startswith('/'):
76
+ path = path.lstrip('/')
77
+ return (urllib.parse.urljoin(prefix, path), *rest)
78
+
79
+
80
+ def register_api_handlers(app: "BaseBeakerApp"):
81
+ app.handlers.extend([
82
+ add_handler_prefix(PREFIX, handler)
83
+ for handler in find_api_handlers()
84
+ ])
@@ -0,0 +1,299 @@
1
+ import json
2
+ import logging
3
+ import typing
4
+ import asyncio
5
+ from inspect import isawaitable, iscoroutinefunction
6
+ from queue import Empty
7
+
8
+ from jupyter_server.base.handlers import JupyterHandler
9
+ from jupyter_server.services.kernels.kernelmanager import AsyncMappingKernelManager
10
+ from jupyter_server.services.sessions.sessionmanager import SessionManager
11
+
12
+ from beaker_notebook.lib.autodiscovery import autodiscover
13
+
14
+ import tornado
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+ from abc import ABC, abstractmethod
19
+
20
+ from functools import lru_cache
21
+
22
+ context_cache = None
23
+
24
+ @lru_cache
25
+ def get_context(context_slug: str):
26
+ global context_cache
27
+ if context_cache is None:
28
+ context_cache = autodiscover("contexts")
29
+ return context_cache.get(context_slug)
30
+
31
+
32
+ # Resource Handlers
33
+
34
+ # class ResourceHandler(ABC):
35
+ # KEY: str
36
+
37
+ # @abstractmethod
38
+ # async def get(self, integration_id, resource_id=None):
39
+ # pass
40
+
41
+ # @abstractmethod
42
+ # async def new(self, integration_id, payload):
43
+ # pass
44
+
45
+ # @abstractmethod
46
+ # async def replace(self, integration_id, resource_id, payload):
47
+ # pass
48
+
49
+ # @abstractmethod
50
+ # async def delete(self, integration_id, resource_id):
51
+ # pass
52
+
53
+
54
+ # class FileResourceHandler(ResourceHandler):
55
+ # KEY="file"
56
+
57
+ # async def get(self, integration_id, resource_id=None):
58
+ # pass
59
+
60
+ # async def new(self, integration_id, payload):
61
+ # return await super().new(integration_id, payload)
62
+
63
+ # async def replace(self, integration_id, resource_id, payload):
64
+ # return await super().replace(integration_id, resource_id, payload)
65
+
66
+ # async def delete(self, integration_id, resource_id):
67
+ # return await super().delete(integration_id, resource_id)
68
+
69
+
70
+ # class ExampleResourceHandler(ResourceHandler):
71
+ # KEY="example"
72
+
73
+ # async def get(self, integration_id, resource_id=None):
74
+ # pass
75
+
76
+ # async def new(self, integration_id, payload):
77
+ # return await super().new(context_slug, integration_id, payload)
78
+
79
+ # async def replace(self, integration_id, resource_id, payload):
80
+ # return await super().replace(context_slug, integration_id, resource_id, payload)
81
+
82
+ # async def delete(self, integration_id, resource_id):
83
+ # return await super().delete(context_slug, integration_id, resource_id)
84
+
85
+
86
+ # Resources: list[ResourceHandler] = [
87
+ # FileResourceHandler,
88
+ # ExampleResourceHandler,
89
+ # ]
90
+
91
+ # ResourceMap = {
92
+ # cls.KEY: cls for cls in Resources
93
+ # }
94
+
95
+
96
+ class BeakerAPIMixin:
97
+ session_manager: SessionManager
98
+ kernel_manager: AsyncMappingKernelManager
99
+
100
+ def stringify_serialization(self, obj):
101
+ return json.loads(json.dumps(obj, default=str))
102
+
103
+ async def call_in_context(
104
+ self,
105
+ session_id: str | None,
106
+ target: str,
107
+ function: str,
108
+ args: typing.Optional[list] = None,
109
+ kwargs: typing.Optional[dict] = None,
110
+ ):
111
+ if args is None:
112
+ args = []
113
+ if kwargs is None:
114
+ kwargs = {}
115
+
116
+ kernel = None
117
+ retries = 0
118
+ max_retries = 5
119
+ interval = 3
120
+ while True:
121
+ try:
122
+ # TODO: session manager ready future
123
+ # TODO: ensure it's defined
124
+ session = await self.session_manager.get_session(name=session_id)
125
+ break
126
+ except Exception as err:
127
+ logger.warning(f"Failed to get session, retrying: {retries}/{max_retries} {err}")
128
+ await asyncio.sleep(interval)
129
+ retries += 1
130
+ if retries >= max_retries:
131
+ logger.error(f"Failed after {max_retries} retries. Giving up")
132
+ return None
133
+
134
+ if session is not None:
135
+ kernel = self.kernel_manager.get_kernel(session["kernel"]["id"])
136
+ if not kernel:
137
+ return None
138
+
139
+ client = kernel.client()
140
+ try:
141
+ content = {
142
+ "target": target,
143
+ "function": function,
144
+ "args": args,
145
+ "kwargs": kwargs
146
+ }
147
+ client.session.send(
148
+ stream=client.shell_channel.socket,
149
+ msg_or_type="call_in_context_request",
150
+ content=content,
151
+ track=True,
152
+ metadata=None,
153
+ )
154
+ if iscoroutinefunction(client.get_shell_msg):
155
+ result = await client.get_shell_msg(timeout=30) # timeout is in seconds, not milliseconds
156
+ else:
157
+ result = client.get_shell_msg(timeout=30)
158
+ except Empty as err:
159
+ raise TimeoutError(err)
160
+ finally:
161
+ client.stop_channels()
162
+ return result["content"]["return"]
163
+
164
+ # Integration Handler
165
+
166
+ class IntegrationHandler(BeakerAPIMixin, JupyterHandler):
167
+ """
168
+ Handles fetching and adding integrations.
169
+ """
170
+ def set_default_headers(self):
171
+ self.set_header("Content-Type", "application/json")
172
+
173
+ async def head(self, session_id=None, integration_id=None):
174
+ integrations = await self.call_in_context(
175
+ session_id=session_id,
176
+ target="context",
177
+ function="list_integrations"
178
+ ) or {}
179
+ self.write({"integrations": list(integrations.keys())})
180
+
181
+ async def get(self, session_id=None, integration_id=None):
182
+ if integration_id is None:
183
+ integrations = await self.call_in_context(
184
+ session_id=session_id,
185
+ target="context",
186
+ function="list_integrations"
187
+ ) or {}
188
+ self.write({"integrations": self.stringify_serialization(integrations)})
189
+ else:
190
+ integration = await self.call_in_context(
191
+ session_id=session_id,
192
+ target=f"integration:{integration_id}",
193
+ function="get_integration",
194
+ kwargs={"integration_id": integration_id}
195
+ )
196
+ self.write(self.stringify_serialization(integration))
197
+
198
+ async def post(self, session_id=None, integration_id=None):
199
+ body = tornado.escape.json_decode(self.request.body)
200
+ try:
201
+ if integration_id is not None:
202
+ body["integration_id"] = integration_id
203
+ result = await self.call_in_context(
204
+ session_id=session_id,
205
+ target=f"integration:{integration_id}",
206
+ function="update_integration",
207
+ kwargs=body
208
+ ) or {}
209
+ else:
210
+ provider_id = body.pop("provider")
211
+ result = await self.call_in_context(
212
+ session_id=session_id,
213
+ target=f"provider:{provider_id}",
214
+ function="add_integration",
215
+ kwargs=body
216
+ ) or {}
217
+ self.write(self.stringify_serialization(result))
218
+ except TimeoutError as e:
219
+ raise tornado.web.HTTPError(status_code=504, log_message="Kernel took too long to repond to request")
220
+ except Exception as e:
221
+ raise tornado.web.HTTPError(status_code=500, log_message=str(e))
222
+
223
+
224
+ class IntegrationResourceHandler(BeakerAPIMixin, JupyterHandler):
225
+ """
226
+ Handles fetching and adding resources belonging to an integration.
227
+ """
228
+ def set_default_headers(self):
229
+ self.set_header("Content-Type", "application/json")
230
+
231
+ async def head(self, session_id=None, integration_id=None, resource_type=None, resource_id=None):
232
+ pass
233
+
234
+ async def get(self, session_id=None, integration_id=None, resource_type=None, resource_id=None):
235
+ if resource_id is None:
236
+ base_kwargs = {"integration_id": integration_id}
237
+ result = await self.call_in_context(
238
+ session_id=session_id,
239
+ target=f"integration:{integration_id}",
240
+ function="list_resources",
241
+ kwargs=base_kwargs | (
242
+ {"resource_type": resource_type}
243
+ if resource_type is not None and resource_type != "all"
244
+ else {}
245
+ )
246
+ )
247
+ self.write({"resources": self.stringify_serialization(result)})
248
+ else:
249
+ try:
250
+ result = await self.call_in_context(
251
+ session_id=session_id,
252
+ target=f"integration:{integration_id}",
253
+ function="get_resource",
254
+ kwargs={"integration_id": integration_id, "resource_id": resource_id}
255
+ )
256
+ self.write(self.stringify_serialization(result))
257
+ except TimeoutError as e:
258
+ raise tornado.web.HTTPError(status_code=504, log_message="Kernel took too long to repond to request")
259
+ except Exception as e:
260
+ raise tornado.web.HTTPError(status_code=500, log_message=str(e))
261
+
262
+ async def post(self, session_id=None, integration_id=None, resource_type=None, resource_id=None):
263
+ function = "add_resource" if resource_id is None else "update_resource"
264
+ kwargs = {"integration_id": integration_id}
265
+ if function == "update_resource":
266
+ kwargs["resource_id"] = resource_id
267
+ kwargs.update(tornado.escape.json_decode(self.request.body))
268
+ try:
269
+ result = await self.call_in_context(
270
+ session_id=session_id,
271
+ target=f"integration:{integration_id}",
272
+ function=function,
273
+ kwargs=kwargs
274
+ )
275
+ self.write(self.stringify_serialization(result))
276
+ except TimeoutError as e:
277
+ raise tornado.web.HTTPError(status_code=504, log_message="Kernel took too long to repond to request")
278
+ except Exception as e:
279
+ raise tornado.web.HTTPError(status_code=500, log_message=str(e))
280
+
281
+
282
+ async def delete(self, session_id=None, integration_id=None, resource_type=None, resource_id=None):
283
+ try:
284
+ await self.call_in_context(
285
+ session_id=session_id,
286
+ target=f"integration:{integration_id}",
287
+ function="remove_resource",
288
+ kwargs={"resource_id": resource_id, "integration_id": integration_id}
289
+ )
290
+ self.write({})
291
+ except TimeoutError as e:
292
+ raise tornado.web.HTTPError(status_code=504, log_message="Kernel took too long to repond to request")
293
+ except Exception as e:
294
+ raise tornado.web.HTTPError(status_code=500, log_message=str(e))
295
+
296
+ handlers = [
297
+ (r'integrations/(?P<session_id>[\w\d-]+)/?(?P<integration_id>[\w\d-]+)?', IntegrationHandler),
298
+ (r'integrations/(?P<session_id>[\w\d-]+)/(?P<integration_id>[\w\d-]+)/(?P<resource_type>\w+)/?(?P<resource_id>[\w\d-]+)?', IntegrationResourceHandler),
299
+ ]