solara 1.30.0__py2.py3-none-any.whl → 1.31.0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {solara-1.30.0.dist-info → solara-1.31.0.dist-info}/METADATA +7 -42
- solara-1.31.0.dist-info/RECORD +5 -0
- {solara-1.30.0.dist-info → solara-1.31.0.dist-info}/WHEEL +1 -1
- {solara/template/portal → solara-1.31.0.dist-info/licenses}/LICENSE +1 -1
- solara/__init__.py +0 -123
- solara/__main__.py +0 -734
- solara/alias.py +0 -6
- solara/autorouting.py +0 -554
- solara/cache.py +0 -294
- solara/checks.html +0 -71
- solara/checks.py +0 -224
- solara/comm.py +0 -28
- solara/components/__init__.py +0 -59
- solara/components/alert.py +0 -155
- solara/components/applayout.py +0 -393
- solara/components/button.py +0 -85
- solara/components/card.py +0 -87
- solara/components/checkbox.py +0 -50
- solara/components/code_highlight_css.py +0 -11
- solara/components/code_highlight_css.vue +0 -63
- solara/components/columns.py +0 -159
- solara/components/component_vue.py +0 -109
- solara/components/cross_filter.py +0 -335
- solara/components/dataframe.py +0 -546
- solara/components/datatable.py +0 -221
- solara/components/datatable.vue +0 -175
- solara/components/details.py +0 -21
- solara/components/download.vue +0 -35
- solara/components/echarts.py +0 -75
- solara/components/echarts.vue +0 -128
- solara/components/figure_altair.py +0 -39
- solara/components/file_browser.py +0 -182
- solara/components/file_download.py +0 -199
- solara/components/file_drop.py +0 -139
- solara/components/file_drop.vue +0 -83
- solara/components/file_list_widget.vue +0 -78
- solara/components/head.py +0 -27
- solara/components/head_tag.py +0 -49
- solara/components/head_tag.vue +0 -60
- solara/components/image.py +0 -173
- solara/components/input.py +0 -440
- solara/components/link.py +0 -55
- solara/components/markdown.py +0 -371
- solara/components/markdown_editor.py +0 -25
- solara/components/markdown_editor.vue +0 -362
- solara/components/matplotlib.py +0 -74
- solara/components/meta.py +0 -47
- solara/components/misc.py +0 -333
- solara/components/pivot_table.py +0 -258
- solara/components/pivot_table.vue +0 -158
- solara/components/progress.py +0 -47
- solara/components/select.py +0 -186
- solara/components/select.vue +0 -27
- solara/components/slider.py +0 -442
- solara/components/slider_date.vue +0 -56
- solara/components/spinner-solara.vue +0 -105
- solara/components/spinner.py +0 -30
- solara/components/sql_code.py +0 -33
- solara/components/sql_code.vue +0 -128
- solara/components/style.py +0 -105
- solara/components/switch.py +0 -68
- solara/components/tab_navigation.py +0 -37
- solara/components/title.py +0 -90
- solara/components/title.vue +0 -38
- solara/components/togglebuttons.py +0 -202
- solara/components/tooltip.py +0 -61
- solara/datatypes.py +0 -143
- solara/express.py +0 -241
- solara/hooks/__init__.py +0 -4
- solara/hooks/dataframe.py +0 -99
- solara/hooks/misc.py +0 -263
- solara/hooks/use_reactive.py +0 -129
- solara/hooks/use_thread.py +0 -129
- solara/kitchensink.py +0 -8
- solara/lab/__init__.py +0 -34
- solara/lab/components/__init__.py +0 -6
- solara/lab/components/chat.py +0 -203
- solara/lab/components/confirmation_dialog.py +0 -165
- solara/lab/components/cross_filter.py +0 -7
- solara/lab/components/input_date.py +0 -298
- solara/lab/components/menu.py +0 -181
- solara/lab/components/menu.vue +0 -38
- solara/lab/components/tabs.py +0 -274
- solara/lab/components/theming.py +0 -98
- solara/lab/components/theming.vue +0 -72
- solara/lab/hooks/__init__.py +0 -0
- solara/lab/hooks/dataframe.py +0 -12
- solara/lab/toestand.py +0 -3
- solara/lab/utils/__init__.py +0 -2
- solara/lab/utils/cookies.py +0 -5
- solara/lab/utils/dataframe.py +0 -115
- solara/lab/utils/headers.py +0 -5
- solara/layout.py +0 -44
- solara/minisettings.py +0 -133
- solara/py.typed +0 -0
- solara/reactive.py +0 -93
- solara/routing.py +0 -268
- solara/scope/__init__.py +0 -87
- solara/scope/types.py +0 -55
- solara/server/__init__.py +0 -0
- solara/server/app.py +0 -490
- solara/server/assets/custom.css +0 -1
- solara/server/assets/custom.js +0 -1
- solara/server/assets/favicon.png +0 -0
- solara/server/assets/favicon.svg +0 -5
- solara/server/assets/style.css +0 -1665
- solara/server/assets/theme-dark.css +0 -437
- solara/server/assets/theme-light.css +0 -420
- solara/server/assets/theme.js +0 -3
- solara/server/cdn_helper.py +0 -77
- solara/server/esm.py +0 -69
- solara/server/fastapi.py +0 -5
- solara/server/flask.py +0 -286
- solara/server/jupyter/__init__.py +0 -2
- solara/server/jupyter/cdn_handler.py +0 -28
- solara/server/jupyter/server_extension.py +0 -29
- solara/server/jupytertools.py +0 -46
- solara/server/kernel.py +0 -319
- solara/server/kernel_context.py +0 -393
- solara/server/patch.py +0 -552
- solara/server/reload.py +0 -242
- solara/server/server.py +0 -437
- solara/server/settings.py +0 -212
- solara/server/shell.py +0 -240
- solara/server/starlette.py +0 -597
- solara/server/static/ansi.js +0 -270
- solara/server/static/highlight-dark.css +0 -82
- solara/server/static/highlight.css +0 -43
- solara/server/static/main-vuetify.js +0 -260
- solara/server/static/main.js +0 -163
- solara/server/static/solara_bootstrap.py +0 -129
- solara/server/static/sun.svg +0 -23
- solara/server/static/webworker.js +0 -42
- solara/server/telemetry.py +0 -212
- solara/server/templates/index.html.j2 +0 -1
- solara/server/templates/loader-plain.css +0 -11
- solara/server/templates/loader-plain.html +0 -20
- solara/server/templates/loader-solara.css +0 -111
- solara/server/templates/loader-solara.html +0 -40
- solara/server/templates/plain.html +0 -82
- solara/server/templates/solara.html.j2 +0 -446
- solara/server/threaded.py +0 -75
- solara/server/utils.py +0 -30
- solara/server/websocket.py +0 -44
- solara/settings.py +0 -56
- solara/tasks.py +0 -847
- solara/template/button.py +0 -16
- solara/template/markdown.py +0 -42
- solara/template/portal/.flake8 +0 -6
- solara/template/portal/.pre-commit-config.yaml +0 -28
- solara/template/portal/Procfile +0 -7
- solara/template/portal/mypy.ini +0 -3
- solara/template/portal/pyproject.toml +0 -26
- solara/template/portal/solara_portal/__init__.py +0 -3
- solara/template/portal/solara_portal/components/__init__.py +0 -2
- solara/template/portal/solara_portal/components/article.py +0 -28
- solara/template/portal/solara_portal/components/data.py +0 -28
- solara/template/portal/solara_portal/components/header.py +0 -6
- solara/template/portal/solara_portal/components/layout.py +0 -6
- solara/template/portal/solara_portal/content/articles/equis-in-vidi.md +0 -85
- solara/template/portal/solara_portal/content/articles/substiterat-vati.md +0 -70
- solara/template/portal/solara_portal/data.py +0 -60
- solara/template/portal/solara_portal/pages/__init__.py +0 -67
- solara/template/portal/solara_portal/pages/article/__init__.py +0 -26
- solara/template/portal/solara_portal/pages/tabular.py +0 -29
- solara/template/portal/solara_portal/pages/viz/__init__.py +0 -69
- solara/template/portal/solara_portal/pages/viz/overview.py +0 -14
- solara/test/__init__.py +0 -0
- solara/test/pytest_plugin.py +0 -698
- solara/toestand.py +0 -772
- solara/util.py +0 -308
- solara/website/__init__.py +0 -0
- solara/website/assets/custom.css +0 -462
- solara/website/assets/images/logo-small.png +0 -0
- solara/website/assets/images/logo.svg +0 -17
- solara/website/assets/images/logo_white.svg +0 -50
- solara/website/assets/theme.js +0 -8
- solara/website/components/__init__.py +0 -5
- solara/website/components/algolia.vue +0 -24
- solara/website/components/algolia_api.vue +0 -157
- solara/website/components/docs.py +0 -118
- solara/website/components/header.py +0 -72
- solara/website/components/hero.py +0 -15
- solara/website/components/mailchimp.py +0 -12
- solara/website/components/mailchimp.vue +0 -47
- solara/website/components/notebook.py +0 -172
- solara/website/pages/__init__.py +0 -564
- solara/website/pages/apps/__init__.py +0 -16
- solara/website/pages/apps/authorization/__init__.py +0 -118
- solara/website/pages/apps/authorization/admin.py +0 -12
- solara/website/pages/apps/authorization/users.py +0 -12
- solara/website/pages/apps/jupyter-dashboard-1.py +0 -116
- solara/website/pages/apps/layout-demo.py +0 -40
- solara/website/pages/apps/multipage/__init__.py +0 -38
- solara/website/pages/apps/multipage/page1.py +0 -26
- solara/website/pages/apps/multipage/page2.py +0 -34
- solara/website/pages/apps/scatter.py +0 -136
- solara/website/pages/apps/scrolling.py +0 -63
- solara/website/pages/apps/tutorial-streamlit.py +0 -18
- solara/website/pages/changelog/__init__.py +0 -8
- solara/website/pages/changelog/changelog.md +0 -180
- solara/website/pages/contact/__init__.py +0 -8
- solara/website/pages/contact/contact.md +0 -17
- solara/website/pages/doc_use_download.py +0 -85
- solara/website/pages/documentation/__init__.py +0 -184
- solara/website/pages/documentation/advanced/__init__.py +0 -36
- solara/website/pages/documentation/advanced/content/00-overview.md +0 -1
- solara/website/pages/documentation/advanced/content/10-howto/00-overview.md +0 -1
- solara/website/pages/documentation/advanced/content/10-howto/10-multipage.md +0 -191
- solara/website/pages/documentation/advanced/content/10-howto/20-layout.md +0 -120
- solara/website/pages/documentation/advanced/content/10-howto/30-testing.md +0 -149
- solara/website/pages/documentation/advanced/content/10-howto/31-debugging.md +0 -66
- solara/website/pages/documentation/advanced/content/10-howto/40-embed.md +0 -43
- solara/website/pages/documentation/advanced/content/10-howto/50-ipywidget_libraries.md +0 -120
- solara/website/pages/documentation/advanced/content/20-understanding/00-introduction.md +0 -4
- solara/website/pages/documentation/advanced/content/20-understanding/05-ipywidgets.md +0 -30
- solara/website/pages/documentation/advanced/content/20-understanding/06-ipyvuetify.md +0 -38
- solara/website/pages/documentation/advanced/content/20-understanding/10-reacton.md +0 -24
- solara/website/pages/documentation/advanced/content/20-understanding/12-reacton-basics.md +0 -104
- solara/website/pages/documentation/advanced/content/20-understanding/15-anatomy.md +0 -19
- solara/website/pages/documentation/advanced/content/20-understanding/17-rules-of-hooks.md +0 -3
- solara/website/pages/documentation/advanced/content/20-understanding/18-containers.md +0 -160
- solara/website/pages/documentation/advanced/content/20-understanding/20-solara.md +0 -13
- solara/website/pages/documentation/advanced/content/20-understanding/40-routing.md +0 -236
- solara/website/pages/documentation/advanced/content/20-understanding/50-solara-server.md +0 -81
- solara/website/pages/documentation/advanced/content/20-understanding/60-voila.md +0 -7
- solara/website/pages/documentation/advanced/content/30-enterprise/00-overview.md +0 -1
- solara/website/pages/documentation/advanced/content/30-enterprise/10-oauth.md +0 -167
- solara/website/pages/documentation/advanced/content/40-development/00-overview.md +0 -0
- solara/website/pages/documentation/advanced/content/40-development/01-contribute.md +0 -41
- solara/website/pages/documentation/advanced/content/40-development/10-setup.md +0 -72
- solara/website/pages/documentation/advanced/content/__init__.py +0 -0
- solara/website/pages/documentation/api/__init__.py +0 -19
- solara/website/pages/documentation/api/cross_filter/__init__.py +0 -9
- solara/website/pages/documentation/api/cross_filter/cross_filter_dataframe.py +0 -23
- solara/website/pages/documentation/api/cross_filter/cross_filter_report.py +0 -22
- solara/website/pages/documentation/api/cross_filter/cross_filter_select.py +0 -22
- solara/website/pages/documentation/api/cross_filter/cross_filter_slider.py +0 -22
- solara/website/pages/documentation/api/hooks/__init__.py +0 -9
- solara/website/pages/documentation/api/hooks/use_cross_filter.py +0 -25
- solara/website/pages/documentation/api/hooks/use_dark_effective.py +0 -13
- solara/website/pages/documentation/api/hooks/use_effect.md +0 -43
- solara/website/pages/documentation/api/hooks/use_effect.py +0 -9
- solara/website/pages/documentation/api/hooks/use_exception.py +0 -33
- solara/website/pages/documentation/api/hooks/use_memo.md +0 -16
- solara/website/pages/documentation/api/hooks/use_memo.py +0 -9
- solara/website/pages/documentation/api/hooks/use_previous.py +0 -32
- solara/website/pages/documentation/api/hooks/use_reactive.py +0 -15
- solara/website/pages/documentation/api/hooks/use_state.py +0 -11
- solara/website/pages/documentation/api/hooks/use_state_or_update.py +0 -68
- solara/website/pages/documentation/api/hooks/use_thread.md +0 -58
- solara/website/pages/documentation/api/hooks/use_thread.py +0 -44
- solara/website/pages/documentation/api/hooks/use_trait_observe.py +0 -13
- solara/website/pages/documentation/api/routing/__init__.py +0 -9
- solara/website/pages/documentation/api/routing/generate_routes.py +0 -11
- solara/website/pages/documentation/api/routing/generate_routes_directory.py +0 -11
- solara/website/pages/documentation/api/routing/resolve_path.py +0 -36
- solara/website/pages/documentation/api/routing/route.py +0 -32
- solara/website/pages/documentation/api/routing/use_route.py +0 -80
- solara/website/pages/documentation/api/routing/use_router.py +0 -15
- solara/website/pages/documentation/api/utilities/__init__.py +0 -9
- solara/website/pages/documentation/api/utilities/component_vue.py +0 -11
- solara/website/pages/documentation/api/utilities/computed.py +0 -16
- solara/website/pages/documentation/api/utilities/display.py +0 -15
- solara/website/pages/documentation/api/utilities/get_kernel_id.py +0 -16
- solara/website/pages/documentation/api/utilities/get_session_id.py +0 -16
- solara/website/pages/documentation/api/utilities/memoize.py +0 -36
- solara/website/pages/documentation/api/utilities/on_kernel_start.py +0 -27
- solara/website/pages/documentation/api/utilities/reactive.py +0 -15
- solara/website/pages/documentation/api/utilities/widget.py +0 -104
- solara/website/pages/documentation/components/__init__.py +0 -12
- solara/website/pages/documentation/components/advanced/__init__.py +0 -9
- solara/website/pages/documentation/components/advanced/link.py +0 -28
- solara/website/pages/documentation/components/advanced/meta.py +0 -21
- solara/website/pages/documentation/components/advanced/style.py +0 -44
- solara/website/pages/documentation/components/common.py +0 -9
- solara/website/pages/documentation/components/data/__init__.py +0 -9
- solara/website/pages/documentation/components/data/dataframe.py +0 -44
- solara/website/pages/documentation/components/data/pivot_table.py +0 -81
- solara/website/pages/documentation/components/enterprise/__init__.py +0 -9
- solara/website/pages/documentation/components/enterprise/avatar.py +0 -19
- solara/website/pages/documentation/components/enterprise/avatar_menu.py +0 -20
- solara/website/pages/documentation/components/input/__init__.py +0 -9
- solara/website/pages/documentation/components/input/button.py +0 -22
- solara/website/pages/documentation/components/input/checkbox.py +0 -12
- solara/website/pages/documentation/components/input/file_browser.py +0 -33
- solara/website/pages/documentation/components/input/file_drop.py +0 -75
- solara/website/pages/documentation/components/input/input.py +0 -18
- solara/website/pages/documentation/components/input/select.py +0 -21
- solara/website/pages/documentation/components/input/slider.py +0 -28
- solara/website/pages/documentation/components/input/switch.py +0 -12
- solara/website/pages/documentation/components/input/togglebuttons.py +0 -20
- solara/website/pages/documentation/components/lab/__init__.py +0 -9
- solara/website/pages/documentation/components/lab/chat.py +0 -108
- solara/website/pages/documentation/components/lab/confirmation_dialog.py +0 -55
- solara/website/pages/documentation/components/lab/cookies_headers.py +0 -48
- solara/website/pages/documentation/components/lab/input_date.py +0 -19
- solara/website/pages/documentation/components/lab/menu.py +0 -21
- solara/website/pages/documentation/components/lab/tab.py +0 -24
- solara/website/pages/documentation/components/lab/tabs.py +0 -44
- solara/website/pages/documentation/components/lab/task.py +0 -12
- solara/website/pages/documentation/components/lab/theming.py +0 -72
- solara/website/pages/documentation/components/lab/use_task.py +0 -12
- solara/website/pages/documentation/components/layout/__init__.py +0 -9
- solara/website/pages/documentation/components/layout/app_bar.py +0 -15
- solara/website/pages/documentation/components/layout/app_bar_title.py +0 -15
- solara/website/pages/documentation/components/layout/app_layout.py +0 -23
- solara/website/pages/documentation/components/layout/card.py +0 -14
- solara/website/pages/documentation/components/layout/card_actions.py +0 -15
- solara/website/pages/documentation/components/layout/column.py +0 -29
- solara/website/pages/documentation/components/layout/columns.py +0 -26
- solara/website/pages/documentation/components/layout/columns_responsive.py +0 -67
- solara/website/pages/documentation/components/layout/griddraggable.py +0 -61
- solara/website/pages/documentation/components/layout/gridfixed.py +0 -21
- solara/website/pages/documentation/components/layout/hbox.py +0 -17
- solara/website/pages/documentation/components/layout/row.py +0 -29
- solara/website/pages/documentation/components/layout/sidebar.py +0 -23
- solara/website/pages/documentation/components/layout/vbox.py +0 -19
- solara/website/pages/documentation/components/output/__init__.py +0 -9
- solara/website/pages/documentation/components/output/file_download.py +0 -12
- solara/website/pages/documentation/components/output/html.py +0 -22
- solara/website/pages/documentation/components/output/image.py +0 -12
- solara/website/pages/documentation/components/output/markdown.py +0 -59
- solara/website/pages/documentation/components/output/markdown_editor.py +0 -53
- solara/website/pages/documentation/components/output/sql_code.py +0 -84
- solara/website/pages/documentation/components/output/tooltip.py +0 -12
- solara/website/pages/documentation/components/page/__init__.py +0 -9
- solara/website/pages/documentation/components/page/head.py +0 -19
- solara/website/pages/documentation/components/page/title.py +0 -28
- solara/website/pages/documentation/components/status/__init__.py +0 -9
- solara/website/pages/documentation/components/status/error.py +0 -40
- solara/website/pages/documentation/components/status/info.py +0 -40
- solara/website/pages/documentation/components/status/progress.py +0 -10
- solara/website/pages/documentation/components/status/spinner.py +0 -10
- solara/website/pages/documentation/components/status/success.py +0 -40
- solara/website/pages/documentation/components/status/warning.py +0 -47
- solara/website/pages/documentation/components/viz/__init__.py +0 -9
- solara/website/pages/documentation/components/viz/altair.py +0 -44
- solara/website/pages/documentation/components/viz/echarts.py +0 -78
- solara/website/pages/documentation/components/viz/matplotlib.py +0 -32
- solara/website/pages/documentation/components/viz/plotly.py +0 -63
- solara/website/pages/documentation/components/viz/plotly_express.py +0 -41
- solara/website/pages/documentation/examples/__init__.py +0 -52
- solara/website/pages/documentation/examples/ai/__init__.py +0 -10
- solara/website/pages/documentation/examples/ai/chatbot.py +0 -96
- solara/website/pages/documentation/examples/ai/tokenizer.py +0 -106
- solara/website/pages/documentation/examples/basics/__init__.py +0 -2
- solara/website/pages/documentation/examples/basics/sine.py +0 -28
- solara/website/pages/documentation/examples/fullscreen/__init__.py +0 -9
- solara/website/pages/documentation/examples/fullscreen/authorization.py +0 -3
- solara/website/pages/documentation/examples/fullscreen/layout_demo.py +0 -3
- solara/website/pages/documentation/examples/fullscreen/multipage.py +0 -3
- solara/website/pages/documentation/examples/fullscreen/scatter.py +0 -3
- solara/website/pages/documentation/examples/fullscreen/scrolling.py +0 -3
- solara/website/pages/documentation/examples/fullscreen/tutorial_streamlit.py +0 -3
- solara/website/pages/documentation/examples/general/__init__.py +0 -9
- solara/website/pages/documentation/examples/general/custom_storage.py +0 -69
- solara/website/pages/documentation/examples/general/deploy_model.py +0 -114
- solara/website/pages/documentation/examples/general/live_update.py +0 -38
- solara/website/pages/documentation/examples/general/login_oauth.py +0 -76
- solara/website/pages/documentation/examples/general/mycard.vue +0 -58
- solara/website/pages/documentation/examples/general/pokemon_search.py +0 -51
- solara/website/pages/documentation/examples/general/vue_component.py +0 -50
- solara/website/pages/documentation/examples/ipycanvas.py +0 -49
- solara/website/pages/documentation/examples/libraries/__init__.py +0 -9
- solara/website/pages/documentation/examples/libraries/altair.py +0 -63
- solara/website/pages/documentation/examples/libraries/bqplot.py +0 -39
- solara/website/pages/documentation/examples/libraries/ipyleaflet.py +0 -32
- solara/website/pages/documentation/examples/libraries/ipyleaflet_advanced.py +0 -65
- solara/website/pages/documentation/examples/utilities/__init__.py +0 -9
- solara/website/pages/documentation/examples/utilities/calculator.py +0 -157
- solara/website/pages/documentation/examples/utilities/countdown_timer.py +0 -64
- solara/website/pages/documentation/examples/utilities/todo.py +0 -195
- solara/website/pages/documentation/examples/visualization/__init__.py +0 -6
- solara/website/pages/documentation/examples/visualization/annotator.py +0 -68
- solara/website/pages/documentation/examples/visualization/linked_views.py +0 -84
- solara/website/pages/documentation/examples/visualization/plotly.py +0 -43
- solara/website/pages/documentation/faq/__init__.py +0 -11
- solara/website/pages/documentation/faq/content/99-faq.md +0 -73
- solara/website/pages/documentation/getting_started/__init__.py +0 -15
- solara/website/pages/documentation/getting_started/content/00-quickstart.md +0 -84
- solara/website/pages/documentation/getting_started/content/01-introduction.md +0 -121
- solara/website/pages/documentation/getting_started/content/02-installing.md +0 -81
- solara/website/pages/documentation/getting_started/content/04-tutorials/00-overview.md +0 -9
- solara/website/pages/documentation/getting_started/content/04-tutorials/10_data_science.py +0 -13
- solara/website/pages/documentation/getting_started/content/04-tutorials/20-web-app.md +0 -84
- solara/website/pages/documentation/getting_started/content/04-tutorials/30-ipywidgets.md +0 -120
- solara/website/pages/documentation/getting_started/content/04-tutorials/40-streamlit.md +0 -141
- solara/website/pages/documentation/getting_started/content/04-tutorials/50-dash.md +0 -140
- solara/website/pages/documentation/getting_started/content/04-tutorials/60-jupyter-dashboard-part1.py +0 -64
- solara/website/pages/documentation/getting_started/content/04-tutorials/SF_crime_sample.csv.gz +0 -0
- solara/website/pages/documentation/getting_started/content/04-tutorials/_data_science.ipynb +0 -445
- solara/website/pages/documentation/getting_started/content/04-tutorials/_jupyter_dashboard_1.ipynb +0 -1000
- solara/website/pages/documentation/getting_started/content/05-fundamentals/00-overview.md +0 -7
- solara/website/pages/documentation/getting_started/content/05-fundamentals/10-components.md +0 -218
- solara/website/pages/documentation/getting_started/content/05-fundamentals/50-state-management.md +0 -83
- solara/website/pages/documentation/getting_started/content/06-reference/00-overview.md +0 -3
- solara/website/pages/documentation/getting_started/content/06-reference/40-static_files.md +0 -27
- solara/website/pages/documentation/getting_started/content/06-reference/41-asset-files.md +0 -32
- solara/website/pages/documentation/getting_started/content/06-reference/60-static-site-generation.md +0 -55
- solara/website/pages/documentation/getting_started/content/06-reference/70-search.md +0 -30
- solara/website/pages/documentation/getting_started/content/06-reference/80-reloading.md +0 -30
- solara/website/pages/documentation/getting_started/content/06-reference/90-notebook-support.md +0 -4
- solara/website/pages/documentation/getting_started/content/06-reference/95-caching.md +0 -143
- solara/website/pages/documentation/getting_started/content/07-deploying/00-overview.md +0 -3
- solara/website/pages/documentation/getting_started/content/07-deploying/10-self-hosted.md +0 -269
- solara/website/pages/documentation/getting_started/content/07-deploying/20-cloud-hosted.md +0 -76
- solara/website/pages/documentation/getting_started/content/08-lab/00-what-is-lab.md +0 -3
- solara/website/pages/documentation/getting_started/content/90-troubleshoot.md +0 -22
- solara/website/pages/documentation/getting_started/content/__init__.py +0 -0
- solara/website/pages/docutils.py +0 -38
- solara/website/pages/showcase/__init__.py +0 -105
- solara/website/pages/showcase/domino_code_assist.py +0 -60
- solara/website/pages/showcase/planeto_tessa.py +0 -19
- solara/website/pages/showcase/solara_dev.py +0 -54
- solara/website/pages/showcase/solarathon_2023_team_2.py +0 -22
- solara/website/pages/showcase/solarathon_2023_team_4.py +0 -22
- solara/website/pages/showcase/solarathon_2023_team_5.py +0 -23
- solara/website/pages/showcase/solarathon_2023_team_6.py +0 -34
- solara/website/pages/showcase/wanderlust.py +0 -27
- solara/website/public/beach.jpeg +0 -0
- solara/website/public/logo.svg +0 -6
- solara/website/public/social/discord.svg +0 -1
- solara/website/public/social/github.svg +0 -1
- solara/website/public/social/twitter.svg +0 -3
- solara/website/public/success.html +0 -25
- solara/website/templates/index.html.j2 +0 -117
- solara/website/utils.py +0 -51
- solara/widgets/__init__.py +0 -1
- solara/widgets/vue/gridlayout.vue +0 -110
- solara/widgets/vue/html.vue +0 -4
- solara/widgets/vue/navigator.vue +0 -104
- solara/widgets/vue/vegalite.vue +0 -115
- solara/widgets/widgets.py +0 -65
- solara-1.30.0.data/data/etc/jupyter/jupyter_notebook_config.d/solara.json +0 -7
- solara-1.30.0.data/data/etc/jupyter/jupyter_server_config.d/solara.json +0 -7
- solara-1.30.0.dist-info/RECORD +0 -438
- solara-1.30.0.dist-info/entry_points.txt +0 -5
- /solara-1.30.0.dist-info/licenses/LICENSE → /LICENSE +0 -0
solara/lab/utils/dataframe.py
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
def get_pandas_major():
|
|
2
|
-
import pandas as pd
|
|
3
|
-
|
|
4
|
-
return int(pd.__version__[0])
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
def df_type(df):
|
|
8
|
-
return df.__class__.__module__.split(".")[0]
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
def df_unique(df, column, limit=None):
|
|
12
|
-
if df_type(df) == "vaex":
|
|
13
|
-
return df.unique(column, limit=limit + 1 if limit else None, limit_raise=False)
|
|
14
|
-
if df_type(df) == "pandas":
|
|
15
|
-
x = df[column].unique() # .to_numpy()
|
|
16
|
-
return x[:limit]
|
|
17
|
-
else:
|
|
18
|
-
raise TypeError(f"{type(df)} not supported")
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def df_value_count(df, column, limit=None):
|
|
22
|
-
if df_type(df) == "vaex":
|
|
23
|
-
dfv = df.groupby(column, agg="count", sort="count", ascending=False)
|
|
24
|
-
dfv = dfv.to_pandas_df().rename({column: "value"}, axis=1)
|
|
25
|
-
return dfv[:limit]
|
|
26
|
-
if df_type(df) == "pandas":
|
|
27
|
-
dfv = df[column].value_counts(dropna=False).to_frame()
|
|
28
|
-
dfv = dfv.reset_index()
|
|
29
|
-
if get_pandas_major() >= 2:
|
|
30
|
-
dfv = dfv.rename({column: "value"}, axis=1)
|
|
31
|
-
else:
|
|
32
|
-
dfv = dfv.rename({"index": "value", column: "count"}, axis=1)
|
|
33
|
-
return dfv[:limit]
|
|
34
|
-
else:
|
|
35
|
-
raise TypeError(f"{type(df)} not supported")
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def df_range(df, column):
|
|
39
|
-
if df_type(df) == "vaex":
|
|
40
|
-
minmax = df[column].minmax()
|
|
41
|
-
return minmax[0].item(), minmax[1].item()
|
|
42
|
-
if df_type(df) == "pandas":
|
|
43
|
-
return df[column].min().item(), df[column].max().item()
|
|
44
|
-
else:
|
|
45
|
-
raise TypeError(f"{type(df)} not supported")
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def df_filter_missing(df, column):
|
|
49
|
-
if df_type(df) == "vaex":
|
|
50
|
-
return df[column].isna()
|
|
51
|
-
if df_type(df) == "pandas":
|
|
52
|
-
return df[column].isna()
|
|
53
|
-
else:
|
|
54
|
-
raise TypeError(f"{type(df)} not supported")
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
def df_filter_values(df, column, values, invert=False):
|
|
58
|
-
if df_type(df) == "vaex":
|
|
59
|
-
filter = df[column].isin(values)
|
|
60
|
-
if invert:
|
|
61
|
-
filter = ~filter
|
|
62
|
-
return filter
|
|
63
|
-
if df_type(df) == "pandas":
|
|
64
|
-
filter = df[column].isin(values)
|
|
65
|
-
if invert:
|
|
66
|
-
filter = ~filter
|
|
67
|
-
return filter
|
|
68
|
-
else:
|
|
69
|
-
raise TypeError(f"{type(df)} not supported")
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
def df_py_types(df):
|
|
73
|
-
"""Return a dict with column names as keys and python types as values.
|
|
74
|
-
|
|
75
|
-
Support types are
|
|
76
|
-
* int
|
|
77
|
-
* float
|
|
78
|
-
* str
|
|
79
|
-
* bool
|
|
80
|
-
|
|
81
|
-
If a type is not supported, the internal type is returned.
|
|
82
|
-
|
|
83
|
-
"""
|
|
84
|
-
import numpy as np
|
|
85
|
-
|
|
86
|
-
if df_type(df) == "vaex":
|
|
87
|
-
schema = df.schema()
|
|
88
|
-
py_types = [int, float, str, bool]
|
|
89
|
-
|
|
90
|
-
def py_type(dtype):
|
|
91
|
-
for k in py_types:
|
|
92
|
-
if dtype == k:
|
|
93
|
-
return k
|
|
94
|
-
return dtype
|
|
95
|
-
|
|
96
|
-
return {name: py_type(dtype) for name, dtype in schema.items()}
|
|
97
|
-
elif df_type(df) == "pandas":
|
|
98
|
-
schema = df.dtypes
|
|
99
|
-
|
|
100
|
-
def py_type(dtype):
|
|
101
|
-
if isinstance(dtype, np.dtype):
|
|
102
|
-
if dtype.kind in "iu":
|
|
103
|
-
return int
|
|
104
|
-
elif dtype.kind == "f":
|
|
105
|
-
return float
|
|
106
|
-
elif dtype.kind == "b":
|
|
107
|
-
return bool
|
|
108
|
-
else:
|
|
109
|
-
return dtype
|
|
110
|
-
else:
|
|
111
|
-
return dtype
|
|
112
|
-
|
|
113
|
-
return {name: py_type(dtype) for name, dtype in schema.items()}
|
|
114
|
-
else:
|
|
115
|
-
raise TypeError(f"{type(df)} not supported")
|
solara/lab/utils/headers.py
DELETED
solara/layout.py
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import reacton.ipyvuetify as v
|
|
2
|
-
import solara
|
|
3
|
-
from solara.kitchensink import vue
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
@solara.component
|
|
7
|
-
def AppIcon(open=False, on_click=None):
|
|
8
|
-
def click(*ignore):
|
|
9
|
-
on_click()
|
|
10
|
-
|
|
11
|
-
icon = v.AppBarNavIcon()
|
|
12
|
-
v.use_event(icon, "click", click)
|
|
13
|
-
return icon
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
@solara.component
|
|
17
|
-
def LayoutApp(children=[], left=None, right=None, open_left=False, open_right=False, title="Solara"):
|
|
18
|
-
open_left, set_open_left = solara.use_state(open_left)
|
|
19
|
-
open_right, set_open_right = solara.use_state(open_right)
|
|
20
|
-
with v.Html(tag="div") as main:
|
|
21
|
-
if left:
|
|
22
|
-
with v.NavigationDrawer(absolute=True, right=False, width="min-content", v_model=open_left):
|
|
23
|
-
AppIcon(open_left, on_click=lambda: set_open_left(not open_left))
|
|
24
|
-
with v.Html(tag="div", children=[left]):
|
|
25
|
-
pass
|
|
26
|
-
with v.Toolbar(dense=True, class_="elevation-3", dark=False):
|
|
27
|
-
if left:
|
|
28
|
-
AppIcon(open_left, on_click=lambda: set_open_left(not open_left))
|
|
29
|
-
v.ToolbarTitle(children=[title])
|
|
30
|
-
v.Spacer()
|
|
31
|
-
if right:
|
|
32
|
-
with v.Btn(icon=True) as btn:
|
|
33
|
-
vue.use_event(btn, "click", lambda *_ignore: set_open_right(not open_right))
|
|
34
|
-
v.Icon(children=["mdi-settings"])
|
|
35
|
-
with v.Row():
|
|
36
|
-
v.Col(cols=12, children=[*children])
|
|
37
|
-
if right:
|
|
38
|
-
with v.NavigationDrawer(absolute=True, right=True, width="min-content", v_model=open_right):
|
|
39
|
-
with v.Btn(icon=True) as btn:
|
|
40
|
-
vue.use_event(btn, "click", lambda *_ignore: set_open_right(not open_right))
|
|
41
|
-
v.Icon(children=["mdi-settings"])
|
|
42
|
-
with v.Html(tag="div", children=[right]):
|
|
43
|
-
pass
|
|
44
|
-
return main
|
solara/minisettings.py
DELETED
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
from typing import Any, Optional
|
|
4
|
-
|
|
5
|
-
# similar API to pydantic/pydantic-settings but we prefer not to have a dependency on pydantic
|
|
6
|
-
# since we cannot be compatible with pydantic1 and 2
|
|
7
|
-
# NOTE: not a public api
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
def _get_type(annotation):
|
|
11
|
-
check_optional_types = [str, int, float, bool, dict, list]
|
|
12
|
-
for check_type in check_optional_types:
|
|
13
|
-
if annotation == Optional[check_type]:
|
|
14
|
-
return check_type
|
|
15
|
-
if hasattr(annotation, "__origin__"):
|
|
16
|
-
if annotation.__origin__ == dict:
|
|
17
|
-
return dict
|
|
18
|
-
return annotation
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
class _Field:
|
|
22
|
-
def __init__(self, default=None, env=None, title=None, default_factory=None, gt=None, alias=None) -> None:
|
|
23
|
-
self.default = default
|
|
24
|
-
self.env = env
|
|
25
|
-
self.fullenv = None
|
|
26
|
-
self.title = title
|
|
27
|
-
self.annotation = None
|
|
28
|
-
self.default_factory = default_factory
|
|
29
|
-
self.gt = gt
|
|
30
|
-
self.alias = alias
|
|
31
|
-
self.field_info = self
|
|
32
|
-
self.extra = {"env_names": [env] if env else []}
|
|
33
|
-
|
|
34
|
-
def __set_name__(self, owner, name):
|
|
35
|
-
prefix = "SOLARA_"
|
|
36
|
-
config = getattr(owner, "Config")
|
|
37
|
-
if config:
|
|
38
|
-
prefix = getattr(config, "env_prefix", prefix).upper()
|
|
39
|
-
if hasattr(config, "fields"):
|
|
40
|
-
fields = config.fields
|
|
41
|
-
if name in fields:
|
|
42
|
-
self.alias = fields[name]
|
|
43
|
-
self.name = name
|
|
44
|
-
self.alias = self.alias or self.name
|
|
45
|
-
self.title = self.title or self.name
|
|
46
|
-
if self.env is None:
|
|
47
|
-
self.env = f"{prefix}{self.name.upper()}"
|
|
48
|
-
else:
|
|
49
|
-
self.env = self.env
|
|
50
|
-
self.annotation = owner.__annotations__.get(self.name)
|
|
51
|
-
assert self.annotation is not None, f"Field {self.name} must have a type annotation"
|
|
52
|
-
self.type_ = _get_type(self.annotation)
|
|
53
|
-
|
|
54
|
-
def __get__(self, instance, owner):
|
|
55
|
-
if instance is None:
|
|
56
|
-
return self
|
|
57
|
-
return instance._values[self.name]
|
|
58
|
-
|
|
59
|
-
def __set__(self, instance, value):
|
|
60
|
-
instance._values[self.name] = value
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
def convert(annotation, value: str) -> Any:
|
|
64
|
-
check_optional_types = [str, int, float, bool, Path]
|
|
65
|
-
for check_type in check_optional_types:
|
|
66
|
-
if annotation == Optional[check_type]:
|
|
67
|
-
annotation = check_type
|
|
68
|
-
return convert(annotation, value)
|
|
69
|
-
if annotation == str:
|
|
70
|
-
return value
|
|
71
|
-
elif annotation == int:
|
|
72
|
-
return int(value)
|
|
73
|
-
elif annotation == float:
|
|
74
|
-
return float(value)
|
|
75
|
-
elif annotation == bool:
|
|
76
|
-
if value in ("True", "true", "1"):
|
|
77
|
-
return True
|
|
78
|
-
elif value in ("False", "false", "0"):
|
|
79
|
-
return False
|
|
80
|
-
else:
|
|
81
|
-
raise ValueError(f"Invalid boolean value {value}")
|
|
82
|
-
else:
|
|
83
|
-
# raise TypeError(f"Unsupported type {annotation}")
|
|
84
|
-
return annotation(value)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
def Field(*args, **kwargs) -> Any:
|
|
88
|
-
return _Field(*args, **kwargs)
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
class BaseSettings:
|
|
92
|
-
__fields__: dict
|
|
93
|
-
|
|
94
|
-
def __init__(self, **kwargs) -> None:
|
|
95
|
-
cls = type(self)
|
|
96
|
-
self._values = {**kwargs}
|
|
97
|
-
keys = {k.upper() for k in os.environ.keys()}
|
|
98
|
-
for key, field in cls.__dict__.items():
|
|
99
|
-
if key in kwargs:
|
|
100
|
-
continue
|
|
101
|
-
if isinstance(field, _Field):
|
|
102
|
-
value = field.default
|
|
103
|
-
if field.default_factory:
|
|
104
|
-
value = field.default_factory()
|
|
105
|
-
|
|
106
|
-
if field.env:
|
|
107
|
-
env_key = field.env.upper()
|
|
108
|
-
if env_key in keys:
|
|
109
|
-
# do a case-insensitive lookup
|
|
110
|
-
for env_var_cased in os.environ.keys():
|
|
111
|
-
if env_key.upper() == env_var_cased.upper():
|
|
112
|
-
value = convert(field.annotation, os.environ[env_var_cased])
|
|
113
|
-
self._values[key] = value
|
|
114
|
-
|
|
115
|
-
def __init_subclass__(cls) -> None:
|
|
116
|
-
cls.__fields__ = {}
|
|
117
|
-
for key, field in cls.__dict__.items():
|
|
118
|
-
if key.startswith("_"):
|
|
119
|
-
continue
|
|
120
|
-
if key == "Config":
|
|
121
|
-
continue
|
|
122
|
-
if not isinstance(field, _Field):
|
|
123
|
-
field = Field(field)
|
|
124
|
-
setattr(cls, key, field)
|
|
125
|
-
field.__set_name__(cls, key)
|
|
126
|
-
cls.__fields__[key] = field
|
|
127
|
-
|
|
128
|
-
def dict(self, by_alias=True):
|
|
129
|
-
values = self._values.copy()
|
|
130
|
-
for key, value in values.items():
|
|
131
|
-
if isinstance(value, BaseSettings):
|
|
132
|
-
values[key] = value.dict(by_alias=by_alias)
|
|
133
|
-
return values
|
solara/py.typed
DELETED
|
File without changes
|
solara/reactive.py
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
from typing import TypeVar
|
|
2
|
-
|
|
3
|
-
from solara.toestand import Reactive
|
|
4
|
-
|
|
5
|
-
__all__ = ["reactive", "Reactive"]
|
|
6
|
-
|
|
7
|
-
T = TypeVar("T")
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
def reactive(value: T) -> Reactive[T]:
|
|
11
|
-
"""Creates a new Reactive object with the given initial value.
|
|
12
|
-
|
|
13
|
-
Reactive objects are mostly used to manage global or application-wide state in
|
|
14
|
-
Solara web applications. They provide an easy-to-use mechanism for keeping
|
|
15
|
-
track of the changing state of data and for propagating those changes to
|
|
16
|
-
the appropriate UI components. For managing local or component-specific
|
|
17
|
-
state, consider using the [`solara.use_state()`](/documentation/api/hooks/use_state) function.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
Reactive variables can be accessed using the `.value` attribute. To modify
|
|
21
|
-
the value, you can either set the `.value` property directly or use the
|
|
22
|
-
`.set()` method. While both approaches are equivalent, the `.set()` method
|
|
23
|
-
is particularly useful when you need to pass it as a callback function to
|
|
24
|
-
other components, such as a slider's `on_value` callback.
|
|
25
|
-
|
|
26
|
-
When a component uses a reactive variable, it
|
|
27
|
-
automatically listens for changes to the variable's value. If the value
|
|
28
|
-
changes, the component will automatically re-render to reflect the updated
|
|
29
|
-
state, without the need to explicitly subscribe to the variable.
|
|
30
|
-
|
|
31
|
-
Reactive objects in Solara are also context-aware, meaning that they can
|
|
32
|
-
maintain separate values for each browser tab or user session. This enables
|
|
33
|
-
each user to have their own independent state, allowing them to interact
|
|
34
|
-
with the web application without affecting the state of other users.
|
|
35
|
-
|
|
36
|
-
Args:
|
|
37
|
-
value (T): The initial value of the reactive variable.
|
|
38
|
-
|
|
39
|
-
Returns:
|
|
40
|
-
Reactive[T]: A new Reactive object with the specified initial value.
|
|
41
|
-
|
|
42
|
-
Example:
|
|
43
|
-
|
|
44
|
-
```python
|
|
45
|
-
>>> counter = solara.reactive(0)
|
|
46
|
-
>>> counter.value
|
|
47
|
-
0
|
|
48
|
-
>>> counter.set(1)
|
|
49
|
-
>>> counter.value
|
|
50
|
-
1
|
|
51
|
-
>>> counter.value += 1
|
|
52
|
-
>>> counter.value
|
|
53
|
-
2
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
## Solara example
|
|
58
|
-
|
|
59
|
-
Here's an example that demonstrates the use of reactive variables in Solara components:
|
|
60
|
-
|
|
61
|
-
```solara
|
|
62
|
-
import solara
|
|
63
|
-
|
|
64
|
-
counter = solara.reactive(0)
|
|
65
|
-
|
|
66
|
-
def increment():
|
|
67
|
-
counter.value += 1
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
@solara.component
|
|
71
|
-
def CounterDisplay():
|
|
72
|
-
solara.Info(f"Counter: {counter.value}")
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
@solara.component
|
|
76
|
-
def IncrementButton():
|
|
77
|
-
|
|
78
|
-
solara.Button("Increment", on_click=increment)
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
@solara.component
|
|
82
|
-
def Page():
|
|
83
|
-
IncrementButton()
|
|
84
|
-
CounterDisplay()
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
In this example, we create a reactive variable counter with an initial value of 0.
|
|
88
|
-
We define two components: `CounterDisplay` and `IncrementButton`. `CounterDisplay` renders the current value of counter,
|
|
89
|
-
while `IncrementButton` increments the value of counter when clicked.
|
|
90
|
-
Whenever the counter value changes, `CounterDisplay` automatically updates to display the new value.
|
|
91
|
-
|
|
92
|
-
"""
|
|
93
|
-
return Reactive(value)
|
solara/routing.py
DELETED
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
import abc
|
|
2
|
-
import logging
|
|
3
|
-
from typing import Callable, List, Optional, Tuple, Union, cast
|
|
4
|
-
|
|
5
|
-
import solara
|
|
6
|
-
from solara import _using_solara_server
|
|
7
|
-
|
|
8
|
-
logger = logging.getLogger("solara.router")
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class _LocationBase(abc.ABC):
|
|
12
|
-
@property
|
|
13
|
-
def pathname(self):
|
|
14
|
-
pass
|
|
15
|
-
|
|
16
|
-
@pathname.setter
|
|
17
|
-
# mypy does not accept this
|
|
18
|
-
# @abc.abstractmethod
|
|
19
|
-
def pathname(self):
|
|
20
|
-
pass
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class _Location(_LocationBase):
|
|
24
|
-
def __init__(self, pathname, setter: Callable[[str], None]) -> None:
|
|
25
|
-
self._pathname = pathname
|
|
26
|
-
self.setter = setter
|
|
27
|
-
|
|
28
|
-
@property
|
|
29
|
-
def pathname(self):
|
|
30
|
-
return self._pathname
|
|
31
|
-
|
|
32
|
-
@pathname.setter
|
|
33
|
-
def pathname(self, value):
|
|
34
|
-
# import pdb
|
|
35
|
-
|
|
36
|
-
# pdb.set_trace()
|
|
37
|
-
self._pathname = value
|
|
38
|
-
self.setter(self._pathname)
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
class Router:
|
|
42
|
-
search: Optional[str]
|
|
43
|
-
|
|
44
|
-
def __init__(self, path: str, routes: List[solara.Route], set_path: Callable[[str], None] = None):
|
|
45
|
-
# see https://developer.mozilla.org/en-US/docs/Web/API/Location for anatomy/nomenclature
|
|
46
|
-
if "?" in path:
|
|
47
|
-
self.path, self.search = path.split("?", 1)
|
|
48
|
-
else:
|
|
49
|
-
self.path = path
|
|
50
|
-
self.search = None
|
|
51
|
-
del path
|
|
52
|
-
self.set_path = set_path
|
|
53
|
-
self.parts = (self.path or "").strip("/").split("/")
|
|
54
|
-
self.routes = routes
|
|
55
|
-
self.root_path = ""
|
|
56
|
-
if _using_solara_server():
|
|
57
|
-
import solara.server.settings
|
|
58
|
-
|
|
59
|
-
self.root_path = solara.server.settings.main.root_path or ""
|
|
60
|
-
# each route in this list corresponds to a part in self.parts
|
|
61
|
-
self.path_routes: List["solara.Route"] = []
|
|
62
|
-
self.path_routes_siblings: List[List["solara.Route"]] = [] # siblings including itself
|
|
63
|
-
# routes = routes.copy()
|
|
64
|
-
route = None
|
|
65
|
-
for part in self.parts:
|
|
66
|
-
for route in routes:
|
|
67
|
-
if (route.path == part) or (route.path == "/" and not part):
|
|
68
|
-
self.path_routes.append(route)
|
|
69
|
-
self.path_routes_siblings.append(routes)
|
|
70
|
-
routes = route.children
|
|
71
|
-
break
|
|
72
|
-
if len(self.parts) == len(self.path_routes):
|
|
73
|
-
# e.g. '/foo/bar' -> ['foo', 'bar'] and bar has a default route
|
|
74
|
-
# but if '' -> [''] we should not
|
|
75
|
-
route = self.path_routes[-1]
|
|
76
|
-
if route:
|
|
77
|
-
default_routes = [k for k in route.children if k.path == "/"]
|
|
78
|
-
if self.parts and self.parts[0] and default_routes:
|
|
79
|
-
self.path_routes.append(default_routes[0])
|
|
80
|
-
self.path_routes_siblings.append(route.children)
|
|
81
|
-
|
|
82
|
-
assert len(self.path_routes) == len(self.path_routes_siblings)
|
|
83
|
-
self.possible_match = (len(self.path_routes[-1].children) == 0) if self.path_routes else False
|
|
84
|
-
|
|
85
|
-
def push(self, path: str):
|
|
86
|
-
assert self.set_path is not None
|
|
87
|
-
self.set_path(path)
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
router_context = solara.create_context(Router("", []))
|
|
91
|
-
_location_context = solara.create_context(cast(_LocationBase, _Location("", lambda x: None)))
|
|
92
|
-
|
|
93
|
-
route_level_context = solara.create_context(0)
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
def use_route_level():
|
|
97
|
-
route_level = solara.use_context(route_level_context)
|
|
98
|
-
return route_level
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
def use_router() -> Router:
|
|
102
|
-
"""Returns the current router object.
|
|
103
|
-
|
|
104
|
-
See also [Understanding Routing](/documentation/advanced/understanding/routing).
|
|
105
|
-
|
|
106
|
-
`use_router` returns the current router object. This is useful to build custom routing.
|
|
107
|
-
|
|
108
|
-
the router object contains the following properties/methods:
|
|
109
|
-
|
|
110
|
-
* `path` - the current pathname (e.g. `/fruit/banana`)
|
|
111
|
-
* `parts` - the current pathname split into parts (e.g. `['fruit', 'banana']`)
|
|
112
|
-
* `search` - the query parameters string (e.g. `color=yellow`).
|
|
113
|
-
* `push(path: str)` - navigate to path (e.g. `router.push('/fruit/banana')`)
|
|
114
|
-
|
|
115
|
-
## Typical usage:
|
|
116
|
-
|
|
117
|
-
```python
|
|
118
|
-
import solara
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
@solara.component
|
|
122
|
-
def Page():
|
|
123
|
-
router = solara.use_router()
|
|
124
|
-
|
|
125
|
-
def redirect():
|
|
126
|
-
router.push(f"/documentation/api/routing/use_route")
|
|
127
|
-
|
|
128
|
-
solara.Button("Navigate using an event", on_click=redirect)
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
"""
|
|
132
|
-
return solara.use_context(router_context)
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
def use_route(
|
|
136
|
-
level=0,
|
|
137
|
-
peek=False,
|
|
138
|
-
) -> Tuple[Optional[solara.Route], List[solara.Route]]:
|
|
139
|
-
"""Returns (if found) the current route that matches the pathname, or None
|
|
140
|
-
|
|
141
|
-
See also [Understanding Routing](/documentation/advanced/understanding/routing).
|
|
142
|
-
|
|
143
|
-
`use_route` returns (if found) the current route that matches the pathname, or None. It also returns all resolved routes of that level
|
|
144
|
-
(i.e. all siblings and itself). This return tuple is useful to build custom navigation (e.g. using tabs or buttons).
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
Routing starts with declaring a set of `routes` in your app (solara picks up the `routes` variable if it exists,
|
|
148
|
-
and it should be in the same namespace as `Page`).
|
|
149
|
-
In the demo below, we declared the following routes.
|
|
150
|
-
|
|
151
|
-
```python
|
|
152
|
-
routes = [
|
|
153
|
-
solara.Route(path="/"),
|
|
154
|
-
solara.Route(
|
|
155
|
-
path="fruit",
|
|
156
|
-
component=Fruit,
|
|
157
|
-
children=[
|
|
158
|
-
solara.Route(path="/"),
|
|
159
|
-
solara.Route(path="kiwi"),
|
|
160
|
-
solara.Route(path="banana"),
|
|
161
|
-
solara.Route(path="apple"),
|
|
162
|
-
],
|
|
163
|
-
),
|
|
164
|
-
]
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
Note that all routes are relative, since a component does not know if it is embedded into a larger application, which may also do routing.
|
|
168
|
-
Therefore you should never use the `route.path` for navigation since the route object has no knowledge of the full url
|
|
169
|
-
(e.g. `/documentation/api/routing/use_route/fruit/banana`) but only knows its small piece of the pathname (e.g. `banana`)
|
|
170
|
-
|
|
171
|
-
Use [`resolve_path`](/documentation/api/routing/resolve_path) to request the full url for navigation,
|
|
172
|
-
or simply use the `Link` component that can do this for us.
|
|
173
|
-
|
|
174
|
-
If the current route has children, any child component that calls `use_route` will return the matched route and its siblings of our children.
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
## Arguments
|
|
178
|
-
|
|
179
|
-
* `level`: the level of the route to return. 0 is the current route, -1 is the parent route, 1 the child route, etc.
|
|
180
|
-
* `peek`: if True, the route level is not incremented. This is useful to peek at the next route level without changing the current route level.
|
|
181
|
-
"""
|
|
182
|
-
|
|
183
|
-
router = solara.use_context(router_context)
|
|
184
|
-
route_level = solara.use_context(route_level_context)
|
|
185
|
-
if not peek:
|
|
186
|
-
route_level_context.provide(route_level + 1)
|
|
187
|
-
route_level += level
|
|
188
|
-
if route_level < len(router.path_routes):
|
|
189
|
-
return router.path_routes[route_level], router.path_routes_siblings[route_level]
|
|
190
|
-
else:
|
|
191
|
-
return None, []
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
def find_route(path: str) -> Optional[solara.Route]:
|
|
195
|
-
router = solara.get_context(router_context)
|
|
196
|
-
route_level = min(solara.get_context(route_level_context), len(router.path_routes_siblings) - 1)
|
|
197
|
-
for route in router.path_routes_siblings[route_level]:
|
|
198
|
-
if path.startswith(route.path) or (not path and route.path == "/"):
|
|
199
|
-
return route
|
|
200
|
-
return None
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
def use_pathname():
|
|
204
|
-
location_proxy = solara.use_context(_location_context)
|
|
205
|
-
|
|
206
|
-
def setter(value):
|
|
207
|
-
location_proxy.pathname = value
|
|
208
|
-
|
|
209
|
-
return location_proxy.pathname, setter
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
def resolve_path(path_or_route: Union[str, solara.Route], level=0) -> str:
|
|
213
|
-
"""Resolve a relative path or a route to an absolute path.
|
|
214
|
-
|
|
215
|
-
If the path is a string and starts with a `/'`, it is returned as is.
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
## Typical usage:
|
|
219
|
-
|
|
220
|
-
```python
|
|
221
|
-
...
|
|
222
|
-
route_current, routes_current_level = solara.routes()
|
|
223
|
-
# route_current.path == "banana"
|
|
224
|
-
path = solara.resolve_path(route_current)
|
|
225
|
-
# path == "/fruit/banana"
|
|
226
|
-
path_same = solara.resolve_path("banana")
|
|
227
|
-
# path_same == path == "/fruit/banana"
|
|
228
|
-
...
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
## Arguments
|
|
232
|
-
|
|
233
|
-
* path_or_route: a path string or a [`solara.Route`](/documentation/api/routing/route) object to resolve.
|
|
234
|
-
|
|
235
|
-
## See also
|
|
236
|
-
|
|
237
|
-
* [Multipage](/documentation/advanced/howto/multipage).
|
|
238
|
-
* [Understanding Routing](/documentation/advanced/understanding/routing).
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
"""
|
|
242
|
-
router = solara.get_context(router_context)
|
|
243
|
-
if isinstance(path_or_route, str):
|
|
244
|
-
path = path_or_route
|
|
245
|
-
if path.startswith("/"):
|
|
246
|
-
return path
|
|
247
|
-
route_level = solara.get_context(route_level_context) + level
|
|
248
|
-
parts = [*router.parts[:route_level], path]
|
|
249
|
-
path = "/" + "/".join(parts)
|
|
250
|
-
if path.startswith("//"):
|
|
251
|
-
path = path[1:]
|
|
252
|
-
return path
|
|
253
|
-
elif isinstance(path_or_route, solara.Route):
|
|
254
|
-
route: solara.Route = path_or_route
|
|
255
|
-
path = _resolve_path("/", route, router.routes)
|
|
256
|
-
if path.startswith("//"):
|
|
257
|
-
path = path[1:]
|
|
258
|
-
return path
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
def _resolve_path(prefix: str, findroute: solara.Route, routes: List[solara.Route]):
|
|
262
|
-
for route in routes:
|
|
263
|
-
path = (prefix + "/" + route.path) if route.path != "/" else prefix
|
|
264
|
-
if findroute is route:
|
|
265
|
-
return path
|
|
266
|
-
possible_path = _resolve_path(path, findroute=findroute, routes=route.children)
|
|
267
|
-
if possible_path is not None:
|
|
268
|
-
return possible_path
|