solara-ui 1.37.2__tar.gz → 1.39.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {solara_ui-1.37.2 → solara_ui-1.39.0}/PKG-INFO +1 -1
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/__init__.py +2 -2
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/__main__.py +8 -1
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/checks.py +4 -1
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/cross_filter.py +2 -2
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/echarts.py +8 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/echarts.vue +1 -1
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/markdown.py +9 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/markdown_editor.py +8 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/markdown_editor.vue +1 -1
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/sql_code.py +8 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/sql_code.vue +1 -1
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/minisettings.py +5 -5
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/flask.py +1 -1
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/starlette.py +82 -4
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/static/solara_bootstrap.py +1 -1
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/utils.py +8 -1
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/test/pytest_plugin.py +17 -7
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/toestand.py +0 -1
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/changelog/changelog.md +11 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/doc_use_download.py +1 -1
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/30-enterprise/10-oauth.md +3 -3
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/getting_started/content/04-tutorials/_data_science.ipynb +11 -11
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/getting_started/content/04-tutorials/_jupyter_dashboard_1.ipynb +56 -39
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/getting_started/content/07-deploying/10-self-hosted.md +3 -3
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/widgets/vue/gridlayout.vue +1 -1
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/widgets/widgets.py +8 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/assets_test.py +5 -5
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/cmdline_test.py +4 -3
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/input_date_test.py +4 -4
- solara_ui-1.39.0/tests/ui/snapshots/tests/integration/latex_test.py/test_widget_latex_solara-flask-chromium-win32-ipywidgets-7-changed-reference.png +0 -0
- solara_ui-1.39.0/tests/ui/snapshots/tests/integration/latex_test.py/test_widget_latex_solara-flask-chromium-win32-ipywidgets-7-reference.png +0 -0
- solara_ui-1.39.0/tests/ui/snapshots/tests/integration/latex_test.py/test_widget_latex_solara-flask-chromium-win32-ipywidgets-8-changed-reference.png +0 -0
- solara_ui-1.39.0/tests/ui/snapshots/tests/integration/latex_test.py/test_widget_latex_solara-flask-chromium-win32-ipywidgets-8-reference.png +0 -0
- solara_ui-1.39.0/tests/ui/snapshots/tests/integration/widget_test.py/test_slider_all-flask-jupyter_lab-chromium-win32-ipywidgets-7-reference.png +0 -0
- solara_ui-1.39.0/tests/ui/snapshots/tests/integration/widget_test.py/test_slider_all-flask-jupyter_lab-chromium-win32-ipywidgets-8-reference.png +0 -0
- solara_ui-1.39.0/tests/ui/snapshots/tests/integration/widget_test.py/test_slider_all-flask-jupyter_notebook-chromium-win32-ipywidgets-7-reference.png +0 -0
- solara_ui-1.39.0/tests/ui/snapshots/tests/integration/widget_test.py/test_slider_all-flask-jupyter_notebook-chromium-win32-ipywidgets-8-reference.png +0 -0
- solara_ui-1.39.0/tests/ui/snapshots/tests/integration/widget_test.py/test_slider_all-flask-solara-chromium-win32-ipywidgets-7-reference.png +0 -0
- solara_ui-1.39.0/tests/ui/snapshots/tests/integration/widget_test.py/test_slider_all-flask-solara-chromium-win32-ipywidgets-8-reference.png +0 -0
- solara_ui-1.39.0/tests/ui/snapshots/tests/integration/widget_test.py/test_slider_all-flask-voila-chromium-win32-ipywidgets-7-reference.png +0 -0
- solara_ui-1.39.0/tests/ui/snapshots/tests/integration/widget_test.py/test_slider_all-flask-voila-chromium-win32-ipywidgets-8-reference.png +0 -0
- solara_ui-1.39.0/tests/ui/snapshots/tests/integration/widget_test.py/test_slider_all-starlette-solara-chromium-win32-ipywidgets-7-reference.png +0 -0
- solara_ui-1.39.0/tests/ui/snapshots/tests/integration/widget_test.py/test_slider_all-starlette-solara-chromium-win32-ipywidgets-8-reference.png +0 -0
- solara_ui-1.39.0/tests/ui/snapshots/tests/integration/widget_test.py/test_solara_button_all-flask-jupyter_lab-chromium-win32-reference.png +0 -0
- solara_ui-1.39.0/tests/ui/snapshots/tests/integration/widget_test.py/test_solara_button_all-flask-jupyter_notebook-chromium-win32-reference.png +0 -0
- solara_ui-1.39.0/tests/ui/snapshots/tests/integration/widget_test.py/test_solara_button_all-flask-solara-chromium-win32-reference.png +0 -0
- solara_ui-1.39.0/tests/ui/snapshots/tests/integration/widget_test.py/test_solara_button_all-flask-voila-chromium-win32-reference.png +0 -0
- solara_ui-1.39.0/tests/ui/snapshots/tests/integration/widget_test.py/test_solara_button_all-starlette-solara-chromium-win32-reference.png +0 -0
- solara_ui-1.39.0/tests/ui/snapshots/tests/integration/widget_test.py/test_widget_button_solara-flask-chromium-win32-reference.png +0 -0
- solara_ui-1.39.0/tests/ui/snapshots/tests/integration/widget_test.py/test_widget_button_solara-starlette-chromium-win32-reference.png +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/solara_test_apps/multipage/05-and-notebooks.ipynb +1 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/solara_test_apps/multipage-widgets/04-color.ipynb +5 -1
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/solara_test_apps/notebookapp_component.ipynb +1 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/.gitignore +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/LICENSE +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/README.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/prefix/etc/jupyter/jupyter_notebook_config.d/solara.json +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/prefix/etc/jupyter/jupyter_server_config.d/solara.json +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/pyproject.toml +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/alias.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/autorouting.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/cache.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/checks.html +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/comm.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/alert.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/applayout.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/button.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/card.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/checkbox.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/code_highlight_css.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/code_highlight_css.vue +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/columns.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/component_vue.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/dataframe.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/datatable.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/datatable.vue +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/details.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/download.vue +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/figure_altair.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/file_browser.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/file_download.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/file_drop.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/file_drop.vue +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/file_list_widget.vue +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/head.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/head_tag.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/head_tag.vue +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/image.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/input.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/link.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/matplotlib.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/meta.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/misc.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/pivot_table.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/pivot_table.vue +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/progress.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/select.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/select.vue +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/slider.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/slider_date.vue +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/spinner-solara.vue +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/spinner.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/style.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/switch.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/tab_navigation.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/title.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/title.vue +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/togglebuttons.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/components/tooltip.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/core.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/datatypes.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/express.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/hooks/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/hooks/dataframe.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/hooks/misc.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/hooks/use_reactive.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/hooks/use_thread.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/kitchensink.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/lab/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/lab/components/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/lab/components/chat.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/lab/components/confirmation_dialog.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/lab/components/cross_filter.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/lab/components/input_date.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/lab/components/menu.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/lab/components/menu.vue +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/lab/components/tabs.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/lab/components/theming.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/lab/components/theming.vue +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/lab/hooks/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/lab/hooks/dataframe.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/lab/toestand.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/lab/utils/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/lab/utils/cookies.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/lab/utils/dataframe.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/lab/utils/headers.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/layout.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/lifecycle.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/py.typed +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/reactive.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/routing.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/scope/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/scope/types.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/app.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/assets/custom.css +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/assets/custom.js +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/assets/favicon.png +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/assets/favicon.svg +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/assets/style.css +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/assets/theme-dark.css +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/assets/theme-light.css +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/assets/theme.js +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/cdn_helper.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/esm.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/fastapi.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/jupyter/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/jupyter/cdn_handler.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/jupyter/server_extension.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/jupytertools.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/kernel.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/kernel_context.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/patch.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/reload.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/server.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/settings.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/shell.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/static/ansi.js +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/static/highlight-dark.css +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/static/highlight.css +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/static/main-vuetify.js +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/static/main.js +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/static/sun.svg +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/static/webworker.js +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/telemetry.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/templates/index.html.j2 +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/templates/loader-plain.css +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/templates/loader-plain.html +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/templates/loader-solara.css +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/templates/loader-solara.html +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/templates/plain.html +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/templates/solara.html.j2 +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/threaded.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/server/websocket.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/settings.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/tasks.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/template/button.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/template/markdown.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/template/portal/.flake8 +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/template/portal/.pre-commit-config.yaml +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/template/portal/LICENSE +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/template/portal/Procfile +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/template/portal/mypy.ini +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/template/portal/pyproject.toml +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/template/portal/solara_portal/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/template/portal/solara_portal/components/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/template/portal/solara_portal/components/article.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/template/portal/solara_portal/components/data.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/template/portal/solara_portal/components/header.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/template/portal/solara_portal/components/layout.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/template/portal/solara_portal/content/articles/equis-in-vidi.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/template/portal/solara_portal/content/articles/substiterat-vati.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/template/portal/solara_portal/data.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/template/portal/solara_portal/pages/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/template/portal/solara_portal/pages/article/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/template/portal/solara_portal/pages/tabular.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/template/portal/solara_portal/pages/viz/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/template/portal/solara_portal/pages/viz/overview.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/test/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/util.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/validate_hooks.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/assets/custom.css +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/assets/images/logo-small.png +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/assets/images/logo.svg +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/assets/images/logo_white.svg +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/assets/theme.js +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/components/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/components/algolia.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/components/algolia.vue +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/components/algolia_api.vue +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/components/docs.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/components/header.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/components/hero.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/components/mailchimp.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/components/mailchimp.vue +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/components/markdown.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/components/notebook.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/components/sidebar.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/apps/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/apps/authorization/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/apps/authorization/admin.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/apps/authorization/users.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/apps/jupyter-dashboard-1.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/apps/layout-demo.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/apps/multipage/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/apps/multipage/page1.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/apps/multipage/page2.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/apps/scatter.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/apps/scrolling.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/apps/tutorial-streamlit.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/changelog/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/contact/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/contact/contact.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/00-overview.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/10-howto/00-overview.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/10-howto/10-multipage.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/10-howto/20-layout.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/10-howto/30-testing.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/10-howto/31-debugging.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/10-howto/40-embed.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/10-howto/50-ipywidget_libraries.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/15-reference/00-overview.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/15-reference/40-static_files.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/15-reference/41-asset-files.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/15-reference/60-static-site-generation.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/15-reference/70-search.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/15-reference/80-reloading.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/15-reference/90-notebook-support.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/15-reference/95-caching.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/20-understanding/00-introduction.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/20-understanding/05-ipywidgets.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/20-understanding/06-ipyvuetify.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/20-understanding/10-reacton.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/20-understanding/12-reacton-basics.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/20-understanding/15-anatomy.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/20-understanding/17-rules-of-hooks.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/20-understanding/18-containers.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/20-understanding/20-solara.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/20-understanding/40-routing.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/20-understanding/50-solara-server.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/20-understanding/60-voila.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/30-enterprise/00-overview.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/40-development/00-overview.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/40-development/01-contribute.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/advanced/content/40-development/10-setup.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/cross_filter/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/cross_filter/cross_filter_dataframe.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/cross_filter/cross_filter_report.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/cross_filter/cross_filter_select.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/cross_filter/cross_filter_slider.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/hooks/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/hooks/use_cross_filter.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/hooks/use_dark_effective.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/hooks/use_effect.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/hooks/use_effect.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/hooks/use_exception.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/hooks/use_memo.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/hooks/use_memo.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/hooks/use_previous.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/hooks/use_reactive.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/hooks/use_state.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/hooks/use_state_or_update.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/hooks/use_thread.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/hooks/use_thread.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/hooks/use_trait_observe.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/routing/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/routing/generate_routes.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/routing/generate_routes_directory.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/routing/resolve_path.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/routing/route.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/routing/use_route.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/routing/use_router.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/utilities/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/utilities/component_vue.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/utilities/computed.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/utilities/display.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/utilities/get_kernel_id.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/utilities/get_session_id.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/utilities/memoize.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/utilities/on_kernel_start.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/utilities/reactive.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/api/utilities/widget.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/advanced/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/advanced/link.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/advanced/meta.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/advanced/style.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/common.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/data/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/data/dataframe.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/data/pivot_table.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/enterprise/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/enterprise/avatar.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/enterprise/avatar_menu.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/input/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/input/button.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/input/checkbox.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/input/file_browser.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/input/file_drop.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/input/input.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/input/select.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/input/slider.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/input/switch.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/input/togglebuttons.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/lab/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/lab/chat.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/lab/confirmation_dialog.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/lab/cookies_headers.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/lab/input_date.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/lab/menu.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/lab/tab.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/lab/tabs.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/lab/task.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/lab/theming.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/lab/use_task.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/layout/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/layout/app_bar.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/layout/app_bar_title.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/layout/app_layout.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/layout/card.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/layout/card_actions.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/layout/column.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/layout/columns.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/layout/columns_responsive.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/layout/details.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/layout/griddraggable.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/layout/gridfixed.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/layout/hbox.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/layout/row.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/layout/sidebar.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/layout/vbox.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/output/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/output/file_download.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/output/html.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/output/image.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/output/markdown.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/output/markdown_editor.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/output/sql_code.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/output/tooltip.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/page/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/page/head.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/page/title.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/status/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/status/error.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/status/info.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/status/progress.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/status/spinner.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/status/success.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/status/warning.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/viz/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/viz/altair.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/viz/echarts.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/viz/matplotlib.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/viz/plotly.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/components/viz/plotly_express.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/ai/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/ai/chatbot.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/ai/tokenizer.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/basics/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/basics/sine.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/fullscreen/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/fullscreen/authorization.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/fullscreen/layout_demo.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/fullscreen/multipage.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/fullscreen/scatter.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/fullscreen/scrolling.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/fullscreen/tutorial_streamlit.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/general/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/general/custom_storage.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/general/deploy_model.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/general/live_update.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/general/login_oauth.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/general/mycard.vue +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/general/pokemon_search.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/general/vue_component.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/ipycanvas.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/libraries/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/libraries/altair.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/libraries/bqplot.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/libraries/ipyleaflet.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/libraries/ipyleaflet_advanced.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/utilities/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/utilities/calculator.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/utilities/countdown_timer.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/utilities/todo.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/visualization/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/visualization/annotator.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/visualization/linked_views.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/examples/visualization/plotly.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/faq/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/faq/content/99-faq.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/getting_started/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/getting_started/content/00-quickstart.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/getting_started/content/01-introduction.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/getting_started/content/02-installing.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/getting_started/content/04-tutorials/00-overview.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/getting_started/content/04-tutorials/10_data_science.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/getting_started/content/04-tutorials/20-web-app.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/getting_started/content/04-tutorials/30-ipywidgets.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/getting_started/content/04-tutorials/40-streamlit.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/getting_started/content/04-tutorials/50-dash.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/getting_started/content/04-tutorials/60-jupyter-dashboard-part1.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/getting_started/content/04-tutorials/SF_crime_sample.csv.gz +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/getting_started/content/05-fundamentals/00-overview.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/getting_started/content/05-fundamentals/10-components.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/getting_started/content/05-fundamentals/50-state-management.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/getting_started/content/07-deploying/00-overview.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/getting_started/content/07-deploying/20-cloud-hosted.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/getting_started/content/80-what-is-lab.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/documentation/getting_started/content/90-troubleshoot.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/docutils.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/showcase/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/showcase/domino_code_assist.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/showcase/planeto_tessa.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/showcase/solara_dev.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/showcase/solarathon_2023_team_2.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/showcase/solarathon_2023_team_4.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/showcase/solarathon_2023_team_5.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/showcase/solarathon_2023_team_6.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/pages/showcase/wanderlust.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/public/beach.jpeg +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/public/logo.svg +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/public/social/discord.svg +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/public/social/github.svg +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/public/social/twitter.svg +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/public/success.html +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/templates/index.html.j2 +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/website/utils.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/widgets/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/widgets/vue/html.vue +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/widgets/vue/navigator.vue +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/solara/widgets/vue/vegalite.vue +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/conftest.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/docs/docs_howto_event_with_future_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/docs/docs_howto_event_with_polling_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/docs/docs_howto_no_browser_api_find_testing_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/docs/docs_howto_no_browser_testing_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/docs/docs_howto_no_browser_threaded_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/api_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/app_widget.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/apps/not-allowed +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/apps/public/test.txt +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/apps/secure/app.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/assets/assets1/common.js +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/assets/assets1/unique1.js +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/assets/assets2/common.js +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/assets/assets2/custom.css +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/assets/assets2/custom.js +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/assets/assets2/unique2.js +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/async_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/cdn_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/conftest.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/create_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/enterprise/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/enterprise/oauth_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/error_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/esm_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/file_download_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/flask_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/latex_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/lifecycle_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/markdown_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/menu_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/popout_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/reconnect_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/reload/apps.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/router_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/server_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/ssg_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/starlette_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/test.vue +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/testapp.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/integration/widget_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/ui/snapshots/tests/integration/latex_test.py/test_widget_latex_solara-flask-chromium-linux-ipywidgets-7-changed-reference.png +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/ui/snapshots/tests/integration/latex_test.py/test_widget_latex_solara-flask-chromium-linux-ipywidgets-7-reference.png +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/ui/snapshots/tests/integration/latex_test.py/test_widget_latex_solara-flask-chromium-linux-ipywidgets-8-changed-reference.png +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/ui/snapshots/tests/integration/latex_test.py/test_widget_latex_solara-flask-chromium-linux-ipywidgets-8-reference.png +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/ui/snapshots/tests/integration/widget_test.py/test_slider_all-flask-jupyter_lab-chromium-linux-ipywidgets-7-reference.png +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/ui/snapshots/tests/integration/widget_test.py/test_slider_all-flask-jupyter_lab-chromium-linux-ipywidgets-8-reference.png +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/ui/snapshots/tests/integration/widget_test.py/test_slider_all-flask-jupyter_notebook-chromium-linux-ipywidgets-7-reference.png +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/ui/snapshots/tests/integration/widget_test.py/test_slider_all-flask-jupyter_notebook-chromium-linux-ipywidgets-8-reference.png +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/ui/snapshots/tests/integration/widget_test.py/test_slider_all-flask-solara-chromium-linux-ipywidgets-7-reference.png +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/ui/snapshots/tests/integration/widget_test.py/test_slider_all-flask-solara-chromium-linux-ipywidgets-8-reference.png +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/ui/snapshots/tests/integration/widget_test.py/test_slider_all-flask-voila-chromium-linux-ipywidgets-7-reference.png +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/ui/snapshots/tests/integration/widget_test.py/test_slider_all-flask-voila-chromium-linux-ipywidgets-8-reference.png +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/ui/snapshots/tests/integration/widget_test.py/test_slider_all-starlette-solara-chromium-linux-ipywidgets-7-reference.png +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/ui/snapshots/tests/integration/widget_test.py/test_slider_all-starlette-solara-chromium-linux-ipywidgets-8-reference.png +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/ui/snapshots/tests/integration/widget_test.py/test_solara_button_all-flask-jupyter_lab-chromium-linux-reference.png +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/ui/snapshots/tests/integration/widget_test.py/test_solara_button_all-flask-jupyter_notebook-chromium-linux-reference.png +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/ui/snapshots/tests/integration/widget_test.py/test_solara_button_all-flask-solara-chromium-linux-reference.png +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/ui/snapshots/tests/integration/widget_test.py/test_solara_button_all-flask-voila-chromium-linux-reference.png +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/ui/snapshots/tests/integration/widget_test.py/test_solara_button_all-starlette-solara-chromium-linux-reference.png +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/ui/snapshots/tests/integration/widget_test.py/test_widget_button_solara-flask-chromium-linux-ipyvuetify3-reference.png +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/ui/snapshots/tests/integration/widget_test.py/test_widget_button_solara-flask-chromium-linux-reference.png +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/ui/snapshots/tests/integration/widget_test.py/test_widget_button_solara-starlette-chromium-linux-ipyvuetify3-reference.png +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/ui/snapshots/tests/integration/widget_test.py/test_widget_button_solara-starlette-chromium-linux-reference.png +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/app_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/applayout_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/autorouting_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/cache_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/cdn_helper_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/chat_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/checkbox_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/common.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/component_frontend_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/component_vue_test.vue +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/confirmation_dialog_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/conftest.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/cross_filter_component_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/cross_filter_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/dataframe_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/datatable_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/display_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/express_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/file_browser_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/file_download_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/hook_use_invalid_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/hooks_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/input_date_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/input_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/kernel_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/lab/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/lifecycle_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/matplotlib_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/no_solara_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/output_widget_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/patch_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/pivottable_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/reload_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/router_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/select_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/settings_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/shell_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/slider_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/solara_test_apps/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/solara_test_apps/food/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/solara_test_apps/food/food.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/solara_test_apps/food/index.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/solara_test_apps/kernel_start.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/solara_test_apps/multipage/01-home.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/solara_test_apps/multipage/02-my_fruit.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/solara_test_apps/multipage/03-some-markdown.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/solara_test_apps/multipage/04-a_directory/00-another-markdown.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/solara_test_apps/multipage/04-a_directory/01-not-an-app.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/solara_test_apps/multipage/04-a_directory/__init__.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/solara_test_apps/multipage/06-custom-routes.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/solara_test_apps/multipage/10-single-file-directory/single-file.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/solara_test_apps/multipage/99-some_other_python_script.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/solara_test_apps/multipage/some_other_file.txt +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/solara_test_apps/multipage-widgets/00-overview.md +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/solara_test_apps/multipage-widgets/01-views.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/solara_test_apps/multipage-widgets/02-likes.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/solara_test_apps/multipage-widgets/03-volume.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/solara_test_apps/notebookapp_element.ipynb +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/solara_test_apps/notebookapp_widget.ipynb +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/solara_test_apps/single_file.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/solara_test_apps/single_file_multiple_routes.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/solara_test_apps/single_file_routes.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/switch_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/tabs_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/task_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/telemetry_tests.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/toestand_computed_reload.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/toestand_test.py +0 -0
- {solara_ui-1.37.2 → solara_ui-1.39.0}/tests/unit/toggle_button_test.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Build webapps using IPywidgets"""
|
|
2
2
|
|
|
3
|
-
__version__ = "1.
|
|
3
|
+
__version__ = "1.39.0"
|
|
4
4
|
github_url = "https://github.com/widgetti/solara"
|
|
5
5
|
git_branch = "master"
|
|
6
6
|
|
|
@@ -11,7 +11,7 @@ from . import comm # noqa: F401
|
|
|
11
11
|
def _using_solara_server():
|
|
12
12
|
import sys
|
|
13
13
|
|
|
14
|
-
if "solara.server" in sys.modules:
|
|
14
|
+
if "solara.server.starlette" in sys.modules or "solara.server.flask" in sys.modules:
|
|
15
15
|
return True
|
|
16
16
|
if sys.argv[0].split("/")[-1] == "solara":
|
|
17
17
|
return True
|
|
@@ -17,6 +17,7 @@ from uvicorn.main import LEVEL_CHOICES, LOOP_CHOICES
|
|
|
17
17
|
|
|
18
18
|
import solara
|
|
19
19
|
from solara.server import settings
|
|
20
|
+
import solara.server.threaded
|
|
20
21
|
|
|
21
22
|
from .server import telemetry
|
|
22
23
|
|
|
@@ -130,7 +131,11 @@ if "SOLARA_MODE" in os.environ:
|
|
|
130
131
|
|
|
131
132
|
|
|
132
133
|
@cli.command()
|
|
133
|
-
@click.option(
|
|
134
|
+
@click.option(
|
|
135
|
+
"--port",
|
|
136
|
+
default=int(os.environ.get("PORT", 8765)),
|
|
137
|
+
help="Port to run the server on, 0 for a random free port, default to $PORT or 8765.",
|
|
138
|
+
)
|
|
134
139
|
@click.option(
|
|
135
140
|
"--host",
|
|
136
141
|
default=settings.main.host,
|
|
@@ -302,6 +307,8 @@ def run(
|
|
|
302
307
|
settings.ssg.enabled = ssg
|
|
303
308
|
settings.search.enabled = search
|
|
304
309
|
reload_dirs = restart_dirs if restart_dirs else None
|
|
310
|
+
if port == 0:
|
|
311
|
+
port = solara.server.threaded.get_free_port()
|
|
305
312
|
del restart_dirs
|
|
306
313
|
url = f"http://{host}:{port}"
|
|
307
314
|
|
|
@@ -124,6 +124,9 @@ def SolaraCheck():
|
|
|
124
124
|
def getcmdline(pid):
|
|
125
125
|
# for linux
|
|
126
126
|
if sys.platform == "linux":
|
|
127
|
+
# if /proc/{pid}/exe exists, follow the symlink
|
|
128
|
+
if os.path.exists(f"/proc/{pid}/exe"):
|
|
129
|
+
return os.readlink(f"/proc/{pid}/exe")
|
|
127
130
|
with open(f"/proc/{pid}/cmdline", "rb") as f:
|
|
128
131
|
return f.read().split(b"\00")[0].decode("utf-8")
|
|
129
132
|
elif sys.platform == "darwin":
|
|
@@ -176,7 +179,7 @@ libraries_extra = [
|
|
|
176
179
|
{"python": "bqplot", "classic": "bqplot/extension", "lab": "bqplot"},
|
|
177
180
|
{"python": "ipyvolume", "classic": "ipyvolume/extension", "lab": "ipyvolume"},
|
|
178
181
|
{"python": "ipywebrtc", "classic": "jupyter-webrtc", "lab": "jupyter-webrtc"},
|
|
179
|
-
{"python": "ipyleaflet", "classic": "
|
|
182
|
+
{"python": "ipyleaflet", "classic": "jupyter-leaflet/extension", "lab": "jupyter-leaflet"},
|
|
180
183
|
]
|
|
181
184
|
|
|
182
185
|
|
|
@@ -275,14 +275,14 @@ def CrossFilterSlider(
|
|
|
275
275
|
with solara.HBox(align_items="center"):
|
|
276
276
|
label = f"Select {column} {mode} " if not invert else f"Drop {column} {mode} "
|
|
277
277
|
|
|
278
|
-
if py_types[column]
|
|
278
|
+
if py_types[column] is int:
|
|
279
279
|
if isinstance(filter_value, int):
|
|
280
280
|
solara.SliderInt(label=label, value=filter_value, min=vmin, max=vmax, on_value=set_filter_value, disabled=not enable, thumb_label=False)
|
|
281
281
|
else:
|
|
282
282
|
solara.Error(f"Filter value is not an integer type, but {type(filter_value)} (value = {filter_value})")
|
|
283
283
|
if filter_value is not None:
|
|
284
284
|
solara.Text(f"{filter_value:,}")
|
|
285
|
-
elif py_types[column]
|
|
285
|
+
elif py_types[column] is float:
|
|
286
286
|
if isinstance(filter_value, float):
|
|
287
287
|
solara.SliderFloat(label=label, value=filter_value, min=vmin, max=vmax, on_value=set_filter_value, disabled=not enable, thumb_label=False)
|
|
288
288
|
else:
|
|
@@ -20,6 +20,14 @@ class EchartsWidget(ipyvuetify.VuetifyTemplate):
|
|
|
20
20
|
on_mouseout = traitlets.Callable(None, allow_none=True)
|
|
21
21
|
# same, for performance
|
|
22
22
|
on_mouseout_enabled = traitlets.Bool(False).tag(sync=True)
|
|
23
|
+
cdn = traitlets.Unicode(None, allow_none=True).tag(sync=True)
|
|
24
|
+
|
|
25
|
+
@traitlets.default("cdn")
|
|
26
|
+
def _cdn(self):
|
|
27
|
+
import solara.settings
|
|
28
|
+
|
|
29
|
+
if not solara.settings.assets.proxy:
|
|
30
|
+
return solara.settings.assets.cdn
|
|
23
31
|
|
|
24
32
|
def vue_on_click(self, data):
|
|
25
33
|
if self.on_click is not None:
|
|
@@ -110,7 +110,7 @@ module.exports = {
|
|
|
110
110
|
return base;
|
|
111
111
|
},
|
|
112
112
|
getCdn() {
|
|
113
|
-
return window.solara ? window.solara.cdn : `${this.getJupyterBaseUrl()}_solara/cdn`
|
|
113
|
+
return this.cdn || (window.solara ? window.solara.cdn : `${this.getJupyterBaseUrl()}_solara/cdn`);
|
|
114
114
|
},
|
|
115
115
|
},
|
|
116
116
|
};
|
|
@@ -76,6 +76,12 @@ def _markdown_template(
|
|
|
76
76
|
html,
|
|
77
77
|
style="",
|
|
78
78
|
):
|
|
79
|
+
cdn = None
|
|
80
|
+
import solara.settings
|
|
81
|
+
|
|
82
|
+
if not solara.settings.assets.proxy:
|
|
83
|
+
cdn = solara.settings.assets.cdn
|
|
84
|
+
|
|
79
85
|
template = (
|
|
80
86
|
"""
|
|
81
87
|
<template>
|
|
@@ -89,6 +95,9 @@ def _markdown_template(
|
|
|
89
95
|
<script>
|
|
90
96
|
module.exports = {
|
|
91
97
|
async mounted() {
|
|
98
|
+
this.cdn = """
|
|
99
|
+
+ (rf"'{cdn}'" if cdn is not None else r"null")
|
|
100
|
+
+ r""";
|
|
92
101
|
await this.loadRequire();
|
|
93
102
|
this.mermaid = await this.loadMermaid();
|
|
94
103
|
this.mermaid.init();
|
|
@@ -11,6 +11,14 @@ class MarkdownEditorWidget(ipyvuetify.VuetifyTemplate):
|
|
|
11
11
|
|
|
12
12
|
value = traitlets.Unicode("").tag(sync=True)
|
|
13
13
|
height = traitlets.Unicode("180px").tag(sync=True)
|
|
14
|
+
cdn = traitlets.Unicode(None, allow_none=True).tag(sync=True)
|
|
15
|
+
|
|
16
|
+
@traitlets.default("cdn")
|
|
17
|
+
def _cdn(self):
|
|
18
|
+
import solara.settings
|
|
19
|
+
|
|
20
|
+
if not solara.settings.assets.proxy:
|
|
21
|
+
return solara.settings.assets.cdn
|
|
14
22
|
|
|
15
23
|
|
|
16
24
|
@solara.component
|
|
@@ -264,7 +264,7 @@ module.exports = {
|
|
|
264
264
|
return base
|
|
265
265
|
},
|
|
266
266
|
getCdn() {
|
|
267
|
-
return window.solara ? window.solara.cdn : `${this.getJupyterBaseUrl()}_solara/cdn
|
|
267
|
+
return this.cdn || (window.solara ? window.solara.cdn : `${this.getJupyterBaseUrl()}_solara/cdn`);
|
|
268
268
|
},
|
|
269
269
|
},
|
|
270
270
|
};
|
|
@@ -13,6 +13,14 @@ class SqlCodeWidget(ipyvue.VueTemplate):
|
|
|
13
13
|
query = traitlets.Unicode(allow_none=True, default_value=None).tag(sync=True)
|
|
14
14
|
tables = traitlets.Dict(allow_none=True, default_value=None).tag(sync=True)
|
|
15
15
|
height = traitlets.Unicode("180px").tag(sync=True)
|
|
16
|
+
cdn = traitlets.Unicode(None, allow_none=True).tag(sync=True)
|
|
17
|
+
|
|
18
|
+
@traitlets.default("cdn")
|
|
19
|
+
def _cdn(self):
|
|
20
|
+
import solara.settings
|
|
21
|
+
|
|
22
|
+
if not solara.settings.assets.proxy:
|
|
23
|
+
return solara.settings.assets.cdn
|
|
16
24
|
|
|
17
25
|
|
|
18
26
|
@solara.component
|
|
@@ -14,7 +14,7 @@ def _get_type(annotation):
|
|
|
14
14
|
if annotation == Optional[check_type]:
|
|
15
15
|
return check_type
|
|
16
16
|
if hasattr(annotation, "__origin__"):
|
|
17
|
-
if annotation.__origin__
|
|
17
|
+
if annotation.__origin__ is dict:
|
|
18
18
|
return dict
|
|
19
19
|
return annotation
|
|
20
20
|
|
|
@@ -72,13 +72,13 @@ def convert(annotation, value: str) -> Any:
|
|
|
72
72
|
annotation = sub_type
|
|
73
73
|
values = value.split(",")
|
|
74
74
|
return [convert(sub_type, k) for k in values]
|
|
75
|
-
if annotation
|
|
75
|
+
if annotation is str:
|
|
76
76
|
return value
|
|
77
|
-
elif annotation
|
|
77
|
+
elif annotation is int:
|
|
78
78
|
return int(value)
|
|
79
|
-
elif annotation
|
|
79
|
+
elif annotation is float:
|
|
80
80
|
return float(value)
|
|
81
|
-
elif annotation
|
|
81
|
+
elif annotation is bool:
|
|
82
82
|
if value in ("True", "true", "1"):
|
|
83
83
|
return True
|
|
84
84
|
elif value in ("False", "false", "0"):
|
|
@@ -199,7 +199,7 @@ def nbext(dir, filename):
|
|
|
199
199
|
for directory in server.nbextensions_directories:
|
|
200
200
|
file = directory / dir / filename
|
|
201
201
|
if file.exists():
|
|
202
|
-
return send_from_directory(directory, dir +
|
|
202
|
+
return send_from_directory(directory, dir + "/" + filename)
|
|
203
203
|
return flask.Response("not found", status=404)
|
|
204
204
|
|
|
205
205
|
|
|
@@ -9,6 +9,7 @@ import threading
|
|
|
9
9
|
import typing
|
|
10
10
|
from typing import Any, Dict, List, Optional, Set, Union, cast
|
|
11
11
|
from uuid import uuid4
|
|
12
|
+
import warnings
|
|
12
13
|
|
|
13
14
|
import anyio
|
|
14
15
|
import starlette.websockets
|
|
@@ -85,7 +86,11 @@ prefix = ""
|
|
|
85
86
|
# Since starlette seems to accept really large values for http, lets do the same for websockets
|
|
86
87
|
# An arbitrarily large value we settled on for now is 32kb
|
|
87
88
|
# If we don't do this, users with many cookies will fail to get a websocket connection.
|
|
88
|
-
websockets.
|
|
89
|
+
ws_version = tuple(map(int, websockets.__version__.split(".")))
|
|
90
|
+
if ws_version[0] >= 13:
|
|
91
|
+
websockets.legacy.http.MAX_LINE_LENGTH = int(os.environ.get("WEBSOCKETS_MAX_LINE_LENGTH", str(1024 * 32))) # type: ignore
|
|
92
|
+
else:
|
|
93
|
+
websockets.legacy.http.MAX_LINE = 1024 * 32 # type: ignore
|
|
89
94
|
|
|
90
95
|
|
|
91
96
|
class WebsocketDebugInfo:
|
|
@@ -322,17 +327,45 @@ def close(request: Request):
|
|
|
322
327
|
|
|
323
328
|
|
|
324
329
|
async def root(request: Request, fullpath: str = ""):
|
|
330
|
+
forwarded_host = request.headers.get("x-forwarded-host")
|
|
331
|
+
forwarded_proto = request.headers.get("x-forwarded-proto")
|
|
332
|
+
host = request.headers.get("host")
|
|
333
|
+
if forwarded_proto and forwarded_proto != request.scope["scheme"]:
|
|
334
|
+
warnings.warn(f"""Header x-forwarded-proto={forwarded_proto!r} does not match scheme={request.scope['scheme']!r} as given by the asgi framework (probably uvicorn)
|
|
335
|
+
|
|
336
|
+
This might be a configuration mismatch behind a reverse proxy and can cause issues with redirect urls, and auth.
|
|
337
|
+
|
|
338
|
+
Most likely, you need to trust your reverse proxy server, see:
|
|
339
|
+
https://solara.dev/documentation/getting_started/deploying/self-hosted
|
|
340
|
+
|
|
341
|
+
If you use uvicorn (the default when you use `solara run`), make sure you
|
|
342
|
+
configure the following environment variables for uvicorn correctly:
|
|
343
|
+
UVICORN_PROXY_HEADERS=1 # only needed for uvicorn < 0.10, since it is the default after 0.10
|
|
344
|
+
FORWARDED_ALLOW_IPS="127.0.0.1" # 127.0.0.1 is the default, replace this by the ip of the proxy server
|
|
345
|
+
|
|
346
|
+
Make sure you replace the IP with the correct IP of the reverse proxy server (instead of 127.0.0.1).
|
|
347
|
+
|
|
348
|
+
If you are sure that only the reverse proxy can reach the solara server, you can consider setting:
|
|
349
|
+
FORWARDED_ALLOW_IPS="*" # This can be a security risk, only use when you know what you are doing
|
|
350
|
+
""")
|
|
325
351
|
if settings.oauth.private and not has_auth_support:
|
|
326
352
|
raise RuntimeError("SOLARA_OAUTH_PRIVATE requires solara-enterprise")
|
|
327
353
|
root_path = settings.main.root_path or ""
|
|
328
354
|
if not settings.main.base_url:
|
|
355
|
+
# Note:
|
|
356
|
+
# starlette does not respect x-forwarded-host, and therefore
|
|
357
|
+
# base_url and expected_origin below could be different
|
|
358
|
+
# x-forwarded-host should only be considered if the same criteria in
|
|
359
|
+
# uvicorn's ProxyHeadersMiddleware accepts x-forwarded-proto
|
|
329
360
|
settings.main.base_url = str(request.base_url)
|
|
330
361
|
# if not explicltly set,
|
|
362
|
+
configured_root_path = settings.main.root_path
|
|
363
|
+
scope = request.scope
|
|
364
|
+
root_path_asgi = scope.get("route_root_path", scope.get("root_path", ""))
|
|
331
365
|
if settings.main.root_path is None:
|
|
332
366
|
# use the default root path from the app, which seems to also include the path
|
|
333
367
|
# if we are mounted under a path
|
|
334
|
-
|
|
335
|
-
root_path = scope.get("route_root_path", scope.get("root_path", ""))
|
|
368
|
+
root_path = root_path_asgi
|
|
336
369
|
logger.debug("root_path: %s", root_path)
|
|
337
370
|
# or use the script-name header, for instance when running under a reverse proxy
|
|
338
371
|
script_name = request.headers.get("script-name")
|
|
@@ -345,6 +378,51 @@ async def root(request: Request, fullpath: str = ""):
|
|
|
345
378
|
root_path = script_name
|
|
346
379
|
settings.main.root_path = root_path
|
|
347
380
|
|
|
381
|
+
# lets be flexible about the trailing slash
|
|
382
|
+
# TODO: maybe we should be more strict about the trailing slash
|
|
383
|
+
naked_root_path = settings.main.root_path.rstrip("/")
|
|
384
|
+
naked_base_url = settings.main.base_url.rstrip("/")
|
|
385
|
+
if not naked_base_url.endswith(naked_root_path):
|
|
386
|
+
msg = f"""base url {naked_base_url!r} does not end with root path {naked_root_path!r}
|
|
387
|
+
|
|
388
|
+
This could be a configuration mismatch behind a reverse proxy and can cause issues with redirect urls, and auth.
|
|
389
|
+
|
|
390
|
+
See also https://solara.dev/documentation/getting_started/deploying/self-hosted
|
|
391
|
+
"""
|
|
392
|
+
if "script-name" in request.headers:
|
|
393
|
+
msg += f"""It looks like the reverse proxy sets the script-name header to {request.headers['script-name']!r}
|
|
394
|
+
"""
|
|
395
|
+
if "x-script-name" in request.headers:
|
|
396
|
+
msg += f"""It looks like the reverse proxy sets the x-script-name header to {request.headers['x-script-name']!r}
|
|
397
|
+
"""
|
|
398
|
+
if configured_root_path:
|
|
399
|
+
msg += f"""It looks like the root path was configured to {configured_root_path!r} in the settings
|
|
400
|
+
"""
|
|
401
|
+
if root_path_asgi:
|
|
402
|
+
msg += f"""It looks like the root path set by the asgi framework was configured to {root_path_asgi!r}
|
|
403
|
+
"""
|
|
404
|
+
warnings.warn(msg)
|
|
405
|
+
if host and forwarded_host and forwarded_proto:
|
|
406
|
+
port = request.base_url.port
|
|
407
|
+
ports = {"http": 80, "https": 443}
|
|
408
|
+
expected_origin = f"{forwarded_proto}://{forwarded_host}"
|
|
409
|
+
if port and port != ports[forwarded_proto]:
|
|
410
|
+
expected_origin += f":{port}"
|
|
411
|
+
starlette_origin = settings.main.base_url
|
|
412
|
+
# strip off trailing / because we compare to the naked root path
|
|
413
|
+
starlette_origin = starlette_origin.rstrip("/")
|
|
414
|
+
if naked_root_path:
|
|
415
|
+
# take off the root path
|
|
416
|
+
starlette_origin = starlette_origin[: -len(naked_root_path)]
|
|
417
|
+
if starlette_origin != expected_origin:
|
|
418
|
+
warnings.warn(f"""Origin as determined by starlette ({starlette_origin!r}) does not match expected origin ({expected_origin!r}) based on x-forwarded-proto ({forwarded_proto!r}) and x-forwarded-host ({forwarded_host!r}) headers.
|
|
419
|
+
|
|
420
|
+
This might be a configuration mismatch behind a reverse proxy and can cause issues with redirect urls, and auth.
|
|
421
|
+
Most likely your proxy server sets the host header incorrectly (value for this request was {host!r})
|
|
422
|
+
|
|
423
|
+
See also https://solara.dev/documentation/getting_started/deploying/self-hosted
|
|
424
|
+
""")
|
|
425
|
+
|
|
348
426
|
request_path = request.url.path
|
|
349
427
|
if request_path.startswith(root_path):
|
|
350
428
|
request_path = request_path[len(root_path) :]
|
|
@@ -370,7 +448,7 @@ async def root(request: Request, fullpath: str = ""):
|
|
|
370
448
|
# however, samesite=none requires Secure https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite
|
|
371
449
|
# when hosted on the localhost domain we can always set the Secure flag
|
|
372
450
|
# to allow samesite https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies
|
|
373
|
-
if request.headers.get("x-forwarded-proto", "http") == "https" or request.base_url.hostname == "localhost":
|
|
451
|
+
if request.scope["scheme"] == "https" or request.headers.get("x-forwarded-proto", "http") == "https" or request.base_url.hostname == "localhost":
|
|
374
452
|
samesite = "none"
|
|
375
453
|
secure = True
|
|
376
454
|
response.set_cookie(
|
|
@@ -119,7 +119,7 @@ async def main():
|
|
|
119
119
|
]
|
|
120
120
|
for dep in requirements:
|
|
121
121
|
await micropip.install(dep, keep_going=True)
|
|
122
|
-
await micropip.install("/wheels/solara-1.
|
|
122
|
+
await micropip.install("/wheels/solara-1.39.0-py2.py3-none-any.whl", keep_going=True)
|
|
123
123
|
import solara
|
|
124
124
|
|
|
125
125
|
el = solara.Warning("lala")
|
|
@@ -3,6 +3,7 @@ import logging
|
|
|
3
3
|
import os
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
import pdb
|
|
6
|
+
import sys
|
|
6
7
|
import traceback
|
|
7
8
|
|
|
8
9
|
from rich import print
|
|
@@ -20,7 +21,13 @@ def start_error(title, msg, exception: Exception = None):
|
|
|
20
21
|
def path_is_child_of(path: Path, parent: Path) -> bool:
|
|
21
22
|
# We use os.path.normpath() because we do not want to follow symlinks
|
|
22
23
|
# in editable installs, since some packages are symlinked
|
|
23
|
-
|
|
24
|
+
path_string = os.path.normpath(path)
|
|
25
|
+
parent_string = os.path.normpath(parent)
|
|
26
|
+
if sys.platform == "win32":
|
|
27
|
+
# on windows, we sometimes get different casing (only seen on CI)
|
|
28
|
+
path_string = path_string.lower()
|
|
29
|
+
parent_string = parent_string.lower()
|
|
30
|
+
return path_string.startswith(parent_string)
|
|
24
31
|
|
|
25
32
|
|
|
26
33
|
@contextlib.contextmanager
|
|
@@ -38,6 +38,7 @@ TEST_PORT_START = int(os.environ.get("PORT", "18765")) + 100 # do not interfere
|
|
|
38
38
|
TEST_HOST = solara.server.settings.main.host
|
|
39
39
|
TIMEOUT = float(os.environ.get("SOLARA_PW_TIMEOUT", "18"))
|
|
40
40
|
PYTEST_IPYWIDGETS_SOLARA_APP_WAIT_TIMEOUT = int(os.environ.get("PYTEST_IPYWIDGETS_SOLARA_APP_WAIT_TIMEOUT", "10"))
|
|
41
|
+
runners = os.environ.get("SOLARA_TEST_RUNNERS", "solara,voila,jupyter_lab,jupyter_notebook").split(",")
|
|
41
42
|
|
|
42
43
|
|
|
43
44
|
@pytest.fixture(scope="session")
|
|
@@ -264,10 +265,13 @@ class ServerVoila(ServerBase):
|
|
|
264
265
|
raise RuntimeError("Jupyter server already running, use lsof -i :{self.port} to find the process and kill it")
|
|
265
266
|
cmd = (
|
|
266
267
|
"voila --no-browser --VoilaTest.log_level=DEBUG --Voila.port_retries=0 --VoilaExecutor.timeout=240"
|
|
267
|
-
f
|
|
268
|
+
f' --Voila.port={self.port} --show_tracebacks=True "{self.notebook_path}" --enable_nbextensions=True'
|
|
268
269
|
)
|
|
269
270
|
logger.info(f"Starting Voila server at {self.base_url} with command {cmd}")
|
|
270
|
-
|
|
271
|
+
if sys.platform == "win32":
|
|
272
|
+
args = cmd
|
|
273
|
+
else:
|
|
274
|
+
args = shlex.split(cmd)
|
|
271
275
|
self.popen = subprocess.Popen(args, shell=False, stdout=sys.stdout, stderr=sys.stderr, stdin=None)
|
|
272
276
|
self.started.set()
|
|
273
277
|
|
|
@@ -294,15 +298,21 @@ class ServerJupyter(ServerBase):
|
|
|
294
298
|
def serve(self):
|
|
295
299
|
if self.has_started():
|
|
296
300
|
raise RuntimeError(f"Jupyter server already running, use lsof -i :{self.port} to find the process and kill it")
|
|
297
|
-
cmd = f'jupyter lab --port={self.port} --no-browser --ServerApp.token="" --port-retries=0 {self.notebook_path}'
|
|
301
|
+
cmd = f'jupyter lab --port={self.port} --no-browser --ServerApp.token="" --port-retries=0 "{self.notebook_path}"'
|
|
298
302
|
logger.info(f"Starting Jupyter (lab) server at {self.base_url} with command {cmd}")
|
|
299
|
-
|
|
303
|
+
if sys.platform == "win32":
|
|
304
|
+
args = cmd
|
|
305
|
+
else:
|
|
306
|
+
args = shlex.split(cmd)
|
|
300
307
|
self.popen = subprocess.Popen(args, shell=False, stdout=sys.stdout, stderr=sys.stderr, stdin=None)
|
|
301
308
|
self.started.set()
|
|
302
309
|
|
|
303
310
|
|
|
304
311
|
@pytest.fixture(scope="session")
|
|
305
312
|
def voila_server(pytestconfig: Any, notebook_path):
|
|
313
|
+
if "voila" not in runners:
|
|
314
|
+
yield None
|
|
315
|
+
return
|
|
306
316
|
port = pytestconfig.getoption("--voila-port")
|
|
307
317
|
host = pytestconfig.getoption("--solara-host")
|
|
308
318
|
write_notebook(["print('hello')"], notebook_path)
|
|
@@ -317,6 +327,9 @@ def voila_server(pytestconfig: Any, notebook_path):
|
|
|
317
327
|
|
|
318
328
|
@pytest.fixture(scope="session")
|
|
319
329
|
def jupyter_server(pytestconfig: Any, notebook_path):
|
|
330
|
+
if "jupyter_lab" not in runners and "jupyter_notebook" not in runners:
|
|
331
|
+
yield None
|
|
332
|
+
return
|
|
320
333
|
port = pytestconfig.getoption("--jupyter-port")
|
|
321
334
|
host = pytestconfig.getoption("--solara-host")
|
|
322
335
|
write_notebook(["print('hello')"], notebook_path)
|
|
@@ -520,9 +533,6 @@ def create_runner_solara(solara_server, solara_app, page_session: "playwright.sy
|
|
|
520
533
|
yield run
|
|
521
534
|
|
|
522
535
|
|
|
523
|
-
runners = os.environ.get("SOLARA_TEST_RUNNERS", "solara,voila,jupyter_lab,jupyter_notebook").split(",")
|
|
524
|
-
|
|
525
|
-
|
|
526
536
|
@pytest.fixture(params=runners)
|
|
527
537
|
def ipywidgets_runner(
|
|
528
538
|
solara_server,
|
|
@@ -144,7 +144,6 @@ class ValueBase(Generic[T]):
|
|
|
144
144
|
for listener2, scope in self.listeners2[scope_id].copy():
|
|
145
145
|
if scope is not None:
|
|
146
146
|
scopes.add(scope)
|
|
147
|
-
stack = contextlib.ExitStack()
|
|
148
147
|
with contextlib.ExitStack() as stack:
|
|
149
148
|
for scope in scopes:
|
|
150
149
|
stack.enter_context(scope)
|
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Solara Changelog
|
|
2
2
|
|
|
3
|
+
## Version 1.38.0
|
|
4
|
+
|
|
5
|
+
* Feature: We detect and warn when there are possible reverse proxy or uvicorn misconfigurations. [#745](https://github.com/widgetti/solara/pull/745)
|
|
6
|
+
* Bug Fix: Auth redirect did not respect SOLARA_BASE_URL. [#747](https://github.com/widgetti/solara/pull/747)
|
|
7
|
+
* Bug Fix: Support for `websockets >= 13.0` and large cookies. [#751](https://github.com/widgetti/solara/pull/751)
|
|
8
|
+
* Bug Fix: Windows support was broken from version 1.35.0 to 1.37.2. This went undetected due to a CI configuration error. [#712](https://github.com/widgetti/solara/pull/712) [#739](https://github.com/widgetti/solara/pull/739)
|
|
9
|
+
|
|
10
|
+
## Version 1.37.2
|
|
11
|
+
|
|
12
|
+
* Bug Fix: If matplotlib was imported before solara, we did not set the backend, now we do. [#741](https://github.com/widgetti/solara/pull/741)
|
|
13
|
+
|
|
3
14
|
## Version 1.37.1
|
|
4
15
|
|
|
5
16
|
* Bug Fix: The newly introduced hooks validator could emit a warning on certain call syntax. This can fail CI pipelines that do now allow warnings [c7c3b6a](https://github.com/widgetti/solara/commit/c7c3b6ab2929c4da1ffc3ab8e2e423cf0cfa7567).
|
|
@@ -20,7 +20,7 @@ def DownloadFile(file_path=file_path, url=url, expected_size=expected_size, on_d
|
|
|
20
20
|
status = "Done 🎉"
|
|
21
21
|
else:
|
|
22
22
|
MEGABYTES = 2.0**20.0
|
|
23
|
-
status = "Downloading {}... ({:6.2f}/{:6.2f} MB)"
|
|
23
|
+
status = f"Downloading {file_path}... ({downloaded_size / MEGABYTES:6.2f}/{expected_size / MEGABYTES:6.2f} MB)"
|
|
24
24
|
# status = "hi"
|
|
25
25
|
# return MarkdownIt(f'{status}')
|
|
26
26
|
assert download.progress is not None
|
|
@@ -170,13 +170,13 @@ Please note that Python 3.6 is not supported for Solara OAuth.
|
|
|
170
170
|
|
|
171
171
|
### Wrong redirection
|
|
172
172
|
|
|
173
|
-
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`. 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`.
|
|
173
|
+
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`.
|
|
174
174
|
|
|
175
175
|
|
|
176
176
|
### Wrong schema detected for redirect URL
|
|
177
177
|
|
|
178
|
-
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`)
|
|
178
|
+
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).
|
|
179
179
|
|
|
180
|
-
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 so Solara can construct the correct redirect URL to send to the OAuth provider.
|
|
180
|
+
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.
|
|
181
181
|
|
|
182
182
|
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.
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"\n",
|
|
70
70
|
"\n",
|
|
71
71
|
"df = px.data.iris()\n",
|
|
72
|
-
"df
|
|
72
|
+
"df"
|
|
73
73
|
]
|
|
74
74
|
},
|
|
75
75
|
{
|
|
@@ -163,6 +163,7 @@
|
|
|
163
163
|
"columns = list(df.columns)\n",
|
|
164
164
|
"x_axis = solara.reactive(\"sepal_length\")\n",
|
|
165
165
|
"\n",
|
|
166
|
+
"\n",
|
|
166
167
|
"@solara.component\n",
|
|
167
168
|
"def Page():\n",
|
|
168
169
|
" # Create a scatter plot by passing \"x_axis.value\" to px.scatter\n",
|
|
@@ -170,10 +171,10 @@
|
|
|
170
171
|
" # and re-execute this function when x_axis value changes\n",
|
|
171
172
|
" fig = px.scatter(df, x_axis.value, \"sepal_width\")\n",
|
|
172
173
|
" solara.FigurePlotly(fig)\n",
|
|
173
|
-
"
|
|
174
|
+
"\n",
|
|
174
175
|
" # Pass x_axis to Select component\n",
|
|
175
176
|
" # The select will control the x_axis reactive variable\n",
|
|
176
|
-
" solara.Select(label=\"X-axis\", value=x_axis, values=columns)
|
|
177
|
+
" solara.Select(label=\"X-axis\", value=x_axis, values=columns)"
|
|
177
178
|
]
|
|
178
179
|
},
|
|
179
180
|
{
|
|
@@ -219,12 +220,13 @@
|
|
|
219
220
|
"source": [
|
|
220
221
|
"y_axis = solara.reactive(\"sepal_width\")\n",
|
|
221
222
|
"\n",
|
|
223
|
+
"\n",
|
|
222
224
|
"@solara.component\n",
|
|
223
225
|
"def Page():\n",
|
|
224
226
|
" fig = px.scatter(df, x_axis.value, y_axis.value)\n",
|
|
225
227
|
" solara.FigurePlotly(fig)\n",
|
|
226
228
|
" solara.Select(label=\"X-axis\", value=x_axis, values=columns)\n",
|
|
227
|
-
" solara.Select(label=\"Y-axis\", value=y_axis, values=columns)
|
|
229
|
+
" solara.Select(label=\"Y-axis\", value=y_axis, values=columns)"
|
|
228
230
|
]
|
|
229
231
|
},
|
|
230
232
|
{
|
|
@@ -267,8 +269,7 @@
|
|
|
267
269
|
" solara.Select(label=\"X-axis\", value=x_axis, values=columns)\n",
|
|
268
270
|
" solara.Select(label=\"Y-axis\", value=y_axis, values=columns)\n",
|
|
269
271
|
" # display it pre-formatted using the backticks `` using Markdown\n",
|
|
270
|
-
" solara.Markdown(f\"`{click_data}`\")
|
|
271
|
-
" "
|
|
272
|
+
" solara.Markdown(f\"`{click_data}`\")"
|
|
272
273
|
]
|
|
273
274
|
},
|
|
274
275
|
{
|
|
@@ -319,7 +320,7 @@
|
|
|
319
320
|
" row_index = click_data.value[\"points\"][\"point_indexes\"][0]\n",
|
|
320
321
|
" x = click_data.value[\"points\"][\"xs\"][0]\n",
|
|
321
322
|
" y = click_data.value[\"points\"][\"ys\"][0]\n",
|
|
322
|
-
" solara.Markdown(f\"`Click on index={row_index} x={x} y={y}`\")
|
|
323
|
+
" solara.Markdown(f\"`Click on index={row_index} x={x} y={y}`\")"
|
|
323
324
|
]
|
|
324
325
|
},
|
|
325
326
|
{
|
|
@@ -373,8 +374,8 @@
|
|
|
373
374
|
"\n",
|
|
374
375
|
"def find_nearest_neighbours(df, xcol, ycol, x, y, n=10):\n",
|
|
375
376
|
" df = df.copy()\n",
|
|
376
|
-
" df[\"distance\"] = ((df[xcol] - x)**2 + (df[ycol] - y)**2)**0.5\n",
|
|
377
|
-
" return df.sort_values(
|
|
377
|
+
" df[\"distance\"] = ((df[xcol] - x) ** 2 + (df[ycol] - y) ** 2) ** 0.5\n",
|
|
378
|
+
" return df.sort_values(\"distance\")[1 : n + 1]\n",
|
|
378
379
|
"\n",
|
|
379
380
|
"\n",
|
|
380
381
|
"@solara.component\n",
|
|
@@ -385,13 +386,12 @@
|
|
|
385
386
|
" x = click_data.value[\"points\"][\"xs\"][0]\n",
|
|
386
387
|
" y = click_data.value[\"points\"][\"ys\"][0]\n",
|
|
387
388
|
"\n",
|
|
388
|
-
" # add an indicator
|
|
389
|
+
" # add an indicator\n",
|
|
389
390
|
" fig.add_trace(px.scatter(x=[x], y=[y], text=[\"⭐️\"]).data[0])\n",
|
|
390
391
|
" df_nearest = find_nearest_neighbours(df, x_axis.value, y_axis.value, x, y, n=3)\n",
|
|
391
392
|
" else:\n",
|
|
392
393
|
" df_nearest = None\n",
|
|
393
394
|
"\n",
|
|
394
|
-
"\n",
|
|
395
395
|
" solara.FigurePlotly(fig, on_click=click_data.set)\n",
|
|
396
396
|
" solara.Select(label=\"X-axis\", value=x_axis, values=columns)\n",
|
|
397
397
|
" solara.Select(label=\"Y-axis\", value=y_axis, values=columns)\n",
|