Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: marimo islands (Windows-related) + doc touchups #3242

Merged
merged 14 commits into from
Jan 2, 2025
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ venv/
ENV/
env.bak/
venv.bak/
uv.lock

# editors
*.swp
Expand Down
85 changes: 84 additions & 1 deletion docs/guides/exporting.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,89 @@ marimo islands are a way to embed marimo outputs and/or python code in your HTML

Check out an [example island-powered document](./island_example.md).

You can use `MarimoIslandGenerator` to embed marimo "islands", or blocks of marimo code and outputs, in a static web page. For example, use this class in conjunction with other static site generators (SSGs) to embed marimo into their generated content.

Haleshot marked this conversation as resolved.
Show resolved Hide resolved
### Generating islands
akshayka marked this conversation as resolved.
Show resolved Hide resolved

There are many ways to generate marimo islands:
akshayka marked this conversation as resolved.
Show resolved Hide resolved

!!! example

=== "using uv run"

```bash
pnpm dev:islands
```

Generate an HTML page with islands:

```bash
# Generate
uv run ./islands/generate.py > islands/__demo__/index.html
# Run the Vite server
pnpm dev:islands
```

=== "Class"

```python
import asyncio
import sys
from marimo._islands import MarimoIslandGenerator

if sys.platform == 'win32':
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())

async def main():
generator = MarimoIslandGenerator()
block1 = generator.add_code("import marimo as mo")
block2 = generator.add_code("mo.md('Hello, islands!')")

# Build the app
app = await generator.build()

# Render the app
output = f"""
<html>
<head>
{generator.render_head()}
</head>
<body>
{block1.render(display_output=False)}
{block2.render()}
</body>
</html>
"""
print(output)
# Save the HTML to a file
output_file = "output.html"
with open(output_file, "w", encoding="utf-8") as f:
f.write(output)

if __name__ == '__main__':
asyncio.run(main())
```

=== "File Reference"

```python
from marimo import MarimoIslandGenerator

# Create the generator from file
generator = MarimoIslandGenerator.from_file("./<notebook-name>.py", display_code=False)

# Generate and print the HTML without building
# This will still work for basic rendering, though without running the cells
html = generator.render_html(include_init_island=False)
print(html)
# Save the HTML to a file
output_file = "output.html"
with open(output_file, "w", encoding="utf-8") as f:
f.write(html)
```

Any relevant `.html` that gets generated can be run through the [`development.md`](https://github.com/marimo-team/marimo/blob/main/frontend/islands/development.md) file instructions.

### Islands in action

!!! warning "Advanced topic!"
Expand Down Expand Up @@ -258,6 +341,6 @@ In order to use marimo islands, you need to import the necessary JS/CSS headers

### Generating islands

While you can generate the HTML code for islands yourself, it it recommend to use our `MarimoIslandGenerator` class to generate the HTML code for you.
While you can generate the HTML code for islands yourself, it is recommended to use our `MarimoIslandGenerator` class to generate the HTML code for you.
akshayka marked this conversation as resolved.
Show resolved Hide resolved

::: marimo.MarimoIslandGenerator
2 changes: 1 addition & 1 deletion frontend/islands/development.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Marimo Islands

marimo islands are a way to render HTML "islands" each with static outputs and code. This differs from the normal "app mode" int that there is no top-level app. In "island mode", we do not have access to the HTML of the parent page.
marimo islands are a way to render HTML "islands" each with static outputs and code. This differs from the normal "app mode" in the sense that there is no top-level app. In "island mode", we do not have access to the HTML of the parent page.

## Development

Expand Down
3 changes: 2 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@
"lint:stylelint": "stylelint src/**/*.css --fix",
"format": "biome format --write .",
"preview": "vite preview",
"dev:islands": "VITE_MARIMO_ISLANDS=true vite --config islands/vite.config.mts",
"dev:islands": "cross-env VITE_MARIMO_ISLANDS=true vite --config islands/vite.config.mts",
"build:islands": "VITE_MARIMO_ISLANDS=true vite --config islands/vite.config.mts build",
"preview:islands": "VITE_MARIMO_VERSION='0.4.6' VITE_MARIMO_ISLANDS=true vite --config islands/vite.config.mts build",
"storybook": "storybook dev -p 6006",
Expand Down Expand Up @@ -200,6 +200,7 @@
"autoprefixer": "^10.4.20",
"babel-plugin-react-compiler": "19.0.0-beta-8a03594-20241020",
"blob-polyfill": "^7.0.20220408",
"cross-env": "^7.0.3",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-jsx-a11y": "^6.9.0",
Expand Down
12 changes: 12 additions & 0 deletions frontend/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

97 changes: 76 additions & 21 deletions marimo/_islands/island_generator.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# Copyright 2024 Marimo. All rights reserved.
from __future__ import annotations

import asyncio
import json
import sys
from textwrap import dedent
from typing import TYPE_CHECKING, List, Optional, Union, cast

Expand All @@ -18,6 +20,9 @@
from marimo._server.file_router import AppFileRouter
from marimo._utils.marimo_path import MarimoPath

if sys.platform == "win32": # handling for windows
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
Haleshot marked this conversation as resolved.
Show resolved Hide resolved

if TYPE_CHECKING:
from marimo._server.session.session_view import SessionView

Expand Down Expand Up @@ -152,28 +157,78 @@ class MarimoIslandGenerator:

# Example

Using the MarimoIslandGenerator class:
```python
import asyncio
import sys
from marimo._islands import MarimoIslandGenerator
Haleshot marked this conversation as resolved.
Show resolved Hide resolved

if sys.platform == 'win32':
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
Haleshot marked this conversation as resolved.
Show resolved Hide resolved

async def main():
generator = MarimoIslandGenerator()
block1 = generator.add_code("import marimo as mo")
block2 = generator.add_code("mo.md('Hello, islands!')")

# Build the app
app = await generator.build()

# Render the app
output = f\"\"\"
<html>
<head>
{generator.render_head()}
</head>
<body>
{block1.render(display_output=False)}
{block2.render()}
</body>
</html>
\"\"\"
print(output)
# Save the HTML to a file
output_file = "output.html"
with open(output_file, "w", encoding="utf-8") as f:
f.write(output)

if __name__ == '__main__':
asyncio.run(main())
```

You can also create the generator from a file:

```python
from marimo.islands import MarimoIslandGenerator

generator = MarimoIslandGenerator()
block1 = generator.add_code("import marimo as mo")
block2 = generator.add_code("mo.md('Hello, islands!')")

# Build the app
app = await generator.build()

# Render the app
output = f\"\"\"
<html>
<head>
{generator.render_head()}
</head>
<body>
{block1.render(display_output=False)}
{block2.render()}
</body>
</html>
\"\"\"
from marimo import MarimoIslandGenerator

# Create the generator from file
generator = MarimoIslandGenerator.from_file(
"./<notebook-name>.py", display_code=False
)

# Generate and print the HTML without building
# This will still work for basic rendering, though without running the cells
html = generator.render_html(include_init_island=False)
print(html)
# Save the HTML to a file
output_file = "output.html"
with open(output_file, "w", encoding="utf-8") as f:
f.write(html)
```

Another way is to use the Islands demo page:

```bash
pnpm dev:islands
```

Generate an HTML page with islands:

```bash
# Generate
uv run ./islands/generate.py > islands/__demo__/index.html
# Run the Vite server
pnpm dev:islands
Haleshot marked this conversation as resolved.
Show resolved Hide resolved
```
"""

Expand Down
Loading