Skip to content
Draft
Changes from 1 commit
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
86 changes: 86 additions & 0 deletions examples/frameworks/shiny/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# /// script
# requires-python = ">=3.12"
# dependencies = [
# "shiny",
# "marimo",
# "vega-datasets==0.9.0",
# ]
# ///
from shiny import App, render, ui
from htmltools import HTML
import marimo
import os
from starlette.middleware.wsgi import WSGIMiddleware
from starlette.applications import Starlette
from starlette.routing import Mount, Route
from starlette.responses import RedirectResponse


ui_dir = os.path.join(os.path.dirname(__file__), "..", "..", "ui")
templates_dir = os.path.join(os.path.dirname(__file__), "templates")

marimo_app = marimo.create_asgi_app()
app_names: list[str] = []

for filename in sorted(os.listdir(ui_dir)):
if filename.endswith(".py"):
app_name = os.path.splitext(filename)[0]
app_path = os.path.join(ui_dir, filename)
marimo_app = marimo_app.with_app(path=f"/{app_name}", root=app_path)
app_names.append(app_name)

shiny_ui = ui.page_fluid(ui.output_ui("_html"))


def shiny_server(input, output, session):
@render.text

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@render.text
@render.ui

def _html():
subdiv = []
for name in app_names:
subdiv.append(
f"""
<div class="bg-base-200 rounded-lg shadow-md hover:shadow-xl
transition-shadow duration-300 w-64">
<a href="/{name}" target="_blank" class="block w-full h-full">
<div class="p-4">
<h2 class="text-xl font-semibold mb-2">{name}</h2>
<p class="text-sm text-gray-500">Click to open app</p>
</div>
</a>
</div>
"""
)
head = """
<head>
<script src="https://cdn.tailwindcss.com" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/full.min.css"
<title>Marimo apps in Shiny</title>
</head>
"""

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To ensure this JS/CSS gets included on the page only once, put it in the UI instead:

shiny_ui = ui.page_fluid(
    ui.head_content(
        ui.tags.script(src="https://cdn.tailwindcss.com"),
        ui.tags.link(href="https://cdn.jsdelivr.net/npm/[email protected]/dist/full.min.css", rel="stylesheet"),
    ),
    ui.output_ui("_html"),
    title="Marimo apps in Shiny"
)

body = f"""
<body>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the <body> is necessary?

Suggested change
<body>

<div class="min-h-screen bg-gradient-to-br from-base-200 to-base-300 p-8">
<div class="container mx-auto px-4 py-16 bg-base-100 rounded-box shadow-xl">
<h1 class="text-4xl font-bold mb-8 text-center">Marimo dashboard in Shiny</h1>
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
{''.join(subdiv)}
</div>
</div>
</body>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
</body>
</body>
Suggested change
</body>

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for your review.

For now, script nor more works.
I'll try again tomorrow

"""
return HTML(head + body)


app = App(shiny_ui, shiny_server)


wsgi_app = WSGIMiddleware(app)

# Create the final ASGI app
asgi_app = Starlette(
routes=[
Route("/", endpoint=lambda request: RedirectResponse(url="/shiny/")),
Mount("/shiny", app=wsgi_app),
Mount("/", app=marimo_app.build()),
]
)
Loading