Skip to content

marimo asgi app mounted outside root cant locate assets #8322

@iferencik

Description

@iferencik

Describe the bug

I am trying to integrate marimo with NiceGUI. My goal is to use NiceGUI to browse the local folders
and build uri to where notebooks would be deployed dynamically in a lazy manner.

I am getting 404 on assets

 127.0.0.1:33076 - "GET /marimo/global_poverty/public-files-sw.js?v=2 HTTP/1.1" 200 OK
INFO:     127.0.0.1:33058 - "GET /marimo/global_poverty/assets/settings-OBbrbhij.js HTTP/1.1" 404 Not Found
INFO:     127.0.0.1:33046 - "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 Not Found
INFO:     127.0.0.1:34238 - "GET /marimo/global_poverty/manifest.json HTTP/1.1" 200 OK
INFO:     127.0.0.1:59580 - "GET /marimo/global_poverty/assets/gradient-yHQUC_QB.png HTTP/1.1" 404 Not Found
INFO:     127.0.0.1:54280 - "GET /marimo/global_poverty/assets/bundle.esm-i_UbZC0w.js HTTP/1.1" 404 Not Found
INFO:     127.0.0.1:57134 - "GET /marimo/global_poverty/assets/noise-60BoTA8O.png HTTP/1.1" 404 Not Found
INFO:     127.0.0.1:54280 - "GET /marimo/global_poverty/android-chrome-192x192.png HTTP/1.1" 200 OK

I set uv to follow symlinks

[tool.marimo.server]
follow_symlink = true

but still can not figure it you what to do to get the assets to work. I can imagine i could mount the static folder manually or using a middleware but it seems to me this scenario is very simple not to be supported by default

For extra context i am using uv inside a docker and oauth2_proxy only as identity provider

Will you submit a PR?

  • Yes

Environment

Details
{
  "marimo": "0.19.9",
  "editable": false,
  "location": "/home/work/py/geo-careatlas/.venv/lib/python3.11/site-packages/marimo",
  "OS": "Linux",
  "OS Version": "6.14.0-37-generic",
  "Processor": "x86_64",
  "Python Version": "3.11.13",
  "Locale": "--",
  "Binaries": {
    "Browser": "--",
    "Node": "v24.7.0"
  },
  "Dependencies": {
    "click": "8.3.1",
    "docutils": "0.22.4",
    "itsdangerous": "2.2.0",
    "jedi": "0.19.2",
    "markdown": "3.10.1",
    "narwhals": "2.16.0",
    "packaging": "26.0",
    "psutil": "7.2.2",
    "pygments": "2.19.2",
    "pymdown-extensions": "10.20.1",
    "pyyaml": "6.0.3",
    "starlette": "0.52.1",
    "tomlkit": "0.14.0",
    "typing-extensions": "4.15.0",
    "uvicorn": "0.40.0",
    "websockets": "16.0"
  },
  "Optional Dependencies": {
    "loro": "1.10.3",
    "openai": "2.17.0",
    "pytest": "9.0.2"
  },
  "Experimental Flags": {}
}
📁 Project overrides from pyproject.toml

[runtime]
pythonpath = ["/home/work/py/geo-careatlas/src"]
dotenv = []

[server]
follow_symlink = true

🏠 User config 

[ai.models]
displayed_models = []
custom_models = []

[ai.custom_providers]

[mcp]
presets = []

[mcp.mcpServers]

[language_servers.pylsp]
enabled = false
enable_mypy = true
enable_ruff = true
enable_flake8 = false
enable_pydocstyle = false
enable_pylint = false
enable_pyflakes = false

[package_management]
manager = "pip"

[display]
theme = "light"
code_editor_font_size = 14
cell_output = "below"
default_width = "medium"
dataframes = "rich"
default_table_page_size = 10
default_table_max_columns = 50
reference_highlighting = true

[diagnostics]
sql_linter = true

[snippets]
custom_paths = []
include_default_snippets = true

[server]
browser = "default"
follow_symlink = false

[runtime]
auto_instantiate = false
auto_reload = "off"
reactive_tests = true
on_cell_change = "autorun"
watcher_on_save = "lazy"
output_max_bytes = 8000000
std_stream_max_bytes = 1000000
default_sql_output = "auto"
default_csv_encoding = "utf-8"

[keymap]
preset = "default"

[keymap.overrides]

[save]
autosave = "after_delay"
autosave_delay = 1000
format_on_save = false

[formatting]
line_length = 79

[completion]
activate_on_typing = true
signature_hint_on_typing = false
copilot = false

Code to reproduce

import os
from fastapi import FastAPI, Request
from nicegui import ui
import marimo

app = FastAPI()


# STANDARD SETUP
notebook_dir = os.path.abspath("./src/careatlas/notebooks")
marimo_server = (
    marimo.create_asgi_app(quiet=True)
    .with_dynamic_directory(path="/marimo", directory=notebook_dir)
    .build()
)

app.mount("/marimo", marimo_server)


@ui.page('/')
def main_page():
    ui.label('Test app').classes('text-3xl font-bold p-4')
    # Deep links now work automatically because the middleware flattens the asset requests
    ui.link('Launch deeper notebook ', '/marimo/central_and_latin_america/thematic_areas/economic_outlook/') \
        .classes('p-4 text-blue-600')
    # first level 
    ui.link('Launch first level notebok ', '/marimo/global_poverty/') \
        .classes('p-4 text-blue-600')
        

ui.run_with(app, title="Demo app", mount_path='/')



Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions