Skip to content

Commit 0d5321f

Browse files
fix: wasm with starlette issue (#6648)
Some of the refactors to `mpl` brought in starlette top-level which does not work for work in wasm --------- Co-authored-by: dylan <dylan@marimo.io>
1 parent 4149015 commit 0d5321f

File tree

4 files changed

+19
-10
lines changed

4 files changed

+19
-10
lines changed

marimo/_mcp/server/lifespan.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
# Copyright 2025 Marimo. All rights reserved.
22
import contextlib
33
from collections.abc import AsyncIterator
4-
5-
from starlette.applications import Starlette
4+
from typing import TYPE_CHECKING
65

76
from marimo._loggers import marimo_logger
87
from marimo._mcp.server.main import setup_mcp_server
98

109
LOGGER = marimo_logger()
1110

11+
if TYPE_CHECKING:
12+
from starlette.applications import Starlette
13+
1214

1315
@contextlib.asynccontextmanager
14-
async def mcp_server_lifespan(app: Starlette) -> AsyncIterator[None]:
16+
async def mcp_server_lifespan(app: "Starlette") -> AsyncIterator[None]:
1517
"""Lifespan for MCP server functionality (exposing marimo as MCP server)."""
1618

1719
try:

marimo/_mcp/server/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
from typing import TYPE_CHECKING
1010

1111
from mcp.server.fastmcp import FastMCP
12-
from starlette.routing import Mount
1312

1413
from marimo._ai._tools.base import ToolContext
1514
from marimo._ai._tools.tools_registry import SUPPORTED_BACKEND_AND_MCP_TOOLS
@@ -34,6 +33,7 @@ def setup_mcp_server(app: "Starlette") -> "StreamableHTTPSessionManager":
3433
Returns:
3534
StreamableHTTPSessionManager: MCP session manager
3635
"""
36+
from starlette.routing import Mount
3737

3838
mcp = FastMCP(
3939
"marimo-mcp-server",

marimo/_plugins/stateless/mpl/_mpl.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
from pathlib import Path
1818
from typing import TYPE_CHECKING, Any, Optional, Union
1919

20-
from starlette.responses import HTMLResponse, Response
21-
2220
from marimo import _loggers
2321
from marimo._output.builder import h
2422
from marimo._output.formatting import as_html
@@ -42,6 +40,7 @@
4240
from matplotlib.figure import Figure, SubFigure
4341
from starlette.applications import Starlette
4442
from starlette.requests import Request
43+
from starlette.responses import HTMLResponse, Response
4544
from starlette.websockets import WebSocket
4645

4746

@@ -222,10 +221,12 @@ def _template(fig_id: str, port: int) -> str:
222221
}
223222

224223

224+
# Toplevel for reuse in endpoints.
225225
async def mpl_js(request: Request) -> Response:
226226
from matplotlib.backends.backend_webagg_core import (
227227
FigureManagerWebAgg,
228228
)
229+
from starlette.responses import Response
229230

230231
del request
231232
return Response(
@@ -235,19 +236,23 @@ async def mpl_js(request: Request) -> Response:
235236

236237

237238
async def mpl_custom_css(request: Request) -> Response:
239+
from starlette.responses import Response
240+
238241
del request
239242
return Response(
240243
content=css_content,
241244
media_type="text/css",
242245
)
243246

244247

248+
# Over all application for handling figures on a per kernel basis
245249
def create_application() -> Starlette:
246250
import matplotlib as mpl
247251
from matplotlib.backends.backend_webagg_core import (
248252
FigureManagerWebAgg,
249253
)
250254
from starlette.applications import Starlette
255+
from starlette.responses import HTMLResponse, Response
251256
from starlette.routing import Mount, Route, WebSocketRoute
252257
from starlette.staticfiles import StaticFiles
253258
from starlette.websockets import (

marimo/_server/api/endpoints/mpl.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,12 @@
77
from typing import TYPE_CHECKING, Any, Callable, Optional
88

99
import websockets
10-
from starlette.responses import Response
11-
12-
# import StaticFiles from starlette
13-
from starlette.staticfiles import StaticFiles
1410

1511
if TYPE_CHECKING:
1612
from collections.abc import Awaitable
1713

1814
from starlette.requests import Request
15+
from starlette.responses import Response
1916
from starlette.websockets import WebSocket
2017

2118

@@ -39,6 +36,7 @@ def mpl_fallback_handler(
3936
Args:
4037
path_prefix: Prefix to add to path when calling _mpl_handler (default "")
4138
"""
39+
from starlette.responses import Response
4240

4341
def decorator(
4442
func: Callable[[Request], Awaitable[Response]],
@@ -80,6 +78,7 @@ async def mpl_static(request: Request) -> Response:
8078
from matplotlib.backends.backend_webagg_core import (
8179
FigureManagerWebAgg,
8280
)
81+
from starlette.staticfiles import StaticFiles
8382

8483
static_app = StaticFiles(
8584
directory=FigureManagerWebAgg.get_static_file_path() # type: ignore[no-untyped-call]
@@ -93,6 +92,7 @@ async def mpl_images(request: Request) -> Response:
9392
"""Fallback for image files from matplotlib."""
9493
path = request.path_params["path"]
9594
import matplotlib as mpl
95+
from starlette.staticfiles import StaticFiles
9696

9797
static_app = StaticFiles(directory=Path(mpl.get_data_path(), "images"))
9898
return await static_app.get_response(path, request.scope)
@@ -130,6 +130,8 @@ async def _mpl_handler(
130130
Returns:
131131
Response from the matplotlib server or error response
132132
"""
133+
from starlette.responses import Response
134+
133135
# Proxy to matplotlib server
134136
# Determine the target port
135137
port = figure_endpoints.get(figurenum, None)

0 commit comments

Comments
 (0)