solara-ui 1.31.0__py2.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 (439) hide show
  1. prefix/etc/jupyter/jupyter_notebook_config.d/solara.json +7 -0
  2. prefix/etc/jupyter/jupyter_server_config.d/solara.json +7 -0
  3. solara/__init__.py +124 -0
  4. solara/__main__.py +734 -0
  5. solara/alias.py +6 -0
  6. solara/autorouting.py +546 -0
  7. solara/cache.py +303 -0
  8. solara/checks.html +71 -0
  9. solara/checks.py +224 -0
  10. solara/comm.py +28 -0
  11. solara/components/__init__.py +59 -0
  12. solara/components/alert.py +155 -0
  13. solara/components/applayout.py +393 -0
  14. solara/components/button.py +85 -0
  15. solara/components/card.py +87 -0
  16. solara/components/checkbox.py +50 -0
  17. solara/components/code_highlight_css.py +11 -0
  18. solara/components/code_highlight_css.vue +63 -0
  19. solara/components/columns.py +159 -0
  20. solara/components/component_vue.py +110 -0
  21. solara/components/cross_filter.py +335 -0
  22. solara/components/dataframe.py +546 -0
  23. solara/components/datatable.py +221 -0
  24. solara/components/datatable.vue +175 -0
  25. solara/components/details.py +21 -0
  26. solara/components/download.vue +35 -0
  27. solara/components/echarts.py +75 -0
  28. solara/components/echarts.vue +128 -0
  29. solara/components/figure_altair.py +39 -0
  30. solara/components/file_browser.py +182 -0
  31. solara/components/file_download.py +199 -0
  32. solara/components/file_drop.py +139 -0
  33. solara/components/file_drop.vue +83 -0
  34. solara/components/file_list_widget.vue +78 -0
  35. solara/components/head.py +27 -0
  36. solara/components/head_tag.py +49 -0
  37. solara/components/head_tag.vue +60 -0
  38. solara/components/image.py +173 -0
  39. solara/components/input.py +436 -0
  40. solara/components/link.py +55 -0
  41. solara/components/markdown.py +378 -0
  42. solara/components/markdown_editor.py +25 -0
  43. solara/components/markdown_editor.vue +362 -0
  44. solara/components/matplotlib.py +74 -0
  45. solara/components/meta.py +47 -0
  46. solara/components/misc.py +333 -0
  47. solara/components/pivot_table.py +258 -0
  48. solara/components/pivot_table.vue +158 -0
  49. solara/components/progress.py +47 -0
  50. solara/components/select.py +182 -0
  51. solara/components/select.vue +27 -0
  52. solara/components/slider.py +442 -0
  53. solara/components/slider_date.vue +56 -0
  54. solara/components/spinner-solara.vue +105 -0
  55. solara/components/spinner.py +30 -0
  56. solara/components/sql_code.py +33 -0
  57. solara/components/sql_code.vue +128 -0
  58. solara/components/style.py +105 -0
  59. solara/components/switch.py +68 -0
  60. solara/components/tab_navigation.py +37 -0
  61. solara/components/title.py +90 -0
  62. solara/components/title.vue +38 -0
  63. solara/components/togglebuttons.py +200 -0
  64. solara/components/tooltip.py +61 -0
  65. solara/datatypes.py +143 -0
  66. solara/express.py +241 -0
  67. solara/hooks/__init__.py +4 -0
  68. solara/hooks/dataframe.py +99 -0
  69. solara/hooks/misc.py +263 -0
  70. solara/hooks/use_reactive.py +129 -0
  71. solara/hooks/use_thread.py +129 -0
  72. solara/kitchensink.py +8 -0
  73. solara/lab/__init__.py +34 -0
  74. solara/lab/components/__init__.py +6 -0
  75. solara/lab/components/chat.py +203 -0
  76. solara/lab/components/confirmation_dialog.py +163 -0
  77. solara/lab/components/cross_filter.py +7 -0
  78. solara/lab/components/input_date.py +298 -0
  79. solara/lab/components/menu.py +181 -0
  80. solara/lab/components/menu.vue +38 -0
  81. solara/lab/components/tabs.py +274 -0
  82. solara/lab/components/theming.py +98 -0
  83. solara/lab/components/theming.vue +72 -0
  84. solara/lab/hooks/__init__.py +0 -0
  85. solara/lab/hooks/dataframe.py +12 -0
  86. solara/lab/toestand.py +3 -0
  87. solara/lab/utils/__init__.py +2 -0
  88. solara/lab/utils/cookies.py +5 -0
  89. solara/lab/utils/dataframe.py +115 -0
  90. solara/lab/utils/headers.py +5 -0
  91. solara/layout.py +44 -0
  92. solara/lifecycle.py +46 -0
  93. solara/minisettings.py +133 -0
  94. solara/py.typed +0 -0
  95. solara/reactive.py +93 -0
  96. solara/routing.py +268 -0
  97. solara/scope/__init__.py +88 -0
  98. solara/scope/types.py +55 -0
  99. solara/server/__init__.py +0 -0
  100. solara/server/app.py +491 -0
  101. solara/server/assets/custom.css +1 -0
  102. solara/server/assets/custom.js +1 -0
  103. solara/server/assets/favicon.png +0 -0
  104. solara/server/assets/favicon.svg +5 -0
  105. solara/server/assets/style.css +1665 -0
  106. solara/server/assets/theme-dark.css +437 -0
  107. solara/server/assets/theme-light.css +420 -0
  108. solara/server/assets/theme.js +3 -0
  109. solara/server/cdn_helper.py +77 -0
  110. solara/server/esm.py +69 -0
  111. solara/server/fastapi.py +5 -0
  112. solara/server/flask.py +286 -0
  113. solara/server/jupyter/__init__.py +2 -0
  114. solara/server/jupyter/cdn_handler.py +28 -0
  115. solara/server/jupyter/server_extension.py +29 -0
  116. solara/server/jupytertools.py +46 -0
  117. solara/server/kernel.py +338 -0
  118. solara/server/kernel_context.py +357 -0
  119. solara/server/patch.py +552 -0
  120. solara/server/reload.py +242 -0
  121. solara/server/server.py +456 -0
  122. solara/server/settings.py +215 -0
  123. solara/server/shell.py +251 -0
  124. solara/server/starlette.py +601 -0
  125. solara/server/static/ansi.js +270 -0
  126. solara/server/static/highlight-dark.css +82 -0
  127. solara/server/static/highlight.css +43 -0
  128. solara/server/static/main-vuetify.js +260 -0
  129. solara/server/static/main.js +163 -0
  130. solara/server/static/solara_bootstrap.py +129 -0
  131. solara/server/static/sun.svg +23 -0
  132. solara/server/static/webworker.js +42 -0
  133. solara/server/telemetry.py +212 -0
  134. solara/server/templates/index.html.j2 +1 -0
  135. solara/server/templates/loader-plain.css +11 -0
  136. solara/server/templates/loader-plain.html +20 -0
  137. solara/server/templates/loader-solara.css +111 -0
  138. solara/server/templates/loader-solara.html +40 -0
  139. solara/server/templates/plain.html +82 -0
  140. solara/server/templates/solara.html.j2 +446 -0
  141. solara/server/threaded.py +75 -0
  142. solara/server/utils.py +30 -0
  143. solara/server/websocket.py +45 -0
  144. solara/settings.py +56 -0
  145. solara/tasks.py +837 -0
  146. solara/template/button.py +16 -0
  147. solara/template/markdown.py +42 -0
  148. solara/template/portal/.flake8 +6 -0
  149. solara/template/portal/.pre-commit-config.yaml +28 -0
  150. solara/template/portal/LICENSE +21 -0
  151. solara/template/portal/Procfile +7 -0
  152. solara/template/portal/mypy.ini +3 -0
  153. solara/template/portal/pyproject.toml +26 -0
  154. solara/template/portal/solara_portal/__init__.py +4 -0
  155. solara/template/portal/solara_portal/components/__init__.py +2 -0
  156. solara/template/portal/solara_portal/components/article.py +28 -0
  157. solara/template/portal/solara_portal/components/data.py +28 -0
  158. solara/template/portal/solara_portal/components/header.py +6 -0
  159. solara/template/portal/solara_portal/components/layout.py +6 -0
  160. solara/template/portal/solara_portal/content/articles/equis-in-vidi.md +85 -0
  161. solara/template/portal/solara_portal/content/articles/substiterat-vati.md +70 -0
  162. solara/template/portal/solara_portal/data.py +60 -0
  163. solara/template/portal/solara_portal/pages/__init__.py +67 -0
  164. solara/template/portal/solara_portal/pages/article/__init__.py +26 -0
  165. solara/template/portal/solara_portal/pages/tabular.py +29 -0
  166. solara/template/portal/solara_portal/pages/viz/__init__.py +70 -0
  167. solara/template/portal/solara_portal/pages/viz/overview.py +14 -0
  168. solara/test/__init__.py +0 -0
  169. solara/test/pytest_plugin.py +697 -0
  170. solara/toestand.py +772 -0
  171. solara/util.py +308 -0
  172. solara/website/__init__.py +0 -0
  173. solara/website/assets/custom.css +468 -0
  174. solara/website/assets/images/logo-small.png +0 -0
  175. solara/website/assets/images/logo.svg +17 -0
  176. solara/website/assets/images/logo_white.svg +50 -0
  177. solara/website/assets/theme.js +8 -0
  178. solara/website/components/__init__.py +5 -0
  179. solara/website/components/algolia.vue +24 -0
  180. solara/website/components/algolia_api.vue +187 -0
  181. solara/website/components/docs.py +118 -0
  182. solara/website/components/header.py +72 -0
  183. solara/website/components/hero.py +15 -0
  184. solara/website/components/mailchimp.py +12 -0
  185. solara/website/components/mailchimp.vue +47 -0
  186. solara/website/components/markdown.py +30 -0
  187. solara/website/components/notebook.py +171 -0
  188. solara/website/pages/__init__.py +575 -0
  189. solara/website/pages/apps/__init__.py +16 -0
  190. solara/website/pages/apps/authorization/__init__.py +119 -0
  191. solara/website/pages/apps/authorization/admin.py +12 -0
  192. solara/website/pages/apps/authorization/users.py +12 -0
  193. solara/website/pages/apps/jupyter-dashboard-1.py +116 -0
  194. solara/website/pages/apps/layout-demo.py +40 -0
  195. solara/website/pages/apps/multipage/__init__.py +38 -0
  196. solara/website/pages/apps/multipage/page1.py +26 -0
  197. solara/website/pages/apps/multipage/page2.py +34 -0
  198. solara/website/pages/apps/scatter.py +136 -0
  199. solara/website/pages/apps/scrolling.py +63 -0
  200. solara/website/pages/apps/tutorial-streamlit.py +18 -0
  201. solara/website/pages/changelog/__init__.py +8 -0
  202. solara/website/pages/changelog/changelog.md +204 -0
  203. solara/website/pages/contact/__init__.py +8 -0
  204. solara/website/pages/contact/contact.md +17 -0
  205. solara/website/pages/doc_use_download.py +85 -0
  206. solara/website/pages/documentation/__init__.py +184 -0
  207. solara/website/pages/documentation/advanced/__init__.py +9 -0
  208. solara/website/pages/documentation/advanced/content/00-overview.md +1 -0
  209. solara/website/pages/documentation/advanced/content/10-howto/00-overview.md +6 -0
  210. solara/website/pages/documentation/advanced/content/10-howto/10-multipage.md +196 -0
  211. solara/website/pages/documentation/advanced/content/10-howto/20-layout.md +125 -0
  212. solara/website/pages/documentation/advanced/content/10-howto/30-testing.md +162 -0
  213. solara/website/pages/documentation/advanced/content/10-howto/31-debugging.md +69 -0
  214. solara/website/pages/documentation/advanced/content/10-howto/40-embed.md +49 -0
  215. solara/website/pages/documentation/advanced/content/10-howto/50-ipywidget_libraries.md +124 -0
  216. solara/website/pages/documentation/advanced/content/15-reference/00-overview.md +3 -0
  217. solara/website/pages/documentation/advanced/content/15-reference/40-static_files.md +31 -0
  218. solara/website/pages/documentation/advanced/content/15-reference/41-asset-files.md +36 -0
  219. solara/website/pages/documentation/advanced/content/15-reference/60-static-site-generation.md +59 -0
  220. solara/website/pages/documentation/advanced/content/15-reference/70-search.md +34 -0
  221. solara/website/pages/documentation/advanced/content/15-reference/80-reloading.md +34 -0
  222. solara/website/pages/documentation/advanced/content/15-reference/90-notebook-support.md +7 -0
  223. solara/website/pages/documentation/advanced/content/15-reference/95-caching.md +148 -0
  224. solara/website/pages/documentation/advanced/content/20-understanding/00-introduction.md +10 -0
  225. solara/website/pages/documentation/advanced/content/20-understanding/05-ipywidgets.md +35 -0
  226. solara/website/pages/documentation/advanced/content/20-understanding/06-ipyvuetify.md +42 -0
  227. solara/website/pages/documentation/advanced/content/20-understanding/10-reacton.md +28 -0
  228. solara/website/pages/documentation/advanced/content/20-understanding/12-reacton-basics.md +108 -0
  229. solara/website/pages/documentation/advanced/content/20-understanding/15-anatomy.md +23 -0
  230. solara/website/pages/documentation/advanced/content/20-understanding/17-rules-of-hooks.md +7 -0
  231. solara/website/pages/documentation/advanced/content/20-understanding/18-containers.md +166 -0
  232. solara/website/pages/documentation/advanced/content/20-understanding/20-solara.md +18 -0
  233. solara/website/pages/documentation/advanced/content/20-understanding/40-routing.md +240 -0
  234. solara/website/pages/documentation/advanced/content/20-understanding/50-solara-server.md +97 -0
  235. solara/website/pages/documentation/advanced/content/20-understanding/60-voila.md +12 -0
  236. solara/website/pages/documentation/advanced/content/30-enterprise/00-overview.md +1 -0
  237. solara/website/pages/documentation/advanced/content/30-enterprise/10-oauth.md +171 -0
  238. solara/website/pages/documentation/advanced/content/40-development/00-overview.md +0 -0
  239. solara/website/pages/documentation/advanced/content/40-development/01-contribute.md +45 -0
  240. solara/website/pages/documentation/advanced/content/40-development/10-setup.md +76 -0
  241. solara/website/pages/documentation/api/__init__.py +19 -0
  242. solara/website/pages/documentation/api/cross_filter/__init__.py +9 -0
  243. solara/website/pages/documentation/api/cross_filter/cross_filter_dataframe.py +23 -0
  244. solara/website/pages/documentation/api/cross_filter/cross_filter_report.py +22 -0
  245. solara/website/pages/documentation/api/cross_filter/cross_filter_select.py +22 -0
  246. solara/website/pages/documentation/api/cross_filter/cross_filter_slider.py +22 -0
  247. solara/website/pages/documentation/api/hooks/__init__.py +9 -0
  248. solara/website/pages/documentation/api/hooks/use_cross_filter.py +25 -0
  249. solara/website/pages/documentation/api/hooks/use_dark_effective.py +12 -0
  250. solara/website/pages/documentation/api/hooks/use_effect.md +43 -0
  251. solara/website/pages/documentation/api/hooks/use_effect.py +9 -0
  252. solara/website/pages/documentation/api/hooks/use_exception.py +33 -0
  253. solara/website/pages/documentation/api/hooks/use_memo.md +16 -0
  254. solara/website/pages/documentation/api/hooks/use_memo.py +9 -0
  255. solara/website/pages/documentation/api/hooks/use_previous.py +33 -0
  256. solara/website/pages/documentation/api/hooks/use_reactive.py +16 -0
  257. solara/website/pages/documentation/api/hooks/use_state.py +10 -0
  258. solara/website/pages/documentation/api/hooks/use_state_or_update.py +69 -0
  259. solara/website/pages/documentation/api/hooks/use_thread.md +58 -0
  260. solara/website/pages/documentation/api/hooks/use_thread.py +44 -0
  261. solara/website/pages/documentation/api/hooks/use_trait_observe.py +12 -0
  262. solara/website/pages/documentation/api/routing/__init__.py +9 -0
  263. solara/website/pages/documentation/api/routing/generate_routes.py +10 -0
  264. solara/website/pages/documentation/api/routing/generate_routes_directory.py +10 -0
  265. solara/website/pages/documentation/api/routing/resolve_path.py +35 -0
  266. solara/website/pages/documentation/api/routing/route.py +31 -0
  267. solara/website/pages/documentation/api/routing/use_route.py +80 -0
  268. solara/website/pages/documentation/api/routing/use_router.py +16 -0
  269. solara/website/pages/documentation/api/utilities/__init__.py +9 -0
  270. solara/website/pages/documentation/api/utilities/component_vue.py +10 -0
  271. solara/website/pages/documentation/api/utilities/computed.py +16 -0
  272. solara/website/pages/documentation/api/utilities/display.py +16 -0
  273. solara/website/pages/documentation/api/utilities/get_kernel_id.py +16 -0
  274. solara/website/pages/documentation/api/utilities/get_session_id.py +16 -0
  275. solara/website/pages/documentation/api/utilities/memoize.py +35 -0
  276. solara/website/pages/documentation/api/utilities/on_kernel_start.py +27 -0
  277. solara/website/pages/documentation/api/utilities/reactive.py +16 -0
  278. solara/website/pages/documentation/api/utilities/widget.py +104 -0
  279. solara/website/pages/documentation/components/__init__.py +12 -0
  280. solara/website/pages/documentation/components/advanced/__init__.py +9 -0
  281. solara/website/pages/documentation/components/advanced/link.py +27 -0
  282. solara/website/pages/documentation/components/advanced/meta.py +20 -0
  283. solara/website/pages/documentation/components/advanced/style.py +45 -0
  284. solara/website/pages/documentation/components/common.py +9 -0
  285. solara/website/pages/documentation/components/data/__init__.py +9 -0
  286. solara/website/pages/documentation/components/data/dataframe.py +44 -0
  287. solara/website/pages/documentation/components/data/pivot_table.py +81 -0
  288. solara/website/pages/documentation/components/enterprise/__init__.py +9 -0
  289. solara/website/pages/documentation/components/enterprise/avatar.py +24 -0
  290. solara/website/pages/documentation/components/enterprise/avatar_menu.py +25 -0
  291. solara/website/pages/documentation/components/input/__init__.py +9 -0
  292. solara/website/pages/documentation/components/input/button.py +23 -0
  293. solara/website/pages/documentation/components/input/checkbox.py +10 -0
  294. solara/website/pages/documentation/components/input/file_browser.py +32 -0
  295. solara/website/pages/documentation/components/input/file_drop.py +76 -0
  296. solara/website/pages/documentation/components/input/input.py +19 -0
  297. solara/website/pages/documentation/components/input/select.py +22 -0
  298. solara/website/pages/documentation/components/input/slider.py +29 -0
  299. solara/website/pages/documentation/components/input/switch.py +10 -0
  300. solara/website/pages/documentation/components/input/togglebuttons.py +21 -0
  301. solara/website/pages/documentation/components/lab/__init__.py +9 -0
  302. solara/website/pages/documentation/components/lab/chat.py +109 -0
  303. solara/website/pages/documentation/components/lab/confirmation_dialog.py +55 -0
  304. solara/website/pages/documentation/components/lab/cookies_headers.py +48 -0
  305. solara/website/pages/documentation/components/lab/input_date.py +20 -0
  306. solara/website/pages/documentation/components/lab/menu.py +22 -0
  307. solara/website/pages/documentation/components/lab/tab.py +25 -0
  308. solara/website/pages/documentation/components/lab/tabs.py +45 -0
  309. solara/website/pages/documentation/components/lab/task.py +11 -0
  310. solara/website/pages/documentation/components/lab/theming.py +72 -0
  311. solara/website/pages/documentation/components/lab/use_task.py +11 -0
  312. solara/website/pages/documentation/components/layout/__init__.py +9 -0
  313. solara/website/pages/documentation/components/layout/app_bar.py +16 -0
  314. solara/website/pages/documentation/components/layout/app_bar_title.py +16 -0
  315. solara/website/pages/documentation/components/layout/app_layout.py +24 -0
  316. solara/website/pages/documentation/components/layout/card.py +15 -0
  317. solara/website/pages/documentation/components/layout/card_actions.py +16 -0
  318. solara/website/pages/documentation/components/layout/column.py +30 -0
  319. solara/website/pages/documentation/components/layout/columns.py +27 -0
  320. solara/website/pages/documentation/components/layout/columns_responsive.py +68 -0
  321. solara/website/pages/documentation/components/layout/griddraggable.py +62 -0
  322. solara/website/pages/documentation/components/layout/gridfixed.py +21 -0
  323. solara/website/pages/documentation/components/layout/hbox.py +18 -0
  324. solara/website/pages/documentation/components/layout/row.py +30 -0
  325. solara/website/pages/documentation/components/layout/sidebar.py +24 -0
  326. solara/website/pages/documentation/components/layout/vbox.py +19 -0
  327. solara/website/pages/documentation/components/output/__init__.py +9 -0
  328. solara/website/pages/documentation/components/output/file_download.py +11 -0
  329. solara/website/pages/documentation/components/output/html.py +21 -0
  330. solara/website/pages/documentation/components/output/image.py +11 -0
  331. solara/website/pages/documentation/components/output/markdown.py +57 -0
  332. solara/website/pages/documentation/components/output/markdown_editor.py +51 -0
  333. solara/website/pages/documentation/components/output/sql_code.py +85 -0
  334. solara/website/pages/documentation/components/output/tooltip.py +11 -0
  335. solara/website/pages/documentation/components/page/__init__.py +9 -0
  336. solara/website/pages/documentation/components/page/head.py +18 -0
  337. solara/website/pages/documentation/components/page/title.py +27 -0
  338. solara/website/pages/documentation/components/status/__init__.py +9 -0
  339. solara/website/pages/documentation/components/status/error.py +40 -0
  340. solara/website/pages/documentation/components/status/info.py +40 -0
  341. solara/website/pages/documentation/components/status/progress.py +10 -0
  342. solara/website/pages/documentation/components/status/spinner.py +11 -0
  343. solara/website/pages/documentation/components/status/success.py +40 -0
  344. solara/website/pages/documentation/components/status/warning.py +47 -0
  345. solara/website/pages/documentation/components/viz/__init__.py +9 -0
  346. solara/website/pages/documentation/components/viz/altair.py +42 -0
  347. solara/website/pages/documentation/components/viz/echarts.py +75 -0
  348. solara/website/pages/documentation/components/viz/matplotlib.py +30 -0
  349. solara/website/pages/documentation/components/viz/plotly.py +63 -0
  350. solara/website/pages/documentation/components/viz/plotly_express.py +41 -0
  351. solara/website/pages/documentation/examples/__init__.py +52 -0
  352. solara/website/pages/documentation/examples/ai/__init__.py +11 -0
  353. solara/website/pages/documentation/examples/ai/chatbot.py +95 -0
  354. solara/website/pages/documentation/examples/ai/tokenizer.py +107 -0
  355. solara/website/pages/documentation/examples/basics/__init__.py +10 -0
  356. solara/website/pages/documentation/examples/basics/sine.py +28 -0
  357. solara/website/pages/documentation/examples/fullscreen/__init__.py +10 -0
  358. solara/website/pages/documentation/examples/fullscreen/authorization.py +3 -0
  359. solara/website/pages/documentation/examples/fullscreen/layout_demo.py +3 -0
  360. solara/website/pages/documentation/examples/fullscreen/multipage.py +3 -0
  361. solara/website/pages/documentation/examples/fullscreen/scatter.py +3 -0
  362. solara/website/pages/documentation/examples/fullscreen/scrolling.py +3 -0
  363. solara/website/pages/documentation/examples/fullscreen/tutorial_streamlit.py +3 -0
  364. solara/website/pages/documentation/examples/general/__init__.py +10 -0
  365. solara/website/pages/documentation/examples/general/custom_storage.py +70 -0
  366. solara/website/pages/documentation/examples/general/deploy_model.py +115 -0
  367. solara/website/pages/documentation/examples/general/live_update.py +38 -0
  368. solara/website/pages/documentation/examples/general/login_oauth.py +81 -0
  369. solara/website/pages/documentation/examples/general/mycard.vue +58 -0
  370. solara/website/pages/documentation/examples/general/pokemon_search.py +51 -0
  371. solara/website/pages/documentation/examples/general/vue_component.py +50 -0
  372. solara/website/pages/documentation/examples/ipycanvas.py +49 -0
  373. solara/website/pages/documentation/examples/libraries/__init__.py +10 -0
  374. solara/website/pages/documentation/examples/libraries/altair.py +64 -0
  375. solara/website/pages/documentation/examples/libraries/bqplot.py +39 -0
  376. solara/website/pages/documentation/examples/libraries/ipyleaflet.py +33 -0
  377. solara/website/pages/documentation/examples/libraries/ipyleaflet_advanced.py +66 -0
  378. solara/website/pages/documentation/examples/utilities/__init__.py +10 -0
  379. solara/website/pages/documentation/examples/utilities/calculator.py +157 -0
  380. solara/website/pages/documentation/examples/utilities/countdown_timer.py +64 -0
  381. solara/website/pages/documentation/examples/utilities/todo.py +196 -0
  382. solara/website/pages/documentation/examples/visualization/__init__.py +6 -0
  383. solara/website/pages/documentation/examples/visualization/annotator.py +69 -0
  384. solara/website/pages/documentation/examples/visualization/linked_views.py +84 -0
  385. solara/website/pages/documentation/examples/visualization/plotly.py +44 -0
  386. solara/website/pages/documentation/faq/__init__.py +12 -0
  387. solara/website/pages/documentation/faq/content/99-faq.md +76 -0
  388. solara/website/pages/documentation/getting_started/__init__.py +9 -0
  389. solara/website/pages/documentation/getting_started/content/00-quickstart.md +89 -0
  390. solara/website/pages/documentation/getting_started/content/01-introduction.md +125 -0
  391. solara/website/pages/documentation/getting_started/content/02-installing.md +134 -0
  392. solara/website/pages/documentation/getting_started/content/04-tutorials/00-overview.md +14 -0
  393. solara/website/pages/documentation/getting_started/content/04-tutorials/10_data_science.py +13 -0
  394. solara/website/pages/documentation/getting_started/content/04-tutorials/20-web-app.md +89 -0
  395. solara/website/pages/documentation/getting_started/content/04-tutorials/30-ipywidgets.md +124 -0
  396. solara/website/pages/documentation/getting_started/content/04-tutorials/40-streamlit.md +146 -0
  397. solara/website/pages/documentation/getting_started/content/04-tutorials/50-dash.md +144 -0
  398. solara/website/pages/documentation/getting_started/content/04-tutorials/60-jupyter-dashboard-part1.py +64 -0
  399. solara/website/pages/documentation/getting_started/content/04-tutorials/SF_crime_sample.csv.gz +0 -0
  400. solara/website/pages/documentation/getting_started/content/04-tutorials/_data_science.ipynb +445 -0
  401. solara/website/pages/documentation/getting_started/content/04-tutorials/_jupyter_dashboard_1.ipynb +1000 -0
  402. solara/website/pages/documentation/getting_started/content/05-fundamentals/00-overview.md +11 -0
  403. solara/website/pages/documentation/getting_started/content/05-fundamentals/10-components.md +223 -0
  404. solara/website/pages/documentation/getting_started/content/05-fundamentals/50-state-management.md +88 -0
  405. solara/website/pages/documentation/getting_started/content/07-deploying/00-overview.md +7 -0
  406. solara/website/pages/documentation/getting_started/content/07-deploying/10-self-hosted.md +273 -0
  407. solara/website/pages/documentation/getting_started/content/07-deploying/20-cloud-hosted.md +80 -0
  408. solara/website/pages/documentation/getting_started/content/80-what-is-lab.md +7 -0
  409. solara/website/pages/documentation/getting_started/content/90-troubleshoot.md +26 -0
  410. solara/website/pages/docutils.py +38 -0
  411. solara/website/pages/showcase/__init__.py +105 -0
  412. solara/website/pages/showcase/domino_code_assist.py +60 -0
  413. solara/website/pages/showcase/planeto_tessa.py +19 -0
  414. solara/website/pages/showcase/solara_dev.py +54 -0
  415. solara/website/pages/showcase/solarathon_2023_team_2.py +22 -0
  416. solara/website/pages/showcase/solarathon_2023_team_4.py +22 -0
  417. solara/website/pages/showcase/solarathon_2023_team_5.py +23 -0
  418. solara/website/pages/showcase/solarathon_2023_team_6.py +34 -0
  419. solara/website/pages/showcase/wanderlust.py +27 -0
  420. solara/website/public/beach.jpeg +0 -0
  421. solara/website/public/logo.svg +6 -0
  422. solara/website/public/social/discord.svg +1 -0
  423. solara/website/public/social/github.svg +1 -0
  424. solara/website/public/social/twitter.svg +3 -0
  425. solara/website/public/success.html +25 -0
  426. solara/website/templates/index.html.j2 +117 -0
  427. solara/website/utils.py +51 -0
  428. solara/widgets/__init__.py +1 -0
  429. solara/widgets/vue/gridlayout.vue +110 -0
  430. solara/widgets/vue/html.vue +4 -0
  431. solara/widgets/vue/navigator.vue +104 -0
  432. solara/widgets/vue/vegalite.vue +115 -0
  433. solara/widgets/widgets.py +66 -0
  434. solara_ui-1.31.0.data/data/etc/jupyter/jupyter_notebook_config.d/solara.json +7 -0
  435. solara_ui-1.31.0.data/data/etc/jupyter/jupyter_server_config.d/solara.json +7 -0
  436. solara_ui-1.31.0.dist-info/METADATA +158 -0
  437. solara_ui-1.31.0.dist-info/RECORD +439 -0
  438. solara_ui-1.31.0.dist-info/WHEEL +5 -0
  439. solara_ui-1.31.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,187 @@
1
+ <template>
2
+ <v-menu
3
+ v-model="show_results"
4
+ offset-y>
5
+ <template v-slot:activator="{ on }">
6
+ <v-text-field
7
+ v-model="query"
8
+ prepend-inner-icon="mdi-magnify"
9
+ hide-details
10
+ :placeholder="mac ? '⌘K to search' : 'Ctrl+K to search'"
11
+ outlined
12
+ rounded
13
+ clearable
14
+ ref="search"
15
+ style="max-width: 50%; flex-grow: 1;"
16
+ @click="show($event, on);"
17
+ @keyup.enter="item = 0"
18
+ ></v-text-field>
19
+ </template>
20
+ <v-list v-if="results != null && results.length == 0">
21
+ <v-list-item>
22
+ <v-list-item-content>
23
+ {{this.query == "" ? "Start Typing to Search" : "No search results found."}}
24
+ </v-list-item-content>
25
+ </v-list-item>
26
+ </v-list>
27
+ <v-list v-else :style="{width: menuWidth + 'px'}">
28
+ <v-list-item-group v-model="item">
29
+ <v-list-item v-for="(element, index) in this.results.hits" :key="element['url']">
30
+ <v-list-item-content>
31
+ <v-list-item-title>
32
+ {{ element.hierarchy.lvl1 }}
33
+ </v-list-item-title>
34
+ <v-list-item-subtitle v-if="element.hierarchy.lvl2 !== null">
35
+ {{ element.hierarchy.lvl2 }}
36
+ </v-list-item-subtitle>
37
+ <v-list-item-subtitle v-html="getSnippet(element)"></v-list-item-subtitle>
38
+ </v-list-item-content>
39
+ </v-list-item>
40
+ </v-list-item-group>
41
+ <v-list-item>
42
+ <v-list-item-content>
43
+ <v-list-item-title>And {{ this.results.nbHits - 10}} More...</v-list-item-title>
44
+ </v-list-item-content>
45
+ </v-list-item>
46
+ </v-list>
47
+ </v-menu>
48
+ </template>
49
+ <script>
50
+ const search = ref(null);
51
+ module.exports = {
52
+ async mounted() {
53
+ window.search = this;
54
+ await this.loadRequire();
55
+ this.algoliasearch = (await this.import([`https://cdn.jsdelivr.net/npm/algoliasearch@4.20.0/dist/algoliasearch-lite.umd.js`]))[0];
56
+ this.initSearch();
57
+ window.search = this;
58
+ this.updateMenuWidth();
59
+ window.addEventListener('resize', this.updateMenuWidth);
60
+
61
+ },
62
+ watch: {
63
+ query ( value ) {
64
+ this.show_results = true;
65
+ this.search();
66
+ },
67
+ item ( value ) {
68
+ if ( this.results.hits != null && this.results.hits.length > 0 ) {
69
+ let url = this.results.hits[value].url;
70
+ if (url.startsWith("https://solara.dev")) {
71
+ url = url.slice(18);
72
+ }
73
+ solara.router.push( url );
74
+ }
75
+ },
76
+ },
77
+ methods: {
78
+ show( e, on ) {
79
+ this.show_results = false;
80
+ this.$nextTick( () => {
81
+ on.click( e )
82
+ } );
83
+ },
84
+ initSearch() {
85
+ this.client = this.algoliasearch( '9KW9L7O5EQ', '647ca12ba642437cc40c2adee4a78d08' );
86
+ this.index = this.client.initIndex( 'solara' );
87
+ this.mac = window.navigator.userAgent.indexOf("Mac") != -1;
88
+ document.addEventListener( 'keydown', ( e ) => {
89
+
90
+ if (this.mac) {
91
+ if ( this.$refs.search && e.metaKey && e.key === 'k' ) {
92
+ this.$refs.search.focus();
93
+ }
94
+ }else{
95
+ if ( this.$refs.search && e.ctrlKey && e.key === 'k' ) {
96
+ this.$refs.search.focus();
97
+ }
98
+ }
99
+ });
100
+ },
101
+ async search() {
102
+ results = await this.index.search( this.query, { hitsPerPage: 10 } );
103
+ if (results) {
104
+ this.results = results;
105
+ }else{
106
+ this.$set(this.results, []);
107
+ }
108
+ },
109
+ getSnippet( element ) {
110
+ if (element.type == "content") {
111
+ return element._highlightResult.content.value;
112
+ }
113
+ let snippet = element._highlightResult.hierarchy[element.type].value;
114
+ if (snippet.matchLevel === "none" ) {
115
+ snippet = element._highlightResult.hierarchy["lvl" + parseInt(element.type[3] - 1)].value
116
+ }
117
+ return snippet;
118
+ },
119
+ updateMenuWidth() {
120
+ // Ensure the element is rendered and has dimensions
121
+ this.$nextTick(() => {
122
+ const activator = this.$refs.search;
123
+ if (activator && activator.$el) {
124
+ // Update the menuWidth with the activator's width
125
+ this.menuWidth = activator.$el.offsetWidth;
126
+ }
127
+ });
128
+ },
129
+ import(dependencies) {
130
+ return this.loadRequire().then(
131
+ () => {
132
+ if (window.jupyterVue) {
133
+ // in jupyterlab, we take Vue from ipyvue/jupyterVue
134
+ define("vue", [], () => window.jupyterVue.Vue);
135
+ } else {
136
+ define("vue", ['jupyter-vue'], jupyterVue => jupyterVue.Vue);
137
+ }
138
+ return new Promise((resolve, reject) => {
139
+ requirejs(dependencies, (...modules) => resolve(modules));
140
+ })
141
+ }
142
+ );
143
+ },
144
+ loadRequire() {
145
+ return new Promise((resolve, reject) => {
146
+ const script = document.createElement('script');
147
+ script.src = `${this.getCdn()}/requirejs@2.3.6/require.js`;
148
+ script.onload = resolve;
149
+ script.onerror = reject;
150
+ document.head.appendChild(script);
151
+ });
152
+ },
153
+ getBaseUrl() {
154
+ if (window.solara && window.solara.rootPath !== undefined) {
155
+ return solara.rootPath + "/";
156
+ }
157
+ // if base url is set, we use ./ for relative paths compared to the base url
158
+ if (document.getElementsByTagName("base").length) {
159
+ return document.baseURI;
160
+ }
161
+ const labConfigData = document.getElementById('jupyter-config-data');
162
+ if (labConfigData) {
163
+ /* lab and Voila */
164
+ return JSON.parse(labConfigData.textContent).baseUrl;
165
+ }
166
+ let base = document.body.dataset.baseUrl || document.baseURI;
167
+ if (!base.endsWith('/')) {
168
+ base += '/';
169
+ }
170
+ return base
171
+ },
172
+ getCdn() {
173
+ return (typeof solara_cdn !== "undefined" && solara_cdn) || `${this.getBaseUrl()}_solara/cdn`;
174
+ },
175
+ },
176
+ data(){
177
+ return {
178
+ query: '',
179
+ results: [],
180
+ item: null,
181
+ show_results: false,
182
+ mac: false,
183
+ menuWidth: 0,
184
+ }
185
+ },
186
+ }
187
+ </script>
@@ -0,0 +1,118 @@
1
+ import solara
2
+ from solara.alias import rv
3
+
4
+
5
+ @solara.component
6
+ def Gallery(route_external=None):
7
+ if route_external is not None:
8
+ route_current = route_external
9
+ else:
10
+ # show a gallery of all the examples
11
+ router = solara.use_router()
12
+ route_current = router.path_routes[-2]
13
+
14
+ with solara.Column(gap="75px", align="center"):
15
+ with solara.Row(justify="center", gap="30px", style={"margin": "30px 0 !important", "flex-wrap": "wrap", "align-items": "start", "row-gap": "30px"}):
16
+ for child in route_current.children:
17
+ if child.path == "/":
18
+ continue
19
+ with solara.v.Html(tag="a", attributes={"href": "#" + child.path}):
20
+ solara.Button(
21
+ child.label,
22
+ color="primary",
23
+ classes=["v-btn--rounded", "v-size--x-large"],
24
+ )
25
+
26
+ with solara.Column(gap="75px", style={"padding-bottom": "75px"}):
27
+ for route in route_current.children:
28
+ if route.children:
29
+ with solara.Column(classes=["subcategory-row", "ps-md-10"]):
30
+ solara.HTML(tag="h2", unsafe_innerHTML=route.label, attributes={"id": route.path}, style="padding-left: 10%;")
31
+ with solara.Row(justify="center", gap="20px", style={"flex-wrap": "wrap", "row-gap": "20px", "max-width": "90rem"}):
32
+ for child in route.children:
33
+ if child.path == "/":
34
+ continue
35
+ path = route.path + "/" + child.path
36
+ if child.path in [
37
+ "button",
38
+ "checkbox",
39
+ "confirmation_dialog",
40
+ "echarts",
41
+ "file_browser",
42
+ "file_download",
43
+ "matplotlib",
44
+ "select",
45
+ "switch",
46
+ "tooltip",
47
+ ]:
48
+ image_url = "https://dxhl76zpt6fap.cloudfront.net/public/api/" + child.path + ".gif"
49
+ elif child.path in ["card", "dataframe", "pivot_table", "slider"]:
50
+ image_url = "https://dxhl76zpt6fap.cloudfront.net/public/api/" + child.path + ".png"
51
+ else:
52
+ image_url = "https://dxhl76zpt6fap.cloudfront.net/public/logo.svg"
53
+
54
+ if path:
55
+ path = path if route_external is None else route_current.path + "/" + path
56
+ title = solara.Link(path, children=[child.label])
57
+ with solara.Card(title, classes=["component-card"], margin=0):
58
+ with solara.Column(align="center"):
59
+ with solara.Link(path):
60
+ solara.Image(image_url, width="12rem")
61
+
62
+
63
+ @solara.component
64
+ def NoPage():
65
+ raise RuntimeError("This page should not be rendered")
66
+
67
+
68
+ @solara.component
69
+ def WithCode(module):
70
+ component = getattr(module, "Page", None)
71
+ with rv.Sheet() as main:
72
+ # It renders code better
73
+ solara.Markdown(
74
+ module.__doc__ or "# no docs yet",
75
+ unsafe_solara_execute=True,
76
+ )
77
+ if component and component != NoPage:
78
+ with solara.Card("Example", margin=0, classes=["mt-8"]):
79
+ component()
80
+ github_url = solara.util.github_url(module.__file__)
81
+ solara.Button(
82
+ label="View source",
83
+ icon_name="mdi-github-circle",
84
+ attributes={"href": github_url, "target": "_blank"},
85
+ text=True,
86
+ outlined=True,
87
+ class_="mt-8",
88
+ )
89
+ return main
90
+
91
+
92
+ @solara.component
93
+ def SubCategoryLayout(children=[]):
94
+ route_current, all_routes = solara.use_route()
95
+ if route_current is None:
96
+ return solara.Error("Page not found")
97
+ elif route_current.path == "/":
98
+ return solara.Error("Not supposed to be rendered")
99
+ elif route_current.module:
100
+ WithCode(route_current.module)
101
+ else:
102
+ with solara.Column(align="center", children=children, style={"flex-grow": 1, "padding": "0"}) as main:
103
+ pass
104
+ return main
105
+
106
+
107
+ @solara.component
108
+ def CategoryLayout(children=[]):
109
+ route_current, all_routes = solara.use_route()
110
+ if route_current is None:
111
+ return solara.Error("Page not found")
112
+
113
+ if route_current.path == "/":
114
+ return Gallery()
115
+ else:
116
+ with solara.Column(align="stretch", style={"width": "1024px", "flex-grow": 1}, children=children) as main:
117
+ pass
118
+ return main
@@ -0,0 +1,72 @@
1
+ from typing import Callable
2
+
3
+ import solara
4
+ import solara.lab
5
+ from solara.alias import rv
6
+ from solara.server import settings
7
+
8
+
9
+ @solara.component_vue("algolia_api.vue")
10
+ def Algolia():
11
+ pass
12
+
13
+
14
+ @solara.component
15
+ def Header(
16
+ on_toggle_left_menu: Callable[[], None] = None,
17
+ on_toggle_right_menu: Callable[[], None] = None,
18
+ ):
19
+ # use routes of parent (assuming we are a child of a layout)
20
+ route_current, all_routes = solara.use_route(level=-1)
21
+ route_current_with_children, all_routes_with_children = solara.use_route()
22
+ router = solara.use_router()
23
+ dark_effective = solara.lab.use_dark_effective()
24
+
25
+ # set states for menu
26
+ with solara.Column(gap="0px"):
27
+ with solara.Div(classes=["news"]):
28
+ solara.HTML(
29
+ "div",
30
+ unsafe_innerHTML="<a href='https://github.com/widgetti/solara' target='_blank' >Star us on github 🤩</a>",
31
+ )
32
+ with solara.v.AppBar(tag="header", flat=True, class_="bg-primary-fade padding-40", height="auto", clipped_left=True):
33
+ with rv.ToolbarTitle(class_="d-flex", style_="align-items:center"):
34
+ if route_current and len(route_current.children) > 0:
35
+ with solara.Button(icon=True, class_="hidden-md-and-up", on_click=lambda: on_toggle_left_menu and on_toggle_left_menu()):
36
+ rv.Icon(children=["mdi-menu"])
37
+ with solara.Link(path_or_route="/"):
38
+ solara.Image(router.root_path + f"/static/assets/images/logo{'_white' if dark_effective else ''}.svg")
39
+ rv.Spacer()
40
+
41
+ if (
42
+ route_current_with_children is not None
43
+ and route_current is not None
44
+ and route_current.path == "documentation"
45
+ and route_current_with_children.path == "/"
46
+ ):
47
+ solara.v.Spacer()
48
+ else:
49
+ if settings.search.enabled:
50
+ from solara_enterprise.search.search import Search
51
+
52
+ Search()
53
+ else:
54
+ with solara.Row(justify="end", style={"align-items": "center", "flex-grow": "1", "background-color": "transparent"}):
55
+ Algolia()
56
+ with rv.Html(tag="ul", class_="main-menu menu d-none d-md-flex"):
57
+ for route in all_routes:
58
+ if route.path in ["apps", "contact", "changelog"]:
59
+ continue
60
+ current = route_current == route
61
+ with rv.Html(tag="li", class_="active" if current else None):
62
+ solara.Link("/" + route.path if route.path != "/" else "/", children=[route.label])
63
+ with rv.Btn(icon=True, tag="a", class_="d-none d-md-flex", attributes={"href": solara.github_url, "target": "_blank"}):
64
+ rv.Icon(children=["mdi-github-circle"])
65
+
66
+ with rv.Btn(icon=True, tag="a", class_="d-none d-md-flex", attributes={"href": "https://discord.solara.dev", "target": "_blank"}):
67
+ rv.Icon(children=["mdi-discord"])
68
+
69
+ solara.lab.ThemeToggle()
70
+
71
+ with solara.Button(icon=True, class_="hidden-md-and-up", on_click=lambda: on_toggle_right_menu and on_toggle_right_menu()):
72
+ rv.Icon(children=["mdi-menu"])
@@ -0,0 +1,15 @@
1
+ import solara
2
+ from solara.alias import rv
3
+
4
+
5
+ @solara.component
6
+ def Hero(title, sub_title, button_text):
7
+ with rv.Html(tag="section", class_="hero text-center") as main:
8
+ with rv.Container():
9
+ with rv.Row():
10
+ with rv.Col(md=8, offset_md=2, sm=10, offset_sm=1):
11
+ (rv.Html(tag="h1", children=[title], class_="mb-4"),)
12
+ (solara.HTML(tag="div", unsafe_innerHTML=f"<h2>{sub_title}</h2>", class_="mb-4"),)
13
+ with solara.Link("/documentation/getting_started"):
14
+ solara.Button(label=button_text, elevation=0, large=True, class_="btn-size--xlarge solara-docs-button")
15
+ return main
@@ -0,0 +1,12 @@
1
+ from pathlib import Path
2
+
3
+ import solara
4
+
5
+ HERE = Path(__file__).parent
6
+
7
+ # html = Path(HERE / "mailchimp.v").read_text()
8
+
9
+
10
+ @solara.component_vue("mailchimp.vue")
11
+ def MailChimp(location: str):
12
+ pass
@@ -0,0 +1,47 @@
1
+ <template>
2
+ <div id="mc_embed_shell">
3
+ <div id="mc_embed_signup">
4
+ <form
5
+ action="https://gmail.us13.list-manage.com/subscribe/post?u=1dcdd74de47214edace5b6f49&amp;id=c60b5def86&amp;f_id=00f4c1e2f0"
6
+ method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate"
7
+ target="_blank">
8
+ <div id="mc_embed_signup_scroll">
9
+ <div class="indicates-required"><span class="asterisk">*</span> indicates required</div>
10
+ <div class="mc-field-group">
11
+ <label for="mce-EMAIL">Email Address <span class="asterisk">*</span></label>
12
+ <input type="email" name="EMAIL" class="required email" id="mce-EMAIL" required="" value=""></div>
13
+ <div class="mc-field-group">
14
+ <label for="mce-LOCATION">signup location </label>
15
+ <input type="text" name="LOCATION" class=" text" id="mce-LOCATION" :value="location">
16
+ </div>
17
+ <!-- <div class="mc-field-group"><label for="mce-FNAME">First Name </label><input type="text" name="FNAME"
18
+ class=" text" id="mce-FNAME" value=""></div>
19
+ <div class="mc-field-group"><label for="mce-LNAME">Last Name </label><input type="text" name="LNAME"
20
+ class=" text" id="mce-LNAME" value=""></div>
21
+ <div class="mc-field-group"><label for="mce-COMPANY">Company </label><input type="text" name="COMPANY"
22
+ class=" text" id="mce-COMPANY" value=""></div> -->
23
+ <div id="mce-responses" class="clear foot">
24
+ <div class="response" id="mce-error-response" style="display: none;"></div>
25
+ <div class="response" id="mce-success-response" style="display: none;"></div>
26
+ </div>
27
+ <div aria-hidden="true" style="position: absolute; left: -5000px;">
28
+ /* real people should not fill this in and expect good things - do not remove this or risk form bot
29
+ signups */
30
+ <input type="text" name="b_1dcdd74de47214edace5b6f49_c60b5def86" tabindex="-1" value="">
31
+ </div>
32
+ </div>
33
+ <div class="optionalParent">
34
+ <div class="clear foot">
35
+ <v-btn type="submit" name="subscribe" id="mc-embedded-subscribe"
36
+ class="button v-btn v-btn-contained"
37
+ style="background-color: rgb(241, 159, 65); border-color: rgb(241, 159, 65);"
38
+ value="Subscribe">Subscribe</v-btn>
39
+ </div>
40
+ </div>
41
+ </form>
42
+ </div>
43
+ <!-- <script> (function ($) { window.fnames = new Array(); window.ftypes = new Array(); fnames[0] = 'EMAIL'; ftypes[0] = 'email'; fnames[1] = 'FNAME'; ftypes[1] = 'text'; fnames[2] = 'LNAME'; ftypes[2] = 'text'; fnames[7] = 'COMPANY'; ftypes[7] = 'text'; fnames[10] = 'WHYCLOUD'; ftypes[10] = 'text'; fnames[3] = 'ADDRESS'; ftypes[3] = 'address'; fnames[4] = 'PHONE'; ftypes[4] = 'phone'; fnames[5] = 'BIRTHDAY'; ftypes[5] = 'birthday'; fnames[6] = 'USECASE'; ftypes[6] = 'text'; fnames[8] = 'POSITION'; ftypes[8] = 'text'; fnames[9] = 'MMERGE9'; ftypes[9] = 'text'; }(jQuery)); var $mcj = jQuery.noConflict(true); </script> -->
44
+ </div>
45
+ </template>
46
+ <script>
47
+ </script>
@@ -0,0 +1,30 @@
1
+ from typing import Dict, List, Union
2
+
3
+ import yaml
4
+
5
+ import solara
6
+
7
+
8
+ # We want to separate metadata from the markdown files before rendering them, which solara.Markdown doesn't support
9
+ @solara.component
10
+ def MarkdownWithMetadata(content: str, unsafe_solara_execute=True):
11
+ if "---" in content:
12
+ pre_content, raw_metadata, post_content = content.split("---")
13
+ metadata: Dict[str, Union[str, List[str]]] = yaml.safe_load(raw_metadata)
14
+
15
+ if len(pre_content) == 0:
16
+ content = post_content
17
+ else:
18
+ content = pre_content + post_content
19
+
20
+ if "title" not in metadata.keys():
21
+ metadata["title"] = content.split("#")[1].split("\n")[0]
22
+
23
+ for key, value in metadata.items():
24
+ if key == "title":
25
+ solara.Title(value)
26
+ elif ":" in key:
27
+ solara.Meta(property=key, content=value)
28
+ else:
29
+ solara.Meta(name=key, content=value)
30
+ solara.Markdown(content, unsafe_solara_execute=unsafe_solara_execute)
@@ -0,0 +1,171 @@
1
+ import ast
2
+ import linecache
3
+ from pathlib import Path
4
+ from typing import Any, Dict
5
+
6
+ import IPython
7
+ import nbformat
8
+
9
+ import solara
10
+ import solara.components.applayout
11
+ import solara.toestand
12
+ from solara.components.markdown import ExceptionGuard
13
+
14
+ HERE = Path(__file__).parent
15
+
16
+
17
+ def execute_notebook(path: Path):
18
+ nb: nbformat.NotebookNode = nbformat.read(path, 4)
19
+ stat = path.stat()
20
+ scope: Dict[str, Any] = {}
21
+ for cell_index, cell in enumerate(nb.cells):
22
+ cell_index += 1 # used 1 based
23
+ cell.scope_snapshot = {}
24
+ if cell.cell_type == "code":
25
+ if cell.source.startswith("## solara: skip"):
26
+ continue
27
+
28
+ def execute(cell=cell):
29
+ source = cell.source
30
+ cell_path = f"app.ipynb input cell {cell_index}"
31
+ entry = (
32
+ stat.st_size,
33
+ stat.st_mtime,
34
+ [line + "\n" for line in source.splitlines()],
35
+ cell_path,
36
+ )
37
+
38
+ linecache.cache[cell_path] = entry
39
+ code = ast.parse(source, cell_path, "exec")
40
+ value = None
41
+ with solara.Column():
42
+ if code.body:
43
+ last_statement = code.body[-1]
44
+ if isinstance(last_statement, ast.Expr):
45
+ code.body.pop()
46
+ last = ast.Expression(last_statement.value)
47
+ exec(compile(code, "<string>", mode="exec"), scope)
48
+ value = eval(compile(last, "<string>", mode="eval"), scope)
49
+ else:
50
+ exec(compile(code, "<string>", mode="exec"), scope)
51
+ import matplotlib_inline.backend_inline
52
+
53
+ matplotlib_inline.backend_inline.flush_figures()
54
+ scope_snapshot = {**scope}
55
+ cell.__dict__["scope_snapshot"] = scope_snapshot
56
+ return value
57
+
58
+ # every cell gets a snapshot of the scope
59
+ # avoid the buggy setitem of NotebookNode
60
+ # which causes an recursion error
61
+ yield cell_index, cell, execute
62
+ elif cell.cell_type == "markdown":
63
+ # last_expressions.append(None)
64
+ yield cell_index, cell, lambda: None
65
+ else:
66
+ raise ValueError(f"Unknown cell type: {cell.cell_type}, supported types are: code, markdown")
67
+
68
+
69
+ @solara.component
70
+ def NotebookExecute(notebook_path: Path, show_last_expressions=False, auto_show_page=False):
71
+ import IPython.core.pylabtools as pylabtools
72
+
73
+ shell = IPython.get_ipython().kernel.shell
74
+
75
+ # TODO: there is a change the cleanup will not be called
76
+ pylabtools.select_figure_formats(shell, ["png"])
77
+
78
+ def cleanup():
79
+ def _cleanup():
80
+ from matplotlib.figure import Figure
81
+
82
+ png_formatter = shell.display_formatter.formatters["image/png"]
83
+ png_formatter.pop(Figure)
84
+
85
+ return _cleanup
86
+
87
+ solara.use_effect(cleanup, [])
88
+ values = list(solara.use_memo(lambda: execute_notebook(notebook_path)))
89
+
90
+ last_page = None
91
+
92
+ solara.components.applayout.should_use_embed.provide(True)
93
+ with solara.Column(style={"max-width": "100%"}) as main:
94
+ for cell_index, cell, executor in values:
95
+ cell_index += 1 # used 1 based
96
+ if cell.cell_type == "code":
97
+ if cell.source.startswith("## solara: skip"):
98
+ continue
99
+ solara.Markdown(
100
+ f"""
101
+ ```python
102
+ {cell.source}
103
+ ```"""
104
+ )
105
+ # we execute here, such that any side effect (display, etc)
106
+ # will be done under the context of the Column
107
+ with ExceptionGuard():
108
+ with solara.AppLayout(navigation=False, toolbar_dark=True):
109
+ # we don't want to listen to reactive variables
110
+ copy = set(solara.toestand.thread_local.reactive_used or [])
111
+ try:
112
+ last_expression = executor()
113
+ finally:
114
+ solara.toestand.thread_local.reactive_used = copy
115
+ scope = cell.scope_snapshot
116
+ page = scope.get("Page")
117
+ if auto_show_page and page != last_page and page is not None:
118
+ page()
119
+ else:
120
+ if show_last_expressions:
121
+ if last_expression is not None:
122
+ solara.display(last_expression)
123
+ last_page = page
124
+ elif cell.cell_type == "markdown":
125
+ solara.Markdown(cell.source)
126
+ else:
127
+ raise ValueError(f"Unknown cell type: {cell.cell_type}, supported types are: code, markdown")
128
+ return main
129
+
130
+
131
+ @solara.component
132
+ def Notebook(notebook_path: Path, show_last_expressions=False, auto_show_page=False, execute=True, outputs={}):
133
+ if execute:
134
+ return NotebookExecute(notebook_path, show_last_expressions, auto_show_page)
135
+ else:
136
+ with solara.Column(style={"max-width": "100%"}) as main:
137
+ nb: nbformat.NotebookNode = nbformat.read(notebook_path, 4)
138
+ for cell_index, cell in enumerate(nb.cells):
139
+ cell_index += 1
140
+ if cell.cell_type == "code":
141
+ if cell.source.startswith("## solara: skip"):
142
+ continue
143
+ solara.Markdown(
144
+ f"""
145
+ ```python
146
+ {cell.source}
147
+ ```"""
148
+ )
149
+ if cell.outputs:
150
+ for output in cell.outputs:
151
+ if output.output_type == "display_data":
152
+ solara.display(output.data, raw=True)
153
+ elif output.output_type == "execute_result":
154
+ if "text/html" in output.data:
155
+ solara.display(output.data, raw=True)
156
+ else:
157
+ cell_id = str(cell.id)
158
+ output = outputs.get(cell_id) or outputs.get(cell_index)
159
+ if output is None:
160
+ if cell_id in outputs or cell_index in outputs:
161
+ pass # explicit None
162
+ else:
163
+ solara.display(f"Output missing for cell: {cell_index} id {cell_id}")
164
+ else:
165
+ solara.display(output)
166
+
167
+ elif cell.cell_type == "markdown":
168
+ solara.Markdown(cell.source)
169
+ else:
170
+ raise ValueError(f"Unknown cell type: {cell.cell_type}, supported types are: code, markdown")
171
+ return main