solara-ui 1.45.0__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 +765 -0
- solara/_stores.py +297 -0
- solara/alias.py +6 -0
- solara/autorouting.py +555 -0
- solara/cache.py +305 -0
- solara/checks.html +71 -0
- solara/checks.py +227 -0
- solara/comm.py +28 -0
- solara/components/__init__.py +77 -0
- solara/components/alert.py +155 -0
- solara/components/applayout.py +397 -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 +134 -0
- solara/components/cross_filter.py +335 -0
- solara/components/dataframe.py +546 -0
- solara/components/datatable.py +214 -0
- solara/components/datatable.vue +175 -0
- solara/components/details.py +56 -0
- solara/components/download.vue +35 -0
- solara/components/echarts.py +86 -0
- solara/components/echarts.vue +139 -0
- solara/components/figure_altair.py +39 -0
- solara/components/file_browser.py +181 -0
- solara/components/file_download.py +199 -0
- solara/components/file_drop.py +159 -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 +456 -0
- solara/components/input_text_area.py +86 -0
- solara/components/link.py +55 -0
- solara/components/markdown.py +441 -0
- solara/components/markdown_editor.py +33 -0
- solara/components/markdown_editor.vue +359 -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 +45 -0
- solara/components/sql_code.py +41 -0
- solara/components/sql_code.vue +125 -0
- solara/components/style.py +105 -0
- solara/components/switch.py +71 -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/core.py +42 -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 +151 -0
- solara/hooks/use_thread.py +129 -0
- solara/kitchensink.py +8 -0
- solara/lab/__init__.py +34 -0
- solara/lab/components/__init__.py +7 -0
- solara/lab/components/chat.py +215 -0
- solara/lab/components/confirmation_dialog.py +163 -0
- solara/lab/components/cross_filter.py +7 -0
- solara/lab/components/input_date.py +339 -0
- solara/lab/components/input_time.py +133 -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 +2 -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 +165 -0
- solara/lab/utils/headers.py +5 -0
- solara/layout.py +44 -0
- solara/lifecycle.py +46 -0
- solara/minisettings.py +141 -0
- solara/py.typed +0 -0
- solara/reactive.py +99 -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 +527 -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 +1681 -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 +91 -0
- solara/server/esm.py +71 -0
- solara/server/fastapi.py +5 -0
- solara/server/flask.py +297 -0
- solara/server/jupyter/__init__.py +2 -0
- solara/server/jupyter/cdn_handler.py +28 -0
- solara/server/jupyter/server_extension.py +40 -0
- solara/server/jupyter/solara.py +91 -0
- solara/server/jupytertools.py +46 -0
- solara/server/kernel.py +388 -0
- solara/server/kernel_context.py +467 -0
- solara/server/patch.py +564 -0
- solara/server/pyinstaller/__init__.py +9 -0
- solara/server/pyinstaller/hook-ipyreact.py +5 -0
- solara/server/pyinstaller/hook-ipyvuetify.py +5 -0
- solara/server/pyinstaller/hook-solara.py +9 -0
- solara/server/qt.py +113 -0
- solara/server/reload.py +251 -0
- solara/server/server.py +484 -0
- solara/server/settings.py +249 -0
- solara/server/shell.py +269 -0
- solara/server/starlette.py +770 -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 +272 -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 +486 -0
- solara/server/threaded.py +84 -0
- solara/server/utils.py +44 -0
- solara/server/websocket.py +45 -0
- solara/settings.py +86 -0
- solara/tasks.py +893 -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 +783 -0
- solara/toestand.py +998 -0
- solara/util.py +348 -0
- solara/validate_hooks.py +258 -0
- solara/website/__init__.py +0 -0
- solara/website/assets/custom.css +444 -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.py +6 -0
- solara/website/components/algolia.vue +24 -0
- solara/website/components/algolia_api.vue +202 -0
- solara/website/components/breadcrumbs.py +28 -0
- solara/website/components/contact.py +144 -0
- solara/website/components/docs.py +143 -0
- solara/website/components/header.py +75 -0
- solara/website/components/mailchimp.py +12 -0
- solara/website/components/mailchimp.vue +47 -0
- solara/website/components/markdown.py +99 -0
- solara/website/components/markdown_nav.vue +34 -0
- solara/website/components/notebook.py +171 -0
- solara/website/components/sidebar.py +105 -0
- solara/website/pages/__init__.py +370 -0
- solara/website/pages/about/__init__.py +9 -0
- solara/website/pages/about/about.md +3 -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/careers/__init__.py +27 -0
- solara/website/pages/changelog/__init__.py +10 -0
- solara/website/pages/changelog/changelog.md +372 -0
- solara/website/pages/contact/__init__.py +34 -0
- solara/website/pages/doc_use_download.py +85 -0
- solara/website/pages/documentation/__init__.py +90 -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 +417 -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 +50 -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 +72 -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 +192 -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 +256 -0
- solara/website/pages/documentation/advanced/content/20-understanding/50-solara-server.md +108 -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 +7 -0
- solara/website/pages/documentation/advanced/content/30-enterprise/10-oauth.md +187 -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 +22 -0
- solara/website/pages/documentation/api/cross_filter/cross_filter_report.py +20 -0
- solara/website/pages/documentation/api/cross_filter/cross_filter_select.py +20 -0
- solara/website/pages/documentation/api/cross_filter/cross_filter_slider.py +20 -0
- solara/website/pages/documentation/api/hooks/__init__.py +9 -0
- solara/website/pages/documentation/api/hooks/use_cross_filter.py +23 -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 +31 -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 +30 -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 +66 -0
- solara/website/pages/documentation/api/hooks/use_thread.md +64 -0
- solara/website/pages/documentation/api/hooks/use_thread.py +42 -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 +29 -0
- solara/website/pages/documentation/api/routing/use_route.py +76 -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 +44 -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 +25 -0
- solara/website/pages/documentation/components/advanced/meta.py +17 -0
- solara/website/pages/documentation/components/advanced/style.py +43 -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 +30 -0
- solara/website/pages/documentation/components/input/file_drop.py +76 -0
- solara/website/pages/documentation/components/input/input.py +43 -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/input_time.py +15 -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 +74 -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 +66 -0
- solara/website/pages/documentation/components/layout/details.py +13 -0
- solara/website/pages/documentation/components/layout/griddraggable.py +62 -0
- solara/website/pages/documentation/components/layout/gridfixed.py +19 -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 +19 -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 +83 -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 +15 -0
- solara/website/pages/documentation/components/page/title.py +25 -0
- solara/website/pages/documentation/components/status/__init__.py +9 -0
- solara/website/pages/documentation/components/status/error.py +39 -0
- solara/website/pages/documentation/components/status/info.py +39 -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 +77 -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 +54 -0
- solara/website/pages/documentation/examples/ai/__init__.py +11 -0
- solara/website/pages/documentation/examples/ai/chatbot.py +113 -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 +32 -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 +65 -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 +62 -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 +67 -0
- solara/website/pages/documentation/examples/visualization/linked_views.py +81 -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 +112 -0
- solara/website/pages/documentation/getting_started/__init__.py +9 -0
- solara/website/pages/documentation/getting_started/content/00-quickstart.md +107 -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 +65 -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 +1021 -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 +228 -0
- solara/website/pages/documentation/getting_started/content/05-fundamentals/50-state-management.md +278 -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 +305 -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/home.vue +1199 -0
- solara/website/pages/our_team/__init__.py +83 -0
- solara/website/pages/pricing/__init__.py +31 -0
- solara/website/pages/roadmap/__init__.py +11 -0
- solara/website/pages/roadmap/roadmap.md +47 -0
- solara/website/pages/scale_ipywidgets.py +45 -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 +107 -0
- solara/widgets/vue/html.vue +4 -0
- solara/widgets/vue/navigator.vue +134 -0
- solara/widgets/vue/vegalite.vue +130 -0
- solara/widgets/widgets.py +74 -0
- solara_ui-1.45.0.data/data/etc/jupyter/jupyter_notebook_config.d/solara.json +7 -0
- solara_ui-1.45.0.data/data/etc/jupyter/jupyter_server_config.d/solara.json +7 -0
- solara_ui-1.45.0.dist-info/METADATA +162 -0
- solara_ui-1.45.0.dist-info/RECORD +464 -0
- solara_ui-1.45.0.dist-info/WHEEL +4 -0
- solara_ui-1.45.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Understanding the way Solara server works
|
|
3
|
+
description: Solara server enables running ipywidgets-based applications as standalone dashboards and apps, allowing multiple "Virtual kernels" to share
|
|
4
|
+
the same process for better performance and scalability.
|
|
5
|
+
---
|
|
6
|
+
# Solara server
|
|
7
|
+
|
|
8
|
+
The solara server enables running ipywidgets based applications without a real Jupyter kernel, allowing multiple "Virtual kernels" to share the same process for better performance and scalability.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
To install the solara server, run:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
$ pip install "solara-server[starlette]"
|
|
16
|
+
$ # pip install solara # to get all solara packages
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
See [our installation guide](/documentation/getting_started/installing) for more information.
|
|
20
|
+
|
|
21
|
+
## WebSocket in Solara
|
|
22
|
+
Solara uses a WebSocket to transmit state and updates directly from the server to the browser. This ensures that the state remains centralized on the server, facilitating state transitions server-side and enabling live updates to be pushed directly to the browser.
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
## Virtual Kernels
|
|
26
|
+
Normally when a browser page connects to a Solara server, a virtual kernel is created and is assigned a unique identifier termed a "Kernel ID." Should a WebSocket disconnection occur, Solara attempts to re-establish the connection, sending the Kernel ID during this process. If the server recognizes this ID (and the requested kernel hasn't expired) the Solara app resumes operations seamlessly.
|
|
27
|
+
|
|
28
|
+
### Virtual kernel lifecycle
|
|
29
|
+
Closing a browser page will directly shut the virtual kernel down (if this page was the last known page to the Solara server). This ensures that active closing of pages will directly clean up any memory usage on the server side for this kernel.
|
|
30
|
+
|
|
31
|
+
However, when the websocket between the web page and the server disconnects, the server keeps the kernel alive for 24 hours after the closure of the last WebSocket connection. The duration is customizable through the `SOLARA_KERNEL_CULL_TIMEOUT` environment variable. This feature is particularly handy in scenarios where devices like computers hibernate, leading to WebSocket disconnections. Upon awakening and subsequent WebSocket reconnection, the Solara app picks up right where it left off.
|
|
32
|
+
|
|
33
|
+
To optimize memory usage or address specific needs, one might opt for a shorter expiration duration. For instance, setting `SOLARA_KERNEL_CULL_TIMEOUT=1m` will cause sessions to expire after just 1 minute. Other possible options are `2d` (2 days), `3h` (3 hours), `30s` (30 seconds), etc. If no units are given, seconds are assumed.
|
|
34
|
+
|
|
35
|
+
### Maximum number of kernels connected
|
|
36
|
+
|
|
37
|
+
Each virtual kernel runs in its own thread, this ensures that one particular user (actually browser page) cannot block the execution of another virtual kernel. However, each thread consumes a bit of resources. If you want to limit the number of kernels, this can be done by setting the `SOLARA_KERNELS_MAX_COUNT` environment variable. The default is unlimited (empty string), but you can set it to any number you like. If the limit is reached, the server will refuse new connections until a kernel is closed.
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
## Handling Multiple Workers
|
|
41
|
+
|
|
42
|
+
In setups with multiple workers, it's possible for a page to (re)connect to a different worker than its original. This can happen after a lost network connection is restored, or when [ipypopout](https://github.com/widgetti/ipypopout) is used, since ipypopout creates a new connection, which can end up at a different worker. This can result in a loss of the virtual kernel, since it lives on the worker that was first connected to. The Solara app will then initiate a fresh start, or simply fail when ipypopout is used. To prevent this scenario, a sticky session configuration is recommended, ensuring consistent client-worker connections. A load balancer, such as [nginx](https://www.nginx.com/), can be used to achieve this. Note that using multiple workers (e.g. by using gunicorn) cannot work since a connection will be made to a different worker each time.
|
|
43
|
+
|
|
44
|
+
If you have questions about setting this up, or require assistance, please [contact us](https://solara.dev/docs/contact).
|
|
45
|
+
|
|
46
|
+
## Sessions
|
|
47
|
+
|
|
48
|
+
Solara uses a browser cookie (named `solara-session-id`) to store a unique session id. This session id is available via [get_session_id()](https://solara.dev/api/get_session_id) and is the same for all
|
|
49
|
+
browser pages. This can be used to store state that outlives a page refresh.
|
|
50
|
+
|
|
51
|
+
We recommend storing the state in an external database, especially in the case of multiple workers/nodes. If you want to store state associated to a session in-memory, make sure to set up sticky sessions.
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
The `solara-session-id` cookie is accessible in the browser using JavaScript. If you deem this a security risk, you can disable the cookie by setting the `SOLARA_SESSION_HTTP_ONLY` environment variable to `True`.
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
## Readiness check
|
|
58
|
+
|
|
59
|
+
To check if the server is ready to accept request, the `/readyz` endpoint is added, and should return a 200 HTTP status code, e.g.:
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
$ curl http://localhost:8765/readyz
|
|
63
|
+
curl -I localhost:8765
|
|
64
|
+
|
|
65
|
+
HTTP/1.1 200 OK
|
|
66
|
+
...
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Live resource information
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
To check resource usage of the server (CPU, memory, etc.), the `/resourcez` endpoint is added, and should return a 200 HTTP status code and include
|
|
73
|
+
various resource information, like threads created and running, number of virtual kernels, etc. in JSON format. To get also memory and cpu usage, you can include
|
|
74
|
+
the `?verbose` query parameter, e.g.:
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
$ curl http://localhost:8765/resourcez\?verbose
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The JSON format may be subject to change.
|
|
81
|
+
|
|
82
|
+
## Ignoring notebook extensions
|
|
83
|
+
|
|
84
|
+
Not all (classic) jupyter notebook extensions are compatible with Solara, and there is not way to distinguish between notebook extensions that are needed for widgets and those that are not.
|
|
85
|
+
To ignore notebook extensions, you can set the `SOLARA_SERVER_IGNORE_NBEXTENSIONS` environment variable. This is a comma separated list of notebook extensions to ignore. For example, to ignore the `dash/main` and `foo/bar` extensions, you can run:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
$ SOLARA_SERVER_IGNORE_NBEXTENSIONS="dash/main,foo/bar" solara run nogit/sol.py -a
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Note that these error are not fatal, and the Solara app will still run.
|
|
92
|
+
|
|
93
|
+
## Production mode
|
|
94
|
+
|
|
95
|
+
By default, solara runs in development mode. This means, it will:
|
|
96
|
+
|
|
97
|
+
* Automatically [reload your project files](/documentation/advanced/reference/reloading) by watching files on the filesystemn
|
|
98
|
+
* Load debug version of the CSS files and JavaScript files for improved error messages (which leads to larger asset files).
|
|
99
|
+
|
|
100
|
+
To disabled all of these option, pass the `--production` flag, or set the environment variable `SOLARA_MODE=production`.
|
|
101
|
+
|
|
102
|
+
## Telemetry
|
|
103
|
+
|
|
104
|
+
Solara uses Mixpanel to collect usage of the solara server. We track when a server is started, stopped and a daily report of the number of unique users and connections made. To opt out of mixpanel telemetry, either:
|
|
105
|
+
|
|
106
|
+
* Set the environmental variable `SOLARA_TELEMETRY_MIXPANEL_ENABLE` to `False`.
|
|
107
|
+
* Install [python-dotenv](https://pypi.org/project/python-dotenv/) and put `SOLARA_TELEMETRY_MIXPANEL_ENABLE=False` in a `.env` file.
|
|
108
|
+
* Run in auto restart mode (e.g. using `$ solara run sol.py --auto-restart`)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Working together with Voilà
|
|
3
|
+
description: Voilà, together with `voila-vuetify` is an alternative to Solara server. The most significant difference is that Voilà will start one kernel/process
|
|
4
|
+
per page request, while Solara server is more scalable.
|
|
5
|
+
---
|
|
6
|
+
# Voilà
|
|
7
|
+
|
|
8
|
+
[Voilà](https://voila.readthedocs.io/) allows you to convert a Jupyter Notebook into an interactive dashboard that allows you to share your work with others.
|
|
9
|
+
|
|
10
|
+
Voilà is Jupyter notebook focused, meaning that it will render all output from your notebook. Using [`voila-vuetify`](https://github.com/voila-dashboards/voila-vuetify) Voilà allows for a more app like experience, showing only the output you want.
|
|
11
|
+
|
|
12
|
+
Voilà, together with `voila-vuetify` is an alternative to [Solara server](./solara-server). The most significant difference is that Voilà will start one kernel/process per page request, while [Solara server](./solara-server) can serve many more users from a single process. Sharing the same process means Solara apps can share memory among users (e.g. a large dataset), which will usually lead to better performance and less resource usage.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Solara enterprise
|
|
2
|
+
|
|
3
|
+
Solara enterprise is a not Open Source, but the source code is visible, is free for non-commercial use and installable from pypi.
|
|
4
|
+
|
|
5
|
+
For commercial use, you require a license. Please see [pricing](/pricing) for more information.
|
|
6
|
+
|
|
7
|
+
Solara-enterprise will stay free for non-commercial use and features that are in solara will **not be moved to solara-enterprise**.
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Using OAuth in your Solara app
|
|
3
|
+
description: Open Authorization can be readily integrated into your Solara applications via the Solara-Enterprise package.
|
|
4
|
+
---
|
|
5
|
+
# OAuth: authentication and authorization support
|
|
6
|
+
|
|
7
|
+
## What is OAuth
|
|
8
|
+
|
|
9
|
+
OAuth (Open Authorization) is an open standard for token-based authentication and authorization. It enables third-party applications to obtain limited access to a user's resources on another service without exposing their credentials. The user can grant access to their resources on one site to another site without sharing their credentials, providing a secure and efficient way to authenticate users.
|
|
10
|
+
|
|
11
|
+
You have probably used OAuth without realizing it when signing into various online services and applications. For example, when you use "Sign in with Google" or "Log in with Facebook" to access a third-party website or application, you are using OAuth. By leveraging OAuth, these services allow users to authenticate themselves using their existing Google or Facebook credentials, simplifying the login process and reducing the need for users to remember multiple usernames and passwords. OAuth has become an essential aspect of online identity management and is widely used by companies and developers to provide a seamless and secure authentication experience.
|
|
12
|
+
|
|
13
|
+
## Installing
|
|
14
|
+
|
|
15
|
+
To install Solara with OAuth support, make sure you have [Solara Enterprise](/documentation/advanced/enterprise) install by run the following command:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
$ pip install solara solara-enterprise[auth]
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
## OAuth support in Solara
|
|
23
|
+
|
|
24
|
+
Solara offers two modes for enabling OAuth: private mode and application controlled mode.
|
|
25
|
+
|
|
26
|
+
### Private mode
|
|
27
|
+
|
|
28
|
+
In private mode, Solara pages or any static resources are not accessible without being authenticated. This mode is suitable for web servers that should not be publicly accessible. To enable private mode, set the following environment variable:
|
|
29
|
+
```bash
|
|
30
|
+
SOLARA_OAUTH_PRIVATE=True
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
### Application controlled mode
|
|
35
|
+
|
|
36
|
+
In application controlled mode, the application is responsible for checking if a user is authenticated. The application can show a login or logout link and provide user information when the user is logged in. Solara comes preconfigured to run on localhost out of the box, and no additional setup is required to enable OAuth for local development and testing.
|
|
37
|
+
|
|
38
|
+
Here's an example of how to implement OAuth in application controlled mode:
|
|
39
|
+
|
|
40
|
+
```solara
|
|
41
|
+
import solara
|
|
42
|
+
from solara_enterprise import auth
|
|
43
|
+
|
|
44
|
+
@solara.component
|
|
45
|
+
def Page():
|
|
46
|
+
if not auth.user.value:
|
|
47
|
+
# `get_login_url` should automatically redirect the user back to the current page.
|
|
48
|
+
# The URL argument is only used here as an example.
|
|
49
|
+
solara.Button("Login", icon_name="mdi-login", href=auth.get_login_url("documentation/advanced/enterprise/oauth"))
|
|
50
|
+
else:
|
|
51
|
+
userinfo = auth.user.value['userinfo']
|
|
52
|
+
if 'name' in userinfo:
|
|
53
|
+
solara.Markdown(f"### Welcome {userinfo['name']}")
|
|
54
|
+
# See above comment
|
|
55
|
+
solara.Button("Logout", icon_name="mdi-logout", href=auth.get_logout_url("documentation/advanced/enterprise/oauth"))
|
|
56
|
+
```
|
|
57
|
+
## How to configure OAuth
|
|
58
|
+
|
|
59
|
+
Solara currently supports [Auth0](https://auth0.com/) as the sole OAuth provider. [Fief](https://fief.dev/) support is **deprecated** (currently untested), but is not planned to be removed. If you would like support for a different provider to be added, [contact us](/contact)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
### Configuring Auth0
|
|
63
|
+
|
|
64
|
+
By default, Solara is configured with a test Auth0 account. This is useful for testing, but you should not use this in production. This account does limit solara running on localhost, port 8765 to 8770 (and 18765 to 18770 for running the tests).
|
|
65
|
+
|
|
66
|
+
To configure your own Auth0 provider, you need to change the following environment variables from their defaults:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
# required if you don't use the default test account
|
|
70
|
+
SOLARA_SESSION_SECRET_KEY="change me"
|
|
71
|
+
# found in the Auth0 dashboard Applications->Applications->Client ID
|
|
72
|
+
SOLARA_OAUTH_CLIENT_ID="cW7owP5Q52YHMZAnJwT8FPlH2ZKvvL3U"
|
|
73
|
+
# found in the Auth0 dashboard Applications->Applications->Client secret
|
|
74
|
+
SOLARA_OAUTH_CLIENT_SECRET="zxITXxoz54OjuSmdn-PluQgAwbeYyoB7ALlnLoodftvAn81usDXW0quchvoNvUYD"
|
|
75
|
+
# found in the Auth0 dashboard Applications->Applications->Domain
|
|
76
|
+
SOLARA_OAUTH_API_BASE_URL="dev-y02f02f2bpr8skxu785.us.auth0.com"
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
You can optionally set the following environment variables:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
SOLARA_OAUTH_SCOPE = "openid profile email"
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Create your own Auth0 Application
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
To create your own Auth0 application, follow these steps:
|
|
89
|
+
|
|
90
|
+
1. Go to the [Auth0 dashboard](https://manage.auth0.com/dashboard/) and click on "Applications" on the left side navigation menu.
|
|
91
|
+
|
|
92
|
+

|
|
93
|
+
|
|
94
|
+
2. Click on "Create Application".
|
|
95
|
+
|
|
96
|
+

|
|
97
|
+
|
|
98
|
+
3. Enter a name for your application and select "Regular Web Applications" as the application type. Click on "Create".
|
|
99
|
+
|
|
100
|
+

|
|
101
|
+
|
|
102
|
+
4. Click "Skip Integration" to skip the integration step.
|
|
103
|
+
|
|
104
|
+
5. Click on the "Settings" tabs and enter the following information:
|
|
105
|
+
|
|
106
|
+
- Allowed Callback URLs: `http://localhost:8765/_solara/auth/authorize, https://yourdomain.com/_solara/auth/authorize`
|
|
107
|
+
- Allowed Logout URLs: `http://localhost:8765/_solara/auth/logout, https://yourdomain.com/_solara/auth/logout`
|
|
108
|
+
|
|
109
|
+
Note that the localhost URLs are only meant for testing. You can remove them once you are ready to deploy your application.
|
|
110
|
+
We recommend setting up a new application for each environment (e.g. development, staging, production).
|
|
111
|
+
|
|
112
|
+

|
|
113
|
+
|
|
114
|
+
6. Configure Solara.
|
|
115
|
+
|
|
116
|
+
At the top of the "Settings" tab, you should see your "Domain", "Client ID" and "Client Secret". You will need to set the following environment variables to these values:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
SOLARA_OAUTH_API_BASE_URL="dev-y02f2bpr8skxu785.us.auth0.com" # replace with your domain
|
|
120
|
+
SOLARA_OAUTH_CLIENT_ID="ELOFERLovc7e7dPwkxO6WFAljtYj9UzJ" # replace with your client ID
|
|
121
|
+
SOLARA_OAUTH_CLIENT_SECRET="..." # not shown here, replace with your client secret
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+

|
|
125
|
+
|
|
126
|
+
Set your `SOLARA_SESSION_SECRET_KEY` to a random string. See the [Generating a secret key](#generating-a-secret-key) for a convenient way to generate a secret key.
|
|
127
|
+
|
|
128
|
+
Solara forces you to set a value for `SOLARA_SESSION_HTTPS_ONLY`, because the OAuth login is only secure when this setting is `True` and your app runs over HTTPS.
|
|
129
|
+
For development, where your app likely doesn't run over HTTPS, you must set it to `False`, otherwise OAuth login will not work.
|
|
130
|
+
For more information on configuring Solara to run over HTTPS, see [HTTPS](/documentation/getting_started/deploying/self-hosted#https).
|
|
131
|
+
|
|
132
|
+
Now you can run the above solara example using your own auth0 provider.
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
### Configuring Fief
|
|
136
|
+
|
|
137
|
+
##### Note: Fief support is not maintained or tested. If you would like Fief to be supported, feel free to [contact us](/contact)
|
|
138
|
+
|
|
139
|
+
You can also configure Solara to use our Fief test account. To do this, you need to set the following environment variables:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
SOLARA_SESSION_SECRET_KEY="change me" # required if you don't use the default test account
|
|
143
|
+
SOLARA_OAUTH_CLIENT_ID="x2np62qgwp6hnEGTP4JYUE3igdZWhT-AvjpjwwDyKXU" # found in the Auth0 dashboard Clients->General Tab->ID
|
|
144
|
+
SOLARA_OAUTH_CLIENT_SECRET="XQlByE1pVIz5h2SBN2GYDwT_ziqArHJgLD3KqMlCHjg" # found in the Auth0 dashboard Clients->General Tab->Secret
|
|
145
|
+
SOLARA_OAUTH_API_BASE_URL="solara-dev.fief.dev" # found in the Fief dashboard Tenants->Base URL
|
|
146
|
+
# different from Solara's default
|
|
147
|
+
SOLARA_OAUTH_LOGOUT_PATH="logout"
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Generating a secret key
|
|
151
|
+
|
|
152
|
+
To generate a secret key, you can use the following code:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
$ python -c "import secrets; print(secrets.token_urlsafe(32))"
|
|
156
|
+
ZgrzSLUyft-JvnNMNJ2LgbCFVqcxPOatANAQhMD5EYU
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
*Note: do not copy this key, run this yourself in a terminal.*
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
## OAuth Component
|
|
163
|
+
|
|
164
|
+
Solara provides two convenient components for creating a user interface for login and logout:
|
|
165
|
+
|
|
166
|
+
1. [Avatar](/documentation/components/enterprise/avatar): This component shows the user's avatar.
|
|
167
|
+
2. [AvatarMenu](/documentation/components/enterprise/avatar_menu): This component shows a menu with the user's avatar and a logout button.
|
|
168
|
+
|
|
169
|
+
## Python version support
|
|
170
|
+
|
|
171
|
+
Please note that Python 3.6 is not supported for Solara OAuth.
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
## Possible issues
|
|
175
|
+
|
|
176
|
+
### Wrong redirection
|
|
177
|
+
|
|
178
|
+
If the redirection back to solara return to the wrong address, it might be due to solara not choosing the right default for `SOLARA_BASE_URL`. This can happen in a situation where you have multiple reverse proxies that communicate via https and therefore need to set the Host header. For instance this variable could be set to `SOLARA_BASE_URL=https://solara.dev` for the solara.dev server. If you application runs behind a subpath, e.g. `/myapp`, you might have to set `SOLARA_ROOT_PATH=/myapp`.
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
### Wrong schema detected for redirect URL
|
|
182
|
+
|
|
183
|
+
Solara needs to give the OAuth providers a redirect URL to get back to your Solara application after navigating to the OAuth provider website. For our documentation server, we ask the OAuth provider to redirect to `https://solara.dev/_solara/auth/authorize`. The protocol part (`https`) and the domain name part (`solara.dev`) of this URL is constructed from the request (what the browser sends to the server).
|
|
184
|
+
|
|
185
|
+
If you are running Solara behind a reverse proxy server (like nginx), make sure that the `X-Forwarded-Proto` and `Host` headers are forwarded correctly, and the proxy server is trusted by uvicorn (by configuring the `FORWARDED_ALLOW_IPS` environment variable) so Solara can construct the correct redirect URL to send to the OAuth provider.
|
|
186
|
+
|
|
187
|
+
See our [self hosted deployment](https://solara.dev/documentation/getting_started/deploying/self-hosted) for more information on how to configure your reverse proxy server.
|
|
File without changes
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Contributing to Solara
|
|
3
|
+
description: You do not need to be a developer to contribute to Solara. We welcome all contributions, bug reports, documentation improvements and code contributions.
|
|
4
|
+
---
|
|
5
|
+
# Contributing to Solara
|
|
6
|
+
|
|
7
|
+
You do not need to be a developer to contribute to Solara. We welcome all contributions, bug reports, documentation improvements and code contributions.
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## Bug reports
|
|
11
|
+
|
|
12
|
+
We use [GitHub to manage issues](https://github.com/widgetti/solara/issues/new) and you should not hesitate to report any bug you find. Please include as much information as possible for us to be able to reproduce the bug. Yes, reporting a bug/issue is a contribution!
|
|
13
|
+
|
|
14
|
+
It might take a while for us to get back to you. If the bug is urgent, and you are able to provide financial support for its rapid resolution, please [contact us](/contact).
|
|
15
|
+
If you can fix the bug yourself, please consider submitting a pull request instead, see [the development guide](/documentation/advanced/development/setup) for more information.
|
|
16
|
+
|
|
17
|
+
If you are unable to address the bug yourself and find it challenging to provide financial support, please be assured we are still committed to rectifying bugs and resolving issues. However, please understand that our ability to address these issues may be impacted by our resources at hand, as sustaining this project also entails financial obligations. Your patience and understanding in this matter is highly appreciated 🙇.
|
|
18
|
+
|
|
19
|
+
## Documentation
|
|
20
|
+
|
|
21
|
+
The documentation is mostly written in Markdown, and can be found at [in the main repository](https://github.com/widgetti/solara/tree/master/solara/website/pages).
|
|
22
|
+
|
|
23
|
+
You can use the GitHub web interface to edit the files, or clone the repository and edit them locally. See [the development guide](/documentation/advanced/development/setup) for more information.
|
|
24
|
+
|
|
25
|
+
If you locally want to render the documentation, run:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
$ solara run solara.website.pages
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Examples or showcase
|
|
32
|
+
|
|
33
|
+
If you have a complete program you want to share, and you think it would be cool to be listed at [our showcase page](/showcase), [please contact us](/contact).
|
|
34
|
+
|
|
35
|
+
If you want to show a particular way of using Solara that you think is very useful
|
|
36
|
+
for others, but it is not a complete program, consider adding to [the examples](/documentation/examples/). See [the development guide](/documentation/advanced/development/setup) for more information.
|
|
37
|
+
|
|
38
|
+
## Share your experiences and ideas
|
|
39
|
+
|
|
40
|
+
If you want to share your thoughts, share your experiences, or just want to talk
|
|
41
|
+
to other people using and developing on Solara, consider using [GitHub discussions](https://github.com/widgetti/solara/discussions) for asynchronous discussions
|
|
42
|
+
or consider joining discord for more synchronous discussions.
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
[](https://discord.gg/dm4GKNDjXN)
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Development setup for Solara
|
|
3
|
+
description: Learn how to set up your installation for developing on the Solara itself.
|
|
4
|
+
---
|
|
5
|
+
# Development
|
|
6
|
+
|
|
7
|
+
See also [the contributing guide](/documentation/advanced/development/contribute) for more information on how to contribute to Solara.
|
|
8
|
+
## Development setup
|
|
9
|
+
|
|
10
|
+
Assuming you have created a virtual environment as described in [the installation guide](/documentation/getting_started/installing), you can install a development install of Solara using:
|
|
11
|
+
|
|
12
|
+
$ git clone git@github.com:widgetti/solara.git
|
|
13
|
+
$ cd solara
|
|
14
|
+
$ pip install -r requirements-dev.txt
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## Running Solara server in auto restart mode
|
|
18
|
+
|
|
19
|
+
By passing the `--auto-restart/-a` flag, the solara server will automatically restart when the sourcecode of the solara server changes, which makes it friendlier for development
|
|
20
|
+
|
|
21
|
+
$ solara run myscript.py -a
|
|
22
|
+
|
|
23
|
+
This will:
|
|
24
|
+
|
|
25
|
+
* Automatically restart the server if any of the source code of solara changes (excluding solara.website)
|
|
26
|
+
|
|
27
|
+
## Contributing
|
|
28
|
+
|
|
29
|
+
If you plan to contribute, also run the following:
|
|
30
|
+
|
|
31
|
+
$ pre-commit install
|
|
32
|
+
|
|
33
|
+
This will cause a test of linters/formatters and mypy to run so the code is in good quality before you git commit.
|
|
34
|
+
|
|
35
|
+
$ playwright install
|
|
36
|
+
|
|
37
|
+
This will install playwright, for when you want to run the integration tests.
|
|
38
|
+
|
|
39
|
+
### Test suite
|
|
40
|
+
|
|
41
|
+
If you want to run the unit tests (quick run when doing development, or when you do test driven development)
|
|
42
|
+
|
|
43
|
+
$ py.test tests/unit
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
If you want to run the integration tests (uses playwright to open a browser to test the live server with a real browser)
|
|
47
|
+
|
|
48
|
+
$ py.test tests/integration
|
|
49
|
+
|
|
50
|
+
Pass the `--headed` flag to see what is going on, [or check out the docs](https://playwright.dev/python/docs/intro)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
### Creating a PR
|
|
54
|
+
|
|
55
|
+
Make sure you forked the repository, and set up the remote and origin correctly.
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
# rename origin to upstream
|
|
59
|
+
$ git remote rename origin upstream
|
|
60
|
+
# add your fork as origin
|
|
61
|
+
$ git remote add origin https://github.com/yourusername/solara.git
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Now we will create a branch, push it, and open a PR
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
# create a branch
|
|
68
|
+
$ git checkout -b fix_some_thing
|
|
69
|
+
# add whatever changes you want to make
|
|
70
|
+
$ git add -p
|
|
71
|
+
# commit your changes
|
|
72
|
+
$ git commit -m "fix: some thing"
|
|
73
|
+
# push your changes
|
|
74
|
+
$ git push
|
|
75
|
+
# click the link that is printed to open a PR
|
|
76
|
+
```
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""
|
|
2
|
+
# Overview
|
|
3
|
+
Click on one of the items on the left.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import solara
|
|
7
|
+
from solara.website.components import CategoryLayout, Gallery
|
|
8
|
+
|
|
9
|
+
_title = "API"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@solara.component
|
|
13
|
+
def Page(route_external=None):
|
|
14
|
+
Gallery(route_external)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@solara.component
|
|
18
|
+
def Layout(children=[]):
|
|
19
|
+
CategoryLayout(children=children)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""# CrossFilterDataFrame"""
|
|
2
|
+
|
|
3
|
+
import plotly
|
|
4
|
+
|
|
5
|
+
import solara
|
|
6
|
+
import solara.lab
|
|
7
|
+
from solara.website.utils import apidoc
|
|
8
|
+
|
|
9
|
+
title = "CrossFilterDataFrame"
|
|
10
|
+
df = plotly.data.gapminder()
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@solara.component
|
|
14
|
+
def Page():
|
|
15
|
+
solara.provide_cross_filter()
|
|
16
|
+
|
|
17
|
+
solara.CrossFilterReport(df, classes=["py-2"])
|
|
18
|
+
solara.CrossFilterSelect(df, "country")
|
|
19
|
+
solara.CrossFilterDataFrame(df)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
__doc__ += apidoc(solara.CrossFilterDataFrame.f) # type: ignore
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""# CrossFilterReport"""
|
|
2
|
+
|
|
3
|
+
import plotly
|
|
4
|
+
|
|
5
|
+
import solara
|
|
6
|
+
import solara.lab
|
|
7
|
+
from solara.website.utils import apidoc
|
|
8
|
+
|
|
9
|
+
df = plotly.data.gapminder()
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@solara.component
|
|
13
|
+
def Page():
|
|
14
|
+
solara.provide_cross_filter()
|
|
15
|
+
solara.CrossFilterReport(df, classes=["py-2"])
|
|
16
|
+
solara.CrossFilterSelect(df, "country")
|
|
17
|
+
solara.CrossFilterSlider(df, "gdpPercap", mode=">")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
__doc__ += apidoc(solara.CrossFilterReport.f) # type: ignore
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""# CrossFilterSelect"""
|
|
2
|
+
|
|
3
|
+
import plotly
|
|
4
|
+
|
|
5
|
+
import solara
|
|
6
|
+
import solara.lab
|
|
7
|
+
from solara.website.utils import apidoc
|
|
8
|
+
|
|
9
|
+
df = plotly.data.tips()
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@solara.component
|
|
13
|
+
def Page():
|
|
14
|
+
solara.provide_cross_filter()
|
|
15
|
+
solara.CrossFilterReport(df, classes=["py-2"])
|
|
16
|
+
solara.CrossFilterSelect(df, "sex")
|
|
17
|
+
solara.CrossFilterSelect(df, "time")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
__doc__ += apidoc(solara.CrossFilterSelect.f) # type: ignore
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""# CrossFilterSlider"""
|
|
2
|
+
|
|
3
|
+
import plotly
|
|
4
|
+
|
|
5
|
+
import solara
|
|
6
|
+
import solara.lab
|
|
7
|
+
from solara.website.utils import apidoc
|
|
8
|
+
|
|
9
|
+
df = plotly.data.gapminder()
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@solara.component
|
|
13
|
+
def Page():
|
|
14
|
+
solara.provide_cross_filter()
|
|
15
|
+
solara.CrossFilterReport(df, classes=["py-2"])
|
|
16
|
+
solara.CrossFilterSlider(df, "pop", mode=">")
|
|
17
|
+
solara.CrossFilterSlider(df, "gdpPercap", mode="<")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
__doc__ += apidoc(solara.CrossFilterSlider.f) # type: ignore
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""# use_cross_filter"""
|
|
2
|
+
|
|
3
|
+
import plotly
|
|
4
|
+
|
|
5
|
+
import solara
|
|
6
|
+
import solara.lab
|
|
7
|
+
from solara.website.utils import apidoc
|
|
8
|
+
|
|
9
|
+
title = "use_cross_filter"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
df = plotly.data.gapminder()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@solara.component
|
|
16
|
+
def Page():
|
|
17
|
+
solara.provide_cross_filter()
|
|
18
|
+
solara.CrossFilterReport(df, classes=["py-2"])
|
|
19
|
+
solara.CrossFilterSelect(df, "continent")
|
|
20
|
+
solara.CrossFilterSlider(df, "gdpPercap", mode=">")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
__doc__ += apidoc(solara.use_cross_filter) # type: ignore
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""# use_dark_effective"""
|
|
2
|
+
|
|
3
|
+
import solara
|
|
4
|
+
import solara.autorouting
|
|
5
|
+
import solara.lab
|
|
6
|
+
from solara.website.utils import apidoc
|
|
7
|
+
|
|
8
|
+
from . import NoPage
|
|
9
|
+
|
|
10
|
+
title = "use_dark_effective"
|
|
11
|
+
Page = NoPage
|
|
12
|
+
__doc__ += apidoc(solara.lab.use_dark_effective) # type: ignore
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# use_effect
|
|
2
|
+
|
|
3
|
+
```python
|
|
4
|
+
def use_effect(
|
|
5
|
+
effect: EffectCallable,
|
|
6
|
+
dependencies: Any | None = None
|
|
7
|
+
) -> None
|
|
8
|
+
...
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Execute non-declarative code within a callback, for instance to add event handlers. `effect` is executed *after* page render, letting us fetch the actual underlying widget object using `solara.get_widget` on an element. `dependencies` should be a list of variables, which when changed trigger re-execution of `effect`. If left empty, `effect` will never re-execute.
|
|
12
|
+
|
|
13
|
+
`effect` can return a cleanup function, which will be called before re-execution of `effect`, or when the component containing `use_effect` is removed.
|
|
14
|
+
|
|
15
|
+
Example use of `use_effect` to attach an event handler to a solara component:
|
|
16
|
+
|
|
17
|
+
```python
|
|
18
|
+
def use_event(el: solara.Element, callback: Callable):
|
|
19
|
+
def add_event_handler():
|
|
20
|
+
def on_enter(widget, event, data):
|
|
21
|
+
callback(widget.v_model)
|
|
22
|
+
|
|
23
|
+
widget = cast(ipyvue.VueWidget, solara.get_widget(el))
|
|
24
|
+
widget.on_event("keyup.enter", on_enter)
|
|
25
|
+
|
|
26
|
+
def cleanup():
|
|
27
|
+
widget.on_event("keyup.enter", on_enter, remove=True)
|
|
28
|
+
|
|
29
|
+
return cleanup
|
|
30
|
+
|
|
31
|
+
solara.use_effect(add_event_handler, dependencies=[])
|
|
32
|
+
|
|
33
|
+
@solara.component
|
|
34
|
+
def Page():
|
|
35
|
+
def function():
|
|
36
|
+
#Do something...
|
|
37
|
+
|
|
38
|
+
input = solara.InputText():
|
|
39
|
+
use_event(input, function)
|
|
40
|
+
...
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
See also the [Reacton docs](https://reacton.solara.dev/en/latest/api/#use_effect).
|