Skip to content

Latest commit

 

History

History
187 lines (127 loc) · 4.48 KB

mep-0004.md

File metadata and controls

187 lines (127 loc) · 4.48 KB
MEP Title Discussion Implementation
4
App Configuration

App Configuration

Abstract

This MEP designs how app-specific configuration is specified.

Motivation

Marimo has several things that could be configured:

  1. editor: directory or system-wide configuration of the marimo editor, including autosave and completion.
  2. kernel: max output size allowed, run unrelated nodes in parallel, max threads
  3. server: security, watch/debug mode
  4. logger: info/warn/debug, ...
  5. app config: how a marimo app appears in the frontend

App config. This MEP lays out a design for app config only.

Some things that could be hypothetically customized:

  1. width: "normal" or "full"
  2. layout: "document", "panels", or "canvas"
  3. page title: "custom title" or None (defaults to basename)

Criteria

  • legible for humans and machines
  • editable by humans and machines
  • minimal git diffs
  • backward/forward compatible
  • easy to reproduce config when sharing

Design

Since app config is specific to a single marimo program, we propose storing it in the app's Python file. That way just the file can be passed along, carrying all settings needed to reproduce the presentation the author wanted.

App constructor, kwargs, private API.

Configuration is passed as keyword args to App constructor. This lets us keep the config options private until we have more confidence in the public API.

@dataclass
class _AppConfig:
    width: Literal["normal", "full"] = "normal"
    layout: Literal["document", "panels", "canvas"] = "document"
    page_title: Optional[str] = None

    def update(self, **kwargs):
        ...

class App:
    def __init__(self, **kwargs):
        self._config = _AppConfig().update(kwargs)
        ...

app = App(width="full", page_title="full width app")

Pros.

  • maximum API flexibility
  • maximum compatibility: marimo program will always be valid, even if some options are changed or removed (invalid options just won't have effect)
  • colocated with app file, easy to ship around.

Cons.

  • not possible for users to specify or edit app config by hand, since API is not public.

Evaluation

legible for humans and machines

  • just constructor args

editable by humans and machines

  • yes, but no public API yet ...

minimal git diffs

  • only changed when app config is changed on frontend

backward/forward compatible

  • kwargs give api flexibility (old verison of marimo will load apps made with a new version without type error, but new settings will get dropped; similar for other way around)

easy to reproduce config when sharing

  • just share app file

Alternatives considered

  1. App constructor, named arguments.
@dataclass
class _AppConfig:
    width: Literal["normal", "full"] = "normal"
    layout: Literal["document", "panels", "canvas"] = "document"
    page_title: Optional[str] = None


class App:
    def __init__(self, width="normal", layout="document", page_title=None):
        self._config = _AppConfig(width, layout, page_title)
        ...

app = App(width="full", page_title="full width app")

Pros.

  • Pythonic
  • human editable
  • easy to ship around

Cons.

  • Locks us into a public API, since App's constructor is considered public. Better be confident about the config before doing this.

Ultimately we will likely update to something like this once we're ready.

  1. App constructor, config argument.
class App:
    def __init__(self, page_config: Optional[dict[str, Any]] = None):
        self._config = _AppConfig().update(**page_config)

app = App(page_config={"width": "full",  "page_title"="my full page app"})

Pros.

  • Groups together related config settings.
  • Leaves room for other kind of config

Cons.

  • Verbose
  • Not very Pythonic (can't switch to more Pythonic alternative #1 in the future)
  1. App method (named or unnamed args).
app = App().configure(width="full", page_title="full width app")

No real benefit over just using constructor, more verbose.

  1. Separate config file.

For example, a TOML file.

[app.myapp]
width="wide"
layout="document"
page_title="a full width app"

[app.myotherapp]
width="normal"
layout="document"
page_title="a full width app"

Pros.

  • Very clean, doesn't require touching marimo program.

Cons.

  • Requires committing and shipping the TOML file for settings to be reproducible. This was a dealbreaker.