solara 1.30.1__py2.py3-none-any.whl → 1.31.0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {solara-1.30.1.dist-info → solara-1.31.0.dist-info}/METADATA +7 -42
- solara-1.31.0.dist-info/RECORD +5 -0
- {solara-1.30.1.dist-info → solara-1.31.0.dist-info}/WHEEL +1 -1
- {solara/template/portal → solara-1.31.0.dist-info/licenses}/LICENSE +1 -1
- solara/__init__.py +0 -123
- solara/__main__.py +0 -734
- solara/alias.py +0 -6
- solara/autorouting.py +0 -545
- solara/cache.py +0 -294
- solara/checks.html +0 -71
- solara/checks.py +0 -224
- solara/comm.py +0 -28
- solara/components/__init__.py +0 -59
- solara/components/alert.py +0 -155
- solara/components/applayout.py +0 -393
- solara/components/button.py +0 -85
- solara/components/card.py +0 -87
- solara/components/checkbox.py +0 -50
- solara/components/code_highlight_css.py +0 -11
- solara/components/code_highlight_css.vue +0 -63
- solara/components/columns.py +0 -159
- solara/components/component_vue.py +0 -110
- solara/components/cross_filter.py +0 -335
- solara/components/dataframe.py +0 -546
- solara/components/datatable.py +0 -221
- solara/components/datatable.vue +0 -175
- solara/components/details.py +0 -21
- solara/components/download.vue +0 -35
- solara/components/echarts.py +0 -75
- solara/components/echarts.vue +0 -128
- solara/components/figure_altair.py +0 -39
- solara/components/file_browser.py +0 -182
- solara/components/file_download.py +0 -199
- solara/components/file_drop.py +0 -139
- solara/components/file_drop.vue +0 -83
- solara/components/file_list_widget.vue +0 -78
- solara/components/head.py +0 -27
- solara/components/head_tag.py +0 -49
- solara/components/head_tag.vue +0 -60
- solara/components/image.py +0 -173
- solara/components/input.py +0 -440
- solara/components/link.py +0 -55
- solara/components/markdown.py +0 -371
- solara/components/markdown_editor.py +0 -25
- solara/components/markdown_editor.vue +0 -362
- solara/components/matplotlib.py +0 -74
- solara/components/meta.py +0 -47
- solara/components/misc.py +0 -333
- solara/components/pivot_table.py +0 -258
- solara/components/pivot_table.vue +0 -158
- solara/components/progress.py +0 -47
- solara/components/select.py +0 -186
- solara/components/select.vue +0 -27
- solara/components/slider.py +0 -442
- solara/components/slider_date.vue +0 -56
- solara/components/spinner-solara.vue +0 -105
- solara/components/spinner.py +0 -30
- solara/components/sql_code.py +0 -33
- solara/components/sql_code.vue +0 -128
- solara/components/style.py +0 -105
- solara/components/switch.py +0 -68
- solara/components/tab_navigation.py +0 -37
- solara/components/title.py +0 -90
- solara/components/title.vue +0 -38
- solara/components/togglebuttons.py +0 -202
- solara/components/tooltip.py +0 -61
- solara/datatypes.py +0 -143
- solara/express.py +0 -241
- solara/hooks/__init__.py +0 -4
- solara/hooks/dataframe.py +0 -99
- solara/hooks/misc.py +0 -263
- solara/hooks/use_reactive.py +0 -129
- solara/hooks/use_thread.py +0 -129
- solara/kitchensink.py +0 -8
- solara/lab/__init__.py +0 -34
- solara/lab/components/__init__.py +0 -6
- solara/lab/components/chat.py +0 -203
- solara/lab/components/confirmation_dialog.py +0 -165
- solara/lab/components/cross_filter.py +0 -7
- solara/lab/components/input_date.py +0 -298
- solara/lab/components/menu.py +0 -181
- solara/lab/components/menu.vue +0 -38
- solara/lab/components/tabs.py +0 -274
- solara/lab/components/theming.py +0 -98
- solara/lab/components/theming.vue +0 -72
- solara/lab/hooks/__init__.py +0 -0
- solara/lab/hooks/dataframe.py +0 -12
- solara/lab/toestand.py +0 -3
- solara/lab/utils/__init__.py +0 -2
- solara/lab/utils/cookies.py +0 -5
- solara/lab/utils/dataframe.py +0 -115
- solara/lab/utils/headers.py +0 -5
- solara/layout.py +0 -44
- solara/minisettings.py +0 -133
- solara/py.typed +0 -0
- solara/reactive.py +0 -93
- solara/routing.py +0 -268
- solara/scope/__init__.py +0 -88
- solara/scope/types.py +0 -55
- solara/server/__init__.py +0 -0
- solara/server/app.py +0 -490
- solara/server/assets/custom.css +0 -1
- solara/server/assets/custom.js +0 -1
- solara/server/assets/favicon.png +0 -0
- solara/server/assets/favicon.svg +0 -5
- solara/server/assets/style.css +0 -1665
- solara/server/assets/theme-dark.css +0 -437
- solara/server/assets/theme-light.css +0 -420
- solara/server/assets/theme.js +0 -3
- solara/server/cdn_helper.py +0 -77
- solara/server/esm.py +0 -69
- solara/server/fastapi.py +0 -5
- solara/server/flask.py +0 -286
- solara/server/jupyter/__init__.py +0 -2
- solara/server/jupyter/cdn_handler.py +0 -28
- solara/server/jupyter/server_extension.py +0 -29
- solara/server/jupytertools.py +0 -46
- solara/server/kernel.py +0 -319
- solara/server/kernel_context.py +0 -396
- solara/server/patch.py +0 -552
- solara/server/reload.py +0 -242
- solara/server/server.py +0 -437
- solara/server/settings.py +0 -212
- solara/server/shell.py +0 -240
- solara/server/starlette.py +0 -597
- solara/server/static/ansi.js +0 -270
- solara/server/static/highlight-dark.css +0 -82
- solara/server/static/highlight.css +0 -43
- solara/server/static/main-vuetify.js +0 -260
- solara/server/static/main.js +0 -163
- solara/server/static/solara_bootstrap.py +0 -129
- solara/server/static/sun.svg +0 -23
- solara/server/static/webworker.js +0 -42
- solara/server/telemetry.py +0 -212
- solara/server/templates/index.html.j2 +0 -1
- solara/server/templates/loader-plain.css +0 -11
- solara/server/templates/loader-plain.html +0 -20
- solara/server/templates/loader-solara.css +0 -111
- solara/server/templates/loader-solara.html +0 -40
- solara/server/templates/plain.html +0 -82
- solara/server/templates/solara.html.j2 +0 -446
- solara/server/threaded.py +0 -75
- solara/server/utils.py +0 -30
- solara/server/websocket.py +0 -44
- solara/settings.py +0 -56
- solara/tasks.py +0 -847
- solara/template/button.py +0 -16
- solara/template/markdown.py +0 -42
- solara/template/portal/.flake8 +0 -6
- solara/template/portal/.pre-commit-config.yaml +0 -28
- solara/template/portal/Procfile +0 -7
- solara/template/portal/mypy.ini +0 -3
- solara/template/portal/pyproject.toml +0 -26
- solara/template/portal/solara_portal/__init__.py +0 -3
- solara/template/portal/solara_portal/components/__init__.py +0 -2
- solara/template/portal/solara_portal/components/article.py +0 -28
- solara/template/portal/solara_portal/components/data.py +0 -28
- solara/template/portal/solara_portal/components/header.py +0 -6
- solara/template/portal/solara_portal/components/layout.py +0 -6
- solara/template/portal/solara_portal/content/articles/equis-in-vidi.md +0 -85
- solara/template/portal/solara_portal/content/articles/substiterat-vati.md +0 -70
- solara/template/portal/solara_portal/data.py +0 -60
- solara/template/portal/solara_portal/pages/__init__.py +0 -67
- solara/template/portal/solara_portal/pages/article/__init__.py +0 -26
- solara/template/portal/solara_portal/pages/tabular.py +0 -29
- solara/template/portal/solara_portal/pages/viz/__init__.py +0 -69
- solara/template/portal/solara_portal/pages/viz/overview.py +0 -14
- solara/test/__init__.py +0 -0
- solara/test/pytest_plugin.py +0 -698
- solara/toestand.py +0 -772
- solara/util.py +0 -308
- solara/website/__init__.py +0 -0
- solara/website/assets/custom.css +0 -462
- solara/website/assets/images/logo-small.png +0 -0
- solara/website/assets/images/logo.svg +0 -17
- solara/website/assets/images/logo_white.svg +0 -50
- solara/website/assets/theme.js +0 -8
- solara/website/components/__init__.py +0 -5
- solara/website/components/algolia.vue +0 -24
- solara/website/components/algolia_api.vue +0 -157
- solara/website/components/docs.py +0 -118
- solara/website/components/header.py +0 -72
- solara/website/components/hero.py +0 -15
- solara/website/components/mailchimp.py +0 -12
- solara/website/components/mailchimp.vue +0 -47
- solara/website/components/markdown.py +0 -30
- solara/website/components/notebook.py +0 -172
- solara/website/pages/__init__.py +0 -575
- solara/website/pages/apps/__init__.py +0 -16
- solara/website/pages/apps/authorization/__init__.py +0 -118
- solara/website/pages/apps/authorization/admin.py +0 -12
- solara/website/pages/apps/authorization/users.py +0 -12
- solara/website/pages/apps/jupyter-dashboard-1.py +0 -116
- solara/website/pages/apps/layout-demo.py +0 -40
- solara/website/pages/apps/multipage/__init__.py +0 -38
- solara/website/pages/apps/multipage/page1.py +0 -26
- solara/website/pages/apps/multipage/page2.py +0 -34
- solara/website/pages/apps/scatter.py +0 -136
- solara/website/pages/apps/scrolling.py +0 -63
- solara/website/pages/apps/tutorial-streamlit.py +0 -18
- solara/website/pages/changelog/__init__.py +0 -8
- solara/website/pages/changelog/changelog.md +0 -195
- solara/website/pages/contact/__init__.py +0 -8
- solara/website/pages/contact/contact.md +0 -17
- solara/website/pages/doc_use_download.py +0 -85
- solara/website/pages/documentation/__init__.py +0 -184
- solara/website/pages/documentation/advanced/__init__.py +0 -9
- solara/website/pages/documentation/advanced/content/00-overview.md +0 -1
- solara/website/pages/documentation/advanced/content/10-howto/00-overview.md +0 -6
- solara/website/pages/documentation/advanced/content/10-howto/10-multipage.md +0 -196
- solara/website/pages/documentation/advanced/content/10-howto/20-layout.md +0 -125
- solara/website/pages/documentation/advanced/content/10-howto/30-testing.md +0 -154
- solara/website/pages/documentation/advanced/content/10-howto/31-debugging.md +0 -69
- solara/website/pages/documentation/advanced/content/10-howto/40-embed.md +0 -49
- solara/website/pages/documentation/advanced/content/10-howto/50-ipywidget_libraries.md +0 -124
- solara/website/pages/documentation/advanced/content/20-understanding/00-introduction.md +0 -10
- solara/website/pages/documentation/advanced/content/20-understanding/05-ipywidgets.md +0 -35
- solara/website/pages/documentation/advanced/content/20-understanding/06-ipyvuetify.md +0 -42
- solara/website/pages/documentation/advanced/content/20-understanding/10-reacton.md +0 -28
- solara/website/pages/documentation/advanced/content/20-understanding/12-reacton-basics.md +0 -108
- solara/website/pages/documentation/advanced/content/20-understanding/15-anatomy.md +0 -23
- solara/website/pages/documentation/advanced/content/20-understanding/17-rules-of-hooks.md +0 -7
- solara/website/pages/documentation/advanced/content/20-understanding/18-containers.md +0 -166
- solara/website/pages/documentation/advanced/content/20-understanding/20-solara.md +0 -18
- solara/website/pages/documentation/advanced/content/20-understanding/40-routing.md +0 -240
- solara/website/pages/documentation/advanced/content/20-understanding/50-solara-server.md +0 -86
- solara/website/pages/documentation/advanced/content/20-understanding/60-voila.md +0 -12
- solara/website/pages/documentation/advanced/content/30-enterprise/00-overview.md +0 -1
- solara/website/pages/documentation/advanced/content/30-enterprise/10-oauth.md +0 -171
- solara/website/pages/documentation/advanced/content/40-development/00-overview.md +0 -0
- solara/website/pages/documentation/advanced/content/40-development/01-contribute.md +0 -45
- solara/website/pages/documentation/advanced/content/40-development/10-setup.md +0 -76
- solara/website/pages/documentation/api/__init__.py +0 -19
- solara/website/pages/documentation/api/cross_filter/__init__.py +0 -9
- solara/website/pages/documentation/api/cross_filter/cross_filter_dataframe.py +0 -23
- solara/website/pages/documentation/api/cross_filter/cross_filter_report.py +0 -22
- solara/website/pages/documentation/api/cross_filter/cross_filter_select.py +0 -22
- solara/website/pages/documentation/api/cross_filter/cross_filter_slider.py +0 -22
- solara/website/pages/documentation/api/hooks/__init__.py +0 -9
- solara/website/pages/documentation/api/hooks/use_cross_filter.py +0 -25
- solara/website/pages/documentation/api/hooks/use_dark_effective.py +0 -13
- solara/website/pages/documentation/api/hooks/use_effect.md +0 -43
- solara/website/pages/documentation/api/hooks/use_effect.py +0 -9
- solara/website/pages/documentation/api/hooks/use_exception.py +0 -33
- solara/website/pages/documentation/api/hooks/use_memo.md +0 -16
- solara/website/pages/documentation/api/hooks/use_memo.py +0 -9
- solara/website/pages/documentation/api/hooks/use_previous.py +0 -32
- solara/website/pages/documentation/api/hooks/use_reactive.py +0 -15
- solara/website/pages/documentation/api/hooks/use_state.py +0 -11
- solara/website/pages/documentation/api/hooks/use_state_or_update.py +0 -68
- solara/website/pages/documentation/api/hooks/use_thread.md +0 -58
- solara/website/pages/documentation/api/hooks/use_thread.py +0 -44
- solara/website/pages/documentation/api/hooks/use_trait_observe.py +0 -13
- solara/website/pages/documentation/api/routing/__init__.py +0 -9
- solara/website/pages/documentation/api/routing/generate_routes.py +0 -11
- solara/website/pages/documentation/api/routing/generate_routes_directory.py +0 -11
- solara/website/pages/documentation/api/routing/resolve_path.py +0 -36
- solara/website/pages/documentation/api/routing/route.py +0 -32
- solara/website/pages/documentation/api/routing/use_route.py +0 -80
- solara/website/pages/documentation/api/routing/use_router.py +0 -15
- solara/website/pages/documentation/api/utilities/__init__.py +0 -9
- solara/website/pages/documentation/api/utilities/component_vue.py +0 -11
- solara/website/pages/documentation/api/utilities/computed.py +0 -16
- solara/website/pages/documentation/api/utilities/display.py +0 -15
- solara/website/pages/documentation/api/utilities/get_kernel_id.py +0 -16
- solara/website/pages/documentation/api/utilities/get_session_id.py +0 -16
- solara/website/pages/documentation/api/utilities/memoize.py +0 -36
- solara/website/pages/documentation/api/utilities/on_kernel_start.py +0 -27
- solara/website/pages/documentation/api/utilities/reactive.py +0 -15
- solara/website/pages/documentation/api/utilities/widget.py +0 -104
- solara/website/pages/documentation/components/__init__.py +0 -12
- solara/website/pages/documentation/components/advanced/__init__.py +0 -9
- solara/website/pages/documentation/components/advanced/link.py +0 -28
- solara/website/pages/documentation/components/advanced/meta.py +0 -21
- solara/website/pages/documentation/components/advanced/style.py +0 -44
- solara/website/pages/documentation/components/common.py +0 -9
- solara/website/pages/documentation/components/data/__init__.py +0 -9
- solara/website/pages/documentation/components/data/dataframe.py +0 -44
- solara/website/pages/documentation/components/data/pivot_table.py +0 -81
- solara/website/pages/documentation/components/enterprise/__init__.py +0 -9
- solara/website/pages/documentation/components/enterprise/avatar.py +0 -19
- solara/website/pages/documentation/components/enterprise/avatar_menu.py +0 -20
- solara/website/pages/documentation/components/input/__init__.py +0 -9
- solara/website/pages/documentation/components/input/button.py +0 -22
- solara/website/pages/documentation/components/input/checkbox.py +0 -12
- solara/website/pages/documentation/components/input/file_browser.py +0 -33
- solara/website/pages/documentation/components/input/file_drop.py +0 -75
- solara/website/pages/documentation/components/input/input.py +0 -18
- solara/website/pages/documentation/components/input/select.py +0 -21
- solara/website/pages/documentation/components/input/slider.py +0 -28
- solara/website/pages/documentation/components/input/switch.py +0 -12
- solara/website/pages/documentation/components/input/togglebuttons.py +0 -20
- solara/website/pages/documentation/components/lab/__init__.py +0 -9
- solara/website/pages/documentation/components/lab/chat.py +0 -108
- solara/website/pages/documentation/components/lab/confirmation_dialog.py +0 -55
- solara/website/pages/documentation/components/lab/cookies_headers.py +0 -48
- solara/website/pages/documentation/components/lab/input_date.py +0 -19
- solara/website/pages/documentation/components/lab/menu.py +0 -21
- solara/website/pages/documentation/components/lab/tab.py +0 -24
- solara/website/pages/documentation/components/lab/tabs.py +0 -44
- solara/website/pages/documentation/components/lab/task.py +0 -12
- solara/website/pages/documentation/components/lab/theming.py +0 -72
- solara/website/pages/documentation/components/lab/use_task.py +0 -12
- solara/website/pages/documentation/components/layout/__init__.py +0 -9
- solara/website/pages/documentation/components/layout/app_bar.py +0 -15
- solara/website/pages/documentation/components/layout/app_bar_title.py +0 -15
- solara/website/pages/documentation/components/layout/app_layout.py +0 -23
- solara/website/pages/documentation/components/layout/card.py +0 -14
- solara/website/pages/documentation/components/layout/card_actions.py +0 -15
- solara/website/pages/documentation/components/layout/column.py +0 -29
- solara/website/pages/documentation/components/layout/columns.py +0 -26
- solara/website/pages/documentation/components/layout/columns_responsive.py +0 -67
- solara/website/pages/documentation/components/layout/griddraggable.py +0 -61
- solara/website/pages/documentation/components/layout/gridfixed.py +0 -21
- solara/website/pages/documentation/components/layout/hbox.py +0 -17
- solara/website/pages/documentation/components/layout/row.py +0 -29
- solara/website/pages/documentation/components/layout/sidebar.py +0 -23
- solara/website/pages/documentation/components/layout/vbox.py +0 -19
- solara/website/pages/documentation/components/output/__init__.py +0 -9
- solara/website/pages/documentation/components/output/file_download.py +0 -12
- solara/website/pages/documentation/components/output/html.py +0 -22
- solara/website/pages/documentation/components/output/image.py +0 -12
- solara/website/pages/documentation/components/output/markdown.py +0 -59
- solara/website/pages/documentation/components/output/markdown_editor.py +0 -53
- solara/website/pages/documentation/components/output/sql_code.py +0 -84
- solara/website/pages/documentation/components/output/tooltip.py +0 -12
- solara/website/pages/documentation/components/page/__init__.py +0 -9
- solara/website/pages/documentation/components/page/head.py +0 -19
- solara/website/pages/documentation/components/page/title.py +0 -28
- solara/website/pages/documentation/components/status/__init__.py +0 -9
- solara/website/pages/documentation/components/status/error.py +0 -40
- solara/website/pages/documentation/components/status/info.py +0 -40
- solara/website/pages/documentation/components/status/progress.py +0 -10
- solara/website/pages/documentation/components/status/spinner.py +0 -10
- solara/website/pages/documentation/components/status/success.py +0 -40
- solara/website/pages/documentation/components/status/warning.py +0 -47
- solara/website/pages/documentation/components/viz/__init__.py +0 -9
- solara/website/pages/documentation/components/viz/altair.py +0 -44
- solara/website/pages/documentation/components/viz/echarts.py +0 -78
- solara/website/pages/documentation/components/viz/matplotlib.py +0 -32
- solara/website/pages/documentation/components/viz/plotly.py +0 -63
- solara/website/pages/documentation/components/viz/plotly_express.py +0 -41
- solara/website/pages/documentation/examples/__init__.py +0 -52
- solara/website/pages/documentation/examples/ai/__init__.py +0 -10
- solara/website/pages/documentation/examples/ai/chatbot.py +0 -96
- solara/website/pages/documentation/examples/ai/tokenizer.py +0 -106
- solara/website/pages/documentation/examples/basics/__init__.py +0 -2
- solara/website/pages/documentation/examples/basics/sine.py +0 -28
- solara/website/pages/documentation/examples/fullscreen/__init__.py +0 -9
- solara/website/pages/documentation/examples/fullscreen/authorization.py +0 -3
- solara/website/pages/documentation/examples/fullscreen/layout_demo.py +0 -3
- solara/website/pages/documentation/examples/fullscreen/multipage.py +0 -3
- solara/website/pages/documentation/examples/fullscreen/scatter.py +0 -3
- solara/website/pages/documentation/examples/fullscreen/scrolling.py +0 -3
- solara/website/pages/documentation/examples/fullscreen/tutorial_streamlit.py +0 -3
- solara/website/pages/documentation/examples/general/__init__.py +0 -9
- solara/website/pages/documentation/examples/general/custom_storage.py +0 -69
- solara/website/pages/documentation/examples/general/deploy_model.py +0 -114
- solara/website/pages/documentation/examples/general/live_update.py +0 -38
- solara/website/pages/documentation/examples/general/login_oauth.py +0 -76
- solara/website/pages/documentation/examples/general/mycard.vue +0 -58
- solara/website/pages/documentation/examples/general/pokemon_search.py +0 -51
- solara/website/pages/documentation/examples/general/vue_component.py +0 -50
- solara/website/pages/documentation/examples/ipycanvas.py +0 -49
- solara/website/pages/documentation/examples/libraries/__init__.py +0 -9
- solara/website/pages/documentation/examples/libraries/altair.py +0 -63
- solara/website/pages/documentation/examples/libraries/bqplot.py +0 -39
- solara/website/pages/documentation/examples/libraries/ipyleaflet.py +0 -32
- solara/website/pages/documentation/examples/libraries/ipyleaflet_advanced.py +0 -65
- solara/website/pages/documentation/examples/utilities/__init__.py +0 -9
- solara/website/pages/documentation/examples/utilities/calculator.py +0 -157
- solara/website/pages/documentation/examples/utilities/countdown_timer.py +0 -64
- solara/website/pages/documentation/examples/utilities/todo.py +0 -195
- solara/website/pages/documentation/examples/visualization/__init__.py +0 -6
- solara/website/pages/documentation/examples/visualization/annotator.py +0 -68
- solara/website/pages/documentation/examples/visualization/linked_views.py +0 -84
- solara/website/pages/documentation/examples/visualization/plotly.py +0 -43
- solara/website/pages/documentation/faq/__init__.py +0 -12
- solara/website/pages/documentation/faq/content/99-faq.md +0 -76
- solara/website/pages/documentation/getting_started/__init__.py +0 -9
- solara/website/pages/documentation/getting_started/content/00-quickstart.md +0 -89
- solara/website/pages/documentation/getting_started/content/01-introduction.md +0 -125
- solara/website/pages/documentation/getting_started/content/02-installing.md +0 -85
- solara/website/pages/documentation/getting_started/content/04-tutorials/00-overview.md +0 -14
- solara/website/pages/documentation/getting_started/content/04-tutorials/10_data_science.py +0 -13
- solara/website/pages/documentation/getting_started/content/04-tutorials/20-web-app.md +0 -89
- solara/website/pages/documentation/getting_started/content/04-tutorials/30-ipywidgets.md +0 -124
- solara/website/pages/documentation/getting_started/content/04-tutorials/40-streamlit.md +0 -146
- solara/website/pages/documentation/getting_started/content/04-tutorials/50-dash.md +0 -144
- solara/website/pages/documentation/getting_started/content/04-tutorials/60-jupyter-dashboard-part1.py +0 -64
- solara/website/pages/documentation/getting_started/content/04-tutorials/SF_crime_sample.csv.gz +0 -0
- solara/website/pages/documentation/getting_started/content/04-tutorials/_data_science.ipynb +0 -445
- solara/website/pages/documentation/getting_started/content/04-tutorials/_jupyter_dashboard_1.ipynb +0 -1000
- solara/website/pages/documentation/getting_started/content/05-fundamentals/00-overview.md +0 -11
- solara/website/pages/documentation/getting_started/content/05-fundamentals/10-components.md +0 -223
- solara/website/pages/documentation/getting_started/content/05-fundamentals/50-state-management.md +0 -88
- solara/website/pages/documentation/getting_started/content/06-reference/00-overview.md +0 -3
- solara/website/pages/documentation/getting_started/content/06-reference/40-static_files.md +0 -31
- solara/website/pages/documentation/getting_started/content/06-reference/41-asset-files.md +0 -36
- solara/website/pages/documentation/getting_started/content/06-reference/60-static-site-generation.md +0 -59
- solara/website/pages/documentation/getting_started/content/06-reference/70-search.md +0 -34
- solara/website/pages/documentation/getting_started/content/06-reference/80-reloading.md +0 -34
- solara/website/pages/documentation/getting_started/content/06-reference/90-notebook-support.md +0 -7
- solara/website/pages/documentation/getting_started/content/06-reference/95-caching.md +0 -148
- solara/website/pages/documentation/getting_started/content/07-deploying/00-overview.md +0 -7
- solara/website/pages/documentation/getting_started/content/07-deploying/10-self-hosted.md +0 -273
- solara/website/pages/documentation/getting_started/content/07-deploying/20-cloud-hosted.md +0 -80
- solara/website/pages/documentation/getting_started/content/80-what-is-lab.md +0 -7
- solara/website/pages/documentation/getting_started/content/90-troubleshoot.md +0 -26
- solara/website/pages/docutils.py +0 -38
- solara/website/pages/showcase/__init__.py +0 -105
- solara/website/pages/showcase/domino_code_assist.py +0 -60
- solara/website/pages/showcase/planeto_tessa.py +0 -19
- solara/website/pages/showcase/solara_dev.py +0 -54
- solara/website/pages/showcase/solarathon_2023_team_2.py +0 -22
- solara/website/pages/showcase/solarathon_2023_team_4.py +0 -22
- solara/website/pages/showcase/solarathon_2023_team_5.py +0 -23
- solara/website/pages/showcase/solarathon_2023_team_6.py +0 -34
- solara/website/pages/showcase/wanderlust.py +0 -27
- solara/website/public/beach.jpeg +0 -0
- solara/website/public/logo.svg +0 -6
- solara/website/public/social/discord.svg +0 -1
- solara/website/public/social/github.svg +0 -1
- solara/website/public/social/twitter.svg +0 -3
- solara/website/public/success.html +0 -25
- solara/website/templates/index.html.j2 +0 -117
- solara/website/utils.py +0 -51
- solara/widgets/__init__.py +0 -1
- solara/widgets/vue/gridlayout.vue +0 -110
- solara/widgets/vue/html.vue +0 -4
- solara/widgets/vue/navigator.vue +0 -104
- solara/widgets/vue/vegalite.vue +0 -115
- solara/widgets/widgets.py +0 -65
- solara-1.30.1.data/data/etc/jupyter/jupyter_notebook_config.d/solara.json +0 -7
- solara-1.30.1.data/data/etc/jupyter/jupyter_server_config.d/solara.json +0 -7
- solara-1.30.1.dist-info/RECORD +0 -437
- solara-1.30.1.dist-info/entry_points.txt +0 -5
- /solara-1.30.1.dist-info/licenses/LICENSE → /LICENSE +0 -0
solara/cache.py
DELETED
|
@@ -1,294 +0,0 @@
|
|
|
1
|
-
import hashlib
|
|
2
|
-
import inspect
|
|
3
|
-
import logging
|
|
4
|
-
import sys
|
|
5
|
-
from typing import (
|
|
6
|
-
Any,
|
|
7
|
-
Callable,
|
|
8
|
-
Dict,
|
|
9
|
-
Generic,
|
|
10
|
-
MutableMapping,
|
|
11
|
-
Optional,
|
|
12
|
-
TypeVar,
|
|
13
|
-
Union,
|
|
14
|
-
cast,
|
|
15
|
-
overload,
|
|
16
|
-
)
|
|
17
|
-
|
|
18
|
-
import cachetools
|
|
19
|
-
import solara
|
|
20
|
-
import solara.settings
|
|
21
|
-
import solara.util
|
|
22
|
-
import typing_extensions
|
|
23
|
-
from reacton.utils import equals
|
|
24
|
-
|
|
25
|
-
logger = logging.getLogger("solara.cache")
|
|
26
|
-
|
|
27
|
-
# placeholder value for missing keys
|
|
28
|
-
_DOES_NOT_EXIST = object()
|
|
29
|
-
|
|
30
|
-
_global_values_used: Dict[Any, Dict[str, Any]] = {}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
T = TypeVar("T")
|
|
34
|
-
R = TypeVar("R")
|
|
35
|
-
K = TypeVar("K")
|
|
36
|
-
V = TypeVar("V")
|
|
37
|
-
P = typing_extensions.ParamSpec("P")
|
|
38
|
-
|
|
39
|
-
Storage = MutableMapping[K, V]
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
class Memory(cachetools.LRUCache):
|
|
43
|
-
def __init__(self, max_items=solara.settings.cache.memory_max_items):
|
|
44
|
-
super().__init__(maxsize=max_items)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
def _default_key(*args, **kwargs):
|
|
48
|
-
kwargs_tuple: Any = ()
|
|
49
|
-
for key, value in kwargs.items():
|
|
50
|
-
kwargs_tuple += (key, value)
|
|
51
|
-
return (args, kwargs_tuple)
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
class MemoizedFunction(Generic[P, R]):
|
|
55
|
-
def __init__(self, function: Callable[P, R], key: Callable[P, R], storage: Optional[Storage], allow_nonlocals=False):
|
|
56
|
-
self.function = function
|
|
57
|
-
f: Callable = self.function
|
|
58
|
-
if not allow_nonlocals:
|
|
59
|
-
nonlocals = inspect.getclosurevars(f).nonlocals
|
|
60
|
-
if nonlocals:
|
|
61
|
-
raise ValueError(f"Memoized functions cannot depend on nonlocal variables, it now depends on {nonlocals}")
|
|
62
|
-
if sys.version_info[:2] < (3, 9):
|
|
63
|
-
# usedforsecurity is only available in Python 3.9+
|
|
64
|
-
codehash = hashlib.md5(f.__code__.co_code).hexdigest()
|
|
65
|
-
else:
|
|
66
|
-
codehash = hashlib.md5(f.__code__.co_code, usedforsecurity=False).hexdigest() # type: ignore
|
|
67
|
-
|
|
68
|
-
self.function_key = (f.__qualname__, codehash)
|
|
69
|
-
current_globals = dict(inspect.getclosurevars(f).globals)
|
|
70
|
-
_global_values_used.setdefault(self.function_key, current_globals)
|
|
71
|
-
self._check_globals()
|
|
72
|
-
self.key = key
|
|
73
|
-
self._storage = storage
|
|
74
|
-
self.intrusive_cancel = True
|
|
75
|
-
# modifications to these are not thread safe
|
|
76
|
-
# but good enough for an indication
|
|
77
|
-
self.hits = 0
|
|
78
|
-
self.misses = 0
|
|
79
|
-
|
|
80
|
-
@property
|
|
81
|
-
def storage(self) -> Storage:
|
|
82
|
-
return self._storage if self._storage is not None else storage
|
|
83
|
-
|
|
84
|
-
def _check_globals(self):
|
|
85
|
-
globals = _global_values_used.get(self.function_key)
|
|
86
|
-
current_globals = dict(inspect.getclosurevars(self.function).globals)
|
|
87
|
-
if current_globals is not globals:
|
|
88
|
-
if not equals(current_globals, globals):
|
|
89
|
-
raise ValueError(
|
|
90
|
-
f"Memoized functions depend on globals variables, but they changed. The first value was {globals}, but now it is {current_globals}"
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> R:
|
|
94
|
-
self._check_globals()
|
|
95
|
-
key = (self.function_key, self.key(*args, **kwargs))
|
|
96
|
-
# if .get is atomic, we do not need to lock
|
|
97
|
-
value = cast(R, self.storage.get(key, _DOES_NOT_EXIST))
|
|
98
|
-
if value is _DOES_NOT_EXIST:
|
|
99
|
-
self.misses += 1
|
|
100
|
-
value = self.function(*args, **kwargs)
|
|
101
|
-
self.storage[key] = value
|
|
102
|
-
else:
|
|
103
|
-
self.hits += 1
|
|
104
|
-
return value
|
|
105
|
-
|
|
106
|
-
def use_thread(self, *args: P.args, **kwargs: P.kwargs) -> solara.Result[R]:
|
|
107
|
-
"""Calls the function in a thread when not in cache, otherwise returns the cached value.
|
|
108
|
-
|
|
109
|
-
This is almost similar to a use_thread on the memoized function, except that
|
|
110
|
-
we ensure that if the function return value is already in the cache, we don't
|
|
111
|
-
have to wait for the thread to finish.
|
|
112
|
-
|
|
113
|
-
This can cause less flickering in the UI, since it will immediately return a
|
|
114
|
-
'FINISHED' result, instead of a 'RUNNING' result when possible.
|
|
115
|
-
"""
|
|
116
|
-
key = (self.function_key, self.key(*args, **kwargs))
|
|
117
|
-
|
|
118
|
-
# we assume generating the key is cheap, but a storage.get might not be
|
|
119
|
-
# since it may have to ask the a server, so we wrap it in use_memo
|
|
120
|
-
def get_current():
|
|
121
|
-
return cast(R, self.storage.get(key, _DOES_NOT_EXIST))
|
|
122
|
-
|
|
123
|
-
value = solara.use_memo(get_current, dependencies=[key])
|
|
124
|
-
|
|
125
|
-
def do_work():
|
|
126
|
-
if value is _DOES_NOT_EXIST:
|
|
127
|
-
self.misses += 1
|
|
128
|
-
self._check_globals()
|
|
129
|
-
new_value = self.function(*args, **kwargs)
|
|
130
|
-
# TODO: what if someone else already put in the value?
|
|
131
|
-
# we do a check in vaex if it differs
|
|
132
|
-
# but we could also store a Future
|
|
133
|
-
self.storage[key] = new_value
|
|
134
|
-
return new_value
|
|
135
|
-
else:
|
|
136
|
-
# although we don't use the return value directly, it's still used on the next time result_thread is
|
|
137
|
-
# returned.
|
|
138
|
-
return value
|
|
139
|
-
|
|
140
|
-
result_thread: solara.Result[R] = solara.use_thread(do_work, dependencies=[key], intrusive_cancel=self.intrusive_cancel)
|
|
141
|
-
if value is _DOES_NOT_EXIST:
|
|
142
|
-
return result_thread
|
|
143
|
-
else:
|
|
144
|
-
self.hits += 1
|
|
145
|
-
# what are the semantics of cancel and retry here?
|
|
146
|
-
return solara.Result(value, state=solara.ResultState.FINISHED)
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
@overload
|
|
150
|
-
def memoize(
|
|
151
|
-
function: None = None,
|
|
152
|
-
key: None = None,
|
|
153
|
-
storage: Optional[Storage] = None,
|
|
154
|
-
allow_nonlocals=False,
|
|
155
|
-
) -> Callable[[Callable[P, R]], MemoizedFunction[P, R]]:
|
|
156
|
-
...
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
@overload
|
|
160
|
-
def memoize(
|
|
161
|
-
function: None = None,
|
|
162
|
-
key: Callable[P, R] = ...,
|
|
163
|
-
storage: Optional[Storage] = None,
|
|
164
|
-
allow_nonlocals=False,
|
|
165
|
-
) -> Callable[[Callable[P, R]], MemoizedFunction[P, R]]:
|
|
166
|
-
...
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
@overload
|
|
170
|
-
def memoize(
|
|
171
|
-
function: Callable[P, R],
|
|
172
|
-
key: None = None,
|
|
173
|
-
storage: None = None,
|
|
174
|
-
allow_nonlocals=False,
|
|
175
|
-
) -> MemoizedFunction[P, R]:
|
|
176
|
-
...
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
def memoize(
|
|
180
|
-
function: Union[None, Callable[P, R]] = None,
|
|
181
|
-
key: Union[None, Callable[P, R]] = None,
|
|
182
|
-
storage: Optional[Storage] = None,
|
|
183
|
-
allow_nonlocals: bool = False,
|
|
184
|
-
) -> Union[Callable[[Callable[P, R]], MemoizedFunction[P, R]], MemoizedFunction[P, R]]:
|
|
185
|
-
"""Will cache function return values based on the arguments.
|
|
186
|
-
|
|
187
|
-
Example:
|
|
188
|
-
|
|
189
|
-
```python
|
|
190
|
-
@solara.memoize
|
|
191
|
-
def mean(values):
|
|
192
|
-
return sum(values) / len(values)
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
If a key function is provided, it will be used to generate the cache key based on the arguments instead.
|
|
196
|
-
This is useful in situations where the arguments are not hashable, but a unique key can be generated
|
|
197
|
-
based on the arguments.
|
|
198
|
-
|
|
199
|
-
Also used in situations where the arguments are expensive to hash, but a cheaper key
|
|
200
|
-
that is unique exists. For example using the filename instead of the file content.
|
|
201
|
-
|
|
202
|
-
Example:
|
|
203
|
-
|
|
204
|
-
```python
|
|
205
|
-
@solara.memoize(key=lambda df, column: (id(df), column))
|
|
206
|
-
def mean(df, column):
|
|
207
|
-
return df[column].mean()
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
Without the key function, the above would fail because a DataFrame is not hashable.
|
|
211
|
-
|
|
212
|
-
The function name and function code are added to the argument based key, together making up a unique cache key.
|
|
213
|
-
Nonlocals variables are not included in the key, and are not allowed by default. Pass `allow_nonlocals=True`
|
|
214
|
-
to allow nonlocals variables, or add them as arguments to the function.
|
|
215
|
-
Globals are by default allowed, and also not included in the key. Solara will try to detect if globals are
|
|
216
|
-
changed, and if so, will raise a ValueError.
|
|
217
|
-
|
|
218
|
-
If a storage is provided, it will be used to store the cached values. If no storage is provided, the
|
|
219
|
-
shared storage will be used. This is useful in situations where the cache should be shared between
|
|
220
|
-
different functions to avoid excessive memory usage by limiting the number of cache entries or the
|
|
221
|
-
memory content.
|
|
222
|
-
|
|
223
|
-
The storage can be any object that implements the MutableMapping interface, for instance a dict or
|
|
224
|
-
a cachetools.LRUCache. Or a new instance of `solara.cache.Memory`, see [caching](/documentation/getting_started/reference/caching)
|
|
225
|
-
for cache storage options.
|
|
226
|
-
|
|
227
|
-
The return value of the decorator behaves like the original function, but also has a few attributes:
|
|
228
|
-
|
|
229
|
-
* `storage`: the storage used to cache the values
|
|
230
|
-
* `key`: the key function used to generate the key
|
|
231
|
-
* `function`: the original function
|
|
232
|
-
* `use_thread`: a hook that will execute the function in a thread, and return a Result object
|
|
233
|
-
If the value is already cached, the function will not be executed in a thread.
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
See also the [reference on caching](/documentation/getting_started/reference/caching) for more caching details.
|
|
237
|
-
|
|
238
|
-
"""
|
|
239
|
-
|
|
240
|
-
def wrapper(func: Callable[P, R]) -> MemoizedFunction[P, R]:
|
|
241
|
-
return MemoizedFunction[P, R](
|
|
242
|
-
func,
|
|
243
|
-
cast(Callable[P, R], key or _default_key),
|
|
244
|
-
storage,
|
|
245
|
-
allow_nonlocals,
|
|
246
|
-
)
|
|
247
|
-
|
|
248
|
-
if function is None:
|
|
249
|
-
return wrapper
|
|
250
|
-
else:
|
|
251
|
-
return wrapper(function)
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
cache_type_map = {
|
|
255
|
-
"memory": "solara.cache.Memory",
|
|
256
|
-
"memory-size": "solara_enterprise.cache.memory_size.MemorySize",
|
|
257
|
-
"disk": "solara_enterprise.cache.disk.Disk",
|
|
258
|
-
"redis": "solara_enterprise.cache.redis.Redis",
|
|
259
|
-
"multi-level": "solara_enterprise.cache.multi_level.MultiLevel",
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
def create(name: str = "memory", *args, **kwargs) -> Storage:
|
|
264
|
-
"""Create a cache storage based on the name.
|
|
265
|
-
|
|
266
|
-
## Arguments
|
|
267
|
-
|
|
268
|
-
- `name`: the name of the cache type, can be one of `memory`, `memory-size`, `disk`, `redis`, `multi-level`
|
|
269
|
-
- `*args`: the arguments to pass to the cache constructor
|
|
270
|
-
- `**kwargs`: the keyword arguments to pass to the cache constructor
|
|
271
|
-
|
|
272
|
-
"""
|
|
273
|
-
if "," in name:
|
|
274
|
-
names = name.split(",")
|
|
275
|
-
logger.info("Set multilevel cache to %r", names)
|
|
276
|
-
caches = []
|
|
277
|
-
for name in names:
|
|
278
|
-
caches.append(create(name, *args, **kwargs))
|
|
279
|
-
cache = create("multi-level", *caches)
|
|
280
|
-
elif name in cache_type_map:
|
|
281
|
-
cls = solara.util.import_item(cache_type_map[name])
|
|
282
|
-
cache = cls(*args, **kwargs)
|
|
283
|
-
else:
|
|
284
|
-
raise ValueError(f"Unknown type of cache {name}")
|
|
285
|
-
return cache
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
storage: Storage = create(solara.settings.cache.type)
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
def configure(name="memory", *args, **kwargs):
|
|
292
|
-
"""Shorthand for solara.cache.storage = solara.cache.create(name, *args, **kwargs)"""
|
|
293
|
-
global storage
|
|
294
|
-
storage = create(name, *args, **kwargs)
|
solara/checks.html
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
<div class="jupyter-widget-checks-container">
|
|
2
|
-
<script>
|
|
3
|
-
(function () {
|
|
4
|
-
console.log("Checking for jupyter-widgets extensions")
|
|
5
|
-
const inLab = window._JUPYTERLAB !== undefined;
|
|
6
|
-
const silent = jupyter_widget_checks_silent;
|
|
7
|
-
const containers = document.getElementsByClassName('jupyter-widget-checks-container');
|
|
8
|
-
const rootEl = containers[containers.length - 1];
|
|
9
|
-
const libraries = window.jupyter_widget_checks_libraries;
|
|
10
|
-
|
|
11
|
-
function getBaseUrl() {
|
|
12
|
-
const labConfigData = document.getElementById("jupyter-config-data");
|
|
13
|
-
if (labConfigData) {
|
|
14
|
-
/* lab and Voila */
|
|
15
|
-
return JSON.parse(labConfigData.textContent).baseUrl;
|
|
16
|
-
}
|
|
17
|
-
let base = document.body.dataset.baseUrl || document.baseURI;
|
|
18
|
-
return base;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function checkLibrary(extensions, library) {
|
|
22
|
-
let installed = false;
|
|
23
|
-
let ok = true;
|
|
24
|
-
if (inLab) {
|
|
25
|
-
installed = _JUPYTERLAB[library.lab] !== undefined
|
|
26
|
-
} else {
|
|
27
|
-
installed = extensions[library.classic] !== undefined;
|
|
28
|
-
let enabled = extensions[library.classic] === true;
|
|
29
|
-
}
|
|
30
|
-
const div = document.createElement("div")
|
|
31
|
-
if (installed) {
|
|
32
|
-
if (!silent) {
|
|
33
|
-
div.innerHTML = `Extension ${library.python} is installed at the server ✅`
|
|
34
|
-
rootEl.appendChild(div)
|
|
35
|
-
}
|
|
36
|
-
} else {
|
|
37
|
-
div.innerHTML = `Extension ${library.python} is <b>NOT</b> installed at the server ❌.`
|
|
38
|
-
rootEl.appendChild(div)
|
|
39
|
-
ok = false;
|
|
40
|
-
}
|
|
41
|
-
return ok;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
async function check() {
|
|
45
|
-
const url = `${getBaseUrl()}api/config/notebook`
|
|
46
|
-
const response = (await fetch(url));
|
|
47
|
-
const data = await response.json()
|
|
48
|
-
const extensions = data["load_extensions"];
|
|
49
|
-
var ok = true;
|
|
50
|
-
let needsInstall = [];
|
|
51
|
-
libraries.forEach((library) => {
|
|
52
|
-
if (!checkLibrary(extensions, library)) {
|
|
53
|
-
ok = false;
|
|
54
|
-
needsInstall.push(library.python)
|
|
55
|
-
console.log("Needs install", library.python)
|
|
56
|
-
}
|
|
57
|
-
})
|
|
58
|
-
console.log(ok, needsInstall)
|
|
59
|
-
if (!ok) {
|
|
60
|
-
const div = document.createElement("div")
|
|
61
|
-
const div2 = document.createElement("div")
|
|
62
|
-
div.innerHTML = `Run <code>${jupyter_python_executable} -m pip install ${needsInstall.join(" ")}</code>. Refresh the page after installation.`
|
|
63
|
-
div2.innerHTML = `Visit <a href="https://solara.dev/documentation/getting_started/troubleshoot" target="_blank">https://solara/dev/documentation/getting_started/troubleshoot</a> for more information.`
|
|
64
|
-
rootEl.appendChild(div)
|
|
65
|
-
rootEl.appendChild(div2)
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
check()
|
|
69
|
-
})();
|
|
70
|
-
</script>
|
|
71
|
-
</div>
|
solara/checks.py
DELETED
|
@@ -1,224 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
import logging
|
|
3
|
-
import os
|
|
4
|
-
import subprocess
|
|
5
|
-
import sys
|
|
6
|
-
import warnings
|
|
7
|
-
from pathlib import Path
|
|
8
|
-
from typing import Optional
|
|
9
|
-
|
|
10
|
-
import IPython.display
|
|
11
|
-
from IPython.core.interactiveshell import InteractiveShell
|
|
12
|
-
from IPython.display import display
|
|
13
|
-
|
|
14
|
-
import solara
|
|
15
|
-
from solara.util import get_solara_home
|
|
16
|
-
|
|
17
|
-
HERE = Path(__file__).parent
|
|
18
|
-
logger = logging.getLogger(__name__)
|
|
19
|
-
|
|
20
|
-
jupyter_checked_path = get_solara_home() / ".jupyter_checked"
|
|
21
|
-
solara_checked_path = get_solara_home() / ".solara_checked"
|
|
22
|
-
solara_version = solara.__version__
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def _should_perform_check(path: Path):
|
|
26
|
-
if path.exists():
|
|
27
|
-
return False
|
|
28
|
-
try:
|
|
29
|
-
home = get_solara_home()
|
|
30
|
-
if not home.exists():
|
|
31
|
-
home.mkdir(parents=True, exist_ok=True)
|
|
32
|
-
# try writing, if we cannot, we will not check
|
|
33
|
-
if not path.exists():
|
|
34
|
-
path.write_text("")
|
|
35
|
-
path.unlink()
|
|
36
|
-
except OSError:
|
|
37
|
-
return False
|
|
38
|
-
return True
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
def should_perform_jupyter_check():
|
|
42
|
-
if "PYTEST_CURRENT_TEST" in os.environ:
|
|
43
|
-
return False
|
|
44
|
-
return _should_perform_check(jupyter_checked_path)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
def should_perform_solara_check():
|
|
48
|
-
if "PYTEST_CURRENT_TEST" in os.environ:
|
|
49
|
-
return False
|
|
50
|
-
import solara.server.settings
|
|
51
|
-
|
|
52
|
-
if solara.server.settings.main.mode == "production":
|
|
53
|
-
return False
|
|
54
|
-
return _should_perform_check(solara_checked_path)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
@solara.component
|
|
58
|
-
def JupyterCheck():
|
|
59
|
-
# We do 2 calls home:
|
|
60
|
-
# * 1 from pure js (should always work)
|
|
61
|
-
# * 1 from a widget (might not work)
|
|
62
|
-
# This way we can see how many installations actually fail
|
|
63
|
-
# Note that we only do this once, we touch ~/.solara/.jupyter_checked
|
|
64
|
-
# to avoid doing it multiple times
|
|
65
|
-
def inject_pure_js_check():
|
|
66
|
-
# do this as an effect, otherwise we will use the display
|
|
67
|
-
# that gets dispatched to solara, which will not come through
|
|
68
|
-
# if the widgets do not work
|
|
69
|
-
IPython.display.display(
|
|
70
|
-
IPython.display.Javascript(
|
|
71
|
-
data=f"""
|
|
72
|
-
const prevIframe = document.getElementById("solara-jupyter-check");
|
|
73
|
-
if(prevIframe)
|
|
74
|
-
prevIframe.remove();
|
|
75
|
-
const iframe = document.createElement('iframe')
|
|
76
|
-
iframe.setAttribute("src", "https://solara.dev/static/public/success.html?check=purejs&version={solara_version}");
|
|
77
|
-
iframe.style.width = "0px";
|
|
78
|
-
iframe.style.height = "0px";
|
|
79
|
-
iframe.style.display = "none";
|
|
80
|
-
iframe.id = "solara-jupyter-check";
|
|
81
|
-
document.body.appendChild(iframe);
|
|
82
|
-
"""
|
|
83
|
-
)
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
# this should always get through, even if widgets do not work
|
|
87
|
-
solara.use_effect(inject_pure_js_check, [])
|
|
88
|
-
|
|
89
|
-
def flag_jupyter_checked():
|
|
90
|
-
try:
|
|
91
|
-
jupyter_checked_path.write_text("")
|
|
92
|
-
except OSError:
|
|
93
|
-
pass
|
|
94
|
-
|
|
95
|
-
solara.use_effect(flag_jupyter_checked, [])
|
|
96
|
-
# this iframe should only get through if the widget installation succeeded
|
|
97
|
-
return solara.v.Html(
|
|
98
|
-
tag="iframe",
|
|
99
|
-
attributes={"src": f"https://solara.dev/static/public/success.html?check=widget&version={solara_version}", "width": "0px", "height": "0px"},
|
|
100
|
-
style_="display: none;",
|
|
101
|
-
)
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
@solara.component
|
|
105
|
-
def SolaraCheck():
|
|
106
|
-
def flag_solara_checked():
|
|
107
|
-
try:
|
|
108
|
-
solara_checked_path.write_text("")
|
|
109
|
-
except OSError:
|
|
110
|
-
pass
|
|
111
|
-
|
|
112
|
-
solara.use_effect(flag_solara_checked, [])
|
|
113
|
-
return solara.v.Html(
|
|
114
|
-
tag="iframe",
|
|
115
|
-
attributes={
|
|
116
|
-
"src": f"https://solara.dev/static/public/success.html?system=solara&check=widget&version={solara_version}",
|
|
117
|
-
"width": "0px",
|
|
118
|
-
"height": "0px",
|
|
119
|
-
},
|
|
120
|
-
style_="display: none;",
|
|
121
|
-
)
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
def getcmdline(pid):
|
|
125
|
-
# for linux
|
|
126
|
-
if sys.platform == "linux":
|
|
127
|
-
with open(f"/proc/{pid}/cmdline", "rb") as f:
|
|
128
|
-
return f.read().split(b"\00")[0].decode("utf-8")
|
|
129
|
-
elif sys.platform == "darwin":
|
|
130
|
-
return subprocess.check_output(["ps", "-o", "command=", "-p", str(pid)]).split(b"\n")[0].split(b" ")[0].decode("utf-8")
|
|
131
|
-
elif sys.platform == "win32":
|
|
132
|
-
return subprocess.check_output(["wmic", "process", "get", "commandline", "/format:list"]).split(b"\n")[0].split(b" ")[0].decode("utf-8")
|
|
133
|
-
else:
|
|
134
|
-
raise ValueError(f"Unsupported platform: {sys.platform}")
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
def get_server_python_executable(silent: bool = False):
|
|
138
|
-
servers = []
|
|
139
|
-
try:
|
|
140
|
-
from jupyter_server import serverapp
|
|
141
|
-
|
|
142
|
-
servers += list(serverapp.list_running_servers())
|
|
143
|
-
except ImportError:
|
|
144
|
-
pass
|
|
145
|
-
try:
|
|
146
|
-
from notebook import notebookapp
|
|
147
|
-
|
|
148
|
-
servers += list(notebookapp.list_running_servers())
|
|
149
|
-
except ImportError:
|
|
150
|
-
pass
|
|
151
|
-
|
|
152
|
-
pythons = [getcmdline(server["pid"]) for server in servers]
|
|
153
|
-
if len(pythons) == 0:
|
|
154
|
-
python = sys.executable
|
|
155
|
-
if not silent:
|
|
156
|
-
warnings.warn("Could not find servers, we are assuming the server is running under Python executable: %s" % python)
|
|
157
|
-
elif len(pythons) > 1:
|
|
158
|
-
info = "\n\t".join(pythons)
|
|
159
|
-
if sys.executable in pythons:
|
|
160
|
-
python = sys.executable
|
|
161
|
-
else:
|
|
162
|
-
python = pythons[0]
|
|
163
|
-
if not silent:
|
|
164
|
-
warnings.warn("Found multiple find servers:\n%s\n" "We are assuming the server is running under Python executable: %s" % (info, python))
|
|
165
|
-
else:
|
|
166
|
-
python = pythons[0]
|
|
167
|
-
return python
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
libraries_minimal = [
|
|
171
|
-
{"python": "ipyvuetify", "classic": "jupyter-vuetify/extension", "lab": "jupyter-vuetify"},
|
|
172
|
-
{"python": "ipyvue", "classic": "jupyter-vue/extension", "lab": "jupyter-vue"},
|
|
173
|
-
]
|
|
174
|
-
|
|
175
|
-
libraries_extra = [
|
|
176
|
-
{"python": "bqplot", "classic": "bqplot/extension", "lab": "bqplot"},
|
|
177
|
-
{"python": "ipyvolume", "classic": "ipyvolume/extension", "lab": "ipyvolume"},
|
|
178
|
-
{"python": "ipywebrtc", "classic": "jupyter-webrtc", "lab": "jupyter-webrtc"},
|
|
179
|
-
{"python": "ipyleaflet", "classic": "ipyleaflet/extension", "lab": "ipyleaflet"},
|
|
180
|
-
]
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
def check_jupyter(
|
|
184
|
-
server_python: Optional[str] = None,
|
|
185
|
-
silent: bool = False,
|
|
186
|
-
libraries: list = libraries_minimal,
|
|
187
|
-
libraries_extra: list = libraries_extra,
|
|
188
|
-
force: bool = False,
|
|
189
|
-
extra: bool = False,
|
|
190
|
-
):
|
|
191
|
-
if solara._using_solara_server():
|
|
192
|
-
# for the server we don't need to do this check
|
|
193
|
-
return
|
|
194
|
-
if not InteractiveShell.initialized():
|
|
195
|
-
# also, in a normal python repr, we don't want to display anything
|
|
196
|
-
return
|
|
197
|
-
try:
|
|
198
|
-
python_executable = server_python or get_server_python_executable(silent)
|
|
199
|
-
if Path(python_executable).resolve() != Path(sys.executable).resolve() or force:
|
|
200
|
-
libraries_json = json.dumps(libraries + (libraries_extra if extra else []))
|
|
201
|
-
display(
|
|
202
|
-
IPython.display.Javascript(
|
|
203
|
-
data="""
|
|
204
|
-
window.jupyter_python_executable = %r;
|
|
205
|
-
window.jupyter_widget_checks_silent = %s;
|
|
206
|
-
window.jupyter_widget_checks_libraries = %s;
|
|
207
|
-
"""
|
|
208
|
-
% (python_executable, str(silent).lower(), libraries_json)
|
|
209
|
-
)
|
|
210
|
-
)
|
|
211
|
-
display(IPython.display.HTML(filename=str(HERE / "checks.html")))
|
|
212
|
-
else:
|
|
213
|
-
if not silent:
|
|
214
|
-
display(
|
|
215
|
-
IPython.display.HTML(
|
|
216
|
-
data="<div>Jupyter server is running under the same Python executable as your kernel, no need to check 👍."
|
|
217
|
-
"<br> <i>Run solara.check_jupyter(force=True) to force checking.</i></div>"
|
|
218
|
-
)
|
|
219
|
-
)
|
|
220
|
-
except Exception:
|
|
221
|
-
logger.exception("Could not check jupyter-widgets extensions.")
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
check_jupyter(silent=True)
|
solara/comm.py
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import traceback
|
|
2
|
-
from typing import Any, Dict
|
|
3
|
-
|
|
4
|
-
try:
|
|
5
|
-
import comm
|
|
6
|
-
except ImportError:
|
|
7
|
-
comm = None # type: ignore
|
|
8
|
-
|
|
9
|
-
orphan_comm_stacks: Dict[Any, str] = {}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
if comm is not None and comm.create_comm is comm._create_comm:
|
|
13
|
-
# only when nobody else has monkey-patched comm.create_comm
|
|
14
|
-
class DummyComm(comm.base_comm.BaseComm): # type: ignore
|
|
15
|
-
def publish_msg(self, msg_type, data=None, metadata=None, buffers=None, **keys):
|
|
16
|
-
pass
|
|
17
|
-
|
|
18
|
-
def create_dummy_comm(*args, **kwargs):
|
|
19
|
-
comm = DummyComm(*args, **kwargs)
|
|
20
|
-
stacktrace = "".join(traceback.format_stack())
|
|
21
|
-
orphan_comm_stacks[comm] = stacktrace
|
|
22
|
-
return comm
|
|
23
|
-
|
|
24
|
-
comm.create_comm = create_dummy_comm
|
|
25
|
-
else:
|
|
26
|
-
|
|
27
|
-
class DummyComm: # type: ignore
|
|
28
|
-
pass
|
solara/components/__init__.py
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
# isort: skip_file
|
|
2
|
-
from .button import Button # noqa: F401
|
|
3
|
-
from .style import Style # noqa: F401 F403
|
|
4
|
-
from .misc import * # noqa: #F401 F403
|
|
5
|
-
from .alert import Warning, Info, Error, Success # noqa: #F401 F403
|
|
6
|
-
from .checkbox import Checkbox # noqa: #F401 F403
|
|
7
|
-
from .cross_filter import ( # noqa: F401
|
|
8
|
-
CrossFilterDataFrame,
|
|
9
|
-
CrossFilterReport,
|
|
10
|
-
CrossFilterSelect,
|
|
11
|
-
CrossFilterSlider,
|
|
12
|
-
)
|
|
13
|
-
from .datatable import DataTable, DataFrame # noqa: #F401 F403
|
|
14
|
-
from .details import Details # noqa: #F401 F403
|
|
15
|
-
from .file_browser import FileBrowser # noqa: #F401 F403
|
|
16
|
-
from .image import Image # noqa: #F401 F403
|
|
17
|
-
from .markdown import Markdown, MarkdownIt # noqa: #F401 F403
|
|
18
|
-
from .slider import ( # noqa: F401 F403
|
|
19
|
-
DateSlider, # noqa: F401 F403
|
|
20
|
-
FloatSlider, # noqa: F401 F403
|
|
21
|
-
IntSlider, # noqa: F401 F403
|
|
22
|
-
ValueSlider, # noqa: F401 F403
|
|
23
|
-
SliderDate, # noqa: F401 F403
|
|
24
|
-
SliderFloat, # noqa: F401 F403
|
|
25
|
-
SliderInt, # noqa: F401 F403
|
|
26
|
-
SliderValue, # noqa: F401 F403
|
|
27
|
-
SliderRangeInt, # noqa: F401 F403
|
|
28
|
-
SliderRangeFloat, # noqa: F401 F403
|
|
29
|
-
) # noqa: F401 F403
|
|
30
|
-
from .sql_code import SqlCode # noqa: #F401 F403
|
|
31
|
-
from .togglebuttons import ( # noqa: #F401 F403
|
|
32
|
-
ToggleButtonsMultiple,
|
|
33
|
-
ToggleButtonsSingle,
|
|
34
|
-
)
|
|
35
|
-
from .input import InputText, InputFloat, InputInt # noqa: #F401 F403
|
|
36
|
-
from .pivot_table import PivotTableView, PivotTable, PivotTableCard # noqa: #F401 F403
|
|
37
|
-
from .head import Head # noqa: #F401 F403
|
|
38
|
-
from .title import Title # noqa: #F401 F403
|
|
39
|
-
from .link import Link # noqa: #F401 F403
|
|
40
|
-
from .applayout import AppLayout, Sidebar, AppBar, AppBarTitle # noqa: #F401 F403
|
|
41
|
-
from .tab_navigation import TabNavigation # noqa: #F401 F403
|
|
42
|
-
from .markdown_editor import MarkdownEditor # noqa: #F401 F403
|
|
43
|
-
from .select import Select, SelectMultiple # noqa: #F401 F403
|
|
44
|
-
from .matplotlib import FigureMatplotlib # noqa: #F401 F403
|
|
45
|
-
from .echarts import FigureEcharts # noqa: #F401 F403
|
|
46
|
-
from .figure_altair import FigureAltair, AltairChart # noqa: #F401 F403
|
|
47
|
-
from .meta import Meta # noqa: #F401 F403
|
|
48
|
-
from .columns import Columns, ColumnsResponsive # noqa: #F401 F403
|
|
49
|
-
from .file_drop import FileDrop, FileDropMultiple # noqa: #F401 F403
|
|
50
|
-
from .file_download import FileDownload # noqa: #F401 F403
|
|
51
|
-
from .tooltip import Tooltip # noqa: #F401 F403
|
|
52
|
-
from .card import Card, CardActions # noqa: #F401 F403
|
|
53
|
-
from .spinner import SpinnerSolara # noqa: #F401 F403
|
|
54
|
-
from .switch import Switch # noqa: #F401 F403
|
|
55
|
-
from .progress import ProgressLinear # noqa: #F401 F403
|
|
56
|
-
from .component_vue import _component_vue, component_vue # noqa: #F401 F403
|
|
57
|
-
import reacton.core
|
|
58
|
-
|
|
59
|
-
reacton.core._default_container = Column # noqa: F405
|