solara 1.30.1__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 (438) hide show
  1. {solara-1.30.1.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.1.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 -545
  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 -110
  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 -88
  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 -396
  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/markdown.py +0 -30
  187. solara/website/components/notebook.py +0 -172
  188. solara/website/pages/__init__.py +0 -575
  189. solara/website/pages/apps/__init__.py +0 -16
  190. solara/website/pages/apps/authorization/__init__.py +0 -118
  191. solara/website/pages/apps/authorization/admin.py +0 -12
  192. solara/website/pages/apps/authorization/users.py +0 -12
  193. solara/website/pages/apps/jupyter-dashboard-1.py +0 -116
  194. solara/website/pages/apps/layout-demo.py +0 -40
  195. solara/website/pages/apps/multipage/__init__.py +0 -38
  196. solara/website/pages/apps/multipage/page1.py +0 -26
  197. solara/website/pages/apps/multipage/page2.py +0 -34
  198. solara/website/pages/apps/scatter.py +0 -136
  199. solara/website/pages/apps/scrolling.py +0 -63
  200. solara/website/pages/apps/tutorial-streamlit.py +0 -18
  201. solara/website/pages/changelog/__init__.py +0 -8
  202. solara/website/pages/changelog/changelog.md +0 -195
  203. solara/website/pages/contact/__init__.py +0 -8
  204. solara/website/pages/contact/contact.md +0 -17
  205. solara/website/pages/doc_use_download.py +0 -85
  206. solara/website/pages/documentation/__init__.py +0 -184
  207. solara/website/pages/documentation/advanced/__init__.py +0 -9
  208. solara/website/pages/documentation/advanced/content/00-overview.md +0 -1
  209. solara/website/pages/documentation/advanced/content/10-howto/00-overview.md +0 -6
  210. solara/website/pages/documentation/advanced/content/10-howto/10-multipage.md +0 -196
  211. solara/website/pages/documentation/advanced/content/10-howto/20-layout.md +0 -125
  212. solara/website/pages/documentation/advanced/content/10-howto/30-testing.md +0 -154
  213. solara/website/pages/documentation/advanced/content/10-howto/31-debugging.md +0 -69
  214. solara/website/pages/documentation/advanced/content/10-howto/40-embed.md +0 -49
  215. solara/website/pages/documentation/advanced/content/10-howto/50-ipywidget_libraries.md +0 -124
  216. solara/website/pages/documentation/advanced/content/20-understanding/00-introduction.md +0 -10
  217. solara/website/pages/documentation/advanced/content/20-understanding/05-ipywidgets.md +0 -35
  218. solara/website/pages/documentation/advanced/content/20-understanding/06-ipyvuetify.md +0 -42
  219. solara/website/pages/documentation/advanced/content/20-understanding/10-reacton.md +0 -28
  220. solara/website/pages/documentation/advanced/content/20-understanding/12-reacton-basics.md +0 -108
  221. solara/website/pages/documentation/advanced/content/20-understanding/15-anatomy.md +0 -23
  222. solara/website/pages/documentation/advanced/content/20-understanding/17-rules-of-hooks.md +0 -7
  223. solara/website/pages/documentation/advanced/content/20-understanding/18-containers.md +0 -166
  224. solara/website/pages/documentation/advanced/content/20-understanding/20-solara.md +0 -18
  225. solara/website/pages/documentation/advanced/content/20-understanding/40-routing.md +0 -240
  226. solara/website/pages/documentation/advanced/content/20-understanding/50-solara-server.md +0 -86
  227. solara/website/pages/documentation/advanced/content/20-understanding/60-voila.md +0 -12
  228. solara/website/pages/documentation/advanced/content/30-enterprise/00-overview.md +0 -1
  229. solara/website/pages/documentation/advanced/content/30-enterprise/10-oauth.md +0 -171
  230. solara/website/pages/documentation/advanced/content/40-development/00-overview.md +0 -0
  231. solara/website/pages/documentation/advanced/content/40-development/01-contribute.md +0 -45
  232. solara/website/pages/documentation/advanced/content/40-development/10-setup.md +0 -76
  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 -12
  379. solara/website/pages/documentation/faq/content/99-faq.md +0 -76
  380. solara/website/pages/documentation/getting_started/__init__.py +0 -9
  381. solara/website/pages/documentation/getting_started/content/00-quickstart.md +0 -89
  382. solara/website/pages/documentation/getting_started/content/01-introduction.md +0 -125
  383. solara/website/pages/documentation/getting_started/content/02-installing.md +0 -85
  384. solara/website/pages/documentation/getting_started/content/04-tutorials/00-overview.md +0 -14
  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 -89
  387. solara/website/pages/documentation/getting_started/content/04-tutorials/30-ipywidgets.md +0 -124
  388. solara/website/pages/documentation/getting_started/content/04-tutorials/40-streamlit.md +0 -146
  389. solara/website/pages/documentation/getting_started/content/04-tutorials/50-dash.md +0 -144
  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 -11
  395. solara/website/pages/documentation/getting_started/content/05-fundamentals/10-components.md +0 -223
  396. solara/website/pages/documentation/getting_started/content/05-fundamentals/50-state-management.md +0 -88
  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 -31
  399. solara/website/pages/documentation/getting_started/content/06-reference/41-asset-files.md +0 -36
  400. solara/website/pages/documentation/getting_started/content/06-reference/60-static-site-generation.md +0 -59
  401. solara/website/pages/documentation/getting_started/content/06-reference/70-search.md +0 -34
  402. solara/website/pages/documentation/getting_started/content/06-reference/80-reloading.md +0 -34
  403. solara/website/pages/documentation/getting_started/content/06-reference/90-notebook-support.md +0 -7
  404. solara/website/pages/documentation/getting_started/content/06-reference/95-caching.md +0 -148
  405. solara/website/pages/documentation/getting_started/content/07-deploying/00-overview.md +0 -7
  406. solara/website/pages/documentation/getting_started/content/07-deploying/10-self-hosted.md +0 -273
  407. solara/website/pages/documentation/getting_started/content/07-deploying/20-cloud-hosted.md +0 -80
  408. solara/website/pages/documentation/getting_started/content/80-what-is-lab.md +0 -7
  409. solara/website/pages/documentation/getting_started/content/90-troubleshoot.md +0 -26
  410. solara/website/pages/docutils.py +0 -38
  411. solara/website/pages/showcase/__init__.py +0 -105
  412. solara/website/pages/showcase/domino_code_assist.py +0 -60
  413. solara/website/pages/showcase/planeto_tessa.py +0 -19
  414. solara/website/pages/showcase/solara_dev.py +0 -54
  415. solara/website/pages/showcase/solarathon_2023_team_2.py +0 -22
  416. solara/website/pages/showcase/solarathon_2023_team_4.py +0 -22
  417. solara/website/pages/showcase/solarathon_2023_team_5.py +0 -23
  418. solara/website/pages/showcase/solarathon_2023_team_6.py +0 -34
  419. solara/website/pages/showcase/wanderlust.py +0 -27
  420. solara/website/public/beach.jpeg +0 -0
  421. solara/website/public/logo.svg +0 -6
  422. solara/website/public/social/discord.svg +0 -1
  423. solara/website/public/social/github.svg +0 -1
  424. solara/website/public/social/twitter.svg +0 -3
  425. solara/website/public/success.html +0 -25
  426. solara/website/templates/index.html.j2 +0 -117
  427. solara/website/utils.py +0 -51
  428. solara/widgets/__init__.py +0 -1
  429. solara/widgets/vue/gridlayout.vue +0 -110
  430. solara/widgets/vue/html.vue +0 -4
  431. solara/widgets/vue/navigator.vue +0 -104
  432. solara/widgets/vue/vegalite.vue +0 -115
  433. solara/widgets/widgets.py +0 -65
  434. solara-1.30.1.data/data/etc/jupyter/jupyter_notebook_config.d/solara.json +0 -7
  435. solara-1.30.1.data/data/etc/jupyter/jupyter_server_config.d/solara.json +0 -7
  436. solara-1.30.1.dist-info/RECORD +0 -437
  437. solara-1.30.1.dist-info/entry_points.txt +0 -5
  438. /solara-1.30.1.dist-info/licenses/LICENSE → /LICENSE +0 -0
solara/__main__.py DELETED
@@ -1,734 +0,0 @@
1
- import os
2
- import shutil
3
- import site
4
- import sys
5
- import threading
6
- import time
7
- import typing
8
- import webbrowser
9
- from enum import Enum
10
- from pathlib import Path
11
-
12
- import rich
13
- import rich_click as click
14
- import uvicorn
15
- from rich import print as rprint
16
- from uvicorn.main import LEVEL_CHOICES, LOOP_CHOICES
17
-
18
- import solara
19
- from solara.server import settings
20
-
21
- from .server import telemetry
22
-
23
- try:
24
- from solara_enterprise.ssg import ssg_crawl
25
- except ImportError:
26
-
27
- def ssg_crawl(*args, **kwargs): # type: ignore
28
- raise RuntimeError('SSG not available, please install solara-enterprise (pip install "solara-enterprise[ssg]"')
29
-
30
-
31
- HERE = Path(__file__).parent
32
-
33
- LOGGING_CONFIG: dict = {
34
- "version": 1,
35
- "disable_existing_loggers": False,
36
- "formatters": {
37
- "default": {
38
- "()": "uvicorn.logging.DefaultFormatter",
39
- "fmt": "%(levelprefix)s %(message)s",
40
- "use_colors": None,
41
- },
42
- "access": {
43
- "()": "uvicorn.logging.AccessFormatter",
44
- "fmt": '%(levelprefix)s %(client_addr)s - "%(request_line)s" %(status_code)s', # noqa: E501
45
- },
46
- },
47
- "handlers": {
48
- "default": {
49
- "formatter": "default",
50
- "class": "logging.StreamHandler",
51
- "stream": "ext://sys.stderr",
52
- },
53
- "rich": {
54
- "class": "rich.logging.RichHandler",
55
- },
56
- "access": {
57
- "formatter": "access",
58
- "class": "logging.StreamHandler",
59
- "stream": "ext://sys.stdout",
60
- },
61
- },
62
- "loggers": {
63
- "solara": {"handlers": ["default"], "level": "ERROR"},
64
- "reacton": {"handlers": ["default"], "level": "ERROR"},
65
- # "react": {"handlers": ["rich"], "level": "DEBUG"},
66
- "uvicorn": {"handlers": ["default"], "level": "ERROR"},
67
- "uvicorn.error": {"level": "ERROR"},
68
- "uvicorn.access": {"handlers": ["access"], "level": "ERROR", "propagate": False},
69
- },
70
- }
71
-
72
-
73
- def _check_version():
74
- import requests
75
-
76
- try:
77
- response = requests.get("https://pypi.org/pypi/solara/json")
78
- latest_version = response.json()["info"]["version"]
79
- except: # noqa: E722
80
- return
81
- if latest_version != solara.__version__:
82
- print(f"New version of Solara available: {latest_version}. You have {solara.__version__}. Please upgrade using:") # noqa: T201
83
- print(f'\t$ pip install "solara=={latest_version}"') # noqa: T201
84
-
85
-
86
- def find_all_packages_paths():
87
- paths = []
88
- # sitepackages = set([os.path.dirname(k) for k in site.getsitepackages()])
89
- sitepackages = {k for k in site.getsitepackages()}
90
- paths.extend(list(sitepackages))
91
- for name, module in sys.modules.items():
92
- if hasattr(module, "__path__"):
93
- try:
94
- path = module.__path__[0]
95
- except: # noqa: E722
96
- pass # happens for namespace packages it seems
97
- # print(f"Error for {name}")
98
- # if path:
99
- # skip = False
100
- # for sitepackage in sitepackages:
101
- # if path.startswith(sitepackage):
102
- # skip = True
103
- # if not skip:
104
- # print(name, path, skip)
105
- paths.append(str(path))
106
- # print("PATHS", paths)
107
- return paths
108
-
109
-
110
- class EnumType(click.Choice):
111
- def __init__(self, enum: typing.Type[Enum], case_sensitive=False):
112
- self._enum = enum
113
- super().__init__(choices=[item.name for item in enum], case_sensitive=case_sensitive)
114
-
115
-
116
- @click.group()
117
- def cli():
118
- pass
119
-
120
-
121
- production_default = False
122
- if "SOLARA_MODE" in os.environ:
123
- # settings.main.mode by default is set to production,
124
- # which is a good default for when you embed in a flask
125
- # app for instance, but not for the CLI, which app developers
126
- # usually run.
127
- production_default = settings.main.mode == "production"
128
- # Note that in the CLI we do set this value to "development"
129
- # or "production" based on the --production flag
130
-
131
-
132
- @cli.command()
133
- @click.option("--port", default=int(os.environ.get("PORT", 8765)))
134
- @click.option(
135
- "--host",
136
- default=settings.main.host,
137
- help="Host to listen on. Defaults to the $HOST environment or $SOLARA_HOST when available or localhost when not given.",
138
- )
139
- @click.option("--dev/--no-dev", default=None, help="Deprecated: use --auto-restart/-a", hidden=True)
140
- @click.option("--production", is_flag=True, default=production_default, help="Run in production mode: https://solara.dev/docs/understanding/solara-server")
141
- @click.option("--reload", is_flag=True, default=None, help="Deprecated: use --auto-restart/-a", hidden=True)
142
- @click.option("-a", "--auto-restart", is_flag=True, default=False, help="Enable auto-restarting of server when the solara server code changes.")
143
- @click.option("--tracer/--no-tracer", default=False)
144
- @click.option("--timing/--no-timing", default=False)
145
- @click.option("--open/--no-open", default=True)
146
- @click.option(
147
- "--restart-dir",
148
- "restart_dirs",
149
- multiple=True,
150
- help="Set restart directories explicitly, instead of using the current working" " directory.",
151
- type=click.Path(exists=True),
152
- )
153
- @click.option(
154
- "--restart-exclude",
155
- "restart_excludes",
156
- multiple=True,
157
- help="Set glob patterns to exclude while watching for files. Includes "
158
- "'.*, .py[cod], .sw.*, ~*' by default; these defaults can be overridden "
159
- "with `--restart-include`. This option has no effect unless watchgod is "
160
- "installed.",
161
- )
162
- @click.option(
163
- "--workers",
164
- default=None,
165
- type=int,
166
- help="Number of worker processes. Defaults to the $WEB_CONCURRENCY environment" " variable if available, or 1. Not valid with --auto-restart/-a.",
167
- )
168
- @click.option(
169
- "--env-file",
170
- type=click.Path(exists=True),
171
- default=None,
172
- help="Environment configuration file.",
173
- show_default=True,
174
- )
175
- @click.option(
176
- "--log-config",
177
- type=click.Path(exists=True),
178
- default=None,
179
- help="Logging configuration file. Supported formats: .ini, .json, .yaml.",
180
- show_default=True,
181
- )
182
- @click.option(
183
- "--log-level",
184
- type=LEVEL_CHOICES,
185
- default=None,
186
- help="Log level. [default: info]",
187
- show_default=True,
188
- )
189
- @click.option(
190
- "--log-level-uvicorn",
191
- type=LEVEL_CHOICES,
192
- default="error",
193
- help="Log level. [default: error]",
194
- show_default=True,
195
- )
196
- @click.option(
197
- "--access-log/--no-access-log",
198
- is_flag=True,
199
- default=True,
200
- help="Enable/Disable access log.",
201
- )
202
- @click.option(
203
- "--root-path",
204
- type=str,
205
- default="",
206
- help="Set the ASGI 'root_path' for applications submounted below a given URL path.",
207
- )
208
- @click.option(
209
- "--theme-loader",
210
- type=str,
211
- default=settings.theme.loader,
212
- help=f"Loader to use when the app is not yet shown to the user. [default: {settings.theme.loader!r}]",
213
- )
214
- @click.option(
215
- "--theme-variant",
216
- type=settings.ThemeVariant,
217
- default=settings.theme.variant.name,
218
- help=f"Use light or dark variant, or auto detect (auto). [default: {settings.theme.variant.name}",
219
- )
220
- @click.option(
221
- "--dark",
222
- type=bool,
223
- default=settings.theme.variant == settings.ThemeVariant.dark,
224
- help="Use dark theme. Shorthand for --theme-variant=dark",
225
- )
226
- @click.option(
227
- "--theme-variant-user-selectable/--no-theme-variant-user-selectable",
228
- type=bool,
229
- hidden=True,
230
- help="Deprecated.",
231
- )
232
- @click.option("--pdb/--no-pdb", "use_pdb", default=False, help="Enter debugger on error")
233
- @click.argument("app")
234
- @click.option(
235
- "--loop",
236
- type=LOOP_CHOICES,
237
- default="auto",
238
- help="Event loop implementation.",
239
- show_default=True,
240
- )
241
- @click.option(
242
- "--ssg/--no-ssg",
243
- is_flag=True,
244
- default=settings.ssg.enabled,
245
- help="(pre) Render static pages.",
246
- )
247
- @click.option(
248
- "--search/--no-search",
249
- is_flag=True,
250
- default=settings.search.enabled,
251
- help="Enable search (requires ssg generated pages).",
252
- )
253
- @click.option(
254
- "--check-version/--no-check-version",
255
- is_flag=True,
256
- default=True,
257
- help="Check installed version again pypi version.",
258
- )
259
- def run(
260
- app,
261
- host,
262
- port,
263
- open,
264
- auto_restart: bool,
265
- reload: bool,
266
- restart_dirs: typing.Optional[typing.List[str]],
267
- restart_excludes: typing.List[str],
268
- dev: bool,
269
- production: bool,
270
- tracer: bool,
271
- timing: bool,
272
- loop: str,
273
- workers: int,
274
- env_file: str,
275
- root_path: str,
276
- log_config: str,
277
- log_level: str,
278
- log_level_uvicorn: str,
279
- access_log: bool,
280
- use_pdb: bool,
281
- theme_loader: str,
282
- theme_variant: settings.ThemeVariant,
283
- dark: bool,
284
- theme_variant_user_selectable: bool,
285
- ssg: bool,
286
- search: bool,
287
- check_version: bool = True,
288
- ):
289
- """Run a Solara app."""
290
- if dev is not None:
291
- print("solara: --dev is deprecated, use --auto-restart/-a instead", file=sys.stderr) # noqa: T201
292
- auto_restart = dev
293
- if reload is not None:
294
- print("solara: --reload is deprecated, use --auto-restart/-a instead", file=sys.stderr) # noqa: T201
295
- auto_restart = reload
296
- if check_version:
297
- _check_version()
298
-
299
- # uvicorn calls it reload, we call it auto restart
300
- reload = auto_restart
301
- del auto_restart
302
- settings.ssg.enabled = ssg
303
- settings.search.enabled = search
304
- reload_dirs = restart_dirs if restart_dirs else None
305
- del restart_dirs
306
- url = f"http://{host}:{port}"
307
-
308
- failed = False
309
- if reload:
310
- telemetry._auto_restart_enabled = True
311
- solara_root = Path(solara.__file__).parent
312
-
313
- reload_dirs = list(reload_dirs if reload_dirs else [])
314
-
315
- # we restart the server when solara or react changes, in principle we should do
316
- # that for all dependencies of the server, but these are changing most often
317
- # during development
318
- # We exclude the website, that will be handled by solara/server/reload.py
319
- reload_dirs = [str(solara_root), str(Path(solara.__file__).parent)]
320
- try:
321
- import solara_enterprise
322
-
323
- reload_dirs.append(str(Path(solara_enterprise.__file__).parent))
324
- del solara_enterprise
325
- except ImportError:
326
- pass
327
- reload_excludes = restart_excludes if restart_excludes else []
328
- del restart_excludes
329
- reload_excludes = [str(solara_root / "website"), str(solara_root / "template")]
330
- reload_excludes.append(app)
331
- del solara_root
332
- reload = True
333
- # avoid sending many restarts
334
- settings.telemetry.mixpanel_enable = False
335
- else:
336
- del restart_excludes
337
-
338
- if production:
339
- settings.main.mode = "production"
340
- else:
341
- settings.main.mode = "development"
342
- server = None
343
-
344
- # TODO: we might want to support this, but it needs to be started from the main thread
345
- # and then uvicorn needs to be started from a thread
346
- # def open_webview():
347
- # import webview
348
-
349
- # while not failed and (server is None or not server.started):
350
- # time.sleep(0.1)
351
- # if not failed:
352
- # window = webview.create_window("Hello world", url, resizable=True)
353
- # window.on_top = True
354
- # # window.show()
355
- # webview.start(debug=True)
356
-
357
- def open_browser():
358
- while not failed and (server is None or not server.started):
359
- time.sleep(0.1)
360
- if not failed:
361
- webbrowser.open(url)
362
-
363
- if open:
364
- threading.Thread(target=open_browser, daemon=True).start()
365
-
366
- rich.print(f"Solara server is starting at {url}")
367
-
368
- if log_level is not None:
369
- LOGGING_CONFIG["loggers"]["solara"]["level"] = log_level.upper()
370
- # LOGGING_CONFIG["loggers"]["reacton"]["level"] = log_level.upper()
371
-
372
- log_level = log_level_uvicorn
373
- del log_level_uvicorn
374
-
375
- kwargs = locals().copy()
376
- # cgi vars: https://datatracker.ietf.org/doc/html/rfc3875
377
- os.environ["SOLARA_APP"] = app
378
- os.environ["SERVER_NAME"] = host
379
- os.environ["SERVER_PORT"] = str(port)
380
-
381
- kwargs["app"] = "solara.server.starlette:app"
382
- kwargs["log_config"] = LOGGING_CONFIG if log_config is None else log_config
383
- kwargs["loop"] = loop
384
- settings.main.use_pdb = use_pdb
385
- settings.theme.loader = theme_loader
386
- if dark:
387
- theme_variant = settings.ThemeVariant.dark
388
- settings.theme.variant = theme_variant
389
- settings.main.tracer = tracer
390
- settings.main.timing = timing
391
- items = (
392
- "theme_variant_user_selectable dark theme_variant theme_loader use_pdb server open_browser open url failed dev tracer"
393
- " timing ssg search check_version production".split()
394
- )
395
- for item in items:
396
- del kwargs[item]
397
-
398
- def start_server():
399
- nonlocal server
400
- nonlocal failed
401
- try:
402
- # we manually create the server instead of calling uvicorn.run
403
- # because we can then access the server variable and check if it is
404
- # running.
405
- config = uvicorn.Config(**kwargs)
406
- server = uvicorn.Server(config=config)
407
- if reload:
408
- sock = config.bind_socket()
409
- from uvicorn.supervisors import ChangeReload
410
-
411
- ChangeReload(
412
- config,
413
- target=run_with_settings(
414
- server, main=settings.main.dict(), theme=settings.theme.dict(), ssg=settings.ssg.dict(), search=settings.search.dict()
415
- ),
416
- sockets=[sock],
417
- ).run()
418
- else:
419
- server.run()
420
- except: # noqa
421
- failed = True
422
- raise
423
-
424
- def ssg_run():
425
- while not failed and (server is None or not server.started):
426
- time.sleep(0.1)
427
- if not failed:
428
- assert server is not None
429
- base_url = f"http://{server.config.host}:{server.config.port}"
430
- rprint("Running Static Site Generator pre-render background task")
431
- ssg_crawl(base_url)
432
- if settings.search.enabled:
433
- from solara_enterprise.search.index import build_index
434
-
435
- build_index("")
436
-
437
- # in dev mode we run the ssg in the child process (see run_with_settings)
438
- if not dev and settings.ssg.enabled:
439
- threading.Thread(target=ssg_run, daemon=True).start()
440
-
441
- # if we don't have to wait for SSG, we can build the index right away
442
- if not settings.ssg.enabled and settings.search.enabled:
443
- from solara_enterprise.search.index import build_index
444
-
445
- build_index("")
446
-
447
- start_server()
448
-
449
- # TODO: if we want to use webview, it should be sth like this
450
- # server_thread = threading.Thread(target=start_server)
451
- # server_thread.start()
452
- # if open:
453
- # # open_webview()
454
- # open_browser()
455
- # server_thread.join()
456
-
457
-
458
- @cli.command()
459
- @click.argument("app")
460
- @click.option("--port", default=int(os.environ.get("PORT", 8765)))
461
- @click.option("--host", default=settings.main.host)
462
- @click.option(
463
- "--headed/--no-headed",
464
- is_flag=True,
465
- default=settings.ssg.headed,
466
- help="Show browser window if true.",
467
- )
468
- def ssg(app: str, port: int, host: str, headed: bool):
469
- """Static site generation"""
470
- settings.ssg.headed = headed
471
- settings.ssg.enabled = True
472
- settings.main.mode = "production" # always override this
473
- os.environ["SOLARA_APP"] = app
474
- from solara.server.starlette import ServerStarlette
475
-
476
- server = ServerStarlette(port=port, host=host)
477
- server.serve_threaded()
478
- server.wait_until_serving()
479
-
480
- base_url = f"http://{server.server.config.host}:{server.server.config.port}"
481
-
482
- ssg_crawl(base_url)
483
-
484
-
485
- @cli.command()
486
- def deploy():
487
- rprint("...")
488
- import time
489
-
490
- time.sleep(1)
491
- rprint("Want your app to run instantly on awesomeapp-mystartup-gh.solara.run?")
492
- rprint("\tCheck out https://solara.dev/documentation/getting_started/deploying/cloud-hosted")
493
-
494
-
495
- @cli.command()
496
- @click.argument("app")
497
- def search(app: str):
498
- """Build search index based on ssg output"""
499
- os.environ["SOLARA_APP"] = app
500
- from solara_enterprise.search.index import build_index
501
-
502
- build_index("")
503
-
504
-
505
- class run_with_settings:
506
- """This cross a process boundary, and takes the serialized settings with it"""
507
-
508
- def __init__(self, server: uvicorn.Server, main: typing.Dict, theme: typing.Dict, ssg: typing.Dict, search: typing.Dict):
509
- self.server = server
510
- self.main = main
511
- self.theme = theme
512
- self.ssg = ssg
513
- self.search = search
514
-
515
- def __call__(self, *args, **kwargs):
516
- # this is now in the new process, where we need to re-apply the settings
517
- failed = False
518
-
519
- def ssg_run():
520
- while not failed and (self.server is None or not self.server.started):
521
- time.sleep(0.1)
522
- if not failed:
523
- assert self.server is not None
524
- base_url = f"http://{self.server.config.host}:{self.server.config.port}"
525
- rprint("Running Static Site Generator pre-render background task")
526
- ssg_crawl(base_url)
527
- if settings.search.enabled:
528
- from solara_enterprise.search.index import build_index
529
-
530
- build_index("")
531
-
532
- settings.main = settings.MainSettings(**self.main)
533
- settings.theme = settings.ThemeSettings(**self.theme)
534
- settings.ssg = settings.SSG(**self.ssg)
535
- settings.search = settings.Search(**self.search)
536
- if settings.ssg.enabled:
537
- threading.Thread(target=ssg_run, daemon=True).start()
538
- try:
539
- return self.server.run(*args, **kwargs)
540
- except: # noqa
541
- failed = True
542
- raise
543
-
544
-
545
- @cli.command()
546
- @click.option("--port", default=int(os.environ.get("PORT", 8000)))
547
- def staticserve(port):
548
- """Experimental static serving"""
549
- import http.server
550
- import os
551
- from functools import partial
552
-
553
- print(f"http://localhost:{port}/") # noqa
554
- wk_dir = os.getcwd() + "/staticbuild"
555
- http.server.SimpleHTTPRequestHandler.extensions_map[".js"] = "application/javascript"
556
- http.server.SimpleHTTPRequestHandler.extensions_map = {k: v + ";charset=UTF-8" for k, v in http.server.SimpleHTTPRequestHandler.extensions_map.items()}
557
- http.server.test(HandlerClass=partial(http.server.SimpleHTTPRequestHandler, directory=wk_dir), port=port, bind="") # type: ignore
558
-
559
-
560
- @cli.command()
561
- def staticbuild():
562
- """Experimental static build"""
563
- # imports locals, otherwise .run() does not use the cli arguments
564
- import solara.server
565
- import solara.server.server
566
-
567
- server_path = HERE / "server"
568
- assets_path = server_path / "assets"
569
- static_path = server_path / "static"
570
-
571
- target_dir = Path("staticbuild")
572
- target_dir.mkdir(exist_ok=True)
573
-
574
- from .server import settings
575
-
576
- copytree(settings.assets.proxy_cache_dir, target_dir / "_solara/cdn/")
577
-
578
- static_dir_target = target_dir / "static"
579
- static_dir_target.mkdir(exist_ok=True)
580
-
581
- assets_dir_target = target_dir / "static" / "assets"
582
- assets_dir_target.mkdir(exist_ok=True)
583
- copytree(assets_path, assets_dir_target)
584
-
585
- for path in (
586
- list(static_path.glob("*.css"))
587
- + list(static_path.glob("*.js"))
588
- + list(static_path.glob("*.ps"))
589
- + list(static_path.glob("*.py"))
590
- + list(static_path.glob("*.png"))
591
- + list(static_path.glob("*.svg"))
592
- ):
593
- shutil.copy(path, static_dir_target)
594
-
595
- include_nbextensions = True
596
- if include_nbextensions:
597
- directories = solara.server.server.get_nbextensions_directories()
598
- nbextensions, ignore = solara.server.server.get_nbextensions()
599
- for name in nbextensions:
600
- for directory in directories:
601
- if (directory / (name + ".js")).exists():
602
- src = (directory / (name + ".js")).parent
603
- dst: Path = (static_dir_target / "nbextensions" / (name + ".js")).parent
604
- dst.mkdir(parents=True, exist_ok=True)
605
- # shutil.copytree(src, dst)
606
- copytree(src, dst)
607
-
608
- target_dir_wheels = target_dir / "wheels"
609
- target_dir_wheels.mkdir(exist_ok=True)
610
- version = solara.__version__
611
- for path in [Path(f"dist/solara-{version}-py2.py3-none-any.whl")]:
612
- shutil.copy(path, target_dir_wheels)
613
-
614
- target_dir_static_dist = target_dir / "static/dist"
615
- target_dir_static_dist.mkdir(exist_ok=True)
616
- voila = server_path / "dist"
617
- for path in list(voila.glob("*.js")) + list(voila.glob("*.woff")):
618
- shutil.copy(path, target_dir_static_dist)
619
-
620
- index_html = solara.server.server.read_root("", render_kwargs={"for_pyodide": True}, use_nbextensions=True)
621
- assert index_html is not None
622
- (target_dir / "index.html").write_text(index_html)
623
-
624
-
625
- @click.group()
626
- def create():
627
- """Quickly create a solara script or project."""
628
- pass
629
-
630
-
631
- @create.command()
632
- @click.argument(
633
- "target",
634
- type=click.Path(exists=False),
635
- default="sol.py",
636
- required=False,
637
- )
638
- def button(target: typing.Optional[Path]):
639
- """Create a button with a click counter."""
640
- write_script("button", target)
641
-
642
-
643
- @create.command()
644
- @click.argument(
645
- "target",
646
- type=click.Path(exists=False),
647
- default="sol.py",
648
- required=False,
649
- )
650
- def markdown(target: typing.Optional[Path] = None):
651
- """Create a markdown editor."""
652
- write_script("markdown", target)
653
-
654
-
655
- def write_script(name: str, target: typing.Optional[Path]):
656
- code = (HERE / "template" / f"{name}.py").read_text()
657
- if target is None:
658
- target = Path("sol.py")
659
- else:
660
- target = Path(target)
661
- target.parent.mkdir(exist_ok=True)
662
- target.write_text(code)
663
- rprint(f"Wrote: {target.resolve()}")
664
- rprint(f"Run as:\n\t $ solara run {target.resolve()}")
665
-
666
-
667
- # recursively copy a directory and allow for existing directories
668
- def copytree(src: Path, dst: Path, copy_function=shutil.copy2, ignore: typing.Callable[[Path], bool] = lambda x: False, rename=lambda x: x):
669
- print(src, " -> ", dst) # noqa
670
- if not src.exists():
671
- return
672
- if not dst.exists():
673
- dst.mkdir(parents=True, exist_ok=True)
674
- for item in src.iterdir():
675
- if ignore(item):
676
- continue
677
- if item.is_dir():
678
- copytree(item, dst / rename(item).name, ignore=ignore, copy_function=copy_function, rename=rename)
679
- else:
680
- copy_function(item, dst / rename(item).name)
681
-
682
-
683
- @create.command()
684
- @click.argument(
685
- "target",
686
- type=click.Path(exists=False),
687
- default="solara_portal",
688
- required=False,
689
- )
690
- def portal(target: Path):
691
- """Create a full Python project template for a data portal"""
692
- target = Path(target)
693
- name = target.name
694
- package_name = name.replace("-", "_")
695
-
696
- def copy_function(src: Path, dst: Path):
697
- dst.write_bytes(
698
- src.read_bytes().replace(b"solara-portal", name.encode("utf8")).replace(b"solara_portal", package_name.encode("utf8")),
699
- )
700
-
701
- def rename(path: Path):
702
- if path.name == "solara_portal":
703
- return path.parent / package_name
704
- else:
705
- return path
706
-
707
- copytree(
708
- HERE / "template" / "portal",
709
- target,
710
- ignore=lambda p: p.name.startswith("__") and p.name != "__init__.py",
711
- copy_function=copy_function,
712
- rename=rename,
713
- )
714
- rprint(f"Wrote: {target.resolve()}")
715
- rprint(f"Install as:\n\t $ (cd {target}; pip install -e .)")
716
- rprint(f"Run as:\n\t $ solara run {package_name}.pages")
717
-
718
-
719
- cli.add_command(run)
720
- cli.add_command(staticbuild)
721
- cli.add_command(create)
722
- cli.add_command(ssg)
723
-
724
-
725
- def main():
726
- args = sys.argv
727
- # skip everything after -- if it exists
728
- if "--" in args:
729
- args = args[: args.index("--")]
730
- cli(args[1:])
731
-
732
-
733
- if __name__ == "__main__":
734
- main()