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,196 @@
1
+ ---
2
+ title: Building multi-page apps in Solara
3
+ description: The simplest way to create a multi-page app is to create a directory with multiple scripts.
4
+ ---
5
+
6
+ # Multi-page support
7
+
8
+ In the [Web App tutorial](/documentation/getting_started/tutorials/web-app), we created an application consisting of a single page. Web applications generally have multiple pages, and Solara supports this as well.
9
+
10
+
11
+ ## Multiple scripts
12
+
13
+ The simplest way to create a multi-page app is to create a directory with multiple scripts.
14
+
15
+ ```bash
16
+ $ solara create button multipage-demo/01-click-button.py
17
+ Wrote: /mypath/multipage-demo/01-click-button.py
18
+ ...
19
+ $ solara create markdown multipage-demo/02-markdown-editor.py
20
+ Wrote: /mypath/multipage-demo/02-markdown-editor.py
21
+ ...
22
+ ```
23
+
24
+
25
+ You should have the following directory structure:
26
+
27
+ ```
28
+ multipage-demo
29
+ ├── 01-click-button.py
30
+ └── 02-markdown-editor.py
31
+ ```
32
+
33
+ Now run Solara, with this directory as argument:
34
+
35
+ ```bash
36
+ $ solara run ./multipage-demo
37
+ Solara server is starting at http://localhost:8765
38
+ ```
39
+
40
+ Giving you an output like:
41
+
42
+ ![screencapture](https://user-images.githubusercontent.com/1765949/214879312-19323de3-c4ce-4528-ac84-5aa0021ca5b4.gif)
43
+
44
+ Solara now:
45
+
46
+ * Sort the paths according to the filename (hence the 01- and 02- prefix)
47
+ * Generate a nice URL by stripping of prefix, splitting the filename taking out `-`, `_` and spaces, and join them together using a `-` (e.g. "/markdown-editor").
48
+ * Generate a nice default title similar to the link, but now capitalize the first letter and join with a space instead (e.g. "Mardown Editor").
49
+ * The first page will be the default (and its URL will be empty instead, i.e., the empty string `""`)
50
+ * Since the first script does not define a `Layout` component, nor did we add a `__init__.py` with a `Layout` component, Solara will add a [Layout component](/documentation/components/layout/app_layout) which includes a navigation sidebar.
51
+ * If a path is a directory, Solara will recursively scan the subdirectory and include it in the navigation. Read more on this in the [Layout section](layout)
52
+
53
+ Solara will render two pages:
54
+
55
+ * http://localhost:8765 with title "Click Button"
56
+ * http://localhost:8765/markdown-editor with title "Markdown Editor"
57
+
58
+
59
+
60
+ ## Classical widgets support
61
+
62
+ Multipage is also supported for regular ipywidgets. An example directory can be seen on [GitHub](https://github.com/widgetti/solara/tree/master/tests/unit/solara_test_apps/multipage),
63
+ which we use for testing.
64
+
65
+ A large difference between using regular ipywidgets for pages compared to using components is that there is no lifecycle
66
+ management in regular ipywidgets. This means Solara cannot clean up your ipywidget-based page (garbage-collect the unused widgets, unregister callbacks)
67
+ when a user navigates away from your page.
68
+
69
+ At the same time, rerunning your regular ipywidget-based script each time a user navigates to that page will result in a buildup of many widgets.
70
+
71
+ This means that Solara will run your page once (the first time it is loaded by a user/browser tab), and, when navigating back,
72
+ will show the page in the same state as when the user left the page.
73
+
74
+
75
+ ## As a package
76
+
77
+ Once you start building a larger application, it pays off using a Python package instead. This allows you to organize and distribute your app as a Python package (as a wheel for instance) and allows you to organize your application
78
+ into reusable packages for components, stores, hooks etc.
79
+
80
+ As a quickstart, we can generate a startup project using:
81
+ ```bash
82
+ $ solara create portal solara-test-portal
83
+ Wrote: /Users/maartenbreddels/github/widgetti/solara/solara-test-portal
84
+ Install as:
85
+ $ (cd solara-test-portal; pip install -e .)
86
+ Run as:
87
+ $ solara run solara_test_portal.pages
88
+ ```
89
+
90
+ You should have the following directory structure:
91
+ ```bash
92
+ ├── LICENSE
93
+ ├── Procfile # will make it run on heroku
94
+ ├── mypy.ini # adds strict type checking
95
+ ├── pyproject.toml # make it installable with pip/hatch etc
96
+ └── solara_test_portal # Python package containing all code
97
+ ├── __init__.py
98
+ ├── components # contains general react components
99
+ │ ├── __init__.py
100
+ │ ├── header.py
101
+ │ └── layout.py
102
+ ├── content # contains content (markdown articles in this case)
103
+ │ └── articles
104
+ │ ├── 7-reasons-why-i-love-vaex-for-data-science.md
105
+ │ └── a-hybrid-apache-arrow-numpy-dataframe-with-vaex-version-4.md
106
+ ├── data.py # here is where we store shared data or application state
107
+ └── pages # contains the pages
108
+ ├── __init__.py
109
+ ├── article
110
+ │ └── __init__.py
111
+ ├── tabular.py
112
+ └── viz
113
+ ├── __init__.py
114
+ └── overview.py
115
+ ```
116
+
117
+ Install it using
118
+ ```bash
119
+ $ (cd solara-test-portal; pip install -e .)
120
+ ```
121
+
122
+ Run it with
123
+ ```bash
124
+ $ solara run solara_test_portal.pages
125
+ Solara server is starting at http://localhost:8765
126
+ ```
127
+
128
+ Go to http://localhost:8765 ([or click here](http://localhost:8765)), explore the source code, edit it, save it, and watch the web app reload instantly.
129
+
130
+
131
+ ## In a single script
132
+
133
+ If you want to setup a multipage app in a single script, you do not need to define a `Page` component, but you can define a list of routes.
134
+
135
+ ```python
136
+ import solara
137
+
138
+
139
+ @solara.component
140
+ def Home():
141
+ solara.Markdown("Home")
142
+
143
+
144
+ @solara.component
145
+ def About():
146
+ solara.Markdown("About")
147
+
148
+
149
+ routes = [
150
+ solara.Route(path="/", component=Home, label="home"),
151
+ solara.Route(path="about", component=About, label="about"),
152
+ ]
153
+ ```
154
+
155
+ See more details in the [Route section](/documentation/advanced/understanding/routing).
156
+
157
+ ## Dynamic pages
158
+
159
+ In the previous section we created the example portal app. Taking a look at
160
+ tabular.py, we see the `Page` component takes an additional arguments.
161
+
162
+ ```python
163
+ @solara.component
164
+ def Page(name: str):
165
+ ...
166
+ ```
167
+
168
+
169
+ Solara recognizes this and will pass all routes such as `/tabular/foo` and `/tabular/bar` to this Page component passing for instance `"foo"` or `"bar"` as an argument, such that you can dynamically render a page based on the URL.
170
+
171
+ An example Page component could look like this:
172
+
173
+ ```python
174
+ @solara.component
175
+ def Page(name: str = "foo"):
176
+ subpages = ["foo", "bar", "solara", "react-ipywidgets"]
177
+ solara.Markdown(f"You are at: {name}")
178
+ # bunch of buttons which navigate to our dynamic route
179
+ with solara.Row():
180
+ for subpage in subpages:
181
+ with solara.Link(subpage):
182
+ solara.Button(label=f"Go to: {subpage}")
183
+ ```
184
+
185
+ By giving the name argument a default value of `"foo"`, Solara will also accept the `/tabular` url.
186
+
187
+ # What you have learned
188
+
189
+ * Putting multiple Solara app script into a directory allows Solara to show a multipage app.
190
+ * If no `Layout` component is provided, Solara adds a default navigation sidebar.
191
+ * Large application can benefit from setting up a Python package, use `solara create portal my-name` to create one.
192
+ * By adding an argument to the `Page` component, routes like `/tabular` will turn into dynamic routes (e.g. `/tabular/dynamic-name`) and pass the argument (`"dynamic-name"` in this case) to the `Page` component to implement dynamic pages.
193
+
194
+ # What next?
195
+
196
+ * Also check out the [Multipage example](/documentation/examples/fullscreen/multipage) for more inspiration.
@@ -0,0 +1,125 @@
1
+ ---
2
+ title: Making different layouts in Solara
3
+ description: Solara comes with a layout system ideal for data apps. Learn how to use them in this short guide.
4
+ ---
5
+
6
+ # Layout
7
+
8
+ Solara comes with a layout system ideal for data apps.
9
+
10
+ The following example shows 80% of what you need to know to lay out your app.
11
+
12
+ ```solara
13
+ import solara
14
+
15
+ @solara.component
16
+ def Page():
17
+ with solara.Column():
18
+ solara.Title("I'm in the browser tab and the toolbar")
19
+ with solara.Sidebar():
20
+ solara.Markdown("## I am in the sidebar")
21
+ solara.SliderInt(label="Ideal for placing controls")
22
+ solara.Info("I'm in the main content area, put your main content here")
23
+ with solara.Card("Use solara.Columns([1, 2]) to create relatively sized columns"):
24
+ with solara.Columns([1, 2]):
25
+ solara.Success("I'm in the first column")
26
+ solara.Warning("I'm in the second column, I am twice as wide")
27
+ solara.Info("I am like the first column")
28
+
29
+ with solara.Card("Use solara.Column() to create a full width column"):
30
+ with solara.Column():
31
+ solara.Success("I'm first in this full with column")
32
+ solara.Warning("I'm second in this full with column")
33
+ solara.Error("I'm third in this full with column")
34
+
35
+ with solara.Card("Use solara.ColumnsResponsive(6, large=4) to response to screen size"):
36
+ with solara.ColumnsResponsive(6, large=4):
37
+ for i in range(6):
38
+ solara.Info("two per column on small screens, three per column on large screens")
39
+ ```
40
+
41
+ [Navigate here to watch this layout in a full browser window](/documentation/examples/fullscreen/layout-demo)
42
+
43
+ The key takeaways are:
44
+
45
+ * By default, Solara will wrap your component in an [AppLayout](/documentation/components/layout/app_layout), which will give you:
46
+ * Room for a sidebar, that you can populate using the [Sidebar](/documentation/components/layout/sidebar) component.
47
+ * A toolbar showing the [Title](/documentation/components/page/title).
48
+ * Not visible here: In the case of [multiple pages](/documentation/advanced/howto/multipage) will include page navigation tabs. See [The multipage demo app](/documentation/examples/fullscreen/multipage) for an example.
49
+ * Use [Card](/documentation/components/layout/card) to put related components together with a title.
50
+ * Use [Column](/documentation/components/layout/column) to simply layout components under each other.
51
+ * Use [Columns](/documentation/components/layout/columns) if you want to have a few columns with relative sizes next to each other.
52
+ * Use [ColumnsResponsive](/documentation/components/layout/columns_responsive) to have the column widths respond to screen size.
53
+
54
+
55
+
56
+ ## Changing the default layout
57
+
58
+ While [AppLayout](/documentation/components/layout/app_layout) may be sufficient in 80% of the cases. Solara provides a way to change this default layout in [Solara server](/documentation/advanced/understanding/solara-server).
59
+
60
+ You can define your own `Layout` component in the `__init__.py` file in the same directory of your app script.
61
+
62
+
63
+ For instance, putting the following `Layout` component in `__init__.py` will give you effectively the same [AppLayout](/documentation/components/layout/app_layout):
64
+ ```python
65
+ @solara.component
66
+ def Layout(children=[]):
67
+ print("I get called before the Page component gets rendered")
68
+ return solara.AppLayout(children=children)
69
+ ```
70
+
71
+
72
+ ### No Layout
73
+ If you do not want to have any layout, you can disable it using:
74
+
75
+ ```python
76
+ @solara.component
77
+ def Layout(children=[]):
78
+ # there will only be 1 child, which is the Page()
79
+ return children[0]
80
+ ```
81
+
82
+ This layout leaves every page responsible for creating its own header, footer, and/or menu structure for navigation.
83
+
84
+
85
+ ### Layout with navigation
86
+
87
+ In case you want to set up your own layout system, which sets up navigation as well, this example may get you started. It may help
88
+ to [understand routing](/documentation/advanced/understanding/routing).
89
+ ```python
90
+ @solara.component
91
+ def Layout(children=[]):
92
+ # Note that children being passed here for this example will be a Page() element.
93
+ route_current, routes_all = solara.use_route()
94
+ with solara.Column():
95
+ # put all buttons in a single row
96
+ with solara.Row():
97
+ for route in routes_all:
98
+ with solara.Link(route):
99
+ solara.Button(route.path, color="red" if route_current == route else None)
100
+ # under the navigation buttons, we add our children (the single Page())
101
+ solara.Column(children=children)
102
+ ```
103
+
104
+
105
+ ### Nested Layouts
106
+
107
+ Each subdirectory (or subpackage) can define a `Layout` component in its own `__init__.py`, which then is embedded into the parent Layout to provide a hierarchical
108
+ nested layout tree.
109
+
110
+ This is useful for larger apps where each subdirectory may add a bit of layout/chrome around your page.
111
+
112
+
113
+
114
+ ## Components
115
+
116
+ The following [Container components](/documentation/advanced/understanding/containers) can be used to define the layout of you app.
117
+
118
+ * [Row](/documentation/components/layout/row)
119
+ * [Column](/documentation/components/layout/column)
120
+ * [ColumnsResponsive](/documentation/components/layout/columns_responsive)
121
+ * [GridFixed](/documentation/components/layout/gridfixed)
122
+ * [GridDraggable](/documentation/components/layout/griddraggable)
123
+ * [VBox](/documentation/components/layout/vbox) (kept for ipywidgets compatibility, please use Column)
124
+ * [HBox](/documentation/components/layout/hbox) (kept for ipywidgets compatibility, please use Row)
125
+ * [AppLayout](/documentation/components/layout/app_layout) Not often used directly, since Solara will already wrap your page in it. Sometimes re-used in a new `Layout` component.
@@ -0,0 +1,162 @@
1
+ ---
2
+ title: Testing your Solara application, both front and back end
3
+ description: Using solara you can test both the front and back end functionalities of your application.
4
+ ---
5
+
6
+ # Testing with Solara
7
+
8
+
9
+ ## Testing without a Browser
10
+
11
+ We recommend using pytest to test the application logic of your Solara components. To get inspiration for writing tests that cover component logic and their interactions with existing components, refer to the [tests in the Solara repository](https://github.com/widgetti/solara/tree/master/tests).
12
+
13
+ ## Testing with a Browser
14
+
15
+ ### Installation
16
+
17
+ Solara is using the `pytest-ipywidgets` pytest plugin together with [Playwright for Python](https://playwright.dev/python/) to test your widgets, components or applications using a browser, for both unit as well as integration tests.
18
+
19
+ To install `pytest-ipywidgets` and Playwright for Python, run the following commands:
20
+ ```
21
+ $ pip install "pytest-ipywidgets[solara]" # or "pytest-ipywidgets[all]" if you also want to test with Jupyter Lab, Jupiter Notebook and Voila.
22
+ $ playwright install chromium
23
+ ```
24
+
25
+ ### Testing widgets using Solara server
26
+
27
+ The most convenient way to test a widget, is by including the `solara_test` fixture in your test function arguments. Here's an example:
28
+
29
+ ```python
30
+ # file tests/ui/test_widget_button.py
31
+ import ipywidgets as widgets
32
+ import playwright.sync_api
33
+ from IPython.display import display
34
+
35
+ def test_widget_button_solara(solara_test, page_session: playwright.sync_api.Page):
36
+ # this all runs in process, which only works with solara
37
+ # also, this test is only with pure ipywidgets
38
+ button = widgets.Button(description="Click Me!")
39
+
40
+ def change_description(obj):
41
+ button.description = "Tested event"
42
+
43
+ button.on_click(change_description)
44
+ display(button)
45
+ button_sel = page_session.locator("text=Click Me!")
46
+ button_sel.wait_for()
47
+ button_sel.click()
48
+ page_session.locator("text=Tested event").wait_for()
49
+ ```
50
+ When this fixture is used, we can use the standard IPython display call to add your widget to the page. Using the `page_session` fixture, we can interact with the widget in the browser,
51
+ in this case we trigger a button click in the browser and check if the button description changes to "Tested event".
52
+
53
+ Run this test with pytest as follows:
54
+
55
+ ```bash
56
+ pytest tests/ui/test_widget_button.py --headed # remove --headed to run headless
57
+ ```
58
+
59
+
60
+
61
+ # Testing in the main Jupyter Environments
62
+
63
+ In case you want to test your component in the main Jupyter environments (e.g., Jupyter Notebook, Jupyter Lab, Voila, and Solara) to ensure it renders correctly, use the `ipywidgets_runner` fixture to run code snippets. Here's an example:
64
+
65
+ ```python
66
+ import ipywidgets as widgets
67
+ import playwright.sync_api
68
+ from IPython.display import display
69
+
70
+
71
+ def test_solara_button_all(ipywidgets_runner, page_session: playwright.sync_api.Page, assert_solara_snapshot):
72
+ # this function (or rather its lines) will be executed in the kernel
73
+ # voila, lab, classic notebook and solara will all execute it
74
+ def kernel_code():
75
+ import solara
76
+
77
+ @solara.component
78
+ def Button():
79
+ text, set_text = solara.use_state("Click Me!")
80
+
81
+ def on_click():
82
+ set_text("Tested event")
83
+
84
+ solara.Button(text, on_click=on_click)
85
+
86
+ display(Button())
87
+
88
+ ipywidgets_runner(kernel_code)
89
+ button_sel = page_session.locator("button >> text=Click Me!")
90
+ assert_solara_snapshot(button_sel.screenshot())
91
+ button_sel.wait_for()
92
+ button_sel.click()
93
+ page_session.locator("button >> text=Tested event").wait_for()
94
+ page_session.wait_for_timeout(1000)
95
+ ```
96
+
97
+ Note that the function in the code will be executed in a different process (a Jupyter kernel), which will make it harder to debug and slower to run.
98
+ Because the function code executes in the kernel, you do not have access to local variables. However, by passing a dictionary as second argument
99
+ to `ipywidgets_runner` we can pass in extra local variables (e.g. `ipywidgets_runner(kernel_code, {"extra_argument": extra_argument})`).
100
+
101
+ ## Limiting the Jupyter Environments
102
+ To limit the ipywidgets_runner fixture to only run in a specific environment, use the `SOLARA_TEST_RUNNERS` environment variable:
103
+
104
+ * `SOLARA_TEST_RUNNERS=solara pytest tests/ui`
105
+ * `SOLARA_TEST_RUNNERS=voila pytest tests/ui`
106
+ * `SOLARA_TEST_RUNNERS=jupyter_lab pytest tests/ui`
107
+ * `SOLARA_TEST_RUNNERS=jupyter_notebook pytest tests/ui`
108
+ * `SOLARA_TEST_RUNNERS=solara,voila pytest tests/ui`
109
+
110
+
111
+
112
+ # Organizing Tests and Managing Snapshots
113
+ We recommend organizing your visual tests in a separate directory, such as `tests/ui`. This allows you to run fast tests (`test/unit`) separately from slow tests (t`est/ui`). Use the `solara_snapshots_directory` fixture to change the default directory for storing snapshots, which is `tests/ui/snapshots` by default.
114
+
115
+ ```bash
116
+ $ pytest tests/unit # run fast test
117
+ $ pytest tests/ui # run slow test
118
+ $ pytest tests # run all tests
119
+ ```
120
+
121
+ To compare a captured image from a part of your page with the reference image, use the `assert_solara_snapshot` fixture. For example, `assert_solara_snapshot(button_sel.screenshot())` will take a screenshot of the button and compare it to the reference image. If the images are different, the test will fail.
122
+
123
+ For local development, you can use the --solara-update-snapshots flag to update the reference images. This will overwrite the existing reference images with the new ones generated during the test run. However, you should carefully review the changes before committing them to your repository to ensure the updates are accurate and expected.
124
+
125
+
126
+ # Continuous Integration Recommendations
127
+
128
+ When a test fails, the output will be placed in a directory structure similar to what would be put in the `solara_snapshots_directory` directory but under the test-results directory in the root of your project (unless changed by passing `--output=someotherdirectory` to pytest).
129
+
130
+ In CI, we recommend downloading this directory using, for example, GitHub Actions:
131
+
132
+ ```yaml
133
+ - name: Download test results
134
+ uses: actions/download-artifact@v2
135
+ with:
136
+ name: myproject-test-results
137
+ path: test-results
138
+ ```
139
+
140
+
141
+ After inspecting and approving the screenshots, you can copy them to the `solara_snapshots_directory` directory and commit them to your repository. This way, you ensure that the reference images are up-to-date and accurate for future tests.
142
+
143
+
144
+ # Note about the Playwright
145
+
146
+ Visual testing with solara is based on [Playwright for Python](https://playwright.dev/python/), which provides a `page` fixture. However, this fixture will make a new page for each test, which is not what we want. Therefore, we provide a `page_session` fixture that will reuse the same page for all tests. This is important because it will make the tests faster.
147
+
148
+ By following these recommendations and guidelines, you can efficiently test your Solara applications and ensure a smooth developer experience.
149
+
150
+ # Configuration
151
+
152
+ ## Changing the Hostname
153
+
154
+ To configure the hostname the socket is bound to when starting the test server, use the `HOST` or `SOLARA_HOST` environment variable (e.g. `SOLARA_HOST=0.0.0.0`). This hostname is also used for the jupyter server and voila. Alternatively the `--solara-host` argument can be passed on the command line for pytest.
155
+
156
+ ## Changing the Port
157
+
158
+ To configure the ports the socket is bound to when starting the test servers, use the `PORT` environment variable (e.g. `PORT=18865`). This port and subsequent port will be used for solara-server, jupyter-server and voila. Alternatively the `--solara-port` argument can be passed on the command line for pytest for the solara server, and `--jupyter-port` and `--voila-port` for the ports of jupyter server and voila respectively.
159
+
160
+ ## Vuetify warmup
161
+
162
+ By default, we insert an ipyvuetify widget with an icon into the frontend to force loading all the vuetify assets, such as CSS and fonts. However, if you are using the solara test plugin to test pure ipywidgets or a 3rd ipywidget based party library you might not need this. Disable this vuetify warmup phase by passing the `--no-solara-vuetify-warmup` argument to pytest, or setting the environment variable `SOLARA_TEST_VUETIFY_WARMUP` to a falsey value (e.g. `SOLARA_TEST_VUETIFY_WARMUP=0`).
@@ -0,0 +1,69 @@
1
+ ---
2
+ title: Debugging Solara applications
3
+ description: You can use the Python debugger to debug your Solara app.
4
+ ---
5
+ # Debugging
6
+
7
+ ## PDB
8
+
9
+ You can use the [python debugger](https://docs.python.org/3/library/pdb.html) to debug your Solara app.
10
+
11
+ Simply add `breakpoint()` to your code, and trigger the code, and you will enter the debugger.
12
+
13
+ ```python
14
+ import solara
15
+
16
+ clicks = solara.reactive(0)
17
+
18
+
19
+ @solara.component
20
+ def Page():
21
+ color = "green"
22
+ if clicks.value >= 5:
23
+ color = "red"
24
+
25
+ def increment():
26
+ clicks.value += 1
27
+ # this will trigger the debugger
28
+ breakpoint()
29
+ print("clicks", clicks) # noqa
30
+
31
+ solara.Button(label=f"Clicked: {clicks}", on_click=increment, color=color)
32
+ ```
33
+
34
+ ## PyCharm or IntelliJ
35
+
36
+ You can also use the debugger of PyCharm or IntelliJ to debug your Solara app.
37
+ The following settings works for PyCharm or IntelliJ:
38
+
39
+ ![](https://dxhl76zpt6fap.cloudfront.net/public/docs/howto/debugger-intellij.webp)
40
+
41
+ ## VSCode
42
+
43
+
44
+ In VSCode, you can use the following launch.json to debug your Solara app:
45
+
46
+ ```json
47
+ {
48
+ // Use IntelliSense to learn about possible attributes.
49
+ // Hover to view descriptions of existing attributes.
50
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
51
+ "version": "0.2.0",
52
+ "configurations": [
53
+ {
54
+ "name": "Solara: Launch",
55
+ "type": "python",
56
+ "request": "launch",
57
+ "program": "/Users/maartenbreddels/miniconda3/envs/dev/bin/solara",
58
+ "args": [
59
+ "run",
60
+ "${file}"
61
+ ],
62
+ "console": "integratedTerminal",
63
+ "justMyCode": true,
64
+ }
65
+ ]
66
+ }
67
+ ```
68
+
69
+ Now keep your script tab open, and press F5 to start debugging (or click the play icon in the UI).
@@ -0,0 +1,49 @@
1
+ ---
2
+ title: Embedding Solara applications into existing websites
3
+ description: Solara can be embedded into existing websites. Although it is technically possible to embed a Solara app into an existing webpage,
4
+ we currently support embedding primarily via iframes.
5
+ ---
6
+
7
+ # Embedding in existing websites
8
+
9
+ Solara can be embedded into existing websites. Although it is technically possible to embed a Solara app into an existing webpage, we currently support embedding primarily via iframes.
10
+
11
+
12
+ ## Embed via iframe
13
+
14
+ Here we demonstrate how to embed Solara into an existing webpage via an iframe. Let's start by creating a simple HTML page (here we choose the filename embed.html):
15
+
16
+ ```html
17
+ <html>
18
+ <body>
19
+ <h1>This is on the main page</h1>
20
+ <iframe src="http://localhost:8765" width="100%" height="100%"></iframe>
21
+ </body>
22
+ </html>
23
+ ```
24
+
25
+ Now, start an http server (in this example we use the standard Python http server):
26
+ ```bash
27
+ $ python -m http.server
28
+ Serving HTTP on :: port 8000 (http://[::]:8000/) ...
29
+ ```
30
+
31
+ Additionally, start the Solara server:
32
+
33
+ ```bash
34
+ $ solara run my-solara-app.py
35
+ Solara server is starting at http://localhost:8765
36
+ ```
37
+
38
+ Ensure the port number matches that of the iframe in `embed.html`. Now open `http://localhost:8000/embed.html` in your browser, and you should see the Solara app embedded in the page.
39
+
40
+ If you do not see your app, you can open the browser developer tools in your browser and look for errors in the console. If you use the Brave browser, you might want to disable the Brave shields for your local server.
41
+
42
+ ### Security considerations
43
+
44
+ Solara uses a cookie to implement sessions. To support cookies settings in an iframe, we set the session cookie using `Secure`, and `SameSite=Strict`. See [https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies](MDN) for more details. This means that we can only support loading via iframes via https or localhost.
45
+
46
+
47
+ ## Embed into an existing page
48
+
49
+ If embedding into an iframe does not suit your needs (for example, dialogs not being fullscreen), [please contact us](/contact) and we can discuss other options.