Get help from the marimo community

Updated 2 weeks ago

Dynamic App configuration

I’m developing a Marino app that is mounted in FastAPI. One of the requirements for this project is that the app needs to have different banners depending on the environment it is deployed. Currently, I’m doing something like:

Plain Text
import marimo as mo
import os 

ENV_ID = os.getenv(“ENV_ID”)

app = marimo.App(html_head_file=f"head_{ENV_ID}.html")


It works but the issue is that when in notebook editor mode, on save, marimo will remove the “import os” and ENV_ID set line. Not a blocker, just a bit cumbersome to put it back every time, but I’m wondering if there could be a formal way to support dynamic app configuration such as this.

Perhaps an app factory approach could work? Could specify path to the factory callable in .marimo.toml.

I think dynamic configuration would be really powerful for those of us using programmatic Marimo deployments.

I’m currently on marimo 0.10.14
M
m
6 comments
you might be able to do:

Plain Text
app = marimo.App(html_head_file=f"head.html")

and then in the first cell.

Plain Text
import os 
ENV_ID = os.getenv(“ENV_ID”)
mo.Html(f"""
<style>
.banner.{ENV_ID} {
  display: flex
  ...
}
</style>
""")

so you have the generic banner in head.html, but style it from the first cell
or you might be able to write a fastapi middleware that grabs the index.html and writes in the banner
The html component almost worked - I’m using sidebar and routes for SPA and the banner only spans the non-sidebar part of the app. However, now that you mention FastAPI middlewares, I’m thinking either that or creating the head.html file on startup could work. Thanks for the tip!
let me know how it goes, and if you'd be willing to share your middleware that updates the html, it could be something nice to include in our docs
Here's what I ended up doing that's working - no middleware, just some logic at initialization:

File structure.
Plain Text
src/myapp/
    pages/
        __init__.py
        custom.css
        head.html
        head_foo.html
        head_bar.html
        home.py
    __init__.py
    app.py


src/myapp/app.py
Plain Text
import os

APP_PAGES_DIR = Path(__file__).parent / "pages"

def setup_marimo_html_header():
    """Setup custom marimo html header file.

    Copy appropriate custom pages/header_*.html file to pages/head.html,
    where marimo.App expects it, based on environment.
    """
    ENV_ID = os.getenv("ENV_ID")
    if ENV_ID is None:
        return
    custom_head_html_path = (
        APP_PAGES_DIR / f"head_{ENV_ID}.html"
    )
    head_html_path = APP_PAGES_DIR / "head.html"
    shutil.copy(custom_head_html_path, head_html_path)

# Setup custom marimo html header file
setup_marimo_html_header()

# Create a marimo asgi app
server = marimo.create_asgi_app()

for app_path in sorted(map(Path, glob.glob(str(APP_PAGES_DIR / "*.py")))):
    app_name = app_path.stem
    if app_name.startswith("__"):
        continue
    server = server.with_app(path=f"/{app_name}", root=str(app_path))

# Create a FastAPI app
app = FastAPI(lifespan=app_lifespan)

app.mount("/", server.build())


src/myapp/pages/home.py
Plain Text
import marimo

__generated_with = "0.10.15"
app = marimo.App(
    width="full",
    css_file="custom.css",
    html_head_file="head.html",
)


This is a simplified version, apologies if I messed up any of the manual translation.
I don't know if this is something that could be done in lifespan instead, but this was the way to make sure it was done before marimo.App is ever loaded.
Add a reply
Sign up and join the conversation on Discord