diff --git a/frontend/src/components/editor/actions/useNotebookActions.tsx b/frontend/src/components/editor/actions/useNotebookActions.tsx index 0e9db7ce7a4..16b84ee058c 100644 --- a/frontend/src/components/editor/actions/useNotebookActions.tsx +++ b/frontend/src/components/editor/actions/useNotebookActions.tsx @@ -387,6 +387,7 @@ export function useNotebookActions() { { icon: , label: "Create molab notebook", + hidden: !sharingWasmEnabled, handle: async () => { const code = await readCode(); const url = createShareableLink({ diff --git a/frontend/src/components/static-html/static-banner.tsx b/frontend/src/components/static-html/static-banner.tsx index e8757b2ca78..ac108c2683d 100644 --- a/frontend/src/components/static-html/static-banner.tsx +++ b/frontend/src/components/static-html/static-banner.tsx @@ -6,6 +6,7 @@ import { useAtomValue } from "jotai"; import { CopyIcon, DownloadIcon } from "lucide-react"; import type React from "react"; import { Constants } from "@/core/constants"; +import { useResolvedMarimoConfig } from "@/core/config/config"; import { codeAtom } from "@/core/saving/file-state"; import { useFilename } from "@/core/saving/filename"; import { isStaticNotebook } from "@/core/static/static-state"; @@ -66,6 +67,9 @@ const StaticBannerDialog = ({ code }: { code: string }) => { filename = filename.slice(lastSlash + 1); } + const [resolvedConfig] = useResolvedMarimoConfig(); + const molabEnabled = resolvedConfig.sharing?.wasm !== false; + const href = window.location.href; const molabLink = createShareableLink({ code, @@ -118,28 +122,30 @@ const StaticBannerDialog = ({ code }: { code: string }) => { )} -
- -

- Run this notebook in{" "} - molab, marimo's - cloud-hosted notebook platform. -

-
+ {molabEnabled && ( +
+ +

+ Run this notebook in{" "} + molab, marimo's + cloud-hosted notebook platform. +

+
+ )}
diff --git a/marimo/_server/api/endpoints/export.py b/marimo/_server/api/endpoints/export.py index 1500f79f70c..93ea9c350c8 100644 --- a/marimo/_server/api/endpoints/export.py +++ b/marimo/_server/api/endpoints/export.py @@ -94,11 +94,13 @@ async def export_as_html( if not app_state.session_manager.should_send_code_to_frontend(): body.include_code = False + resolved_config = session.config_manager.get_config() html, filename = Exporter().export_as_html( app=session.app_file_manager.app, filename=session.app_file_manager.filename, session_view=session.session_view, - display_config=session.config_manager.get_config()["display"], + display_config=resolved_config["display"], + sharing_config=resolved_config.get("sharing"), request=body, ) diff --git a/marimo/_server/export/__init__.py b/marimo/_server/export/__init__.py index 18473723924..9164765ad39 100644 --- a/marimo/_server/export/__init__.py +++ b/marimo/_server/export/__init__.py @@ -167,15 +167,17 @@ def export_as_wasm( # Inline the layout file, if it exists app.inline_layout_file() config = get_default_config_manager(current_path=path.absolute_name) + resolved = config.get_config() result = Exporter().export_as_wasm( filename=path.short_name, app=app, - display_config=config.get_config()["display"], + display_config=resolved["display"], mode=mode, code=app.to_py(), asset_url=asset_url, show_code=show_code, + sharing_config=resolved.get("sharing"), ) return ExportResult( contents=result[0], @@ -332,7 +334,8 @@ async def run_app_then_export_as_html( file_manager.app.inline_layout_file() config = get_default_config_manager(current_path=file_manager.path) - display_config = cast(DisplayConfig, config.get_config()["display"]) + resolved = config.get_config() + display_config = cast(DisplayConfig, resolved["display"]) session_view, did_error = await run_app_until_completion( file_manager, cli_args, @@ -344,6 +347,7 @@ async def run_app_then_export_as_html( app=file_manager.app, session_view=session_view, display_config=display_config, + sharing_config=resolved.get("sharing"), request=ExportAsHTMLRequest( include_code=include_code, download=False, @@ -377,7 +381,8 @@ async def run_app_then_export_as_wasm( file_manager.app.inline_layout_file() config = get_default_config_manager(current_path=file_manager.path) - display_config = cast(DisplayConfig, config.get_config()["display"]) + resolved = config.get_config() + display_config = cast(DisplayConfig, resolved["display"]) session_view, did_error = await run_app_until_completion( file_manager, @@ -406,6 +411,7 @@ async def run_app_then_export_as_wasm( asset_url=asset_url, session_snapshot=session_snapshot, notebook_snapshot=notebook_snapshot, + sharing_config=resolved.get("sharing"), ) return ExportResult( contents=html, diff --git a/marimo/_server/export/exporter.py b/marimo/_server/export/exporter.py index cee285b552e..5b4a3de96a9 100644 --- a/marimo/_server/export/exporter.py +++ b/marimo/_server/export/exporter.py @@ -15,6 +15,7 @@ DEFAULT_CONFIG, DisplayConfig, MarimoConfig, + SharingConfig, ) from marimo._config.settings import GLOBAL_SETTINGS from marimo._config.utils import deep_copy @@ -101,12 +102,13 @@ def export_as_html( session_view: SessionView, display_config: DisplayConfig, request: ExportAsHTMLRequest, + sharing_config: SharingConfig | None = None, ) -> tuple[str, str]: index_html = get_html_contents() filename = get_filename(filename) - # Configure notebook with display settings - config = self._prepare_display_config(display_config) + # Configure notebook with display and sharing settings + config = self._prepare_display_config(display_config, sharing_config) # Serialize notebook state session_snapshot = serialize_session_view( @@ -157,15 +159,15 @@ def export_as_html( return html, download_filename def _prepare_display_config( - self, display_config: DisplayConfig + self, + display_config: DisplayConfig, + sharing_config: SharingConfig | None = None, ) -> MarimoConfig: - """Prepare config with display settings for static notebook.""" - # We only want pass the display config in the static notebook, - # since we use: - # - display.theme - # - display.cell_output + """Prepare config with display and sharing settings for static notebook.""" config = deep_copy(DEFAULT_CONFIG) config["display"] = display_config + if sharing_config: + config["sharing"] = sharing_config # type: ignore[typeddict-item] return cast(MarimoConfig, config) def _inline_virtual_files( @@ -349,14 +351,13 @@ def export_as_wasm( asset_url: str | None = None, session_snapshot: NotebookSessionV1 | None = None, notebook_snapshot: NotebookV1 | None = None, + sharing_config: SharingConfig | None = None, ) -> tuple[str, str]: """Export notebook as a WASM-powered standalone HTML file.""" index_html = get_html_contents() filename = get_filename(filename) - # We only want to pass the display config in the static notebook - config: MarimoConfig = deep_copy(DEFAULT_CONFIG) - config["display"] = display_config + config = self._prepare_display_config(display_config, sharing_config) # Remove autosave config["save"]["autosave"] = "off"