solara-ui 1.31.0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- prefix/etc/jupyter/jupyter_notebook_config.d/solara.json +7 -0
- prefix/etc/jupyter/jupyter_server_config.d/solara.json +7 -0
- solara/__init__.py +124 -0
- solara/__main__.py +734 -0
- solara/alias.py +6 -0
- solara/autorouting.py +546 -0
- solara/cache.py +303 -0
- solara/checks.html +71 -0
- solara/checks.py +224 -0
- solara/comm.py +28 -0
- solara/components/__init__.py +59 -0
- solara/components/alert.py +155 -0
- solara/components/applayout.py +393 -0
- solara/components/button.py +85 -0
- solara/components/card.py +87 -0
- solara/components/checkbox.py +50 -0
- solara/components/code_highlight_css.py +11 -0
- solara/components/code_highlight_css.vue +63 -0
- solara/components/columns.py +159 -0
- solara/components/component_vue.py +110 -0
- solara/components/cross_filter.py +335 -0
- solara/components/dataframe.py +546 -0
- solara/components/datatable.py +221 -0
- solara/components/datatable.vue +175 -0
- solara/components/details.py +21 -0
- solara/components/download.vue +35 -0
- solara/components/echarts.py +75 -0
- solara/components/echarts.vue +128 -0
- solara/components/figure_altair.py +39 -0
- solara/components/file_browser.py +182 -0
- solara/components/file_download.py +199 -0
- solara/components/file_drop.py +139 -0
- solara/components/file_drop.vue +83 -0
- solara/components/file_list_widget.vue +78 -0
- solara/components/head.py +27 -0
- solara/components/head_tag.py +49 -0
- solara/components/head_tag.vue +60 -0
- solara/components/image.py +173 -0
- solara/components/input.py +436 -0
- solara/components/link.py +55 -0
- solara/components/markdown.py +378 -0
- solara/components/markdown_editor.py +25 -0
- solara/components/markdown_editor.vue +362 -0
- solara/components/matplotlib.py +74 -0
- solara/components/meta.py +47 -0
- solara/components/misc.py +333 -0
- solara/components/pivot_table.py +258 -0
- solara/components/pivot_table.vue +158 -0
- solara/components/progress.py +47 -0
- solara/components/select.py +182 -0
- solara/components/select.vue +27 -0
- solara/components/slider.py +442 -0
- solara/components/slider_date.vue +56 -0
- solara/components/spinner-solara.vue +105 -0
- solara/components/spinner.py +30 -0
- solara/components/sql_code.py +33 -0
- solara/components/sql_code.vue +128 -0
- solara/components/style.py +105 -0
- solara/components/switch.py +68 -0
- solara/components/tab_navigation.py +37 -0
- solara/components/title.py +90 -0
- solara/components/title.vue +38 -0
- solara/components/togglebuttons.py +200 -0
- solara/components/tooltip.py +61 -0
- solara/datatypes.py +143 -0
- solara/express.py +241 -0
- solara/hooks/__init__.py +4 -0
- solara/hooks/dataframe.py +99 -0
- solara/hooks/misc.py +263 -0
- solara/hooks/use_reactive.py +129 -0
- solara/hooks/use_thread.py +129 -0
- solara/kitchensink.py +8 -0
- solara/lab/__init__.py +34 -0
- solara/lab/components/__init__.py +6 -0
- solara/lab/components/chat.py +203 -0
- solara/lab/components/confirmation_dialog.py +163 -0
- solara/lab/components/cross_filter.py +7 -0
- solara/lab/components/input_date.py +298 -0
- solara/lab/components/menu.py +181 -0
- solara/lab/components/menu.vue +38 -0
- solara/lab/components/tabs.py +274 -0
- solara/lab/components/theming.py +98 -0
- solara/lab/components/theming.vue +72 -0
- solara/lab/hooks/__init__.py +0 -0
- solara/lab/hooks/dataframe.py +12 -0
- solara/lab/toestand.py +3 -0
- solara/lab/utils/__init__.py +2 -0
- solara/lab/utils/cookies.py +5 -0
- solara/lab/utils/dataframe.py +115 -0
- solara/lab/utils/headers.py +5 -0
- solara/layout.py +44 -0
- solara/lifecycle.py +46 -0
- solara/minisettings.py +133 -0
- solara/py.typed +0 -0
- solara/reactive.py +93 -0
- solara/routing.py +268 -0
- solara/scope/__init__.py +88 -0
- solara/scope/types.py +55 -0
- solara/server/__init__.py +0 -0
- solara/server/app.py +491 -0
- solara/server/assets/custom.css +1 -0
- solara/server/assets/custom.js +1 -0
- solara/server/assets/favicon.png +0 -0
- solara/server/assets/favicon.svg +5 -0
- solara/server/assets/style.css +1665 -0
- solara/server/assets/theme-dark.css +437 -0
- solara/server/assets/theme-light.css +420 -0
- solara/server/assets/theme.js +3 -0
- solara/server/cdn_helper.py +77 -0
- solara/server/esm.py +69 -0
- solara/server/fastapi.py +5 -0
- solara/server/flask.py +286 -0
- solara/server/jupyter/__init__.py +2 -0
- solara/server/jupyter/cdn_handler.py +28 -0
- solara/server/jupyter/server_extension.py +29 -0
- solara/server/jupytertools.py +46 -0
- solara/server/kernel.py +338 -0
- solara/server/kernel_context.py +357 -0
- solara/server/patch.py +552 -0
- solara/server/reload.py +242 -0
- solara/server/server.py +456 -0
- solara/server/settings.py +215 -0
- solara/server/shell.py +251 -0
- solara/server/starlette.py +601 -0
- solara/server/static/ansi.js +270 -0
- solara/server/static/highlight-dark.css +82 -0
- solara/server/static/highlight.css +43 -0
- solara/server/static/main-vuetify.js +260 -0
- solara/server/static/main.js +163 -0
- solara/server/static/solara_bootstrap.py +129 -0
- solara/server/static/sun.svg +23 -0
- solara/server/static/webworker.js +42 -0
- solara/server/telemetry.py +212 -0
- solara/server/templates/index.html.j2 +1 -0
- solara/server/templates/loader-plain.css +11 -0
- solara/server/templates/loader-plain.html +20 -0
- solara/server/templates/loader-solara.css +111 -0
- solara/server/templates/loader-solara.html +40 -0
- solara/server/templates/plain.html +82 -0
- solara/server/templates/solara.html.j2 +446 -0
- solara/server/threaded.py +75 -0
- solara/server/utils.py +30 -0
- solara/server/websocket.py +45 -0
- solara/settings.py +56 -0
- solara/tasks.py +837 -0
- solara/template/button.py +16 -0
- solara/template/markdown.py +42 -0
- solara/template/portal/.flake8 +6 -0
- solara/template/portal/.pre-commit-config.yaml +28 -0
- solara/template/portal/LICENSE +21 -0
- solara/template/portal/Procfile +7 -0
- solara/template/portal/mypy.ini +3 -0
- solara/template/portal/pyproject.toml +26 -0
- solara/template/portal/solara_portal/__init__.py +4 -0
- solara/template/portal/solara_portal/components/__init__.py +2 -0
- solara/template/portal/solara_portal/components/article.py +28 -0
- solara/template/portal/solara_portal/components/data.py +28 -0
- solara/template/portal/solara_portal/components/header.py +6 -0
- solara/template/portal/solara_portal/components/layout.py +6 -0
- solara/template/portal/solara_portal/content/articles/equis-in-vidi.md +85 -0
- solara/template/portal/solara_portal/content/articles/substiterat-vati.md +70 -0
- solara/template/portal/solara_portal/data.py +60 -0
- solara/template/portal/solara_portal/pages/__init__.py +67 -0
- solara/template/portal/solara_portal/pages/article/__init__.py +26 -0
- solara/template/portal/solara_portal/pages/tabular.py +29 -0
- solara/template/portal/solara_portal/pages/viz/__init__.py +70 -0
- solara/template/portal/solara_portal/pages/viz/overview.py +14 -0
- solara/test/__init__.py +0 -0
- solara/test/pytest_plugin.py +697 -0
- solara/toestand.py +772 -0
- solara/util.py +308 -0
- solara/website/__init__.py +0 -0
- solara/website/assets/custom.css +468 -0
- solara/website/assets/images/logo-small.png +0 -0
- solara/website/assets/images/logo.svg +17 -0
- solara/website/assets/images/logo_white.svg +50 -0
- solara/website/assets/theme.js +8 -0
- solara/website/components/__init__.py +5 -0
- solara/website/components/algolia.vue +24 -0
- solara/website/components/algolia_api.vue +187 -0
- solara/website/components/docs.py +118 -0
- solara/website/components/header.py +72 -0
- solara/website/components/hero.py +15 -0
- solara/website/components/mailchimp.py +12 -0
- solara/website/components/mailchimp.vue +47 -0
- solara/website/components/markdown.py +30 -0
- solara/website/components/notebook.py +171 -0
- solara/website/pages/__init__.py +575 -0
- solara/website/pages/apps/__init__.py +16 -0
- solara/website/pages/apps/authorization/__init__.py +119 -0
- solara/website/pages/apps/authorization/admin.py +12 -0
- solara/website/pages/apps/authorization/users.py +12 -0
- solara/website/pages/apps/jupyter-dashboard-1.py +116 -0
- solara/website/pages/apps/layout-demo.py +40 -0
- solara/website/pages/apps/multipage/__init__.py +38 -0
- solara/website/pages/apps/multipage/page1.py +26 -0
- solara/website/pages/apps/multipage/page2.py +34 -0
- solara/website/pages/apps/scatter.py +136 -0
- solara/website/pages/apps/scrolling.py +63 -0
- solara/website/pages/apps/tutorial-streamlit.py +18 -0
- solara/website/pages/changelog/__init__.py +8 -0
- solara/website/pages/changelog/changelog.md +204 -0
- solara/website/pages/contact/__init__.py +8 -0
- solara/website/pages/contact/contact.md +17 -0
- solara/website/pages/doc_use_download.py +85 -0
- solara/website/pages/documentation/__init__.py +184 -0
- solara/website/pages/documentation/advanced/__init__.py +9 -0
- solara/website/pages/documentation/advanced/content/00-overview.md +1 -0
- solara/website/pages/documentation/advanced/content/10-howto/00-overview.md +6 -0
- solara/website/pages/documentation/advanced/content/10-howto/10-multipage.md +196 -0
- solara/website/pages/documentation/advanced/content/10-howto/20-layout.md +125 -0
- solara/website/pages/documentation/advanced/content/10-howto/30-testing.md +162 -0
- solara/website/pages/documentation/advanced/content/10-howto/31-debugging.md +69 -0
- solara/website/pages/documentation/advanced/content/10-howto/40-embed.md +49 -0
- solara/website/pages/documentation/advanced/content/10-howto/50-ipywidget_libraries.md +124 -0
- solara/website/pages/documentation/advanced/content/15-reference/00-overview.md +3 -0
- solara/website/pages/documentation/advanced/content/15-reference/40-static_files.md +31 -0
- solara/website/pages/documentation/advanced/content/15-reference/41-asset-files.md +36 -0
- solara/website/pages/documentation/advanced/content/15-reference/60-static-site-generation.md +59 -0
- solara/website/pages/documentation/advanced/content/15-reference/70-search.md +34 -0
- solara/website/pages/documentation/advanced/content/15-reference/80-reloading.md +34 -0
- solara/website/pages/documentation/advanced/content/15-reference/90-notebook-support.md +7 -0
- solara/website/pages/documentation/advanced/content/15-reference/95-caching.md +148 -0
- solara/website/pages/documentation/advanced/content/20-understanding/00-introduction.md +10 -0
- solara/website/pages/documentation/advanced/content/20-understanding/05-ipywidgets.md +35 -0
- solara/website/pages/documentation/advanced/content/20-understanding/06-ipyvuetify.md +42 -0
- solara/website/pages/documentation/advanced/content/20-understanding/10-reacton.md +28 -0
- solara/website/pages/documentation/advanced/content/20-understanding/12-reacton-basics.md +108 -0
- solara/website/pages/documentation/advanced/content/20-understanding/15-anatomy.md +23 -0
- solara/website/pages/documentation/advanced/content/20-understanding/17-rules-of-hooks.md +7 -0
- solara/website/pages/documentation/advanced/content/20-understanding/18-containers.md +166 -0
- solara/website/pages/documentation/advanced/content/20-understanding/20-solara.md +18 -0
- solara/website/pages/documentation/advanced/content/20-understanding/40-routing.md +240 -0
- solara/website/pages/documentation/advanced/content/20-understanding/50-solara-server.md +97 -0
- solara/website/pages/documentation/advanced/content/20-understanding/60-voila.md +12 -0
- solara/website/pages/documentation/advanced/content/30-enterprise/00-overview.md +1 -0
- solara/website/pages/documentation/advanced/content/30-enterprise/10-oauth.md +171 -0
- solara/website/pages/documentation/advanced/content/40-development/00-overview.md +0 -0
- solara/website/pages/documentation/advanced/content/40-development/01-contribute.md +45 -0
- solara/website/pages/documentation/advanced/content/40-development/10-setup.md +76 -0
- solara/website/pages/documentation/api/__init__.py +19 -0
- solara/website/pages/documentation/api/cross_filter/__init__.py +9 -0
- solara/website/pages/documentation/api/cross_filter/cross_filter_dataframe.py +23 -0
- solara/website/pages/documentation/api/cross_filter/cross_filter_report.py +22 -0
- solara/website/pages/documentation/api/cross_filter/cross_filter_select.py +22 -0
- solara/website/pages/documentation/api/cross_filter/cross_filter_slider.py +22 -0
- solara/website/pages/documentation/api/hooks/__init__.py +9 -0
- solara/website/pages/documentation/api/hooks/use_cross_filter.py +25 -0
- solara/website/pages/documentation/api/hooks/use_dark_effective.py +12 -0
- solara/website/pages/documentation/api/hooks/use_effect.md +43 -0
- solara/website/pages/documentation/api/hooks/use_effect.py +9 -0
- solara/website/pages/documentation/api/hooks/use_exception.py +33 -0
- solara/website/pages/documentation/api/hooks/use_memo.md +16 -0
- solara/website/pages/documentation/api/hooks/use_memo.py +9 -0
- solara/website/pages/documentation/api/hooks/use_previous.py +33 -0
- solara/website/pages/documentation/api/hooks/use_reactive.py +16 -0
- solara/website/pages/documentation/api/hooks/use_state.py +10 -0
- solara/website/pages/documentation/api/hooks/use_state_or_update.py +69 -0
- solara/website/pages/documentation/api/hooks/use_thread.md +58 -0
- solara/website/pages/documentation/api/hooks/use_thread.py +44 -0
- solara/website/pages/documentation/api/hooks/use_trait_observe.py +12 -0
- solara/website/pages/documentation/api/routing/__init__.py +9 -0
- solara/website/pages/documentation/api/routing/generate_routes.py +10 -0
- solara/website/pages/documentation/api/routing/generate_routes_directory.py +10 -0
- solara/website/pages/documentation/api/routing/resolve_path.py +35 -0
- solara/website/pages/documentation/api/routing/route.py +31 -0
- solara/website/pages/documentation/api/routing/use_route.py +80 -0
- solara/website/pages/documentation/api/routing/use_router.py +16 -0
- solara/website/pages/documentation/api/utilities/__init__.py +9 -0
- solara/website/pages/documentation/api/utilities/component_vue.py +10 -0
- solara/website/pages/documentation/api/utilities/computed.py +16 -0
- solara/website/pages/documentation/api/utilities/display.py +16 -0
- solara/website/pages/documentation/api/utilities/get_kernel_id.py +16 -0
- solara/website/pages/documentation/api/utilities/get_session_id.py +16 -0
- solara/website/pages/documentation/api/utilities/memoize.py +35 -0
- solara/website/pages/documentation/api/utilities/on_kernel_start.py +27 -0
- solara/website/pages/documentation/api/utilities/reactive.py +16 -0
- solara/website/pages/documentation/api/utilities/widget.py +104 -0
- solara/website/pages/documentation/components/__init__.py +12 -0
- solara/website/pages/documentation/components/advanced/__init__.py +9 -0
- solara/website/pages/documentation/components/advanced/link.py +27 -0
- solara/website/pages/documentation/components/advanced/meta.py +20 -0
- solara/website/pages/documentation/components/advanced/style.py +45 -0
- solara/website/pages/documentation/components/common.py +9 -0
- solara/website/pages/documentation/components/data/__init__.py +9 -0
- solara/website/pages/documentation/components/data/dataframe.py +44 -0
- solara/website/pages/documentation/components/data/pivot_table.py +81 -0
- solara/website/pages/documentation/components/enterprise/__init__.py +9 -0
- solara/website/pages/documentation/components/enterprise/avatar.py +24 -0
- solara/website/pages/documentation/components/enterprise/avatar_menu.py +25 -0
- solara/website/pages/documentation/components/input/__init__.py +9 -0
- solara/website/pages/documentation/components/input/button.py +23 -0
- solara/website/pages/documentation/components/input/checkbox.py +10 -0
- solara/website/pages/documentation/components/input/file_browser.py +32 -0
- solara/website/pages/documentation/components/input/file_drop.py +76 -0
- solara/website/pages/documentation/components/input/input.py +19 -0
- solara/website/pages/documentation/components/input/select.py +22 -0
- solara/website/pages/documentation/components/input/slider.py +29 -0
- solara/website/pages/documentation/components/input/switch.py +10 -0
- solara/website/pages/documentation/components/input/togglebuttons.py +21 -0
- solara/website/pages/documentation/components/lab/__init__.py +9 -0
- solara/website/pages/documentation/components/lab/chat.py +109 -0
- solara/website/pages/documentation/components/lab/confirmation_dialog.py +55 -0
- solara/website/pages/documentation/components/lab/cookies_headers.py +48 -0
- solara/website/pages/documentation/components/lab/input_date.py +20 -0
- solara/website/pages/documentation/components/lab/menu.py +22 -0
- solara/website/pages/documentation/components/lab/tab.py +25 -0
- solara/website/pages/documentation/components/lab/tabs.py +45 -0
- solara/website/pages/documentation/components/lab/task.py +11 -0
- solara/website/pages/documentation/components/lab/theming.py +72 -0
- solara/website/pages/documentation/components/lab/use_task.py +11 -0
- solara/website/pages/documentation/components/layout/__init__.py +9 -0
- solara/website/pages/documentation/components/layout/app_bar.py +16 -0
- solara/website/pages/documentation/components/layout/app_bar_title.py +16 -0
- solara/website/pages/documentation/components/layout/app_layout.py +24 -0
- solara/website/pages/documentation/components/layout/card.py +15 -0
- solara/website/pages/documentation/components/layout/card_actions.py +16 -0
- solara/website/pages/documentation/components/layout/column.py +30 -0
- solara/website/pages/documentation/components/layout/columns.py +27 -0
- solara/website/pages/documentation/components/layout/columns_responsive.py +68 -0
- solara/website/pages/documentation/components/layout/griddraggable.py +62 -0
- solara/website/pages/documentation/components/layout/gridfixed.py +21 -0
- solara/website/pages/documentation/components/layout/hbox.py +18 -0
- solara/website/pages/documentation/components/layout/row.py +30 -0
- solara/website/pages/documentation/components/layout/sidebar.py +24 -0
- solara/website/pages/documentation/components/layout/vbox.py +19 -0
- solara/website/pages/documentation/components/output/__init__.py +9 -0
- solara/website/pages/documentation/components/output/file_download.py +11 -0
- solara/website/pages/documentation/components/output/html.py +21 -0
- solara/website/pages/documentation/components/output/image.py +11 -0
- solara/website/pages/documentation/components/output/markdown.py +57 -0
- solara/website/pages/documentation/components/output/markdown_editor.py +51 -0
- solara/website/pages/documentation/components/output/sql_code.py +85 -0
- solara/website/pages/documentation/components/output/tooltip.py +11 -0
- solara/website/pages/documentation/components/page/__init__.py +9 -0
- solara/website/pages/documentation/components/page/head.py +18 -0
- solara/website/pages/documentation/components/page/title.py +27 -0
- solara/website/pages/documentation/components/status/__init__.py +9 -0
- solara/website/pages/documentation/components/status/error.py +40 -0
- solara/website/pages/documentation/components/status/info.py +40 -0
- solara/website/pages/documentation/components/status/progress.py +10 -0
- solara/website/pages/documentation/components/status/spinner.py +11 -0
- solara/website/pages/documentation/components/status/success.py +40 -0
- solara/website/pages/documentation/components/status/warning.py +47 -0
- solara/website/pages/documentation/components/viz/__init__.py +9 -0
- solara/website/pages/documentation/components/viz/altair.py +42 -0
- solara/website/pages/documentation/components/viz/echarts.py +75 -0
- solara/website/pages/documentation/components/viz/matplotlib.py +30 -0
- solara/website/pages/documentation/components/viz/plotly.py +63 -0
- solara/website/pages/documentation/components/viz/plotly_express.py +41 -0
- solara/website/pages/documentation/examples/__init__.py +52 -0
- solara/website/pages/documentation/examples/ai/__init__.py +11 -0
- solara/website/pages/documentation/examples/ai/chatbot.py +95 -0
- solara/website/pages/documentation/examples/ai/tokenizer.py +107 -0
- solara/website/pages/documentation/examples/basics/__init__.py +10 -0
- solara/website/pages/documentation/examples/basics/sine.py +28 -0
- solara/website/pages/documentation/examples/fullscreen/__init__.py +10 -0
- solara/website/pages/documentation/examples/fullscreen/authorization.py +3 -0
- solara/website/pages/documentation/examples/fullscreen/layout_demo.py +3 -0
- solara/website/pages/documentation/examples/fullscreen/multipage.py +3 -0
- solara/website/pages/documentation/examples/fullscreen/scatter.py +3 -0
- solara/website/pages/documentation/examples/fullscreen/scrolling.py +3 -0
- solara/website/pages/documentation/examples/fullscreen/tutorial_streamlit.py +3 -0
- solara/website/pages/documentation/examples/general/__init__.py +10 -0
- solara/website/pages/documentation/examples/general/custom_storage.py +70 -0
- solara/website/pages/documentation/examples/general/deploy_model.py +115 -0
- solara/website/pages/documentation/examples/general/live_update.py +38 -0
- solara/website/pages/documentation/examples/general/login_oauth.py +81 -0
- solara/website/pages/documentation/examples/general/mycard.vue +58 -0
- solara/website/pages/documentation/examples/general/pokemon_search.py +51 -0
- solara/website/pages/documentation/examples/general/vue_component.py +50 -0
- solara/website/pages/documentation/examples/ipycanvas.py +49 -0
- solara/website/pages/documentation/examples/libraries/__init__.py +10 -0
- solara/website/pages/documentation/examples/libraries/altair.py +64 -0
- solara/website/pages/documentation/examples/libraries/bqplot.py +39 -0
- solara/website/pages/documentation/examples/libraries/ipyleaflet.py +33 -0
- solara/website/pages/documentation/examples/libraries/ipyleaflet_advanced.py +66 -0
- solara/website/pages/documentation/examples/utilities/__init__.py +10 -0
- solara/website/pages/documentation/examples/utilities/calculator.py +157 -0
- solara/website/pages/documentation/examples/utilities/countdown_timer.py +64 -0
- solara/website/pages/documentation/examples/utilities/todo.py +196 -0
- solara/website/pages/documentation/examples/visualization/__init__.py +6 -0
- solara/website/pages/documentation/examples/visualization/annotator.py +69 -0
- solara/website/pages/documentation/examples/visualization/linked_views.py +84 -0
- solara/website/pages/documentation/examples/visualization/plotly.py +44 -0
- solara/website/pages/documentation/faq/__init__.py +12 -0
- solara/website/pages/documentation/faq/content/99-faq.md +76 -0
- solara/website/pages/documentation/getting_started/__init__.py +9 -0
- solara/website/pages/documentation/getting_started/content/00-quickstart.md +89 -0
- solara/website/pages/documentation/getting_started/content/01-introduction.md +125 -0
- solara/website/pages/documentation/getting_started/content/02-installing.md +134 -0
- solara/website/pages/documentation/getting_started/content/04-tutorials/00-overview.md +14 -0
- solara/website/pages/documentation/getting_started/content/04-tutorials/10_data_science.py +13 -0
- solara/website/pages/documentation/getting_started/content/04-tutorials/20-web-app.md +89 -0
- solara/website/pages/documentation/getting_started/content/04-tutorials/30-ipywidgets.md +124 -0
- solara/website/pages/documentation/getting_started/content/04-tutorials/40-streamlit.md +146 -0
- solara/website/pages/documentation/getting_started/content/04-tutorials/50-dash.md +144 -0
- solara/website/pages/documentation/getting_started/content/04-tutorials/60-jupyter-dashboard-part1.py +64 -0
- 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 +445 -0
- solara/website/pages/documentation/getting_started/content/04-tutorials/_jupyter_dashboard_1.ipynb +1000 -0
- solara/website/pages/documentation/getting_started/content/05-fundamentals/00-overview.md +11 -0
- solara/website/pages/documentation/getting_started/content/05-fundamentals/10-components.md +223 -0
- solara/website/pages/documentation/getting_started/content/05-fundamentals/50-state-management.md +88 -0
- solara/website/pages/documentation/getting_started/content/07-deploying/00-overview.md +7 -0
- solara/website/pages/documentation/getting_started/content/07-deploying/10-self-hosted.md +273 -0
- solara/website/pages/documentation/getting_started/content/07-deploying/20-cloud-hosted.md +80 -0
- solara/website/pages/documentation/getting_started/content/80-what-is-lab.md +7 -0
- solara/website/pages/documentation/getting_started/content/90-troubleshoot.md +26 -0
- solara/website/pages/docutils.py +38 -0
- solara/website/pages/showcase/__init__.py +105 -0
- solara/website/pages/showcase/domino_code_assist.py +60 -0
- solara/website/pages/showcase/planeto_tessa.py +19 -0
- solara/website/pages/showcase/solara_dev.py +54 -0
- solara/website/pages/showcase/solarathon_2023_team_2.py +22 -0
- solara/website/pages/showcase/solarathon_2023_team_4.py +22 -0
- solara/website/pages/showcase/solarathon_2023_team_5.py +23 -0
- solara/website/pages/showcase/solarathon_2023_team_6.py +34 -0
- solara/website/pages/showcase/wanderlust.py +27 -0
- solara/website/public/beach.jpeg +0 -0
- solara/website/public/logo.svg +6 -0
- solara/website/public/social/discord.svg +1 -0
- solara/website/public/social/github.svg +1 -0
- solara/website/public/social/twitter.svg +3 -0
- solara/website/public/success.html +25 -0
- solara/website/templates/index.html.j2 +117 -0
- solara/website/utils.py +51 -0
- solara/widgets/__init__.py +1 -0
- solara/widgets/vue/gridlayout.vue +110 -0
- solara/widgets/vue/html.vue +4 -0
- solara/widgets/vue/navigator.vue +104 -0
- solara/widgets/vue/vegalite.vue +115 -0
- solara/widgets/widgets.py +66 -0
- solara_ui-1.31.0.data/data/etc/jupyter/jupyter_notebook_config.d/solara.json +7 -0
- solara_ui-1.31.0.data/data/etc/jupyter/jupyter_server_config.d/solara.json +7 -0
- solara_ui-1.31.0.dist-info/METADATA +158 -0
- solara_ui-1.31.0.dist-info/RECORD +439 -0
- solara_ui-1.31.0.dist-info/WHEEL +5 -0
- solara_ui-1.31.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Fundamentals of Solara
|
|
3
|
+
description: These articles dive deeper into the fundamental aspects of Soalra, like using components, hooks, and managing state.
|
|
4
|
+
---
|
|
5
|
+
# Fundamentals
|
|
6
|
+
|
|
7
|
+
If you want to dive deeper into Solara, this section is for you. We will cover the following topics:
|
|
8
|
+
|
|
9
|
+
* [Components](/documentation/getting_started/fundamentals/components)
|
|
10
|
+
* Hooks (soon)
|
|
11
|
+
* [State management](/documentation/getting_started/fundamentals/state-management)
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Introduction to Solara components
|
|
3
|
+
description: In Solara, components are the building blocks of your web application. They allow you to create modular, reusable, and maintainable user interface elements
|
|
4
|
+
that can be combined to create a complete and interactive application.
|
|
5
|
+
---
|
|
6
|
+
<!-- TODO: column auto -->
|
|
7
|
+
|
|
8
|
+
# Introduction to Components
|
|
9
|
+
|
|
10
|
+
In Solara, components are the building blocks of your web application. They allow you to create modular, reusable, and maintainable user interface (UI) elements that can be combined to create a complete and interactive application. Components can range from simple UI elements, such as buttons or text inputs, to more complex and custom visualizations or forms.
|
|
11
|
+
|
|
12
|
+
The primary benefits of using components in Solara include:
|
|
13
|
+
|
|
14
|
+
* Modularity: Components can be designed independently and then combined to form more complex UIs. This modular approach promotes separation of concerns, making it easier to reason about and maintain each part of your application.
|
|
15
|
+
* Reusability: Components can be reused across different parts of your application or even across multiple projects. This can save time and effort by reducing the need to rewrite similar code and can lead to more consistent UIs.
|
|
16
|
+
* Maintainability: By breaking your application into smaller, self-contained components, it becomes easier to understand, debug, and update your code. This results in more maintainable and resilient applications.
|
|
17
|
+
* Performance: When a component instance depends on a specific state, and that state changes, only the render function of the affected component instance will be re-executed. This selective re-rendering ensures that other components or instances that do not depend on the changed state remain unaffected, leading to more efficient performance.
|
|
18
|
+
|
|
19
|
+
## Types of Components
|
|
20
|
+
|
|
21
|
+
In Solara, there are two main types of components: Widget Components and Function Components.
|
|
22
|
+
|
|
23
|
+
## Widget components
|
|
24
|
+
|
|
25
|
+
Widget Components correspond to ipywidgets and are responsible for rendering visual elements in the browser, such as buttons, sliders, or performing layout tasks. These components are the foundation of your user interface and provide the essential building blocks for creating interactive applications.
|
|
26
|
+
|
|
27
|
+
Solara mainly uses the [ipyvuetify library](/documentation/advanced/understanding/ipyvuetify) for its widget components. It provides a set of high-level components that can be used to create rich, interactive user interfaces.
|
|
28
|
+
|
|
29
|
+
See the [components page](/documentation/components) for a complete list of basic UI components.
|
|
30
|
+
|
|
31
|
+
## Function Components
|
|
32
|
+
|
|
33
|
+
Function Components (Components for short), on the other hand, are responsible for combining logic, state, and other components to create more complex and dynamic applications. These components serve as a way to create reusable and modular structures that can be easily integrated into your application.
|
|
34
|
+
|
|
35
|
+
These are the components that you will be writing when building Solara applications.
|
|
36
|
+
|
|
37
|
+
By utilizing both Widget Components and Function Components, you can create flexible and powerful applications that provide a rich user experience while maintaining a clean and organized codebase.
|
|
38
|
+
|
|
39
|
+
## Creating New Components
|
|
40
|
+
|
|
41
|
+
In Solara, users can create their own custom components without any special distinction from the built-in components provided by the framework, they are all components. These user-defined components have the same capabilities and can be composed seamlessly alongside Solara's components, allowing for the creation of highly customized and reusable user interfaces.
|
|
42
|
+
|
|
43
|
+
# Defining Components
|
|
44
|
+
To create a component in Solara, you'll start by defining a Python function decorated with @solara.component. Inside the function, you can create the component's structure by calling Solara's built-in components or creating custom components to suit your specific needs. If a single element is created, it's taken as the component's main element. If multiple elements are created, they are automatically wrapped in a Column component.
|
|
45
|
+
|
|
46
|
+
Here's an example of a simple Solara component that displays a button:
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
import solara
|
|
50
|
+
|
|
51
|
+
@solara.component
|
|
52
|
+
def MyButton():
|
|
53
|
+
solara.Button("Click me!")
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
In this example, we create a component function named MyButton and apply the @solara.component decorator to it. Within the component function, a Button component from Solara is created, displaying the text "Click me!".
|
|
57
|
+
|
|
58
|
+
## Using Components
|
|
59
|
+
Once you've created your components, you can use them in your Solara app by calling the components to create elements. Elements, the lightweight representations of components, can be combined to build complex UIs. They can also be passed as arguments to other components, enabling a flexible and modular application structure.
|
|
60
|
+
|
|
61
|
+
Here's an example of using the `MyButton` component we defined earlier:
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
import solara
|
|
65
|
+
|
|
66
|
+
@solara.component
|
|
67
|
+
def MyApp():
|
|
68
|
+
MyButton()
|
|
69
|
+
MyButton()
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
In this example, we create a `MyApp` function decorated with `@solara.component`. The function create two MyButton elements, resulting in two buttons (or two component instances).
|
|
73
|
+
|
|
74
|
+
## Handling User Interactions
|
|
75
|
+
Components in Solara can capture user input and respond to events, such as button clicks or form submissions. To handle user interactions, you'll define callback functions and connect them to your components using Solara's event handling system.
|
|
76
|
+
|
|
77
|
+
Here's an example of a Solara component that displays a button and responds to click events:
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
import solara
|
|
81
|
+
|
|
82
|
+
def on_button_click(event):
|
|
83
|
+
print("Button clicked!")
|
|
84
|
+
|
|
85
|
+
@solara.component
|
|
86
|
+
def MyInteractiveButton():
|
|
87
|
+
solara.Button("Click me!", on_click=on_button_click)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
In this example, we define a function called on_button_click that will be executed when the button is clicked. In the MyInteractiveButton function, we create a Button component and set the on_click argument to the on_button_click function.
|
|
91
|
+
|
|
92
|
+
By following these steps, you can create and use components to build rich, interactive applications with Solara.
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
## Component Arguments and State
|
|
96
|
+
In Solara, components can accept arguments and maintain internal state to manage their behavior and appearance. This section will explain how to use arguments and state in your Solara components and provide code examples to demonstrate their usage.
|
|
97
|
+
|
|
98
|
+
### Component Arguments
|
|
99
|
+
Arguments are the values that you pass to a component when you call it, allowing you to customize its behavior and appearance. You can define the arguments your component accepts by specifying them as parameters in the component function. This makes your components more reusable and flexible, as you can easily modify their behavior by passing different argument values.
|
|
100
|
+
|
|
101
|
+
Here's an example of a Solara component that accepts an argument:
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
import solara
|
|
105
|
+
|
|
106
|
+
@solara.component
|
|
107
|
+
def MyButton(text):
|
|
108
|
+
solara.Button(text)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
In this example, we define a function called MyButton that takes a single argument, text. The render function creates a Button component from Solara with the specified text.
|
|
112
|
+
|
|
113
|
+
### Using Application state in Components
|
|
114
|
+
To manage the state of a component in Solara, you can use the solara.reactive() function to create reactive variables. Reactive variables are used to store values that can change over time and automatically trigger component updates when their values change. This allows you to create components that respond to changes in data and user interactions.
|
|
115
|
+
|
|
116
|
+
Here's an example that demonstrates the use of reactive variables in Solara components:
|
|
117
|
+
```solara
|
|
118
|
+
import solara
|
|
119
|
+
|
|
120
|
+
counter = solara.reactive(0)
|
|
121
|
+
|
|
122
|
+
def increment():
|
|
123
|
+
counter.value += 1
|
|
124
|
+
|
|
125
|
+
@solara.component
|
|
126
|
+
def CounterDisplay():
|
|
127
|
+
solara.Info(f"Counter: {counter.value}")
|
|
128
|
+
|
|
129
|
+
@solara.component
|
|
130
|
+
def IncrementButton():
|
|
131
|
+
solara.Button("Increment", on_click=increment)
|
|
132
|
+
|
|
133
|
+
@solara.component
|
|
134
|
+
def Page():
|
|
135
|
+
IncrementButton()
|
|
136
|
+
CounterDisplay()
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
In this example, we create a reactive variable counter with an initial value of 0. We define two components: `CounterDisplay` and `IncrementButton`. `CounterDisplay` renders the current value of counter, while `IncrementButton` increments the value of counter when clicked. Whenever the counter value changes, `CounterDisplay` automatically updates to display the new value.
|
|
141
|
+
|
|
142
|
+
By using arguments and state in your Solara components, you can create more dynamic and interactive applications that respond to user input and changes in data.
|
|
143
|
+
|
|
144
|
+
### Internal State in Components
|
|
145
|
+
|
|
146
|
+
In addition to using reactive variables for global or application-wide state, you can also manage internal or component-specific state using the use_state hook in Solara. The use_state hook allows you to define state variables that are local to a component, and automatically trigger updates when their values change.
|
|
147
|
+
|
|
148
|
+
To use the use_state hook, call the solara.use_state() function inside your component function. This function takes an initial value as an argument and returns a tuple containing the current state value and a function to update the state.
|
|
149
|
+
|
|
150
|
+
Here's an example that demonstrates the use of the use_state hook to manage internal state in a Solara component:
|
|
151
|
+
|
|
152
|
+
```solara
|
|
153
|
+
import solara
|
|
154
|
+
|
|
155
|
+
@solara.component
|
|
156
|
+
def Counter():
|
|
157
|
+
count, set_count = solara.use_state(0)
|
|
158
|
+
|
|
159
|
+
def increment():
|
|
160
|
+
set_count(count + 1)
|
|
161
|
+
|
|
162
|
+
solara.Button("Increment", on_click=increment)
|
|
163
|
+
solara.Info(f"Counter: {count}")
|
|
164
|
+
|
|
165
|
+
@solara.component
|
|
166
|
+
def Page():
|
|
167
|
+
Counter()
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
In this example, we define a Counter component that uses the use_state hook to manage its internal state. We create a state variable count with an initial value of 0 and a function set_count to update the state. The increment function increments the value of count when the button is clicked. Whenever the count value changes, the component automatically updates to display the new value.
|
|
171
|
+
|
|
172
|
+
By using the use_state hook, you can manage the internal state of your components and create more dynamic and interactive applications that respond to user input and changes in data.
|
|
173
|
+
|
|
174
|
+
## Lazy Rendering in Solara Components
|
|
175
|
+
|
|
176
|
+
In Solara, understanding the relationship between components, elements, and instances is essential to grasp the rendering process. Components serve as a blueprint or template for defining the structure and behavior of a part of the user interface. Elements are lightweight virtual representations of components, created when the components are invoked. Instances, on the other hand, represent the function body of the component and its state.
|
|
177
|
+
|
|
178
|
+
Solara employs a "lazy rendering" approach, where the rendering of a component's children is deferred until it is necessary. When a component is invoked, an element is created immediately, representing that particular instance of the component. However, the actual rendering of the component's children is postponed until the component is rendered within the virtual tree, either as a child of another component or as the root component. This allows Solara to optimize the rendering process and update only the necessary components when the application state or component arguments change.
|
|
179
|
+
|
|
180
|
+
Lazy rendering in Solara ensures that the render function is executed only when necessary, improving the application's performance. To illustrate this concept, let's consider the following example:
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
```solara
|
|
184
|
+
import solara
|
|
185
|
+
|
|
186
|
+
counter = solara.reactive(0)
|
|
187
|
+
|
|
188
|
+
@solara.component
|
|
189
|
+
def CounterDisplay():
|
|
190
|
+
solara.Info(f"Counter: {counter.value}")
|
|
191
|
+
|
|
192
|
+
@solara.component
|
|
193
|
+
def IncrementButton():
|
|
194
|
+
def increment():
|
|
195
|
+
counter.value += 1
|
|
196
|
+
|
|
197
|
+
solara.Button("Increment", on_click=increment)
|
|
198
|
+
|
|
199
|
+
@solara.component
|
|
200
|
+
def RandomText():
|
|
201
|
+
import random
|
|
202
|
+
solara.Info(f"Random number: {random.random()}")
|
|
203
|
+
|
|
204
|
+
@solara.component
|
|
205
|
+
def Page():
|
|
206
|
+
IncrementButton()
|
|
207
|
+
CounterDisplay()
|
|
208
|
+
RandomText()
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
In this example, we define several components: `IncrementButton`, `CounterDisplay`, and `RandomText`. The `IncrementButton` component increments the value of the counter reactive variable when clicked. The `CounterDisplay` component displays the current value of the counter. The `RandomText` component displays a random number but does not depend on any state or reactive variables.
|
|
212
|
+
|
|
213
|
+
When the user clicks the `IncrementButton`, the counter reactive variable is updated, and the `CounterDisplay` component re-renders to show the new value. The RandomText component does not re-render in this scenario because it does not depend on any state or reactive variables.
|
|
214
|
+
|
|
215
|
+
This example demonstrates Solara's lazy rendering, where only the relevant components are instantiated and rendered based on changes in their arguments or internal state. This ensures that the render function is executed only when necessary, improving the application's performance.
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
## Conclusions
|
|
219
|
+
In conclusion, understanding components, their arguments, and how to manage their internal state is crucial for building Solara applications. To create more advanced components, you need to have a deeper understanding of hooks, such as the use_state hook we have already discussed.
|
|
220
|
+
|
|
221
|
+
In the next fundamentals article, we will explore more hooks available in Solara, which will enable you to build more sophisticated components that cater to a wide range of use cases. By learning about hooks, you can create powerful components that can manage state, interact with other components, and respond to user input.
|
|
222
|
+
|
|
223
|
+
To summarize, components are the building blocks of Solara applications, and they can accept arguments to customize their behavior and appearance. Managing state in components can be done either through local (component) state or application-wide state, each with its advantages and disadvantages. By striking a balance between reusable components and application-specific code, you can create scalable and maintainable applications in Solara. With a solid understanding of components and their state management, you are well on your way to creating powerful and interactive web applications with Solara.
|
solara/website/pages/documentation/getting_started/content/05-fundamentals/50-state-management.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Introduction to state management in Solara
|
|
3
|
+
description: State management is a crucial aspect of building data-focused web applications with Solara. By effectively managing state, you can create interactive
|
|
4
|
+
and responsive applications that react to changes in data and user input.
|
|
5
|
+
---
|
|
6
|
+
# Introduction
|
|
7
|
+
|
|
8
|
+
State management is a crucial aspect of building data-focused web applications with Solara. By effectively managing state, you can create interactive and responsive applications that react to changes in data and user input. In Solara, there are two primary ways to define state: global application state using [`solara.reactive`](/documentation/api/utilities/reactive) and local component state using [`solara.use_state`](/documentation/api/hooks/use_state) or [`solara.use_reactive`](/documentation/api/hooks/use_reactive). This article will discuss these two approaches and provide examples of how to use them in your Solara applications.
|
|
9
|
+
|
|
10
|
+
## Two main ways of defining state in Solara
|
|
11
|
+
|
|
12
|
+
### Global application state using solara.reactive
|
|
13
|
+
|
|
14
|
+
Using [`solara.reactive`](/documentation/api/utilities/reactive) allows you to create global state variables that can be accessed and modified from any component within your application. This approach is useful when you need to manage state that is shared across multiple components or when you want to maintain consistency throughout your application.
|
|
15
|
+
|
|
16
|
+
Example:
|
|
17
|
+
|
|
18
|
+
```solara
|
|
19
|
+
import solara
|
|
20
|
+
|
|
21
|
+
color = solara.reactive("red")
|
|
22
|
+
|
|
23
|
+
@solara.component
|
|
24
|
+
def SomeAppSpecificComponent():
|
|
25
|
+
solara.Select(label="Color", values=["red", "green", "blue", "orange"], value=color)
|
|
26
|
+
solara.Markdown("### Solara is awesome", style={"color": color.value})
|
|
27
|
+
|
|
28
|
+
@solara.component
|
|
29
|
+
def Page():
|
|
30
|
+
SomeAppSpecificComponent()
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
In this case, the `SomeAppSpecificComponent` is not reusable in the sense that a second component has a different state. The `color` variable is global and shared across all components. This component is meant to be used only once, and mainly helps to organize the code.
|
|
35
|
+
|
|
36
|
+
## Local component state using solara.use_state
|
|
37
|
+
|
|
38
|
+
[`solara.use_state`](/documentation/api/hooks/use_state) is a hook that allows you to manage local state within a specific component. This approach is beneficial when you want to encapsulate state within a component, making it self-contained and modular. Local state management is suitable for situations where state changes only affect the component and do not need to be shared across the application.
|
|
39
|
+
|
|
40
|
+
Example:
|
|
41
|
+
```solara
|
|
42
|
+
import solara
|
|
43
|
+
|
|
44
|
+
@solara.component
|
|
45
|
+
def ReusableComponent():
|
|
46
|
+
# color = solara.use_reactive("red") # another possibility
|
|
47
|
+
color, set_color = solara.use_state("red") # local state
|
|
48
|
+
solara.Select(label="Color",values=["red", "green", "blue", "orange"],
|
|
49
|
+
value=color, on_value=set_color)
|
|
50
|
+
solara.Markdown("### Solara is awesome", style={"color": color})
|
|
51
|
+
|
|
52
|
+
@solara.component
|
|
53
|
+
def Page():
|
|
54
|
+
# this component is used twice, but each instance has its own state
|
|
55
|
+
ReusableComponent()
|
|
56
|
+
ReusableComponent()
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Local component state using solara.use_reactive
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
`use_reactive` is the middle ground between `use_state` and `reactive`. It allows you to create a reactive variable that is scoped to a specific component. This is more a matter of taste, we generally recommend using `use_reactive`, but if you prefer a little less magic, you can use `use_state` instead.
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
If we take the previous example using `use_state`, are replace `use_state` by `use_reactive`, we get:
|
|
67
|
+
```solara
|
|
68
|
+
import solara
|
|
69
|
+
|
|
70
|
+
@solara.component
|
|
71
|
+
def ReusableComponent():
|
|
72
|
+
color = solara.use_reactive("red") # another possibility
|
|
73
|
+
solara.Select(label="Color",values=["red", "green", "blue", "orange"],
|
|
74
|
+
value=color)
|
|
75
|
+
solara.Markdown("### Solara is awesome", style={"color": color.value})
|
|
76
|
+
|
|
77
|
+
@solara.component
|
|
78
|
+
def Page():
|
|
79
|
+
# this component is used twice, but each instance has its own state
|
|
80
|
+
ReusableComponent()
|
|
81
|
+
ReusableComponent()
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Conclusion
|
|
86
|
+
Understanding the advantages and disadvantages of reusable components and application-specific code can help you strike the right balance between modularity and simplicity when building your Solara applications.
|
|
87
|
+
|
|
88
|
+
By understanding the trade-offs between local and application state, as well as reusable components and application-specific code, you can make better decisions when designing and building your Solara applications. Both approaches have their benefits and drawbacks, but choosing the right method for your specific use case will help you create more efficient, maintainable, and scalable applications.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Overview of how to deploy your Solara application or dashboard
|
|
3
|
+
description: Solara apps can be easily either self hosted, or hosted on a variety of cloud platforms.
|
|
4
|
+
---
|
|
5
|
+
# Deploying a solara app
|
|
6
|
+
|
|
7
|
+
A Solara app can be [self hosted](/documentation/getting_started/deploying/self-hosted) or [cloud hosted](/documentation/getting_started/deploying/cloud-hosted).
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Deploying and hosting your own Solara app
|
|
3
|
+
description: Solara is compatible with many different hosting solutions, such as Flask, Starlette, FastAPI, and Voila.
|
|
4
|
+
---
|
|
5
|
+
# Self hosted deployment
|
|
6
|
+
|
|
7
|
+
* [Flask](#flask)
|
|
8
|
+
* [Starlette](#flask)
|
|
9
|
+
* [FastAPI](#flask)
|
|
10
|
+
* [Voila](#voila)
|
|
11
|
+
* [Panel](#panel)
|
|
12
|
+
* [Nginx](#nginx)
|
|
13
|
+
* [Docker](#docker)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
Solara runs on several web frameworks, such as
|
|
17
|
+
|
|
18
|
+
* [Flask](https://flask.palletsprojects.com/)
|
|
19
|
+
* [Starlette](https://www.starlette.io/) (and thus [FastAPI](https://fastapi.tiangolo.com/))
|
|
20
|
+
|
|
21
|
+
The most straightforward and well-tested method to deploy Solara is through the `solara run` command:
|
|
22
|
+
|
|
23
|
+
$ solara run sol.py --production
|
|
24
|
+
|
|
25
|
+
which uses Starlette under the hood.
|
|
26
|
+
|
|
27
|
+
Your `sol.py` file could resemble the following:
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
import solara
|
|
31
|
+
|
|
32
|
+
clicks = solara.reactive(0)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@solara.component
|
|
36
|
+
def Page():
|
|
37
|
+
color = "green"
|
|
38
|
+
if clicks.value >= 5:
|
|
39
|
+
color = "red"
|
|
40
|
+
|
|
41
|
+
def increment():
|
|
42
|
+
clicks.value += 1
|
|
43
|
+
print("clicks", clicks) # noqa
|
|
44
|
+
|
|
45
|
+
solara.Button(label=f"Clicked: {clicks}", on_click=increment, color=color)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
If you're aiming to integrate Solara with other web frameworks such as [Flask](https://flask.palletsprojects.com/deploying/), [Starlette](https://www.starlette.io/), or [FastAPI](https://fastapi.tiangolo.com/), you normally do not execute `solara run sol.py`.
|
|
50
|
+
Instead, start your chosen web framework as directed by their documentation and configure Solara via environment variables. For instance, instead of running the development server like `solara run sol.py`, set the `SOLARA_APP` environment variable to `sol.py`:
|
|
51
|
+
|
|
52
|
+
$ export SOLARA_APP=sol.py
|
|
53
|
+
# run flask or starlette
|
|
54
|
+
|
|
55
|
+
or look at the examples below for more detailed instructions per web framework. Note that when solara is used this way it [by default runs in production mode](https://solara.dev/documentation/advanced/understanding/solara-server).
|
|
56
|
+
|
|
57
|
+
## Flask
|
|
58
|
+
|
|
59
|
+
For Flask, you can consult [the Flask documentation](https://flask.palletsprojects.com/deploying/).
|
|
60
|
+
|
|
61
|
+
A common solution is to use [gunicorn](https://gunicorn.org/) as the WSGI HTTP Server.
|
|
62
|
+
|
|
63
|
+
A typical command would be:
|
|
64
|
+
```
|
|
65
|
+
$ SOLARA_APP=sol.py gunicorn --workers 4 --threads=20 -b 0.0.0.0:8765 solara.server.flask:app
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Note that we need at least 1 thread per user due to the use of a websocket.
|
|
69
|
+
|
|
70
|
+
### Embedding in an existing Flask application
|
|
71
|
+
|
|
72
|
+
If you already have a Flask app and want to add your Solara app behind a prefix, say `'/solara/'`, you can add the [Blueprint](https://flask.palletsprojects.com/blueprints/) to your existing app as follows.
|
|
73
|
+
|
|
74
|
+
```python
|
|
75
|
+
from flask import Flask
|
|
76
|
+
import solara.server.flask
|
|
77
|
+
|
|
78
|
+
app = Flask(__name__)
|
|
79
|
+
app.register_blueprint(solara.server.flask.blueprint, url_prefix="/solara/")
|
|
80
|
+
|
|
81
|
+
@app.route("/")
|
|
82
|
+
def hello_world():
|
|
83
|
+
return "<p>Hello, World!</p>"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Save this file as `"app.py"` and run
|
|
87
|
+
|
|
88
|
+
$ SOLARA_APP=sol.py flask run
|
|
89
|
+
* Running on http://127.0.0.1:5000/
|
|
90
|
+
|
|
91
|
+
If you navigate to [http://127.0.0.1:5000/solara](http://127.0.0.1:5000/solara) you should see the Solara app.
|
|
92
|
+
|
|
93
|
+
## Starlette
|
|
94
|
+
|
|
95
|
+
For [Starlette](https://www.starlette.io/) we will assume [uvicorn](http://www.uvicorn.org/) for the ASGI webserver and follow their [deployment documentation](https://www.uvicorn.org/deployment/):
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
$ SOLARA_APP=sol.py uvicorn --workers 4 --host 0.0.0.0 --port 8765 solara.server.starlette:app
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Embedding in an existing Starlette application
|
|
102
|
+
|
|
103
|
+
If you already have a Starlette app and want to add your Solara app behind a prefix, say `'/solara/'`, you can mount the Starlette routes for Solara to your existing app as follows.
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
from starlette.applications import Starlette
|
|
107
|
+
from starlette.requests import Request
|
|
108
|
+
from starlette.responses import JSONResponse
|
|
109
|
+
from starlette.routing import Mount, Route
|
|
110
|
+
|
|
111
|
+
import solara.server.starlette
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def myroot(request: Request):
|
|
115
|
+
return JSONResponse({"framework": "solara"})
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
routes = [
|
|
119
|
+
Route("/", endpoint=myroot),
|
|
120
|
+
Mount("/solara/", routes=solara.server.starlette.routes),
|
|
121
|
+
]
|
|
122
|
+
|
|
123
|
+
app = Starlette(routes=routes)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Save this file as `"solara_on_starlette.py"` and run
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
$ SOLARA_APP=sol.py uvicorn solara_on_starlette:app
|
|
130
|
+
...
|
|
131
|
+
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
|
132
|
+
...
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
If you navigate to [http://127.0.0.1:8000/solara](http://127.0.0.1:8000/solara) you should see the Solara app.
|
|
136
|
+
|
|
137
|
+
## FastAPI
|
|
138
|
+
|
|
139
|
+
Since [FastAPI](https://fastapi.tiangolo.com/) is built on Starlette, see the section on [Starlette](#starlette) about how to deploy a Starlette app.
|
|
140
|
+
|
|
141
|
+
### Embedding in an existing FastAPI application
|
|
142
|
+
|
|
143
|
+
Use `app.mount` to mount the Solara app into your existing FastAPI app.
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
from fastapi import FastAPI
|
|
147
|
+
import solara.server.fastapi
|
|
148
|
+
|
|
149
|
+
app = FastAPI()
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
@app.get("/")
|
|
153
|
+
def read_root():
|
|
154
|
+
return {"Hello": "World"}
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
app.mount("/solara/", app=solara.server.fastapi.app)
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Save this file as `"solara_on_fastapi.py"` and run
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
$ SOLARA_APP=sol.py uvicorn solara_on_fastapi:app
|
|
164
|
+
...
|
|
165
|
+
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
|
166
|
+
...
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
If you navigate to [http://127.0.0.1:8000/solara](http://127.0.0.1:8000/solara) you should see the Solara app.
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
## Voila
|
|
173
|
+
|
|
174
|
+
If you use Voila, [you can use those deployment options](https://voila.readthedocs.io/en/stable/deploy.html).
|
|
175
|
+
|
|
176
|
+
Make sure you run a notebook where you display the app, e.g.
|
|
177
|
+
```python
|
|
178
|
+
@solara.component
|
|
179
|
+
def Page():
|
|
180
|
+
...
|
|
181
|
+
element = Page()
|
|
182
|
+
display(element)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Or consider using [Voila-vuetify](https://github.com/voila-dashboards/voila-vuetify).
|
|
186
|
+
|
|
187
|
+
Solara apps in Voila do not have support for [routing](/documentation/advanced/understanding/routing)/[multipage](/documentation/advanced/howto/multipage).
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
## Panel
|
|
191
|
+
|
|
192
|
+
[Panel](https://panel.holoviz.org/) supports [IPyWidgets](https://panel.holoviz.org/reference/panes/IPyWidget.html), which
|
|
193
|
+
means we can also embed the resulting widget from Reacton or Solara. See their [section on deployment](https://panel.holoviz.org/user_guide/Server_Deployment.html) and use the following code as an example of how to include a react component.
|
|
194
|
+
```python
|
|
195
|
+
import panel as pn
|
|
196
|
+
import solara
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
@solara.component
|
|
200
|
+
def ButtonClick(label="Hi"):
|
|
201
|
+
clicks, set_clicks = solara.use_state(0)
|
|
202
|
+
def increment():
|
|
203
|
+
set_clicks(clicks + 1)
|
|
204
|
+
return solara.Button(f"{label}: Clicked {clicks} times", on_click=increment)
|
|
205
|
+
|
|
206
|
+
# this creates just an element, Panel doesn't know what to do with that
|
|
207
|
+
element = ButtonClick("Solara+Panel")
|
|
208
|
+
# we explicitly ask Reacton to render it, and give us the widget
|
|
209
|
+
button_widget, render_context = reacton.render_fixed(element)
|
|
210
|
+
# mark this panel to be served by the panel server
|
|
211
|
+
pn.panel(button_widget).servable()
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
For development/testing purposes, run this script as:
|
|
215
|
+
|
|
216
|
+
$ panel serve solara_in_panel.py
|
|
217
|
+
|
|
218
|
+
Solara apps in Panel do not have support for [routing](/documentation/advanced/understanding/routing)/[multipage](/documentation/advanced/howto/multipage).
|
|
219
|
+
|
|
220
|
+
## Nginx
|
|
221
|
+
|
|
222
|
+
If you use Nginx as a (reverse) proxy in front of your Python web server, a minimal
|
|
223
|
+
configuration would be:
|
|
224
|
+
|
|
225
|
+
```
|
|
226
|
+
server {
|
|
227
|
+
server_name widgetti.io;
|
|
228
|
+
listen 80
|
|
229
|
+
location /solara/ {
|
|
230
|
+
# the local solara server (could be using Starlette/uvicorn)
|
|
231
|
+
proxy_pass http://localhost:8765/;
|
|
232
|
+
|
|
233
|
+
proxy_set_header Host $host;
|
|
234
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
235
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
236
|
+
proxy_set_header X-Script-Name /solara; # informs solara to produce correct urls
|
|
237
|
+
|
|
238
|
+
proxy_http_version 1.1;
|
|
239
|
+
proxy_set_header Upgrade $http_upgrade;
|
|
240
|
+
proxy_set_header Connection "upgrade";
|
|
241
|
+
proxy_read_timeout 86400;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Note that if we use `location /` instead of `location /solara/`, we can skip the `proxy_set_header X-Script-Name /solara` line.
|
|
247
|
+
|
|
248
|
+
An alternative to using the `X-Script-Name` header with uvicorn, would be to pass the `--root-path` flag, e.g.:
|
|
249
|
+
|
|
250
|
+
```
|
|
251
|
+
$ SOLARA_APP=sol.py uvicorn --workers 1 --root-path /solara -b 0.0.0.0:8765 solara.server.flask:app
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Docker
|
|
255
|
+
|
|
256
|
+
There is nothing special about running Solara in Docker. The only things you probably need to change is the interface the server binds to.
|
|
257
|
+
Solara by default binds to localhost, so that it is not accessible from the outside world. Apart from that localhost (or `::1` in case of IPv6)
|
|
258
|
+
might not be available, you probably want the outside world to see your Solara app. For that, you can use `--host=0.0.0.0` or `--host=::` option to bind to all interfaces.
|
|
259
|
+
|
|
260
|
+
Your Dockerfile could look like:
|
|
261
|
+
|
|
262
|
+
```Dockerfile
|
|
263
|
+
FROM ....
|
|
264
|
+
|
|
265
|
+
...
|
|
266
|
+
CMD ["solara", "run", "sol.py", "--host=0.0.0.0", "--production"]
|
|
267
|
+
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
For a complete example, you can take a look at:
|
|
271
|
+
* [https://huggingface.co/spaces/solara-dev/template](https://huggingface.co/spaces/solara-dev/template)
|
|
272
|
+
* [https://huggingface.co/spaces/giswqs/solara-template/tree/main](https://huggingface.co/spaces/giswqs/solara-template/tree/main)
|
|
273
|
+
* [https://github.com/opengeos/solara-template](https://github.com/opengeos/solara-template)
|