solara 1.30.0__py2.py3-none-any.whl → 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. {solara-1.30.0.dist-info → solara-1.31.0.dist-info}/METADATA +7 -42
  2. solara-1.31.0.dist-info/RECORD +5 -0
  3. {solara-1.30.0.dist-info → solara-1.31.0.dist-info}/WHEEL +1 -1
  4. {solara/template/portal → solara-1.31.0.dist-info/licenses}/LICENSE +1 -1
  5. solara/__init__.py +0 -123
  6. solara/__main__.py +0 -734
  7. solara/alias.py +0 -6
  8. solara/autorouting.py +0 -554
  9. solara/cache.py +0 -294
  10. solara/checks.html +0 -71
  11. solara/checks.py +0 -224
  12. solara/comm.py +0 -28
  13. solara/components/__init__.py +0 -59
  14. solara/components/alert.py +0 -155
  15. solara/components/applayout.py +0 -393
  16. solara/components/button.py +0 -85
  17. solara/components/card.py +0 -87
  18. solara/components/checkbox.py +0 -50
  19. solara/components/code_highlight_css.py +0 -11
  20. solara/components/code_highlight_css.vue +0 -63
  21. solara/components/columns.py +0 -159
  22. solara/components/component_vue.py +0 -109
  23. solara/components/cross_filter.py +0 -335
  24. solara/components/dataframe.py +0 -546
  25. solara/components/datatable.py +0 -221
  26. solara/components/datatable.vue +0 -175
  27. solara/components/details.py +0 -21
  28. solara/components/download.vue +0 -35
  29. solara/components/echarts.py +0 -75
  30. solara/components/echarts.vue +0 -128
  31. solara/components/figure_altair.py +0 -39
  32. solara/components/file_browser.py +0 -182
  33. solara/components/file_download.py +0 -199
  34. solara/components/file_drop.py +0 -139
  35. solara/components/file_drop.vue +0 -83
  36. solara/components/file_list_widget.vue +0 -78
  37. solara/components/head.py +0 -27
  38. solara/components/head_tag.py +0 -49
  39. solara/components/head_tag.vue +0 -60
  40. solara/components/image.py +0 -173
  41. solara/components/input.py +0 -440
  42. solara/components/link.py +0 -55
  43. solara/components/markdown.py +0 -371
  44. solara/components/markdown_editor.py +0 -25
  45. solara/components/markdown_editor.vue +0 -362
  46. solara/components/matplotlib.py +0 -74
  47. solara/components/meta.py +0 -47
  48. solara/components/misc.py +0 -333
  49. solara/components/pivot_table.py +0 -258
  50. solara/components/pivot_table.vue +0 -158
  51. solara/components/progress.py +0 -47
  52. solara/components/select.py +0 -186
  53. solara/components/select.vue +0 -27
  54. solara/components/slider.py +0 -442
  55. solara/components/slider_date.vue +0 -56
  56. solara/components/spinner-solara.vue +0 -105
  57. solara/components/spinner.py +0 -30
  58. solara/components/sql_code.py +0 -33
  59. solara/components/sql_code.vue +0 -128
  60. solara/components/style.py +0 -105
  61. solara/components/switch.py +0 -68
  62. solara/components/tab_navigation.py +0 -37
  63. solara/components/title.py +0 -90
  64. solara/components/title.vue +0 -38
  65. solara/components/togglebuttons.py +0 -202
  66. solara/components/tooltip.py +0 -61
  67. solara/datatypes.py +0 -143
  68. solara/express.py +0 -241
  69. solara/hooks/__init__.py +0 -4
  70. solara/hooks/dataframe.py +0 -99
  71. solara/hooks/misc.py +0 -263
  72. solara/hooks/use_reactive.py +0 -129
  73. solara/hooks/use_thread.py +0 -129
  74. solara/kitchensink.py +0 -8
  75. solara/lab/__init__.py +0 -34
  76. solara/lab/components/__init__.py +0 -6
  77. solara/lab/components/chat.py +0 -203
  78. solara/lab/components/confirmation_dialog.py +0 -165
  79. solara/lab/components/cross_filter.py +0 -7
  80. solara/lab/components/input_date.py +0 -298
  81. solara/lab/components/menu.py +0 -181
  82. solara/lab/components/menu.vue +0 -38
  83. solara/lab/components/tabs.py +0 -274
  84. solara/lab/components/theming.py +0 -98
  85. solara/lab/components/theming.vue +0 -72
  86. solara/lab/hooks/__init__.py +0 -0
  87. solara/lab/hooks/dataframe.py +0 -12
  88. solara/lab/toestand.py +0 -3
  89. solara/lab/utils/__init__.py +0 -2
  90. solara/lab/utils/cookies.py +0 -5
  91. solara/lab/utils/dataframe.py +0 -115
  92. solara/lab/utils/headers.py +0 -5
  93. solara/layout.py +0 -44
  94. solara/minisettings.py +0 -133
  95. solara/py.typed +0 -0
  96. solara/reactive.py +0 -93
  97. solara/routing.py +0 -268
  98. solara/scope/__init__.py +0 -87
  99. solara/scope/types.py +0 -55
  100. solara/server/__init__.py +0 -0
  101. solara/server/app.py +0 -490
  102. solara/server/assets/custom.css +0 -1
  103. solara/server/assets/custom.js +0 -1
  104. solara/server/assets/favicon.png +0 -0
  105. solara/server/assets/favicon.svg +0 -5
  106. solara/server/assets/style.css +0 -1665
  107. solara/server/assets/theme-dark.css +0 -437
  108. solara/server/assets/theme-light.css +0 -420
  109. solara/server/assets/theme.js +0 -3
  110. solara/server/cdn_helper.py +0 -77
  111. solara/server/esm.py +0 -69
  112. solara/server/fastapi.py +0 -5
  113. solara/server/flask.py +0 -286
  114. solara/server/jupyter/__init__.py +0 -2
  115. solara/server/jupyter/cdn_handler.py +0 -28
  116. solara/server/jupyter/server_extension.py +0 -29
  117. solara/server/jupytertools.py +0 -46
  118. solara/server/kernel.py +0 -319
  119. solara/server/kernel_context.py +0 -393
  120. solara/server/patch.py +0 -552
  121. solara/server/reload.py +0 -242
  122. solara/server/server.py +0 -437
  123. solara/server/settings.py +0 -212
  124. solara/server/shell.py +0 -240
  125. solara/server/starlette.py +0 -597
  126. solara/server/static/ansi.js +0 -270
  127. solara/server/static/highlight-dark.css +0 -82
  128. solara/server/static/highlight.css +0 -43
  129. solara/server/static/main-vuetify.js +0 -260
  130. solara/server/static/main.js +0 -163
  131. solara/server/static/solara_bootstrap.py +0 -129
  132. solara/server/static/sun.svg +0 -23
  133. solara/server/static/webworker.js +0 -42
  134. solara/server/telemetry.py +0 -212
  135. solara/server/templates/index.html.j2 +0 -1
  136. solara/server/templates/loader-plain.css +0 -11
  137. solara/server/templates/loader-plain.html +0 -20
  138. solara/server/templates/loader-solara.css +0 -111
  139. solara/server/templates/loader-solara.html +0 -40
  140. solara/server/templates/plain.html +0 -82
  141. solara/server/templates/solara.html.j2 +0 -446
  142. solara/server/threaded.py +0 -75
  143. solara/server/utils.py +0 -30
  144. solara/server/websocket.py +0 -44
  145. solara/settings.py +0 -56
  146. solara/tasks.py +0 -847
  147. solara/template/button.py +0 -16
  148. solara/template/markdown.py +0 -42
  149. solara/template/portal/.flake8 +0 -6
  150. solara/template/portal/.pre-commit-config.yaml +0 -28
  151. solara/template/portal/Procfile +0 -7
  152. solara/template/portal/mypy.ini +0 -3
  153. solara/template/portal/pyproject.toml +0 -26
  154. solara/template/portal/solara_portal/__init__.py +0 -3
  155. solara/template/portal/solara_portal/components/__init__.py +0 -2
  156. solara/template/portal/solara_portal/components/article.py +0 -28
  157. solara/template/portal/solara_portal/components/data.py +0 -28
  158. solara/template/portal/solara_portal/components/header.py +0 -6
  159. solara/template/portal/solara_portal/components/layout.py +0 -6
  160. solara/template/portal/solara_portal/content/articles/equis-in-vidi.md +0 -85
  161. solara/template/portal/solara_portal/content/articles/substiterat-vati.md +0 -70
  162. solara/template/portal/solara_portal/data.py +0 -60
  163. solara/template/portal/solara_portal/pages/__init__.py +0 -67
  164. solara/template/portal/solara_portal/pages/article/__init__.py +0 -26
  165. solara/template/portal/solara_portal/pages/tabular.py +0 -29
  166. solara/template/portal/solara_portal/pages/viz/__init__.py +0 -69
  167. solara/template/portal/solara_portal/pages/viz/overview.py +0 -14
  168. solara/test/__init__.py +0 -0
  169. solara/test/pytest_plugin.py +0 -698
  170. solara/toestand.py +0 -772
  171. solara/util.py +0 -308
  172. solara/website/__init__.py +0 -0
  173. solara/website/assets/custom.css +0 -462
  174. solara/website/assets/images/logo-small.png +0 -0
  175. solara/website/assets/images/logo.svg +0 -17
  176. solara/website/assets/images/logo_white.svg +0 -50
  177. solara/website/assets/theme.js +0 -8
  178. solara/website/components/__init__.py +0 -5
  179. solara/website/components/algolia.vue +0 -24
  180. solara/website/components/algolia_api.vue +0 -157
  181. solara/website/components/docs.py +0 -118
  182. solara/website/components/header.py +0 -72
  183. solara/website/components/hero.py +0 -15
  184. solara/website/components/mailchimp.py +0 -12
  185. solara/website/components/mailchimp.vue +0 -47
  186. solara/website/components/notebook.py +0 -172
  187. solara/website/pages/__init__.py +0 -564
  188. solara/website/pages/apps/__init__.py +0 -16
  189. solara/website/pages/apps/authorization/__init__.py +0 -118
  190. solara/website/pages/apps/authorization/admin.py +0 -12
  191. solara/website/pages/apps/authorization/users.py +0 -12
  192. solara/website/pages/apps/jupyter-dashboard-1.py +0 -116
  193. solara/website/pages/apps/layout-demo.py +0 -40
  194. solara/website/pages/apps/multipage/__init__.py +0 -38
  195. solara/website/pages/apps/multipage/page1.py +0 -26
  196. solara/website/pages/apps/multipage/page2.py +0 -34
  197. solara/website/pages/apps/scatter.py +0 -136
  198. solara/website/pages/apps/scrolling.py +0 -63
  199. solara/website/pages/apps/tutorial-streamlit.py +0 -18
  200. solara/website/pages/changelog/__init__.py +0 -8
  201. solara/website/pages/changelog/changelog.md +0 -180
  202. solara/website/pages/contact/__init__.py +0 -8
  203. solara/website/pages/contact/contact.md +0 -17
  204. solara/website/pages/doc_use_download.py +0 -85
  205. solara/website/pages/documentation/__init__.py +0 -184
  206. solara/website/pages/documentation/advanced/__init__.py +0 -36
  207. solara/website/pages/documentation/advanced/content/00-overview.md +0 -1
  208. solara/website/pages/documentation/advanced/content/10-howto/00-overview.md +0 -1
  209. solara/website/pages/documentation/advanced/content/10-howto/10-multipage.md +0 -191
  210. solara/website/pages/documentation/advanced/content/10-howto/20-layout.md +0 -120
  211. solara/website/pages/documentation/advanced/content/10-howto/30-testing.md +0 -149
  212. solara/website/pages/documentation/advanced/content/10-howto/31-debugging.md +0 -66
  213. solara/website/pages/documentation/advanced/content/10-howto/40-embed.md +0 -43
  214. solara/website/pages/documentation/advanced/content/10-howto/50-ipywidget_libraries.md +0 -120
  215. solara/website/pages/documentation/advanced/content/20-understanding/00-introduction.md +0 -4
  216. solara/website/pages/documentation/advanced/content/20-understanding/05-ipywidgets.md +0 -30
  217. solara/website/pages/documentation/advanced/content/20-understanding/06-ipyvuetify.md +0 -38
  218. solara/website/pages/documentation/advanced/content/20-understanding/10-reacton.md +0 -24
  219. solara/website/pages/documentation/advanced/content/20-understanding/12-reacton-basics.md +0 -104
  220. solara/website/pages/documentation/advanced/content/20-understanding/15-anatomy.md +0 -19
  221. solara/website/pages/documentation/advanced/content/20-understanding/17-rules-of-hooks.md +0 -3
  222. solara/website/pages/documentation/advanced/content/20-understanding/18-containers.md +0 -160
  223. solara/website/pages/documentation/advanced/content/20-understanding/20-solara.md +0 -13
  224. solara/website/pages/documentation/advanced/content/20-understanding/40-routing.md +0 -236
  225. solara/website/pages/documentation/advanced/content/20-understanding/50-solara-server.md +0 -81
  226. solara/website/pages/documentation/advanced/content/20-understanding/60-voila.md +0 -7
  227. solara/website/pages/documentation/advanced/content/30-enterprise/00-overview.md +0 -1
  228. solara/website/pages/documentation/advanced/content/30-enterprise/10-oauth.md +0 -167
  229. solara/website/pages/documentation/advanced/content/40-development/00-overview.md +0 -0
  230. solara/website/pages/documentation/advanced/content/40-development/01-contribute.md +0 -41
  231. solara/website/pages/documentation/advanced/content/40-development/10-setup.md +0 -72
  232. solara/website/pages/documentation/advanced/content/__init__.py +0 -0
  233. solara/website/pages/documentation/api/__init__.py +0 -19
  234. solara/website/pages/documentation/api/cross_filter/__init__.py +0 -9
  235. solara/website/pages/documentation/api/cross_filter/cross_filter_dataframe.py +0 -23
  236. solara/website/pages/documentation/api/cross_filter/cross_filter_report.py +0 -22
  237. solara/website/pages/documentation/api/cross_filter/cross_filter_select.py +0 -22
  238. solara/website/pages/documentation/api/cross_filter/cross_filter_slider.py +0 -22
  239. solara/website/pages/documentation/api/hooks/__init__.py +0 -9
  240. solara/website/pages/documentation/api/hooks/use_cross_filter.py +0 -25
  241. solara/website/pages/documentation/api/hooks/use_dark_effective.py +0 -13
  242. solara/website/pages/documentation/api/hooks/use_effect.md +0 -43
  243. solara/website/pages/documentation/api/hooks/use_effect.py +0 -9
  244. solara/website/pages/documentation/api/hooks/use_exception.py +0 -33
  245. solara/website/pages/documentation/api/hooks/use_memo.md +0 -16
  246. solara/website/pages/documentation/api/hooks/use_memo.py +0 -9
  247. solara/website/pages/documentation/api/hooks/use_previous.py +0 -32
  248. solara/website/pages/documentation/api/hooks/use_reactive.py +0 -15
  249. solara/website/pages/documentation/api/hooks/use_state.py +0 -11
  250. solara/website/pages/documentation/api/hooks/use_state_or_update.py +0 -68
  251. solara/website/pages/documentation/api/hooks/use_thread.md +0 -58
  252. solara/website/pages/documentation/api/hooks/use_thread.py +0 -44
  253. solara/website/pages/documentation/api/hooks/use_trait_observe.py +0 -13
  254. solara/website/pages/documentation/api/routing/__init__.py +0 -9
  255. solara/website/pages/documentation/api/routing/generate_routes.py +0 -11
  256. solara/website/pages/documentation/api/routing/generate_routes_directory.py +0 -11
  257. solara/website/pages/documentation/api/routing/resolve_path.py +0 -36
  258. solara/website/pages/documentation/api/routing/route.py +0 -32
  259. solara/website/pages/documentation/api/routing/use_route.py +0 -80
  260. solara/website/pages/documentation/api/routing/use_router.py +0 -15
  261. solara/website/pages/documentation/api/utilities/__init__.py +0 -9
  262. solara/website/pages/documentation/api/utilities/component_vue.py +0 -11
  263. solara/website/pages/documentation/api/utilities/computed.py +0 -16
  264. solara/website/pages/documentation/api/utilities/display.py +0 -15
  265. solara/website/pages/documentation/api/utilities/get_kernel_id.py +0 -16
  266. solara/website/pages/documentation/api/utilities/get_session_id.py +0 -16
  267. solara/website/pages/documentation/api/utilities/memoize.py +0 -36
  268. solara/website/pages/documentation/api/utilities/on_kernel_start.py +0 -27
  269. solara/website/pages/documentation/api/utilities/reactive.py +0 -15
  270. solara/website/pages/documentation/api/utilities/widget.py +0 -104
  271. solara/website/pages/documentation/components/__init__.py +0 -12
  272. solara/website/pages/documentation/components/advanced/__init__.py +0 -9
  273. solara/website/pages/documentation/components/advanced/link.py +0 -28
  274. solara/website/pages/documentation/components/advanced/meta.py +0 -21
  275. solara/website/pages/documentation/components/advanced/style.py +0 -44
  276. solara/website/pages/documentation/components/common.py +0 -9
  277. solara/website/pages/documentation/components/data/__init__.py +0 -9
  278. solara/website/pages/documentation/components/data/dataframe.py +0 -44
  279. solara/website/pages/documentation/components/data/pivot_table.py +0 -81
  280. solara/website/pages/documentation/components/enterprise/__init__.py +0 -9
  281. solara/website/pages/documentation/components/enterprise/avatar.py +0 -19
  282. solara/website/pages/documentation/components/enterprise/avatar_menu.py +0 -20
  283. solara/website/pages/documentation/components/input/__init__.py +0 -9
  284. solara/website/pages/documentation/components/input/button.py +0 -22
  285. solara/website/pages/documentation/components/input/checkbox.py +0 -12
  286. solara/website/pages/documentation/components/input/file_browser.py +0 -33
  287. solara/website/pages/documentation/components/input/file_drop.py +0 -75
  288. solara/website/pages/documentation/components/input/input.py +0 -18
  289. solara/website/pages/documentation/components/input/select.py +0 -21
  290. solara/website/pages/documentation/components/input/slider.py +0 -28
  291. solara/website/pages/documentation/components/input/switch.py +0 -12
  292. solara/website/pages/documentation/components/input/togglebuttons.py +0 -20
  293. solara/website/pages/documentation/components/lab/__init__.py +0 -9
  294. solara/website/pages/documentation/components/lab/chat.py +0 -108
  295. solara/website/pages/documentation/components/lab/confirmation_dialog.py +0 -55
  296. solara/website/pages/documentation/components/lab/cookies_headers.py +0 -48
  297. solara/website/pages/documentation/components/lab/input_date.py +0 -19
  298. solara/website/pages/documentation/components/lab/menu.py +0 -21
  299. solara/website/pages/documentation/components/lab/tab.py +0 -24
  300. solara/website/pages/documentation/components/lab/tabs.py +0 -44
  301. solara/website/pages/documentation/components/lab/task.py +0 -12
  302. solara/website/pages/documentation/components/lab/theming.py +0 -72
  303. solara/website/pages/documentation/components/lab/use_task.py +0 -12
  304. solara/website/pages/documentation/components/layout/__init__.py +0 -9
  305. solara/website/pages/documentation/components/layout/app_bar.py +0 -15
  306. solara/website/pages/documentation/components/layout/app_bar_title.py +0 -15
  307. solara/website/pages/documentation/components/layout/app_layout.py +0 -23
  308. solara/website/pages/documentation/components/layout/card.py +0 -14
  309. solara/website/pages/documentation/components/layout/card_actions.py +0 -15
  310. solara/website/pages/documentation/components/layout/column.py +0 -29
  311. solara/website/pages/documentation/components/layout/columns.py +0 -26
  312. solara/website/pages/documentation/components/layout/columns_responsive.py +0 -67
  313. solara/website/pages/documentation/components/layout/griddraggable.py +0 -61
  314. solara/website/pages/documentation/components/layout/gridfixed.py +0 -21
  315. solara/website/pages/documentation/components/layout/hbox.py +0 -17
  316. solara/website/pages/documentation/components/layout/row.py +0 -29
  317. solara/website/pages/documentation/components/layout/sidebar.py +0 -23
  318. solara/website/pages/documentation/components/layout/vbox.py +0 -19
  319. solara/website/pages/documentation/components/output/__init__.py +0 -9
  320. solara/website/pages/documentation/components/output/file_download.py +0 -12
  321. solara/website/pages/documentation/components/output/html.py +0 -22
  322. solara/website/pages/documentation/components/output/image.py +0 -12
  323. solara/website/pages/documentation/components/output/markdown.py +0 -59
  324. solara/website/pages/documentation/components/output/markdown_editor.py +0 -53
  325. solara/website/pages/documentation/components/output/sql_code.py +0 -84
  326. solara/website/pages/documentation/components/output/tooltip.py +0 -12
  327. solara/website/pages/documentation/components/page/__init__.py +0 -9
  328. solara/website/pages/documentation/components/page/head.py +0 -19
  329. solara/website/pages/documentation/components/page/title.py +0 -28
  330. solara/website/pages/documentation/components/status/__init__.py +0 -9
  331. solara/website/pages/documentation/components/status/error.py +0 -40
  332. solara/website/pages/documentation/components/status/info.py +0 -40
  333. solara/website/pages/documentation/components/status/progress.py +0 -10
  334. solara/website/pages/documentation/components/status/spinner.py +0 -10
  335. solara/website/pages/documentation/components/status/success.py +0 -40
  336. solara/website/pages/documentation/components/status/warning.py +0 -47
  337. solara/website/pages/documentation/components/viz/__init__.py +0 -9
  338. solara/website/pages/documentation/components/viz/altair.py +0 -44
  339. solara/website/pages/documentation/components/viz/echarts.py +0 -78
  340. solara/website/pages/documentation/components/viz/matplotlib.py +0 -32
  341. solara/website/pages/documentation/components/viz/plotly.py +0 -63
  342. solara/website/pages/documentation/components/viz/plotly_express.py +0 -41
  343. solara/website/pages/documentation/examples/__init__.py +0 -52
  344. solara/website/pages/documentation/examples/ai/__init__.py +0 -10
  345. solara/website/pages/documentation/examples/ai/chatbot.py +0 -96
  346. solara/website/pages/documentation/examples/ai/tokenizer.py +0 -106
  347. solara/website/pages/documentation/examples/basics/__init__.py +0 -2
  348. solara/website/pages/documentation/examples/basics/sine.py +0 -28
  349. solara/website/pages/documentation/examples/fullscreen/__init__.py +0 -9
  350. solara/website/pages/documentation/examples/fullscreen/authorization.py +0 -3
  351. solara/website/pages/documentation/examples/fullscreen/layout_demo.py +0 -3
  352. solara/website/pages/documentation/examples/fullscreen/multipage.py +0 -3
  353. solara/website/pages/documentation/examples/fullscreen/scatter.py +0 -3
  354. solara/website/pages/documentation/examples/fullscreen/scrolling.py +0 -3
  355. solara/website/pages/documentation/examples/fullscreen/tutorial_streamlit.py +0 -3
  356. solara/website/pages/documentation/examples/general/__init__.py +0 -9
  357. solara/website/pages/documentation/examples/general/custom_storage.py +0 -69
  358. solara/website/pages/documentation/examples/general/deploy_model.py +0 -114
  359. solara/website/pages/documentation/examples/general/live_update.py +0 -38
  360. solara/website/pages/documentation/examples/general/login_oauth.py +0 -76
  361. solara/website/pages/documentation/examples/general/mycard.vue +0 -58
  362. solara/website/pages/documentation/examples/general/pokemon_search.py +0 -51
  363. solara/website/pages/documentation/examples/general/vue_component.py +0 -50
  364. solara/website/pages/documentation/examples/ipycanvas.py +0 -49
  365. solara/website/pages/documentation/examples/libraries/__init__.py +0 -9
  366. solara/website/pages/documentation/examples/libraries/altair.py +0 -63
  367. solara/website/pages/documentation/examples/libraries/bqplot.py +0 -39
  368. solara/website/pages/documentation/examples/libraries/ipyleaflet.py +0 -32
  369. solara/website/pages/documentation/examples/libraries/ipyleaflet_advanced.py +0 -65
  370. solara/website/pages/documentation/examples/utilities/__init__.py +0 -9
  371. solara/website/pages/documentation/examples/utilities/calculator.py +0 -157
  372. solara/website/pages/documentation/examples/utilities/countdown_timer.py +0 -64
  373. solara/website/pages/documentation/examples/utilities/todo.py +0 -195
  374. solara/website/pages/documentation/examples/visualization/__init__.py +0 -6
  375. solara/website/pages/documentation/examples/visualization/annotator.py +0 -68
  376. solara/website/pages/documentation/examples/visualization/linked_views.py +0 -84
  377. solara/website/pages/documentation/examples/visualization/plotly.py +0 -43
  378. solara/website/pages/documentation/faq/__init__.py +0 -11
  379. solara/website/pages/documentation/faq/content/99-faq.md +0 -73
  380. solara/website/pages/documentation/getting_started/__init__.py +0 -15
  381. solara/website/pages/documentation/getting_started/content/00-quickstart.md +0 -84
  382. solara/website/pages/documentation/getting_started/content/01-introduction.md +0 -121
  383. solara/website/pages/documentation/getting_started/content/02-installing.md +0 -81
  384. solara/website/pages/documentation/getting_started/content/04-tutorials/00-overview.md +0 -9
  385. solara/website/pages/documentation/getting_started/content/04-tutorials/10_data_science.py +0 -13
  386. solara/website/pages/documentation/getting_started/content/04-tutorials/20-web-app.md +0 -84
  387. solara/website/pages/documentation/getting_started/content/04-tutorials/30-ipywidgets.md +0 -120
  388. solara/website/pages/documentation/getting_started/content/04-tutorials/40-streamlit.md +0 -141
  389. solara/website/pages/documentation/getting_started/content/04-tutorials/50-dash.md +0 -140
  390. solara/website/pages/documentation/getting_started/content/04-tutorials/60-jupyter-dashboard-part1.py +0 -64
  391. solara/website/pages/documentation/getting_started/content/04-tutorials/SF_crime_sample.csv.gz +0 -0
  392. solara/website/pages/documentation/getting_started/content/04-tutorials/_data_science.ipynb +0 -445
  393. solara/website/pages/documentation/getting_started/content/04-tutorials/_jupyter_dashboard_1.ipynb +0 -1000
  394. solara/website/pages/documentation/getting_started/content/05-fundamentals/00-overview.md +0 -7
  395. solara/website/pages/documentation/getting_started/content/05-fundamentals/10-components.md +0 -218
  396. solara/website/pages/documentation/getting_started/content/05-fundamentals/50-state-management.md +0 -83
  397. solara/website/pages/documentation/getting_started/content/06-reference/00-overview.md +0 -3
  398. solara/website/pages/documentation/getting_started/content/06-reference/40-static_files.md +0 -27
  399. solara/website/pages/documentation/getting_started/content/06-reference/41-asset-files.md +0 -32
  400. solara/website/pages/documentation/getting_started/content/06-reference/60-static-site-generation.md +0 -55
  401. solara/website/pages/documentation/getting_started/content/06-reference/70-search.md +0 -30
  402. solara/website/pages/documentation/getting_started/content/06-reference/80-reloading.md +0 -30
  403. solara/website/pages/documentation/getting_started/content/06-reference/90-notebook-support.md +0 -4
  404. solara/website/pages/documentation/getting_started/content/06-reference/95-caching.md +0 -143
  405. solara/website/pages/documentation/getting_started/content/07-deploying/00-overview.md +0 -3
  406. solara/website/pages/documentation/getting_started/content/07-deploying/10-self-hosted.md +0 -269
  407. solara/website/pages/documentation/getting_started/content/07-deploying/20-cloud-hosted.md +0 -76
  408. solara/website/pages/documentation/getting_started/content/08-lab/00-what-is-lab.md +0 -3
  409. solara/website/pages/documentation/getting_started/content/90-troubleshoot.md +0 -22
  410. solara/website/pages/documentation/getting_started/content/__init__.py +0 -0
  411. solara/website/pages/docutils.py +0 -38
  412. solara/website/pages/showcase/__init__.py +0 -105
  413. solara/website/pages/showcase/domino_code_assist.py +0 -60
  414. solara/website/pages/showcase/planeto_tessa.py +0 -19
  415. solara/website/pages/showcase/solara_dev.py +0 -54
  416. solara/website/pages/showcase/solarathon_2023_team_2.py +0 -22
  417. solara/website/pages/showcase/solarathon_2023_team_4.py +0 -22
  418. solara/website/pages/showcase/solarathon_2023_team_5.py +0 -23
  419. solara/website/pages/showcase/solarathon_2023_team_6.py +0 -34
  420. solara/website/pages/showcase/wanderlust.py +0 -27
  421. solara/website/public/beach.jpeg +0 -0
  422. solara/website/public/logo.svg +0 -6
  423. solara/website/public/social/discord.svg +0 -1
  424. solara/website/public/social/github.svg +0 -1
  425. solara/website/public/social/twitter.svg +0 -3
  426. solara/website/public/success.html +0 -25
  427. solara/website/templates/index.html.j2 +0 -117
  428. solara/website/utils.py +0 -51
  429. solara/widgets/__init__.py +0 -1
  430. solara/widgets/vue/gridlayout.vue +0 -110
  431. solara/widgets/vue/html.vue +0 -4
  432. solara/widgets/vue/navigator.vue +0 -104
  433. solara/widgets/vue/vegalite.vue +0 -115
  434. solara/widgets/widgets.py +0 -65
  435. solara-1.30.0.data/data/etc/jupyter/jupyter_notebook_config.d/solara.json +0 -7
  436. solara-1.30.0.data/data/etc/jupyter/jupyter_server_config.d/solara.json +0 -7
  437. solara-1.30.0.dist-info/RECORD +0 -438
  438. solara-1.30.0.dist-info/entry_points.txt +0 -5
  439. /solara-1.30.0.dist-info/licenses/LICENSE → /LICENSE +0 -0
solara/alias.py DELETED
@@ -1,6 +0,0 @@
1
- import reacton # noqa: F401
2
- from reacton import ipyvue as rvue # noqa: F401
3
- from reacton import ipyvuetify as rv # noqa: F401
4
- from reacton import ipywidgets as rw # noqa: F401
5
-
6
- import solara as sol # noqa: F401
solara/autorouting.py DELETED
@@ -1,554 +0,0 @@
1
- import dataclasses
2
- import difflib
3
- import importlib
4
- import inspect
5
- import pkgutil
6
- import re
7
- import warnings
8
- from pathlib import Path
9
- from types import ModuleType
10
- from typing import Any, Callable, Dict, List, Optional, cast
11
-
12
- import ipywidgets
13
- import reacton
14
- import reacton.core
15
-
16
- import solara
17
- import solara.checks
18
- from solara.alias import rv
19
- from solara.util import cwd, nested_get
20
-
21
- autoroute_level_context = solara.create_context(0)
22
- DEBUG = False
23
-
24
- solara_root = Path(solara.__file__).parent
25
-
26
- DefaultLayout = solara.AppLayout
27
-
28
-
29
- def source_to_module(path: Path, initial_namespace={}) -> ModuleType:
30
- fullname = path.stem
31
- mod = ModuleType(fullname)
32
- mod.__file__ = str(path)
33
- mod.__dict__.update(initial_namespace)
34
- if path.suffix == ".py":
35
- with open(path, encoding="utf8") as f:
36
- ast = compile(f.read(), path, "exec")
37
- exec(ast, mod.__dict__)
38
- elif path.suffix == ".ipynb":
39
- import nbformat
40
-
41
- nb: nbformat.NotebookNode = nbformat.read(path, 4)
42
- with cwd(Path(path).parent):
43
- for cell_index, cell in enumerate(nb.cells):
44
- cell_index += 1 # used 1 based
45
- if cell.cell_type == "code":
46
- source = cell.source
47
- cell_path = f"{path} input cell {cell_index}"
48
- ast = compile(source, cell_path, "exec")
49
- exec(ast, mod.__dict__)
50
- else:
51
- raise TypeError(f"Only .py and .ipynb supported (not {path})")
52
- return mod
53
-
54
-
55
- def count_arguments(f: Callable):
56
- if isinstance(f, reacton.core.ComponentFunction):
57
- f = f.f
58
- sig = inspect.signature(f)
59
- return len([k for name, k in sig.parameters.items() if (k.default == k.empty) and (k.kind != k.VAR_POSITIONAL) and (k.kind != k.VAR_KEYWORD)])
60
-
61
-
62
- def arg_cast(args: List[str], f: Callable):
63
- if isinstance(f, reacton.core.ComponentFunction):
64
- f = f.f
65
- sig = inspect.signature(f)
66
- results = []
67
- for i, (name, param) in enumerate(sig.parameters.items()):
68
- if i >= len(args):
69
- break
70
- # TODO: can we give a better error message?
71
- # raise TypeError(f"{f} expected positional argument {param}, but not enough argument supplied")
72
- annotation = param.annotation
73
- value = args[i]
74
- check_optional_types = [str, int, float]
75
- for check_type in check_optional_types:
76
- if annotation == Optional[check_type]:
77
- annotation = check_type
78
- if annotation == param.empty:
79
- results.append(value)
80
- else:
81
- try:
82
- results.append(annotation(value))
83
- except Exception as e:
84
- raise ValueError(f"Cannot cast argument {name} of {f} to type {annotation} with value {value}") from e
85
- return results
86
-
87
-
88
- @solara.component
89
- def RoutingProvider(children: List[reacton.core.Element] = [], routes: List[solara.Route] = [], pathname: str = ""):
90
- """Wraps the app, adds extra context, like navigation/routing."""
91
- path, set_path = solara.use_state(pathname, key="solara-context-path")
92
- # TODO: since we provide a cross filter context here, I don't think name `RoutingProvider` is a good name
93
- # we might want to change/refactor this.
94
- solara.provide_cross_filter()
95
- nav = solara.Navigator(location=path, on_location=set_path)
96
- solara.routing._location_context.provide(solara.routing._Location(path, set_path))
97
- solara.routing.router_context.provide(solara.routing.Router(path, routes=routes, set_path=set_path))
98
-
99
- def get_nav_widget():
100
- # not sure why get_widget(nav) does not work
101
- nav_widget.current = solara.get_widget(main).children[0] # type: ignore
102
-
103
- import solara.widgets as w
104
-
105
- nav_widget = solara.use_ref(cast(Optional[w.Navigator], None))
106
- if nav_widget.current:
107
- nav_widget.current.location = path
108
- solara.use_effect(get_nav_widget)
109
-
110
- if solara.checks.should_perform_solara_check():
111
- children = [solara.checks.SolaraCheck(), *children]
112
-
113
- main = solara.VBox(
114
- children=[
115
- nav,
116
- *children,
117
- ]
118
- )
119
-
120
- return main
121
-
122
-
123
- @solara.component
124
- def RenderPage(main_name: str = "Page"):
125
- """Renders the page that matches the route."""
126
- router = solara.use_context(solara.routing.router_context)
127
- # we use these to cache script runs that use regular ipywidgets
128
- modules = cast(Dict[str, ModuleType], solara.use_memo(dict, dependencies=[]))
129
- modules_modified_times = cast(Dict[str, float], solara.use_memo(dict, dependencies=[]))
130
-
131
- if not router.path_routes:
132
- with solara.VBox() as main:
133
- solara.Error(f"Page not found: {router.path}")
134
- parent = "/" + "/".join(router.parts[:-1])
135
- with solara.Link(parent):
136
- solara.Button(f"Go to parent: {parent}", text=True)
137
- if DEBUG:
138
- from reacton.core import pp
139
-
140
- from solara.components.captureoutput import CaptureOutput
141
-
142
- with CaptureOutput():
143
- pp(router.routes)
144
- return main
145
-
146
- layouts = [] # nested layouts
147
- level_max = len(router.path_routes) - 1
148
- for level in range(level_max + 1):
149
- # we always level_start the 'package'/'root' layout
150
- roots = [k for k in router.path_routes_siblings[level] if k.path == "/"]
151
- if len(roots) == 1:
152
- root = roots[0]
153
- if root.layout:
154
- layouts.append(root.layout)
155
- route = router.path_routes[level]
156
- # and, if not the root layout, include the layout for the current route
157
- if route.path != "/" and route.layout:
158
- layouts.append(route.layout)
159
- # used in for example the docs for use_route, only the route path are specified,
160
- # nothing else, which means we will not follow that route path, but limit it to rendering
161
- # router.path_routes[level_max] instead. It's assumed that component (Page) will continue
162
- # handling the rest of the routing
163
- if route.data is None and route.module is None and route.component is None:
164
- level_max = level - 1
165
- route_current = router.path_routes[level_max]
166
- routes_siblings = router.path_routes_siblings[level_max]
167
- routes_siblings_index = routes_siblings.index(route_current)
168
- # if no layouts are found, we use the default layout
169
- if layouts == []:
170
- layouts = [DefaultLayout]
171
- if route_current.data is None and route_current.module is None and route_current.component is None:
172
- return solara.Error(f"Page not found: {router.path}, route does not link to a path or module or component")
173
-
174
- def wrap_in_layouts(element: reacton.core.Element, layouts):
175
- for Layout in reversed(layouts):
176
- element = Layout(children=[element])
177
- return element
178
-
179
- def get_args(f):
180
- if len(router.path_routes) < len(router.parts):
181
- arg_strings = router.parts[len(router.path_routes) :]
182
- args = arg_cast(arg_strings, f)
183
- return args
184
- else:
185
- return []
186
-
187
- if isinstance(route_current.data, Path):
188
- path = cast(Path, route_current.data)
189
- if path.suffix == ".md":
190
- with solara.HBox() as navigation:
191
- if routes_siblings_index > 0:
192
- prev = routes_siblings[routes_siblings_index - 1]
193
- with solara.Link(prev):
194
- solara.Button(f"{prev.label}", text=True, icon_name="mdi-arrow-left")
195
- rv.Spacer()
196
- if routes_siblings_index < len(routes_siblings) - 1:
197
- next = routes_siblings[routes_siblings_index + 1]
198
- with solara.Link(next):
199
- solara.Button(f"{next.label}", text=True, icon_name="mdi-arrow-right")
200
- is_relative = str(path.resolve()).startswith(str(solara_root.resolve()))
201
- if is_relative:
202
- # this is now hardcoded to solara only
203
- url = solara.util.github_edit_url(path)
204
- with solara.Div(style={"position": "relative"}) as content:
205
- with solara.Tooltip("Edit on GitHub"):
206
- solara.Button(
207
- icon_name="mdi-pencil", icon=True, href=url, target="_blank", style={"position": "absolute", "top": "0px", "right": "0px"}
208
- )
209
- solara.Markdown(path.read_text(), unsafe_solara_execute=True)
210
- else:
211
- content = solara.Markdown(path.read_text(), unsafe_solara_execute=True)
212
-
213
- main = solara.Div(
214
- classes=["solara-autorouter-content"],
215
- children=[
216
- solara.Title(route_current.label or "No title"),
217
- content,
218
- navigation,
219
- ],
220
- )
221
- main = wrap_in_layouts(main, layouts)
222
- else:
223
- main = solara.Error(f"Suffix {path.suffix} not supported")
224
- else:
225
- title = route_current.label or "No title"
226
- title_element = solara.Title(title)
227
- module = None
228
- Page = route_current.component
229
- if route_current.module is not None and (Page is None):
230
- # if not a custom component is given, we try to find a Page component
231
- # in the module
232
- assert route_current.module is not None
233
- module = route_current.module
234
- namespace = module.__dict__
235
- Page = nested_get(namespace, main_name, Page)
236
- if Page is None:
237
- # app is for backwards compatibility
238
- Page = namespace.get("page", namespace.get("app", Page))
239
- Page = nested_get(namespace, main_name, Page)
240
-
241
- if isinstance(Page, ipywidgets.Widget):
242
- # If we have a widget, we need to execute this again for each
243
- # connection, since we cannot share widgets between connections/users.
244
- # We also cannot tear them down, so we cache the widget based pages.
245
- # To support hot reload, we manually need to check the mtimes
246
- # because the reload support for modules in reloader.py only works
247
- # for modules.
248
- if route_current.file is None:
249
- page = solara.Error(f"{route_current.path} is not associated with a file")
250
- else:
251
- assert route_current.file is not None
252
- if route_current.path not in modules:
253
- modules[route_current.path] = source_to_module(route_current.file)
254
- modules_modified_times[route_current.path] = route_current.file.stat().st_mtime
255
- else:
256
- if modules_modified_times[route_current.path] != route_current.file.stat().st_mtime:
257
- # out of date, 'reload'
258
- modules[route_current.path] = source_to_module(route_current.file)
259
- modules_modified_times[route_current.path] = route_current.file.stat().st_mtime
260
- Page = nested_get(modules[route_current.path], main_name, None)
261
- if Page is None:
262
- Page = getattr(modules[route_current.path], "app", None)
263
- Page = getattr(modules[route_current.path], "page", Page)
264
- main = solara.Div(
265
- classes=["solara-autorouter-content"],
266
- children=[
267
- title_element,
268
- Page,
269
- ],
270
- )
271
- main = wrap_in_layouts(main, layouts)
272
- elif Page is not None:
273
- if isinstance(Page, reacton.core.ComponentFunction):
274
- args = get_args(Page)
275
- page = Page(*args)
276
- elif isinstance(Page, solara.Element):
277
- page = Page
278
- else:
279
- page = solara.Error(f"{Page} is not a component or element, but {type(Page)}")
280
- main = solara.Div(
281
- classes=["solara-autorouter-content"],
282
- children=[
283
- title_element,
284
- page,
285
- ],
286
- )
287
- main = wrap_in_layouts(main, layouts)
288
- else:
289
- if route_current.module:
290
- path_str = route_current.module.__file__
291
- local_scope = route_current.module.__dict__
292
- ignore = ["display"]
293
- options = [k for k in list(local_scope) if k not in ignore and not k.startswith("_")]
294
- matches = difflib.get_close_matches(main_name, options)
295
- msg = f"No object with name {main_name} found for {path_str}"
296
- if matches:
297
- msg += " Did you mean: " + " or ".join(map(repr, matches))
298
- else:
299
- msg += " We did find: " + " or ".join(map(repr, options))
300
- else:
301
- msg = f"{module} does not have a Page component or an app element"
302
-
303
- with DefaultLayout() as main:
304
- solara.Error(msg)
305
- return main
306
-
307
-
308
- def get_page(module: ModuleType, required=True):
309
- page = getattr(module, "Page", None)
310
- if required and page is None:
311
- raise NameError(f"No component names 'Page' in module {module}")
312
- return page
313
-
314
-
315
- def get_renderable(module: ModuleType, required=False):
316
- var_names = "app Page page".split()
317
- for var_name in var_names:
318
- if not hasattr(module, var_name):
319
- continue
320
- entry = getattr(module, var_name)
321
- return entry
322
- if required:
323
- raise NameError(f"No component, element or widget found in module {module} with names: {', '.join(var_names[:-1])} or {var_names[-1]}")
324
-
325
-
326
- def get_title(module: ModuleType, required=True):
327
- assert module.__file__ is not None
328
- name = Path(module.__file__).stem
329
- if module.__file__.endswith("__init__.py"):
330
- name = Path(module.__file__).parent.stem
331
- # if title is a submodule it may shadown the variable in __init__
332
- # in this case, _title is an escape hatch
333
- if hasattr(module, "_title") and isinstance(module._title, str):
334
- title = module._title
335
- elif hasattr(module, "title") and isinstance(module.title, str):
336
- title = module.title
337
- else:
338
- match = re.match("([0-9\\-_ ]*)(.*)", name)
339
- if match:
340
- _prefix, name = match.groups()
341
- title_parts = re.split("[\\-_ ]+", name)
342
- title = " ".join(k.title() for k in title_parts)
343
- return title
344
-
345
-
346
- def fix_route(route: solara.Route, new_file: Path, new_layout=None) -> solara.Route:
347
- file = route.file or new_file
348
- layout = route.layout or new_layout
349
- children = fix_routes(route.children, new_file) if route.children else []
350
-
351
- return dataclasses.replace(route, file=file, children=children, layout=layout)
352
-
353
-
354
- def fix_routes(routes: List[solara.Route], new_file: Path, new_layout=None):
355
- new_routes = []
356
- for route in routes:
357
- if route.path == "/":
358
- route = fix_route(route, new_file, new_layout)
359
- else:
360
- route = fix_route(route, new_file)
361
- new_routes.append(route)
362
- return new_routes
363
-
364
-
365
- def generate_routes(module: ModuleType) -> List[solara.Route]:
366
- """Generate routes from a module.
367
-
368
- This is a recursive function that will generate routes for all submodules.
369
-
370
- Note this only support .py files, since Markdown files and Jupyter notebook
371
- files are not Python modules.
372
-
373
-
374
- See [our multipage guide](/documentation/advanced/howto/multipage#as-a-package) for more details.
375
-
376
-
377
- """
378
- from .server import reload
379
-
380
- assert module.__file__ is not None
381
- routes = []
382
- children: List[solara.Route]
383
- file = Path(module.__file__)
384
-
385
- if module.__file__.endswith("__init__.py"):
386
- if hasattr(module, "routes"):
387
- # if routes if provided, use them instead of us generating them
388
- children = getattr(module, "routes")
389
- children = fix_routes(children, file)
390
- return children
391
- route_order = getattr(module, "route_order", None)
392
- layout = getattr(module, "Layout", None)
393
- title = get_title(module)
394
- children = getattr(module, "routes", [])
395
- if hasattr(module, "Page"):
396
- routes.append(
397
- solara.Route(path="/", component=get_page(module), data=module, module=module, layout=layout, children=children, label=title, file=file)
398
- )
399
-
400
- assert module.__file__ is not None
401
- reload.reloader.watcher.add_file(module.__file__)
402
- for info in pkgutil.iter_modules([str(Path(module.__file__).parent)]):
403
- submod = importlib.import_module(module.__name__ + f".{info.name}")
404
- subfile = Path(submod.__file__) if submod.__file__ is not None else None
405
- title = get_title(submod)
406
-
407
- name = info.name
408
- # ideally, we do this similar to generate_routes_directory
409
- # however, this may break things.
410
- # name = name.replace("_", "-")
411
- if info.ispkg:
412
- route = solara.Route(
413
- name, component=get_page(submod, required=False), children=generate_routes(submod), module=submod, layout=None, label=title
414
- )
415
- # skip empty subpackages
416
- if len(route.children) == 0:
417
- continue
418
- else:
419
- # skip empty modules
420
- if get_renderable(submod) is None and not hasattr(submod, "routes"):
421
- continue
422
- children = getattr(submod, "routes", [])
423
- if subfile:
424
- children = fix_routes(children, subfile)
425
- module_layout = getattr(submod, "Layout", None)
426
- route = solara.Route(
427
- name, component=get_page(submod, required=False), module=submod, layout=module_layout, children=children, label=title, file=subfile
428
- )
429
- routes.append(route)
430
- if route_order:
431
- lookup = {k.path: k for k in routes}
432
- for k in route_order:
433
- if k not in lookup:
434
- raise KeyError(f"Route {k!r} listen in route_order not found in {module}")
435
- routes = [lookup[k] for k in route_order]
436
- if set(lookup) - set(route_order):
437
- warnings.warn(f"Some routes are not in route_order: {set(lookup) - set(route_order)}")
438
-
439
- else:
440
- layout = getattr(module, "Layout", None)
441
- children = []
442
- if hasattr(module, "routes"):
443
- children = getattr(module, "routes", [])
444
- root = get_root(children)
445
- if layout is not None and root is not None and root.layout is None:
446
- warnings.warn(f'You defined routes in {file}, in this case, layout should be set on the root route (with path="/"), not on the module level')
447
- layout = None
448
- children = fix_routes(children, file, layout)
449
- return [
450
- solara.Route(
451
- path="/",
452
- component=get_page(module, required=False),
453
- data=None,
454
- module=module,
455
- label=get_title(module),
456
- layout=layout,
457
- children=children,
458
- file=file,
459
- )
460
- ]
461
-
462
- return routes
463
-
464
-
465
- def generate_routes_directory(path: Path) -> List[solara.Route]:
466
- """Generate routes for a directory.
467
-
468
- This is a recursive function that will generate routes for all
469
- subdirectories and files in the directory. It will skip any
470
- files or directories that start with an underscore or a dot.
471
-
472
- Markdown files ending in .md will be rendered as markdown.
473
-
474
- Python files ending in .py, or Jupyter notebooks ending in .ipynb
475
- will be executed and its `Page` component will be rendered.
476
-
477
- Automatic titles will be [generated as explained in the multipage guide](/documentation/advanced/howto/multipage).
478
-
479
- """
480
-
481
- subpaths = list(sorted(path.iterdir()))
482
- routes = []
483
- first = True
484
- has_index = len([k for k in subpaths if k.name == "__init__"]) > 0
485
- init = path / "__init__.py"
486
- layout = None
487
- if init.exists():
488
- init_module = source_to_module(init)
489
- layout = getattr(init_module, "Layout", None)
490
-
491
- suffixes = [".py", ".ipynb", ".md"]
492
- for subpath in subpaths:
493
- # only handle directories and recognized file types
494
- if not (subpath.is_dir() or subpath.suffix in suffixes):
495
- continue
496
- if subpath.stem.startswith("_") or subpath.stem.startswith("."):
497
- continue
498
- route = _generate_route_path(subpath, layout=layout, first=first, has_index=has_index)
499
- first = False
500
- routes.append(route)
501
- return routes
502
-
503
-
504
- def _generate_route_path(subpath: Path, layout=None, first=False, has_index=False, initial_namespace={}) -> solara.Route:
505
- from .server import reload
506
-
507
- name = subpath.stem
508
- match = re.match("([0-9\\-_ ]*)(.*)", name)
509
- if match:
510
- _prefix, name = match.groups()
511
- title_parts = re.split("[\\-_ ]+", name)
512
- title = " ".join(k.title() for k in title_parts)
513
- if not has_index and first:
514
- route_path = "/"
515
- else:
516
- route_path = "-".join([k.lower() for k in title_parts])
517
- component = None
518
- children: List[solara.Route] = []
519
- module: Optional[ModuleType] = None
520
- data: Any = None
521
- module_layout = layout if first else None
522
- if subpath.suffix == ".md":
523
- data = subpath
524
- reload.reloader.watcher.add_file(subpath)
525
- elif subpath.is_dir():
526
- children = generate_routes_directory(subpath)
527
- else:
528
- reload.reloader.watcher.add_file(subpath)
529
- module = source_to_module(subpath, initial_namespace=initial_namespace)
530
- title = get_title(module)
531
- layout = getattr(module, "Layout", module_layout)
532
- root = get_root(children)
533
- if hasattr(module, "routes"):
534
- children = getattr(module, "routes", [])
535
- root = get_root(children)
536
- if layout is not None and root is not None and root.layout is None:
537
- warnings.warn(f'You defined routes in {subpath}, in this case, layout should be set on the root route (with path="/"), not on the module level')
538
- layout = None
539
- children = fix_routes(children, subpath, layout)
540
- component = get_page(module, required=False)
541
- if root and component and root.component and component is not root.component:
542
- warnings.warn(
543
- f"In {subpath}, you defined a Page component, but also a component on the root route (with path='/') "
544
- "which is not equal to the Page component at the module level. This is not recommended."
545
- )
546
- route = solara.Route(route_path, component=component, module=module, label=title, children=children, data=data, layout=layout, file=subpath)
547
- return route
548
-
549
-
550
- def get_root(routes: List[solara.Route]) -> Optional[solara.Route]:
551
- for route in routes:
552
- if route.path == "/":
553
- return route
554
- return None