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
solara/server/flask.py ADDED
@@ -0,0 +1,286 @@
1
+ import asyncio
2
+ import logging
3
+ import mimetypes
4
+ import os
5
+ import threading
6
+ from http.server import HTTPServer
7
+ from pathlib import Path
8
+ from typing import Any, Dict, List
9
+ from urllib.parse import urlparse
10
+ from uuid import uuid4
11
+
12
+ import flask
13
+ import simple_websocket
14
+ from flask import Blueprint, Flask, abort, request, send_from_directory, url_for
15
+ from flask_sock import Sock
16
+
17
+ try:
18
+ import solara_enterprise # type: ignore
19
+
20
+ del solara_enterprise
21
+
22
+ has_solara_enterprise = True
23
+ except ImportError:
24
+ has_solara_enterprise = False
25
+
26
+ if has_solara_enterprise:
27
+ from solara_enterprise.auth.flask import allowed # type: ignore
28
+ from solara_enterprise.auth.flask import (
29
+ authorize,
30
+ get_user,
31
+ init_flask,
32
+ login,
33
+ logout,
34
+ )
35
+ else:
36
+
37
+ def allowed():
38
+ return True
39
+
40
+
41
+ import solara
42
+ import solara.settings
43
+ from solara.server.threaded import ServerBase
44
+
45
+ from . import app as appmod
46
+ from . import cdn_helper, kernel_context, server, settings, websocket
47
+
48
+ os.environ["SERVER_SOFTWARE"] = "solara/" + str(solara.__version__)
49
+
50
+ logger = logging.getLogger("solara.server.flask")
51
+ blueprint = Blueprint("blueprint-solara", __name__)
52
+ websocket_extension = Sock()
53
+
54
+
55
+ class WebsocketWrapper(websocket.WebsocketWrapper):
56
+ ws: simple_websocket.Server
57
+
58
+ def __init__(self, ws: simple_websocket.Server) -> None:
59
+ self.ws = ws
60
+ self.lock = threading.Lock()
61
+
62
+ def close(self):
63
+ with self.lock:
64
+ self.ws.close()
65
+
66
+ def send_text(self, data: str) -> None:
67
+ with self.lock:
68
+ self.ws.send(data)
69
+
70
+ def send_bytes(self, data: bytes) -> None:
71
+ with self.lock:
72
+ self.ws.send(data)
73
+
74
+ async def receive(self):
75
+ from anyio import to_thread
76
+
77
+ try:
78
+ return await to_thread.run_sync(lambda: self.ws.receive()) # type: ignore
79
+ except simple_websocket.ws.ConnectionClosed:
80
+ raise websocket.WebSocketDisconnect()
81
+
82
+
83
+ class ServerFlask(ServerBase):
84
+ server: Any
85
+ name = "flask"
86
+
87
+ def __init__(self, port: int, host: str = "localhost", flask_app=None, url_prefix="", **kwargs):
88
+ super().__init__(port, host, **kwargs)
89
+ self.app = flask_app or app
90
+ self.url_prefix = url_prefix
91
+ self.server = None
92
+
93
+ def has_started(self):
94
+ return server.is_ready(f"http://{self.host}:{self.port}{self.url_prefix}")
95
+
96
+ def signal_stop(self):
97
+ if self.server:
98
+ assert isinstance(self.server, HTTPServer)
99
+ self.server.shutdown() # type: ignore
100
+
101
+ def serve(self):
102
+ from werkzeug.serving import make_server
103
+
104
+ self.server = make_server(self.host, self.port, self.app, threaded=True) # type: ignore
105
+ assert isinstance(self.server, HTTPServer)
106
+ self.started.set()
107
+ self.server.serve_forever(poll_interval=0.05) # type: ignore
108
+
109
+
110
+ @blueprint.route("/jupyter/api/kernels/<id>")
111
+ def kernels(id):
112
+ if not allowed():
113
+ abort(401)
114
+ return {"name": "lala", "id": "dsa"}
115
+
116
+
117
+ @websocket_extension.route("/jupyter/api/kernels/<kernel_id>/<name>")
118
+ def kernels_connection(ws: simple_websocket.Server, kernel_id: str, name: str):
119
+ if not settings.main.base_url:
120
+ settings.main.base_url = url_for("blueprint-solara.read_root", _external=True)
121
+ if settings.oauth.private and not has_solara_enterprise:
122
+ raise RuntimeError("SOLARA_OAUTH_PRIVATE requires solara-enterprise")
123
+ if has_solara_enterprise:
124
+ user = get_user()
125
+ if user is None and settings.oauth.private:
126
+ logger.error("app is private, requires login")
127
+ ws.close(1008, "app is private, requires login") # policy violation
128
+ return
129
+ else:
130
+ user = None
131
+
132
+ try:
133
+ page_id = request.args["session_id"]
134
+ session_id = request.cookies.get(server.COOKIE_KEY_SESSION_ID)
135
+ logger.info("Solara kernel requested for session_id=%s kernel_id=%s", session_id, kernel_id)
136
+ if session_id is None:
137
+ logger.warning("no session cookie")
138
+ session_id = "session-id-cookie-unavailable:" + str(uuid4())
139
+ ws_wrapper = WebsocketWrapper(ws)
140
+ headers_dict: Dict[str, List[str]] = {}
141
+ for k, v in request.headers.__iter__():
142
+ if k not in headers_dict.keys():
143
+ headers_dict[k] = [v]
144
+ else:
145
+ headers_dict[k].append(v)
146
+ asyncio.run(
147
+ server.app_loop(
148
+ ws_wrapper,
149
+ cookies=request.cookies.to_dict(),
150
+ headers=headers_dict,
151
+ session_id=session_id,
152
+ kernel_id=kernel_id,
153
+ page_id=page_id,
154
+ user=user,
155
+ )
156
+ )
157
+ except: # noqa
158
+ logger.exception("Error in kernel handler")
159
+ raise
160
+
161
+
162
+ @blueprint.route("/_solara/api/close/<kernel_id>", methods=["GET", "POST"])
163
+ def close(kernel_id: str):
164
+ page_id = request.args["session_id"]
165
+ if kernel_id in kernel_context.contexts:
166
+ context = kernel_context.contexts[kernel_id]
167
+ context.page_close(page_id)
168
+ return ""
169
+
170
+
171
+ @blueprint.route("/static/public/<path:path>")
172
+ def public(path):
173
+ if not allowed():
174
+ abort(401)
175
+ directories = [app.directory.parent / "public" for app in appmod.apps.values()]
176
+ for directory in directories:
177
+ file = directory / path
178
+ if file.exists():
179
+ return send_from_directory(directory, path)
180
+ return flask.Response("not found", status=404)
181
+
182
+
183
+ @blueprint.route("/static/assets/<path:path>")
184
+ def assets(path):
185
+ if not allowed():
186
+ abort(401)
187
+ overrides = [app.directory.parent / "assets" for app in appmod.apps.values()]
188
+ default = server.solara_static.parent / "assets"
189
+ directories = [*overrides, default]
190
+ for directory in directories:
191
+ file = directory / path
192
+ if file.exists():
193
+ return send_from_directory(directory, path)
194
+ return flask.Response("not found", status=404)
195
+
196
+
197
+ @blueprint.route("/static/nbextensions/<dir>/<filename>")
198
+ def nbext(dir, filename):
199
+ if not allowed():
200
+ abort(401)
201
+ for directory in server.nbextensions_directories:
202
+ file = directory / dir / filename
203
+ if file.exists():
204
+ return send_from_directory(directory / dir, filename)
205
+ return flask.Response("not found", status=404)
206
+
207
+
208
+ @blueprint.route("/static/<path:path>")
209
+ def serve_static(path):
210
+ if not allowed():
211
+ abort(401)
212
+ return send_from_directory(server.solara_static, path)
213
+
214
+
215
+ if solara.settings.assets.proxy:
216
+
217
+ @blueprint.route(f"/{cdn_helper.cdn_url_path}/<path:path>")
218
+ def cdn(path):
219
+ if not allowed():
220
+ abort(401)
221
+ cache_directory = settings.assets.proxy_cache_dir
222
+ content = cdn_helper.get_data(Path(cache_directory), path)
223
+ mime = mimetypes.guess_type(path)
224
+ return flask.Response(content, mimetype=mime[0])
225
+
226
+
227
+ @blueprint.route("/", defaults={"path": ""})
228
+ @blueprint.route("/<path:path>")
229
+ def read_root(path):
230
+ root_path = url_for(".read_root")
231
+ if root_path.endswith("/"):
232
+ root_path = root_path[:-1]
233
+
234
+ if not settings.main.base_url:
235
+ settings.main.base_url = url_for("blueprint-solara.read_root", _external=True)
236
+
237
+ session_id = request.cookies.get(server.COOKIE_KEY_SESSION_ID) or str(uuid4())
238
+ if root_path:
239
+ path = flask.request.path[len(root_path) :]
240
+ content = server.read_root(path, root_path=root_path)
241
+ if content is None:
242
+ if not allowed():
243
+ abort(401)
244
+ return flask.Response("not found", status=404)
245
+
246
+ if not allowed():
247
+ return login()
248
+
249
+ samesite = "lax"
250
+ secure = False
251
+ # we want samesite, so we can set a cookie when embedded in an iframe, such as on huggingface
252
+ # however, samesite=none requires Secure https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite
253
+ # when hosted on the localhost domain we can always set the Secure flag
254
+ # to allow samesite https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies
255
+ o = urlparse(request.base_url)
256
+ if request.headers.get("x-forwarded-proto", "http") == "https" or o.hostname == "localhost":
257
+ samesite = "none"
258
+ secure = True
259
+
260
+ assert session_id is not None
261
+ response = flask.Response(content, mimetype="text/html")
262
+ response.set_cookie(server.COOKIE_KEY_SESSION_ID, value=session_id, secure=secure, samesite=samesite)
263
+ return response
264
+
265
+
266
+ if has_solara_enterprise:
267
+ blueprint.route("/_solara/auth/authorize")(authorize)
268
+ blueprint.route("/_solara/auth/logout")(logout)
269
+ blueprint.route("/_solara/auth/login")(login)
270
+
271
+
272
+ @blueprint.route("/readyz")
273
+ def readyz():
274
+ json, status = server.readyz()
275
+ return flask.Response(json, mimetype="application/json", status=status)
276
+
277
+
278
+ # using the blueprint and websocket blueprint makes it easier to integrate into other applications
279
+ websocket_extension.init_app(blueprint)
280
+ app = Flask(__name__, static_url_path="/_static") # do not intervere with out static files
281
+ app.register_blueprint(blueprint)
282
+ if has_solara_enterprise:
283
+ init_flask(app)
284
+
285
+ if __name__ == "__main__":
286
+ app.run(debug=False, port=8765)
@@ -0,0 +1,2 @@
1
+ from .server_extension import _load_jupyter_server_extension # noqa
2
+ from .server_extension import load_jupyter_server_extension # noqa
@@ -0,0 +1,28 @@
1
+ import logging
2
+ import mimetypes
3
+
4
+ import tornado.web
5
+ from jupyter_server.base.handlers import JupyterHandler
6
+
7
+ from solara.server import settings
8
+ from solara.server.cdn_helper import get_data
9
+
10
+ logger = logging.getLogger("Solara.cdn")
11
+
12
+
13
+ class CdnHandler(JupyterHandler):
14
+ def initialize(self, cache_directory=settings.assets.proxy_cache_dir):
15
+ self.cache_directory = cache_directory
16
+ logging.info("Using %r as cache directory", self.cache_directory)
17
+
18
+ async def get(self, path=None):
19
+ try:
20
+ content = get_data(self.cache_directory, path)
21
+ except Exception as e:
22
+ logger.warning(e)
23
+ raise tornado.web.HTTPError(500)
24
+
25
+ mime = mimetypes.guess_type(path)
26
+ if mime[0] is not None:
27
+ self.set_header("Content-Type", mime[0])
28
+ self.write(content)
@@ -0,0 +1,29 @@
1
+ from jupyter_server.utils import url_path_join
2
+
3
+ from solara.server.cdn_helper import cdn_url_path
4
+ from solara.server.jupyter.cdn_handler import CdnHandler
5
+
6
+
7
+ def _jupyter_server_extension_paths():
8
+ return [{"module": "solara.server.jupyter.server_extension"}]
9
+
10
+
11
+ def _load_jupyter_server_extension(server_app):
12
+ web_app = server_app.web_app
13
+
14
+ host_pattern = ".*$"
15
+ base_url = url_path_join(web_app.settings["base_url"])
16
+
17
+ web_app.add_handlers(
18
+ host_pattern,
19
+ [
20
+ (url_path_join(base_url, f"/{cdn_url_path}/(.*)"), CdnHandler, {}),
21
+ ],
22
+ )
23
+
24
+
25
+ # For backward compatibility
26
+ load_jupyter_server_extension = _load_jupyter_server_extension
27
+
28
+ # For future compatibility
29
+ _jupyter_server_extension_points = _jupyter_server_extension_paths
@@ -0,0 +1,46 @@
1
+ import json
2
+ from pathlib import Path
3
+ from typing import List
4
+
5
+ # based on notebook config, but to reduce the dependencies
6
+ # and with modern typing and use of pathlib
7
+
8
+
9
+ def recursive_update(target, new):
10
+ """Recursively update one dictionary using another.
11
+
12
+ None values will delete their keys.
13
+ """
14
+ for k, v in new.items():
15
+ if isinstance(v, dict):
16
+ if k not in target:
17
+ target[k] = {}
18
+ recursive_update(target[k], v)
19
+ if not target[k]:
20
+ # Prune empty subdicts
21
+ del target[k]
22
+
23
+ elif v is None:
24
+ target.pop(k, None)
25
+
26
+ else:
27
+ target[k] = v
28
+
29
+
30
+ def _get_config(directory: Path, config_name: str):
31
+ paths = [directory / f"{config_name}.json"]
32
+ paths.extend((directory / f"{config_name}.d/").glob("*.json"))
33
+ data: dict = {}
34
+ for path in paths:
35
+ if path.is_file():
36
+ with open(path, encoding="utf-8") as f:
37
+ recursive_update(data, json.load(f))
38
+ return data
39
+
40
+
41
+ def get_config(directories: List[Path], config_name: str):
42
+ config: dict = {}
43
+ # step through back to front, to ensure front of the list is top priority
44
+ for directory in directories[::-1]:
45
+ recursive_update(config, _get_config(directory, config_name))
46
+ return config