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.
- {solara-1.30.1.dist-info → solara-1.31.0.dist-info}/METADATA +7 -42
- solara-1.31.0.dist-info/RECORD +5 -0
- {solara-1.30.1.dist-info → solara-1.31.0.dist-info}/WHEEL +1 -1
- {solara/template/portal → solara-1.31.0.dist-info/licenses}/LICENSE +1 -1
- solara/__init__.py +0 -123
- solara/__main__.py +0 -734
- solara/alias.py +0 -6
- solara/autorouting.py +0 -545
- solara/cache.py +0 -294
- solara/checks.html +0 -71
- solara/checks.py +0 -224
- solara/comm.py +0 -28
- solara/components/__init__.py +0 -59
- solara/components/alert.py +0 -155
- solara/components/applayout.py +0 -393
- solara/components/button.py +0 -85
- solara/components/card.py +0 -87
- solara/components/checkbox.py +0 -50
- solara/components/code_highlight_css.py +0 -11
- solara/components/code_highlight_css.vue +0 -63
- solara/components/columns.py +0 -159
- solara/components/component_vue.py +0 -110
- solara/components/cross_filter.py +0 -335
- solara/components/dataframe.py +0 -546
- solara/components/datatable.py +0 -221
- solara/components/datatable.vue +0 -175
- solara/components/details.py +0 -21
- solara/components/download.vue +0 -35
- solara/components/echarts.py +0 -75
- solara/components/echarts.vue +0 -128
- solara/components/figure_altair.py +0 -39
- solara/components/file_browser.py +0 -182
- solara/components/file_download.py +0 -199
- solara/components/file_drop.py +0 -139
- solara/components/file_drop.vue +0 -83
- solara/components/file_list_widget.vue +0 -78
- solara/components/head.py +0 -27
- solara/components/head_tag.py +0 -49
- solara/components/head_tag.vue +0 -60
- solara/components/image.py +0 -173
- solara/components/input.py +0 -440
- solara/components/link.py +0 -55
- solara/components/markdown.py +0 -371
- solara/components/markdown_editor.py +0 -25
- solara/components/markdown_editor.vue +0 -362
- solara/components/matplotlib.py +0 -74
- solara/components/meta.py +0 -47
- solara/components/misc.py +0 -333
- solara/components/pivot_table.py +0 -258
- solara/components/pivot_table.vue +0 -158
- solara/components/progress.py +0 -47
- solara/components/select.py +0 -186
- solara/components/select.vue +0 -27
- solara/components/slider.py +0 -442
- solara/components/slider_date.vue +0 -56
- solara/components/spinner-solara.vue +0 -105
- solara/components/spinner.py +0 -30
- solara/components/sql_code.py +0 -33
- solara/components/sql_code.vue +0 -128
- solara/components/style.py +0 -105
- solara/components/switch.py +0 -68
- solara/components/tab_navigation.py +0 -37
- solara/components/title.py +0 -90
- solara/components/title.vue +0 -38
- solara/components/togglebuttons.py +0 -202
- solara/components/tooltip.py +0 -61
- solara/datatypes.py +0 -143
- solara/express.py +0 -241
- solara/hooks/__init__.py +0 -4
- solara/hooks/dataframe.py +0 -99
- solara/hooks/misc.py +0 -263
- solara/hooks/use_reactive.py +0 -129
- solara/hooks/use_thread.py +0 -129
- solara/kitchensink.py +0 -8
- solara/lab/__init__.py +0 -34
- solara/lab/components/__init__.py +0 -6
- solara/lab/components/chat.py +0 -203
- solara/lab/components/confirmation_dialog.py +0 -165
- solara/lab/components/cross_filter.py +0 -7
- solara/lab/components/input_date.py +0 -298
- solara/lab/components/menu.py +0 -181
- solara/lab/components/menu.vue +0 -38
- solara/lab/components/tabs.py +0 -274
- solara/lab/components/theming.py +0 -98
- solara/lab/components/theming.vue +0 -72
- solara/lab/hooks/__init__.py +0 -0
- solara/lab/hooks/dataframe.py +0 -12
- solara/lab/toestand.py +0 -3
- solara/lab/utils/__init__.py +0 -2
- solara/lab/utils/cookies.py +0 -5
- solara/lab/utils/dataframe.py +0 -115
- solara/lab/utils/headers.py +0 -5
- solara/layout.py +0 -44
- solara/minisettings.py +0 -133
- solara/py.typed +0 -0
- solara/reactive.py +0 -93
- solara/routing.py +0 -268
- solara/scope/__init__.py +0 -88
- solara/scope/types.py +0 -55
- solara/server/__init__.py +0 -0
- solara/server/app.py +0 -490
- solara/server/assets/custom.css +0 -1
- solara/server/assets/custom.js +0 -1
- solara/server/assets/favicon.png +0 -0
- solara/server/assets/favicon.svg +0 -5
- solara/server/assets/style.css +0 -1665
- solara/server/assets/theme-dark.css +0 -437
- solara/server/assets/theme-light.css +0 -420
- solara/server/assets/theme.js +0 -3
- solara/server/cdn_helper.py +0 -77
- solara/server/esm.py +0 -69
- solara/server/fastapi.py +0 -5
- solara/server/flask.py +0 -286
- solara/server/jupyter/__init__.py +0 -2
- solara/server/jupyter/cdn_handler.py +0 -28
- solara/server/jupyter/server_extension.py +0 -29
- solara/server/jupytertools.py +0 -46
- solara/server/kernel.py +0 -319
- solara/server/kernel_context.py +0 -396
- solara/server/patch.py +0 -552
- solara/server/reload.py +0 -242
- solara/server/server.py +0 -437
- solara/server/settings.py +0 -212
- solara/server/shell.py +0 -240
- solara/server/starlette.py +0 -597
- solara/server/static/ansi.js +0 -270
- solara/server/static/highlight-dark.css +0 -82
- solara/server/static/highlight.css +0 -43
- solara/server/static/main-vuetify.js +0 -260
- solara/server/static/main.js +0 -163
- solara/server/static/solara_bootstrap.py +0 -129
- solara/server/static/sun.svg +0 -23
- solara/server/static/webworker.js +0 -42
- solara/server/telemetry.py +0 -212
- solara/server/templates/index.html.j2 +0 -1
- solara/server/templates/loader-plain.css +0 -11
- solara/server/templates/loader-plain.html +0 -20
- solara/server/templates/loader-solara.css +0 -111
- solara/server/templates/loader-solara.html +0 -40
- solara/server/templates/plain.html +0 -82
- solara/server/templates/solara.html.j2 +0 -446
- solara/server/threaded.py +0 -75
- solara/server/utils.py +0 -30
- solara/server/websocket.py +0 -44
- solara/settings.py +0 -56
- solara/tasks.py +0 -847
- solara/template/button.py +0 -16
- solara/template/markdown.py +0 -42
- solara/template/portal/.flake8 +0 -6
- solara/template/portal/.pre-commit-config.yaml +0 -28
- solara/template/portal/Procfile +0 -7
- solara/template/portal/mypy.ini +0 -3
- solara/template/portal/pyproject.toml +0 -26
- solara/template/portal/solara_portal/__init__.py +0 -3
- solara/template/portal/solara_portal/components/__init__.py +0 -2
- solara/template/portal/solara_portal/components/article.py +0 -28
- solara/template/portal/solara_portal/components/data.py +0 -28
- solara/template/portal/solara_portal/components/header.py +0 -6
- solara/template/portal/solara_portal/components/layout.py +0 -6
- solara/template/portal/solara_portal/content/articles/equis-in-vidi.md +0 -85
- solara/template/portal/solara_portal/content/articles/substiterat-vati.md +0 -70
- solara/template/portal/solara_portal/data.py +0 -60
- solara/template/portal/solara_portal/pages/__init__.py +0 -67
- solara/template/portal/solara_portal/pages/article/__init__.py +0 -26
- solara/template/portal/solara_portal/pages/tabular.py +0 -29
- solara/template/portal/solara_portal/pages/viz/__init__.py +0 -69
- solara/template/portal/solara_portal/pages/viz/overview.py +0 -14
- solara/test/__init__.py +0 -0
- solara/test/pytest_plugin.py +0 -698
- solara/toestand.py +0 -772
- solara/util.py +0 -308
- solara/website/__init__.py +0 -0
- solara/website/assets/custom.css +0 -462
- solara/website/assets/images/logo-small.png +0 -0
- solara/website/assets/images/logo.svg +0 -17
- solara/website/assets/images/logo_white.svg +0 -50
- solara/website/assets/theme.js +0 -8
- solara/website/components/__init__.py +0 -5
- solara/website/components/algolia.vue +0 -24
- solara/website/components/algolia_api.vue +0 -157
- solara/website/components/docs.py +0 -118
- solara/website/components/header.py +0 -72
- solara/website/components/hero.py +0 -15
- solara/website/components/mailchimp.py +0 -12
- solara/website/components/mailchimp.vue +0 -47
- solara/website/components/markdown.py +0 -30
- solara/website/components/notebook.py +0 -172
- solara/website/pages/__init__.py +0 -575
- solara/website/pages/apps/__init__.py +0 -16
- solara/website/pages/apps/authorization/__init__.py +0 -118
- solara/website/pages/apps/authorization/admin.py +0 -12
- solara/website/pages/apps/authorization/users.py +0 -12
- solara/website/pages/apps/jupyter-dashboard-1.py +0 -116
- solara/website/pages/apps/layout-demo.py +0 -40
- solara/website/pages/apps/multipage/__init__.py +0 -38
- solara/website/pages/apps/multipage/page1.py +0 -26
- solara/website/pages/apps/multipage/page2.py +0 -34
- solara/website/pages/apps/scatter.py +0 -136
- solara/website/pages/apps/scrolling.py +0 -63
- solara/website/pages/apps/tutorial-streamlit.py +0 -18
- solara/website/pages/changelog/__init__.py +0 -8
- solara/website/pages/changelog/changelog.md +0 -195
- solara/website/pages/contact/__init__.py +0 -8
- solara/website/pages/contact/contact.md +0 -17
- solara/website/pages/doc_use_download.py +0 -85
- solara/website/pages/documentation/__init__.py +0 -184
- solara/website/pages/documentation/advanced/__init__.py +0 -9
- solara/website/pages/documentation/advanced/content/00-overview.md +0 -1
- solara/website/pages/documentation/advanced/content/10-howto/00-overview.md +0 -6
- solara/website/pages/documentation/advanced/content/10-howto/10-multipage.md +0 -196
- solara/website/pages/documentation/advanced/content/10-howto/20-layout.md +0 -125
- solara/website/pages/documentation/advanced/content/10-howto/30-testing.md +0 -154
- solara/website/pages/documentation/advanced/content/10-howto/31-debugging.md +0 -69
- solara/website/pages/documentation/advanced/content/10-howto/40-embed.md +0 -49
- solara/website/pages/documentation/advanced/content/10-howto/50-ipywidget_libraries.md +0 -124
- solara/website/pages/documentation/advanced/content/20-understanding/00-introduction.md +0 -10
- solara/website/pages/documentation/advanced/content/20-understanding/05-ipywidgets.md +0 -35
- solara/website/pages/documentation/advanced/content/20-understanding/06-ipyvuetify.md +0 -42
- solara/website/pages/documentation/advanced/content/20-understanding/10-reacton.md +0 -28
- solara/website/pages/documentation/advanced/content/20-understanding/12-reacton-basics.md +0 -108
- solara/website/pages/documentation/advanced/content/20-understanding/15-anatomy.md +0 -23
- solara/website/pages/documentation/advanced/content/20-understanding/17-rules-of-hooks.md +0 -7
- solara/website/pages/documentation/advanced/content/20-understanding/18-containers.md +0 -166
- solara/website/pages/documentation/advanced/content/20-understanding/20-solara.md +0 -18
- solara/website/pages/documentation/advanced/content/20-understanding/40-routing.md +0 -240
- solara/website/pages/documentation/advanced/content/20-understanding/50-solara-server.md +0 -86
- solara/website/pages/documentation/advanced/content/20-understanding/60-voila.md +0 -12
- solara/website/pages/documentation/advanced/content/30-enterprise/00-overview.md +0 -1
- solara/website/pages/documentation/advanced/content/30-enterprise/10-oauth.md +0 -171
- solara/website/pages/documentation/advanced/content/40-development/00-overview.md +0 -0
- solara/website/pages/documentation/advanced/content/40-development/01-contribute.md +0 -45
- solara/website/pages/documentation/advanced/content/40-development/10-setup.md +0 -76
- solara/website/pages/documentation/api/__init__.py +0 -19
- solara/website/pages/documentation/api/cross_filter/__init__.py +0 -9
- solara/website/pages/documentation/api/cross_filter/cross_filter_dataframe.py +0 -23
- solara/website/pages/documentation/api/cross_filter/cross_filter_report.py +0 -22
- solara/website/pages/documentation/api/cross_filter/cross_filter_select.py +0 -22
- solara/website/pages/documentation/api/cross_filter/cross_filter_slider.py +0 -22
- solara/website/pages/documentation/api/hooks/__init__.py +0 -9
- solara/website/pages/documentation/api/hooks/use_cross_filter.py +0 -25
- solara/website/pages/documentation/api/hooks/use_dark_effective.py +0 -13
- solara/website/pages/documentation/api/hooks/use_effect.md +0 -43
- solara/website/pages/documentation/api/hooks/use_effect.py +0 -9
- solara/website/pages/documentation/api/hooks/use_exception.py +0 -33
- solara/website/pages/documentation/api/hooks/use_memo.md +0 -16
- solara/website/pages/documentation/api/hooks/use_memo.py +0 -9
- solara/website/pages/documentation/api/hooks/use_previous.py +0 -32
- solara/website/pages/documentation/api/hooks/use_reactive.py +0 -15
- solara/website/pages/documentation/api/hooks/use_state.py +0 -11
- solara/website/pages/documentation/api/hooks/use_state_or_update.py +0 -68
- solara/website/pages/documentation/api/hooks/use_thread.md +0 -58
- solara/website/pages/documentation/api/hooks/use_thread.py +0 -44
- solara/website/pages/documentation/api/hooks/use_trait_observe.py +0 -13
- solara/website/pages/documentation/api/routing/__init__.py +0 -9
- solara/website/pages/documentation/api/routing/generate_routes.py +0 -11
- solara/website/pages/documentation/api/routing/generate_routes_directory.py +0 -11
- solara/website/pages/documentation/api/routing/resolve_path.py +0 -36
- solara/website/pages/documentation/api/routing/route.py +0 -32
- solara/website/pages/documentation/api/routing/use_route.py +0 -80
- solara/website/pages/documentation/api/routing/use_router.py +0 -15
- solara/website/pages/documentation/api/utilities/__init__.py +0 -9
- solara/website/pages/documentation/api/utilities/component_vue.py +0 -11
- solara/website/pages/documentation/api/utilities/computed.py +0 -16
- solara/website/pages/documentation/api/utilities/display.py +0 -15
- solara/website/pages/documentation/api/utilities/get_kernel_id.py +0 -16
- solara/website/pages/documentation/api/utilities/get_session_id.py +0 -16
- solara/website/pages/documentation/api/utilities/memoize.py +0 -36
- solara/website/pages/documentation/api/utilities/on_kernel_start.py +0 -27
- solara/website/pages/documentation/api/utilities/reactive.py +0 -15
- solara/website/pages/documentation/api/utilities/widget.py +0 -104
- solara/website/pages/documentation/components/__init__.py +0 -12
- solara/website/pages/documentation/components/advanced/__init__.py +0 -9
- solara/website/pages/documentation/components/advanced/link.py +0 -28
- solara/website/pages/documentation/components/advanced/meta.py +0 -21
- solara/website/pages/documentation/components/advanced/style.py +0 -44
- solara/website/pages/documentation/components/common.py +0 -9
- solara/website/pages/documentation/components/data/__init__.py +0 -9
- solara/website/pages/documentation/components/data/dataframe.py +0 -44
- solara/website/pages/documentation/components/data/pivot_table.py +0 -81
- solara/website/pages/documentation/components/enterprise/__init__.py +0 -9
- solara/website/pages/documentation/components/enterprise/avatar.py +0 -19
- solara/website/pages/documentation/components/enterprise/avatar_menu.py +0 -20
- solara/website/pages/documentation/components/input/__init__.py +0 -9
- solara/website/pages/documentation/components/input/button.py +0 -22
- solara/website/pages/documentation/components/input/checkbox.py +0 -12
- solara/website/pages/documentation/components/input/file_browser.py +0 -33
- solara/website/pages/documentation/components/input/file_drop.py +0 -75
- solara/website/pages/documentation/components/input/input.py +0 -18
- solara/website/pages/documentation/components/input/select.py +0 -21
- solara/website/pages/documentation/components/input/slider.py +0 -28
- solara/website/pages/documentation/components/input/switch.py +0 -12
- solara/website/pages/documentation/components/input/togglebuttons.py +0 -20
- solara/website/pages/documentation/components/lab/__init__.py +0 -9
- solara/website/pages/documentation/components/lab/chat.py +0 -108
- solara/website/pages/documentation/components/lab/confirmation_dialog.py +0 -55
- solara/website/pages/documentation/components/lab/cookies_headers.py +0 -48
- solara/website/pages/documentation/components/lab/input_date.py +0 -19
- solara/website/pages/documentation/components/lab/menu.py +0 -21
- solara/website/pages/documentation/components/lab/tab.py +0 -24
- solara/website/pages/documentation/components/lab/tabs.py +0 -44
- solara/website/pages/documentation/components/lab/task.py +0 -12
- solara/website/pages/documentation/components/lab/theming.py +0 -72
- solara/website/pages/documentation/components/lab/use_task.py +0 -12
- solara/website/pages/documentation/components/layout/__init__.py +0 -9
- solara/website/pages/documentation/components/layout/app_bar.py +0 -15
- solara/website/pages/documentation/components/layout/app_bar_title.py +0 -15
- solara/website/pages/documentation/components/layout/app_layout.py +0 -23
- solara/website/pages/documentation/components/layout/card.py +0 -14
- solara/website/pages/documentation/components/layout/card_actions.py +0 -15
- solara/website/pages/documentation/components/layout/column.py +0 -29
- solara/website/pages/documentation/components/layout/columns.py +0 -26
- solara/website/pages/documentation/components/layout/columns_responsive.py +0 -67
- solara/website/pages/documentation/components/layout/griddraggable.py +0 -61
- solara/website/pages/documentation/components/layout/gridfixed.py +0 -21
- solara/website/pages/documentation/components/layout/hbox.py +0 -17
- solara/website/pages/documentation/components/layout/row.py +0 -29
- solara/website/pages/documentation/components/layout/sidebar.py +0 -23
- solara/website/pages/documentation/components/layout/vbox.py +0 -19
- solara/website/pages/documentation/components/output/__init__.py +0 -9
- solara/website/pages/documentation/components/output/file_download.py +0 -12
- solara/website/pages/documentation/components/output/html.py +0 -22
- solara/website/pages/documentation/components/output/image.py +0 -12
- solara/website/pages/documentation/components/output/markdown.py +0 -59
- solara/website/pages/documentation/components/output/markdown_editor.py +0 -53
- solara/website/pages/documentation/components/output/sql_code.py +0 -84
- solara/website/pages/documentation/components/output/tooltip.py +0 -12
- solara/website/pages/documentation/components/page/__init__.py +0 -9
- solara/website/pages/documentation/components/page/head.py +0 -19
- solara/website/pages/documentation/components/page/title.py +0 -28
- solara/website/pages/documentation/components/status/__init__.py +0 -9
- solara/website/pages/documentation/components/status/error.py +0 -40
- solara/website/pages/documentation/components/status/info.py +0 -40
- solara/website/pages/documentation/components/status/progress.py +0 -10
- solara/website/pages/documentation/components/status/spinner.py +0 -10
- solara/website/pages/documentation/components/status/success.py +0 -40
- solara/website/pages/documentation/components/status/warning.py +0 -47
- solara/website/pages/documentation/components/viz/__init__.py +0 -9
- solara/website/pages/documentation/components/viz/altair.py +0 -44
- solara/website/pages/documentation/components/viz/echarts.py +0 -78
- solara/website/pages/documentation/components/viz/matplotlib.py +0 -32
- solara/website/pages/documentation/components/viz/plotly.py +0 -63
- solara/website/pages/documentation/components/viz/plotly_express.py +0 -41
- solara/website/pages/documentation/examples/__init__.py +0 -52
- solara/website/pages/documentation/examples/ai/__init__.py +0 -10
- solara/website/pages/documentation/examples/ai/chatbot.py +0 -96
- solara/website/pages/documentation/examples/ai/tokenizer.py +0 -106
- solara/website/pages/documentation/examples/basics/__init__.py +0 -2
- solara/website/pages/documentation/examples/basics/sine.py +0 -28
- solara/website/pages/documentation/examples/fullscreen/__init__.py +0 -9
- solara/website/pages/documentation/examples/fullscreen/authorization.py +0 -3
- solara/website/pages/documentation/examples/fullscreen/layout_demo.py +0 -3
- solara/website/pages/documentation/examples/fullscreen/multipage.py +0 -3
- solara/website/pages/documentation/examples/fullscreen/scatter.py +0 -3
- solara/website/pages/documentation/examples/fullscreen/scrolling.py +0 -3
- solara/website/pages/documentation/examples/fullscreen/tutorial_streamlit.py +0 -3
- solara/website/pages/documentation/examples/general/__init__.py +0 -9
- solara/website/pages/documentation/examples/general/custom_storage.py +0 -69
- solara/website/pages/documentation/examples/general/deploy_model.py +0 -114
- solara/website/pages/documentation/examples/general/live_update.py +0 -38
- solara/website/pages/documentation/examples/general/login_oauth.py +0 -76
- solara/website/pages/documentation/examples/general/mycard.vue +0 -58
- solara/website/pages/documentation/examples/general/pokemon_search.py +0 -51
- solara/website/pages/documentation/examples/general/vue_component.py +0 -50
- solara/website/pages/documentation/examples/ipycanvas.py +0 -49
- solara/website/pages/documentation/examples/libraries/__init__.py +0 -9
- solara/website/pages/documentation/examples/libraries/altair.py +0 -63
- solara/website/pages/documentation/examples/libraries/bqplot.py +0 -39
- solara/website/pages/documentation/examples/libraries/ipyleaflet.py +0 -32
- solara/website/pages/documentation/examples/libraries/ipyleaflet_advanced.py +0 -65
- solara/website/pages/documentation/examples/utilities/__init__.py +0 -9
- solara/website/pages/documentation/examples/utilities/calculator.py +0 -157
- solara/website/pages/documentation/examples/utilities/countdown_timer.py +0 -64
- solara/website/pages/documentation/examples/utilities/todo.py +0 -195
- solara/website/pages/documentation/examples/visualization/__init__.py +0 -6
- solara/website/pages/documentation/examples/visualization/annotator.py +0 -68
- solara/website/pages/documentation/examples/visualization/linked_views.py +0 -84
- solara/website/pages/documentation/examples/visualization/plotly.py +0 -43
- solara/website/pages/documentation/faq/__init__.py +0 -12
- solara/website/pages/documentation/faq/content/99-faq.md +0 -76
- solara/website/pages/documentation/getting_started/__init__.py +0 -9
- solara/website/pages/documentation/getting_started/content/00-quickstart.md +0 -89
- solara/website/pages/documentation/getting_started/content/01-introduction.md +0 -125
- solara/website/pages/documentation/getting_started/content/02-installing.md +0 -85
- solara/website/pages/documentation/getting_started/content/04-tutorials/00-overview.md +0 -14
- solara/website/pages/documentation/getting_started/content/04-tutorials/10_data_science.py +0 -13
- solara/website/pages/documentation/getting_started/content/04-tutorials/20-web-app.md +0 -89
- solara/website/pages/documentation/getting_started/content/04-tutorials/30-ipywidgets.md +0 -124
- solara/website/pages/documentation/getting_started/content/04-tutorials/40-streamlit.md +0 -146
- solara/website/pages/documentation/getting_started/content/04-tutorials/50-dash.md +0 -144
- solara/website/pages/documentation/getting_started/content/04-tutorials/60-jupyter-dashboard-part1.py +0 -64
- solara/website/pages/documentation/getting_started/content/04-tutorials/SF_crime_sample.csv.gz +0 -0
- solara/website/pages/documentation/getting_started/content/04-tutorials/_data_science.ipynb +0 -445
- solara/website/pages/documentation/getting_started/content/04-tutorials/_jupyter_dashboard_1.ipynb +0 -1000
- solara/website/pages/documentation/getting_started/content/05-fundamentals/00-overview.md +0 -11
- solara/website/pages/documentation/getting_started/content/05-fundamentals/10-components.md +0 -223
- solara/website/pages/documentation/getting_started/content/05-fundamentals/50-state-management.md +0 -88
- solara/website/pages/documentation/getting_started/content/06-reference/00-overview.md +0 -3
- solara/website/pages/documentation/getting_started/content/06-reference/40-static_files.md +0 -31
- solara/website/pages/documentation/getting_started/content/06-reference/41-asset-files.md +0 -36
- solara/website/pages/documentation/getting_started/content/06-reference/60-static-site-generation.md +0 -59
- solara/website/pages/documentation/getting_started/content/06-reference/70-search.md +0 -34
- solara/website/pages/documentation/getting_started/content/06-reference/80-reloading.md +0 -34
- solara/website/pages/documentation/getting_started/content/06-reference/90-notebook-support.md +0 -7
- solara/website/pages/documentation/getting_started/content/06-reference/95-caching.md +0 -148
- solara/website/pages/documentation/getting_started/content/07-deploying/00-overview.md +0 -7
- solara/website/pages/documentation/getting_started/content/07-deploying/10-self-hosted.md +0 -273
- solara/website/pages/documentation/getting_started/content/07-deploying/20-cloud-hosted.md +0 -80
- solara/website/pages/documentation/getting_started/content/80-what-is-lab.md +0 -7
- solara/website/pages/documentation/getting_started/content/90-troubleshoot.md +0 -26
- solara/website/pages/docutils.py +0 -38
- solara/website/pages/showcase/__init__.py +0 -105
- solara/website/pages/showcase/domino_code_assist.py +0 -60
- solara/website/pages/showcase/planeto_tessa.py +0 -19
- solara/website/pages/showcase/solara_dev.py +0 -54
- solara/website/pages/showcase/solarathon_2023_team_2.py +0 -22
- solara/website/pages/showcase/solarathon_2023_team_4.py +0 -22
- solara/website/pages/showcase/solarathon_2023_team_5.py +0 -23
- solara/website/pages/showcase/solarathon_2023_team_6.py +0 -34
- solara/website/pages/showcase/wanderlust.py +0 -27
- solara/website/public/beach.jpeg +0 -0
- solara/website/public/logo.svg +0 -6
- solara/website/public/social/discord.svg +0 -1
- solara/website/public/social/github.svg +0 -1
- solara/website/public/social/twitter.svg +0 -3
- solara/website/public/success.html +0 -25
- solara/website/templates/index.html.j2 +0 -117
- solara/website/utils.py +0 -51
- solara/widgets/__init__.py +0 -1
- solara/widgets/vue/gridlayout.vue +0 -110
- solara/widgets/vue/html.vue +0 -4
- solara/widgets/vue/navigator.vue +0 -104
- solara/widgets/vue/vegalite.vue +0 -115
- solara/widgets/widgets.py +0 -65
- solara-1.30.1.data/data/etc/jupyter/jupyter_notebook_config.d/solara.json +0 -7
- solara-1.30.1.data/data/etc/jupyter/jupyter_server_config.d/solara.json +0 -7
- solara-1.30.1.dist-info/RECORD +0 -437
- solara-1.30.1.dist-info/entry_points.txt +0 -5
- /solara-1.30.1.dist-info/licenses/LICENSE → /LICENSE +0 -0
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
"""# Todo application
|
|
2
|
-
|
|
3
|
-
Demonstrates the use of reactive variables in combinations with dataclasses.
|
|
4
|
-
|
|
5
|
-
With solara we can get a type safe view onto a field in a dataclass, pydantic model, or
|
|
6
|
-
attr object.
|
|
7
|
-
|
|
8
|
-
This is using the experimental `solara.lab.Ref` class, which is not yet part of the
|
|
9
|
-
official API.
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
```python
|
|
13
|
-
import dataclasses
|
|
14
|
-
import solara
|
|
15
|
-
from solara.lab import Ref
|
|
16
|
-
|
|
17
|
-
@dataclasses.dataclass(frozen=True)
|
|
18
|
-
class TodoItem:
|
|
19
|
-
text: str
|
|
20
|
-
done: bool
|
|
21
|
-
|
|
22
|
-
todo_item = solara.reactive(TodoItem("Buy milk", False))
|
|
23
|
-
|
|
24
|
-
# now text is a reactive variable that is always in sync with todo_item.text
|
|
25
|
-
text = Ref(todo_item.fields.text)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
# we can now modify the reactive text variable
|
|
29
|
-
# and see its value reflect in the todo_item
|
|
30
|
-
text.value = "Buy skimmed milk"
|
|
31
|
-
assert todo_item.value.text == "Buy skimmed milk"
|
|
32
|
-
|
|
33
|
-
# Or, the other way around
|
|
34
|
-
todo_item.value = TodoItem("Buy whole milk", False)
|
|
35
|
-
assert text.value == "Buy whole milk"
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
Apart from dataclasses, pydantic models etc, we also supports dictionaries and lists.
|
|
39
|
-
|
|
40
|
-
```python
|
|
41
|
-
todo_items = solara.reactive([TodoItem("Buy milk", False), TodoItem("Buy eggs", False)])
|
|
42
|
-
todo_item_eggs = Ref(todo_items.fields[1])
|
|
43
|
-
todo_item_eggs.value = TodoItem("Buy eggs", True)
|
|
44
|
-
assert todo_items.value[1].done == True
|
|
45
|
-
|
|
46
|
-
# However, if a list becomes shorter, and the valid index is now out of range, the
|
|
47
|
-
# reactive variables will act as if it is "not connected", and will not trigger
|
|
48
|
-
# updates anymore. Accessing the value will raise an IndexError.
|
|
49
|
-
|
|
50
|
-
todo_items.value = [TodoItem("Buy milk", False)]
|
|
51
|
-
# anyone listening to todo_item_eggs will *not* be notified.
|
|
52
|
-
try:
|
|
53
|
-
value = todo_item_eggs.value
|
|
54
|
-
except IndexError:
|
|
55
|
-
print("this is expected")
|
|
56
|
-
else:
|
|
57
|
-
raise AssertionError("Expected an IndexError")
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
"""
|
|
61
|
-
import dataclasses
|
|
62
|
-
from typing import Callable
|
|
63
|
-
|
|
64
|
-
import reacton.ipyvuetify as v
|
|
65
|
-
|
|
66
|
-
import solara
|
|
67
|
-
from solara.lab.toestand import Ref
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
# our model for a todo item, immutable/frozen avoids common bugs
|
|
71
|
-
@dataclasses.dataclass(frozen=True)
|
|
72
|
-
class TodoItem:
|
|
73
|
-
text: str
|
|
74
|
-
done: bool
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
@solara.component
|
|
78
|
-
def TodoEdit(todo_item: solara.Reactive[TodoItem], on_delete: Callable[[], None], on_close: Callable[[], None]):
|
|
79
|
-
"""Takes a reactive todo item and allows editing it. Will not modify the original item until 'save' is clicked."""
|
|
80
|
-
copy = solara.use_reactive(todo_item.value)
|
|
81
|
-
|
|
82
|
-
def save():
|
|
83
|
-
todo_item.value = copy.value
|
|
84
|
-
on_close()
|
|
85
|
-
|
|
86
|
-
with solara.Card("Edit", margin=0):
|
|
87
|
-
solara.InputText(label="", value=Ref(copy.fields.text))
|
|
88
|
-
with solara.CardActions():
|
|
89
|
-
v.Spacer()
|
|
90
|
-
solara.Button("Save", icon_name="mdi-content-save", on_click=save, outlined=True, text=True)
|
|
91
|
-
solara.Button("Close", icon_name="mdi-window-close", on_click=on_close, outlined=True, text=True)
|
|
92
|
-
solara.Button("Delete", icon_name="mdi-delete", on_click=on_delete, outlined=True, text=True)
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
@solara.component
|
|
96
|
-
def TodoListItem(todo_item: solara.Reactive[TodoItem], on_delete: Callable[[TodoItem], None]):
|
|
97
|
-
"""Displays a single todo item, modifications are done 'in place'.
|
|
98
|
-
|
|
99
|
-
For demonstration purposes, we allow editing the item in a dialog as well.
|
|
100
|
-
This will not modify the original item until 'save' is clicked.
|
|
101
|
-
"""
|
|
102
|
-
edit, set_edit = solara.use_state(False)
|
|
103
|
-
with v.ListItem():
|
|
104
|
-
solara.Button(icon_name="mdi-delete", icon=True, on_click=lambda: on_delete(todo_item.value))
|
|
105
|
-
solara.Checkbox(value=Ref(todo_item.fields.done)) # , color="success")
|
|
106
|
-
solara.InputText(label="", value=Ref(todo_item.fields.text))
|
|
107
|
-
solara.Button(icon_name="mdi-pencil", icon=True, on_click=lambda: set_edit(True))
|
|
108
|
-
with v.Dialog(v_model=edit, persistent=True, max_width="500px", on_v_model=set_edit):
|
|
109
|
-
if edit: # 'reset' the component state on open/close
|
|
110
|
-
|
|
111
|
-
def on_delete_in_edit():
|
|
112
|
-
on_delete(todo_item.value)
|
|
113
|
-
set_edit(False)
|
|
114
|
-
|
|
115
|
-
TodoEdit(todo_item, on_delete=on_delete_in_edit, on_close=lambda: set_edit(False))
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
@solara.component
|
|
119
|
-
def TodoNew(on_new: Callable[[TodoItem], None]):
|
|
120
|
-
"""Component that managed entering new todo items"""
|
|
121
|
-
new_text, set_new_text = solara.use_state("")
|
|
122
|
-
text_field = v.TextField(v_model=new_text, on_v_model=set_new_text, label="Enter a new todo item")
|
|
123
|
-
|
|
124
|
-
def create_new_item(*ignore_args):
|
|
125
|
-
if not new_text:
|
|
126
|
-
return
|
|
127
|
-
new_item = TodoItem(text=new_text, done=False)
|
|
128
|
-
on_new(new_item)
|
|
129
|
-
# reset text
|
|
130
|
-
set_new_text("")
|
|
131
|
-
|
|
132
|
-
v.use_event(text_field, "keydown.enter", create_new_item)
|
|
133
|
-
return text_field
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
initial_items = [
|
|
137
|
-
TodoItem("Learn Solara", done=True),
|
|
138
|
-
TodoItem("Write cool apps", done=False),
|
|
139
|
-
TodoItem("Relax", done=False),
|
|
140
|
-
]
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
# We store out reactive state, and our logic in a class for organization
|
|
144
|
-
# purposes, but this is not required.
|
|
145
|
-
# Note that all the above components do not refer to this class, but only
|
|
146
|
-
# to do the Todo items.
|
|
147
|
-
# This means all above components are reusable, and can be used in other
|
|
148
|
-
# places, while the components below use 'application'/'global' state.
|
|
149
|
-
# They are not suited for reuse.
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
class State:
|
|
153
|
-
todos = solara.reactive(initial_items)
|
|
154
|
-
|
|
155
|
-
@staticmethod
|
|
156
|
-
def on_new(item: TodoItem):
|
|
157
|
-
State.todos.value = [item] + State.todos.value
|
|
158
|
-
|
|
159
|
-
@staticmethod
|
|
160
|
-
def on_delete(item: TodoItem):
|
|
161
|
-
new_items = list(State.todos.value)
|
|
162
|
-
new_items.remove(item)
|
|
163
|
-
State.todos.value = new_items
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
@solara.component
|
|
167
|
-
def TodoStatus():
|
|
168
|
-
"""Status of our todo list"""
|
|
169
|
-
items = State.todos.value
|
|
170
|
-
count = len(items)
|
|
171
|
-
items_done = [item for item in items if item.done]
|
|
172
|
-
count_done = len(items_done)
|
|
173
|
-
|
|
174
|
-
if count != count_done:
|
|
175
|
-
with solara.Row():
|
|
176
|
-
percent = count_done / count * 100
|
|
177
|
-
solara.ProgressLinear(value=percent)
|
|
178
|
-
with solara.Row():
|
|
179
|
-
solara.Text(f"Remaining: {count - count_done}")
|
|
180
|
-
solara.Text(f"Completed: {count_done}")
|
|
181
|
-
else:
|
|
182
|
-
solara.Success("All done, awesome!", dense=True)
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
@solara.component
|
|
186
|
-
def Page():
|
|
187
|
-
with solara.Card("Todo list", style="min-width: 500px"):
|
|
188
|
-
TodoNew(on_new=State.on_new)
|
|
189
|
-
if State.todos.value:
|
|
190
|
-
TodoStatus()
|
|
191
|
-
for index, item in enumerate(State.todos.value):
|
|
192
|
-
todo_item = Ref(State.todos.fields[index])
|
|
193
|
-
TodoListItem(todo_item, on_delete=State.on_delete)
|
|
194
|
-
else:
|
|
195
|
-
solara.Info("No todo items, enter some text above, and hit enter")
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
"""# Image annotation with Solara
|
|
2
|
-
|
|
3
|
-
This example displays how to annotate images with different drawing tools in plotly figures. Use the canvas
|
|
4
|
-
below to draw shapes and visualize the canvas callback.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Check [plotly docs](https://dash.plotly.com/annotations) for more information about image annotation.
|
|
8
|
-
"""
|
|
9
|
-
import json
|
|
10
|
-
|
|
11
|
-
import plotly.graph_objects as go
|
|
12
|
-
|
|
13
|
-
import solara
|
|
14
|
-
|
|
15
|
-
title = "Plotly Image Annotator"
|
|
16
|
-
shapes = solara.reactive(None)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class CustomEncoder(json.JSONEncoder):
|
|
20
|
-
"""
|
|
21
|
-
Custom JSON encoder for Plotly objects.
|
|
22
|
-
|
|
23
|
-
Plotly may return objects that the standard JSON encoder can't handle. This
|
|
24
|
-
encoder converts such objects to str, allowing serialization by json.dumps
|
|
25
|
-
"""
|
|
26
|
-
|
|
27
|
-
def default(self, o):
|
|
28
|
-
if isinstance(o, object):
|
|
29
|
-
return str(o)
|
|
30
|
-
return super().default(o)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
@solara.component
|
|
34
|
-
def Page():
|
|
35
|
-
def on_relayout(data):
|
|
36
|
-
if data is None:
|
|
37
|
-
return
|
|
38
|
-
|
|
39
|
-
relayout_data = data["relayout_data"]
|
|
40
|
-
|
|
41
|
-
if "shapes" in relayout_data:
|
|
42
|
-
shapes.value = relayout_data["shapes"]
|
|
43
|
-
|
|
44
|
-
fig = go.FigureWidget(
|
|
45
|
-
layout=go.Layout(
|
|
46
|
-
showlegend=False,
|
|
47
|
-
autosize=False,
|
|
48
|
-
width=600,
|
|
49
|
-
height=600,
|
|
50
|
-
dragmode="drawrect",
|
|
51
|
-
modebar={
|
|
52
|
-
"add": [
|
|
53
|
-
"drawclosedpath",
|
|
54
|
-
"drawcircle",
|
|
55
|
-
"drawrect",
|
|
56
|
-
"eraseshape",
|
|
57
|
-
]
|
|
58
|
-
},
|
|
59
|
-
)
|
|
60
|
-
)
|
|
61
|
-
|
|
62
|
-
solara.FigurePlotly(fig, on_relayout=on_relayout)
|
|
63
|
-
if not shapes.value:
|
|
64
|
-
solara.Markdown("## Draw on the canvas")
|
|
65
|
-
else:
|
|
66
|
-
solara.Markdown("## Data returned by drawing")
|
|
67
|
-
formatted_shapes = str(json.dumps(shapes.value, indent=2, cls=CustomEncoder))
|
|
68
|
-
solara.Preformatted(formatted_shapes)
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
"""# Linked views
|
|
2
|
-
|
|
3
|
-
This example shows how to create linked views. The clicked row information is passed up to the parent component using an event,
|
|
4
|
-
and then passed down to both child components.
|
|
5
|
-
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
import dataclasses
|
|
9
|
-
from typing import Callable, cast
|
|
10
|
-
|
|
11
|
-
import plotly.express as px
|
|
12
|
-
|
|
13
|
-
import solara
|
|
14
|
-
|
|
15
|
-
df = px.data.iris()
|
|
16
|
-
columns = list(df.columns)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
@dataclasses.dataclass
|
|
20
|
-
class ClickPoint:
|
|
21
|
-
row_index: int
|
|
22
|
-
x_column: str
|
|
23
|
-
y_column: str
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def find_row_index(fig, click_data):
|
|
27
|
-
# goes from trace index and point index to row index in a dataframe
|
|
28
|
-
# requires passing df.index as to custom_data
|
|
29
|
-
trace_index = click_data["points"]["trace_indexes"][0]
|
|
30
|
-
point_index = click_data["points"]["point_indexes"][0]
|
|
31
|
-
trace = fig.data[trace_index]
|
|
32
|
-
return trace.customdata[point_index][0]
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
@solara.component
|
|
36
|
-
def ClickScatter(df, x, y, color, click_row, on_click: Callable[[ClickPoint], None]):
|
|
37
|
-
x, set_x = solara.use_state(x)
|
|
38
|
-
y, set_y = solara.use_state(y)
|
|
39
|
-
fig = px.scatter(df, x, y, color=color, custom_data=[df.index])
|
|
40
|
-
|
|
41
|
-
def on_click_trace(click_data):
|
|
42
|
-
# sanity checks
|
|
43
|
-
assert click_data["event_type"] == "plotly_click"
|
|
44
|
-
row_index = find_row_index(fig, click_data)
|
|
45
|
-
on_click(ClickPoint(row_index, x, y))
|
|
46
|
-
|
|
47
|
-
if click_row:
|
|
48
|
-
click_x = df[x].values[click_row]
|
|
49
|
-
click_y = df[y].values[click_row]
|
|
50
|
-
fig.add_trace(px.scatter(x=[click_x], y=[click_y], text=["⭐️"]).data[0])
|
|
51
|
-
# make the figure a bit smaller
|
|
52
|
-
fig.update_layout(width=400)
|
|
53
|
-
with solara.VBox() as main:
|
|
54
|
-
solara.FigurePlotly(fig, on_click=on_click_trace)
|
|
55
|
-
solara.Select(label="X-axis", value=x, values=columns, on_value=set_x)
|
|
56
|
-
solara.Select(label="Y-axis", value=y, values=columns, on_value=set_y)
|
|
57
|
-
return main
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
@solara.component
|
|
61
|
-
def Page():
|
|
62
|
-
click_point, set_click_point = solara.use_state(cast(ClickPoint, None))
|
|
63
|
-
if click_point:
|
|
64
|
-
clicked_row = click_point.row_index
|
|
65
|
-
else:
|
|
66
|
-
clicked_row = None
|
|
67
|
-
|
|
68
|
-
with solara.VBox() as main:
|
|
69
|
-
with solara.HBox():
|
|
70
|
-
ClickScatter(df, "sepal_length", "sepal_width", "species", clicked_row, on_click=set_click_point)
|
|
71
|
-
ClickScatter(df, "petal_length", "petal_width", "species", clicked_row, on_click=set_click_point)
|
|
72
|
-
if click_point is not None:
|
|
73
|
-
clicked_row = click_point.row_index
|
|
74
|
-
solara.Success(f"Clicked on row {clicked_row}. Which is highlighted in the both plots.")
|
|
75
|
-
solara.Markdown(
|
|
76
|
-
f"""
|
|
77
|
-
```python
|
|
78
|
-
row_data = {df.iloc[clicked_row].to_dict()}
|
|
79
|
-
```"""
|
|
80
|
-
)
|
|
81
|
-
else:
|
|
82
|
-
solara.Info("Click to select a point")
|
|
83
|
-
|
|
84
|
-
return main
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
"""# Scatter plot using Plotly
|
|
2
|
-
|
|
3
|
-
This example shows how to use Plotly to create a scatter plot and a slider to do some filtering.
|
|
4
|
-
|
|
5
|
-
Inspired by the dash documentation.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
## Note
|
|
9
|
-
|
|
10
|
-
Solara supports plotly and plotly express. Create your figure (not a figure widget)
|
|
11
|
-
and pass it to the [FigurePlotly](/documentation/components/viz/plotly) component.
|
|
12
|
-
|
|
13
|
-
"""
|
|
14
|
-
import pandas as pd
|
|
15
|
-
import plotly.express as px
|
|
16
|
-
import solara
|
|
17
|
-
|
|
18
|
-
title = "Scatter plot using Plotly"
|
|
19
|
-
|
|
20
|
-
try:
|
|
21
|
-
df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv")
|
|
22
|
-
except Exception:
|
|
23
|
-
df = None
|
|
24
|
-
|
|
25
|
-
if df is not None:
|
|
26
|
-
year_min = df["year"].min()
|
|
27
|
-
year_max = df["year"].max()
|
|
28
|
-
years = df["year"].unique().tolist()
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
@solara.component
|
|
32
|
-
def Page():
|
|
33
|
-
with solara.Div() as main:
|
|
34
|
-
index = solara.ui_slider(value=0, min=0, max=len(years) - 1, tick_labels=years, key="year slider index")
|
|
35
|
-
selected_year = years[index]
|
|
36
|
-
|
|
37
|
-
filtered_df = df[df.year == selected_year].copy()
|
|
38
|
-
|
|
39
|
-
fig = px.scatter(filtered_df, x="gdpPercap", y="lifeExp", size="pop", color="continent", hover_name="country", log_x=True, size_max=55)
|
|
40
|
-
fig.update_layout(transition_duration=1500)
|
|
41
|
-
|
|
42
|
-
solara.FigurePlotly(fig, dependencies=[selected_year])
|
|
43
|
-
return main
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
|
|
3
|
-
import solara
|
|
4
|
-
from solara.website.components.markdown import MarkdownWithMetadata
|
|
5
|
-
|
|
6
|
-
title = "FAQ"
|
|
7
|
-
HERE = Path(__file__)
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
@solara.component
|
|
11
|
-
def Page(route_external=None):
|
|
12
|
-
MarkdownWithMetadata(Path(HERE.parent / "content" / "99-faq.md").read_text())
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: FAQ about Solara
|
|
3
|
-
description: Answers to some common questions about using Solara, and building your app using the framework
|
|
4
|
-
---
|
|
5
|
-
# FAQ
|
|
6
|
-
|
|
7
|
-
## I am not interested in the server, I'm happy with Jupyter/Voila, what's in it for me?
|
|
8
|
-
|
|
9
|
-
That means you simply do not use or install the server component, just use the Reacton components and run it with Voila.
|
|
10
|
-
|
|
11
|
-
## Is the Solara server better than Voilà?
|
|
12
|
-
|
|
13
|
-
No, they are different, and there are situations where I would recommend Voila instead of Solara.
|
|
14
|
-
|
|
15
|
-
If your app is compute-heavy, and a lot of the compute is happening in pure Python, the GIL (Global Interpreter Lock) can become a bottleneck with Solara, and Voila might give you better performance per client.
|
|
16
|
-
|
|
17
|
-
If you have a lot of users with short sessions, Solara spares you from having to start up a kernel for each request. Since Solara can use multiple workers in the near future, you can still scale up using multiple processes. Voila will have one process per user, while Solara can share a process with many users.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
## Can Solara run a normal Python script?
|
|
21
|
-
|
|
22
|
-
Yes, this is the preferred way of using Solara. You edit a Python script, save it, Solara will detect the file change and reload the page in your browser (no interaction is needed).
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
$ solara myapp.py
|
|
26
|
-
Solara server is starting at http://localhost:8766
|
|
27
|
-
... file change detected ...
|
|
28
|
-
(server refreshes, your page will reload)
|
|
29
|
-
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
## Can Solara run from a Python package/module?
|
|
33
|
-
|
|
34
|
-
Over time, when your application becomes larger, you probably want to structure your application into a Python package. Instead of a filename, you pass in the package name on the command line
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
$ solara mystartup.killerapp --dev
|
|
38
|
-
....
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## Can Solara run Jupyter notebook?
|
|
42
|
-
|
|
43
|
-
Yes, Solara will execute each cell, and after that will look for a variable or component called `Page`, like with a normal script. All other output, Markdown or other types of cells will be ignored.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
## Can I use Solara in my existing FastAPI/Starlette/Flask server?
|
|
48
|
-
|
|
49
|
-
Yes, take a look at the `solara.server.starlette` and `solara.server.fastapi` and `solara.server.flask` module. The usage will change over time, so read the source and be ready to change this in the future. We do plan to provide a stable API for this in the future.
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
## How to fix: inotify watch limit reached?
|
|
53
|
-
|
|
54
|
-
Add the line
|
|
55
|
-
|
|
56
|
-
fs.inotify.max_user_watches=524288
|
|
57
|
-
|
|
58
|
-
To your /etc/sysctl.conf file, and run `sudo sysctl -p.`
|
|
59
|
-
|
|
60
|
-
Or if you are using visual studio code, please read: https://code.visualstudio.com/docs/setup/linux#_visual-studio-code-is-unable-to-watch-for-file-changes-in-this-large-workspace-error-enospc
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
## How can I recognize if I run in Solara, Voila or Jupyter Notebook/Lab
|
|
64
|
-
|
|
65
|
-
Voila and Solara set the following environment variables (based on the CGI spec):
|
|
66
|
-
|
|
67
|
-
* SERVER_SOFTWARE
|
|
68
|
-
* Solara: e.g. 'solara/1.2.3'
|
|
69
|
-
* Voila: e.g. 'voila/1.2.3'
|
|
70
|
-
* SERVER_PORT (e.g. '8765')
|
|
71
|
-
* SERVER_NAME (e.g. 'killerapp.com')
|
|
72
|
-
* SCRIPT_NAME (only Voila, e.g. 'voila/render/notebook.ipynb')
|
|
73
|
-
* PATH_TRANSLATED (only Solara e.g. '/mnt/someapp/app.py')
|
|
74
|
-
|
|
75
|
-
Jupyter Notebook/Lab/Server do not set these variables. With this information,
|
|
76
|
-
it should be possible to recognize in which environment you are running in.
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
|
|
3
|
-
from solara.autorouting import generate_routes_directory
|
|
4
|
-
from solara.website.components.markdown import MarkdownWithMetadata
|
|
5
|
-
|
|
6
|
-
HERE = Path(__file__)
|
|
7
|
-
# if we didn't put the content in the subdirectory, but pointed to the current file
|
|
8
|
-
# we would include the current file recursively, causing an infinite loop
|
|
9
|
-
routes = generate_routes_directory(HERE.parent / "content", MarkdownWithMetadata)
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Solara Quickstart
|
|
3
|
-
description: Get started with building web- and data-apps in pure python with Solara.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Quickstart
|
|
7
|
-
|
|
8
|
-
This 1-minute quickstart will get you to:
|
|
9
|
-
|
|
10
|
-
* Install Solara.
|
|
11
|
-
* Write your first Solara script.
|
|
12
|
-
* Run your script using Solara server.
|
|
13
|
-
* (Optional) Reuse your code in the Jupyter notebook.
|
|
14
|
-
|
|
15
|
-
If you are an existing ipywidget user and do not want to learn the component based method, you might want to skip the quickstart and directly go to the [IPywidgets user tutorial](/documentation/getting_started/tutorials/ipywidgets).
|
|
16
|
-
|
|
17
|
-
## Installation
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
Run `pip install solara`, or follow the [Installation instructions](/documentation/getting_started/installing) for more detailed instructions.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
## First script
|
|
24
|
-
|
|
25
|
-
Put the following Python snippet in a file (we suggest `sol.py`), or put it in a Jupyter notebook cell:
|
|
26
|
-
|
|
27
|
-
```solara
|
|
28
|
-
import solara
|
|
29
|
-
|
|
30
|
-
# Declare reactive variables at the top level. Components using these variables
|
|
31
|
-
# will be re-executed when their values change.
|
|
32
|
-
sentence = solara.reactive("Solara makes our team more productive.")
|
|
33
|
-
word_limit = solara.reactive(10)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
@solara.component
|
|
37
|
-
def Page():
|
|
38
|
-
# Calculate word_count within the component to ensure re-execution when reactive variables change.
|
|
39
|
-
word_count = len(sentence.value.split())
|
|
40
|
-
|
|
41
|
-
solara.SliderInt("Word limit", value=word_limit, min=2, max=20)
|
|
42
|
-
solara.InputText(label="Your sentence", value=sentence, continuous_update=True)
|
|
43
|
-
|
|
44
|
-
# Display messages based on the current word count and word limit.
|
|
45
|
-
if word_count >= int(word_limit.value):
|
|
46
|
-
solara.Error(f"With {word_count} words, you passed the word limit of {word_limit.value}.")
|
|
47
|
-
elif word_count >= int(0.8 * word_limit.value):
|
|
48
|
-
solara.Warning(f"With {word_count} words, you are close to the word limit of {word_limit.value}.")
|
|
49
|
-
else:
|
|
50
|
-
solara.Success("Great short writing!")
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
# The following line is required only when running the code in a Jupyter notebook:
|
|
54
|
-
Page()
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
Yes, the above example is running live on the Solara documentation web server. If you change the slider the output updates.
|
|
58
|
-
|
|
59
|
-
## Run the script using Solara server
|
|
60
|
-
|
|
61
|
-
Run from the command line in the same directory where you put your file (`sol.py`):
|
|
62
|
-
|
|
63
|
-
```bash
|
|
64
|
-
$ solara run sol.py
|
|
65
|
-
Solara server is starting at http://localhost:8765
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
If you open the URL in your browser ([http://localhost:8765](http://localhost:8765)), you should see the same graph in your browser, now running on your computer.
|
|
69
|
-
|
|
70
|
-
## Reuse your code in the Jupyter notebook.
|
|
71
|
-
|
|
72
|
-
From Jupyter Notebook (classic) or Jupyter Lab, navigate to the same directory as `sol.py`. Enter the following code in a notebook cell:
|
|
73
|
-
|
|
74
|
-
```python
|
|
75
|
-
from sol import Page
|
|
76
|
-
display(Page())
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
You should see the following output:
|
|
80
|
-
|
|
81
|
-
<img src="https://dxhl76zpt6fap.cloudfront.net/public/quickstart-notebook.webp" alt="Markdown Monster icon" style="border: 1px solid #ccc;" />
|
|
82
|
-
|
|
83
|
-
In case you forgot how to start a notebook server:
|
|
84
|
-
|
|
85
|
-
$ jupyter notebook
|
|
86
|
-
|
|
87
|
-
Or the more modern Jupyter lab:
|
|
88
|
-
|
|
89
|
-
$ jupyter lab
|