Giter Club home page Giter Club logo

marimo-team / marimo Goto Github PK

View Code? Open in Web Editor NEW
4.0K 18.0 103.0 67.81 MB

A reactive notebook for Python — run reproducible experiments, execute as a script, deploy as an app, and version with git.

Home Page: https://marimo.io

License: Apache License 2.0

Makefile 0.07% JavaScript 0.44% TypeScript 44.47% CSS 2.41% Python 51.45% HTML 0.77% MDX 0.30% Shell 0.09%
notebooks python data-science machine-learning artificial-intelligence data-visualization developer-tools reactive pipeline web-app dag dataflow

marimo's Introduction

A reactive Python notebook that's reproducible, git-friendly, and deployable as scripts or apps.

Docs · Discord · Examples

marimo is a reactive Python notebook: run a cell or interact with a UI element, and marimo automatically runs dependent cells, keeping code and outputs consistent. marimo notebooks are stored as pure Python, executable as scripts, and deployable as apps.

Highlights.

  • reactive: run a cell, and marimo automatically runs all dependent cells
  • interactive: bind sliders, tables, plots, and more to Python — no callbacks required
  • reproducible: no hidden state, deterministic execution
  • executable: execute as a Python script, parametrized by CLI args
  • shareable: deploy as an interactive web app, or run in the browser via WASM
  • git-friendly: stored as .py files
pip install marimo && marimo tutorial intro

Try marimo at our online playground, which runs entirely in the browser!

Jump to the quickstart for a primer on our CLI.

A reactive programming environment

marimo guarantees your notebook code, outputs, and program state are consistent. This solves many problems associated with traditional notebooks like Jupyter.

A reactive programming environment. Run a cell and marimo reacts by automatically running the cells that reference its variables, eliminating the error-prone task of manually re-running cells. Delete a cell and marimo scrubs its variables from program memory, eliminating hidden state.

Deterministic execution order. Notebooks are executed in a deterministic order, based on variable references instead of cells' positions on the page. Organize your notebooks to best fit the stories you'd like to tell.

Synchronized UI elements. Interact with UI elements like sliders, dropdowns, and dataframe transformers, and the cells that use them are automatically re-run with their latest values.

Performant runtime. marimo runs only those cells that need to be run by statically analyzing your code. You can optionally disable expensive cells to prevent them from automatically running.

Batteries-included. marimo comes with GitHub Copilot, Black code formatting, HTML export, fast code completion, a VS Code extension, and many more quality-of-life features.

Quickstart

Installation. In a terminal, run

pip install marimo  # or conda install -c conda-forge marimo
marimo tutorial intro

Or run in Gitpod.

Click this link to open the repo in a Gitpod Workspace:

https://gitpod.io/#https://github.com/marimo-team/marimo

Create notebooks.

Create or edit notebooks with

marimo edit

Run apps. Run your notebook as a web app, with Python code hidden and uneditable:

marimo run your_notebook.py

Execute as scripts. Execute a notebook as a script at the command line:

python your_notebook.py

Automatically convert Jupyter notebooks. Automatically convert Jupyter notebooks to marimo notebooks with the CLI

marimo convert your_notebook.ipynb > your_notebook.py

or use our web interface.

Tutorials. List all tutorials:

marimo tutorial --help

Questions?

See the FAQ at our docs.

Learn more

marimo is easy to get started with, with lots of room for power users. For example, here's an embedding visualizer made in marimo (video):

Check out our docs, the examples/ folder, and our gallery to learn more.

Tutorial Inputs Plots Layout

Contributing

We appreciate all contributions! You don't need to be an expert to help out. Please see CONTRIBUTING.md for more details on how to get started.

Questions? Reach out to us on Discord.

Community

We're building a community. Come hang out with us!

Inspiration ✨

marimo is a reinvention of the Python notebook as a reproducible, interactive, and shareable Python program, instead of an error-prone JSON scratchpad.

We believe that the tools we use shape the way we think — better tools, for better minds. With marimo, we hope to provide the Python community with a better programming environment to do research and communicate it; to experiment with code and share it; to learn computational science and teach it.

Our inspiration comes from many places and projects, especially Pluto.jl, ObservableHQ, and Bret Victor's essays. marimo is part of a greater movement toward reactive dataflow programming. From IPyflow, streamlit, TensorFlow, PyTorch, JAX, and React, the ideas of functional, declarative, and reactive programming are transforming a broad range of tools for the better.

marimo's People

Contributors

akshayka avatar baggiponte avatar bckmnn avatar chirokas avatar dbrans avatar deepyaman avatar dmadisetti avatar ericjanto avatar fuenfundachtzig avatar ideoforms avatar jettil avatar liquidcarbon avatar memtech3 avatar metaboulie avatar mohahf19 avatar mscolnick avatar pavelzw avatar renovate[bot] avatar riyavsinha avatar scls19fr avatar wasimsandhu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

marimo's Issues

Show total number of rows, columns for dataframes

Description

For large dataframes, marimo only shows a subset of the rows and columns. But the user often still wants to know how many total rows there are. We should show the total rows/columns as a footer after the dataframe.

Suggested solution

Modify the Pandas formatter to also display the total number of rows/columns, in text. For example

[ dataframe shown here ...]
406 rows x 9 columns

We can do this entirely in Python, modifying the Pandas formatter here: https://github.com/marimo-team/marimo/blob/main/marimo/_output/formatters/pandas_formatters.py#L31-L33

Alternative

No response

Additional context

No response

mo.ui.plotly: send tooltip back in selection

Description

One of our users was using reactive plotly.

Their plot had some tooltips, and they would like the tooltips to be sent back with selection.

Suggested solution

Include a "tooltip" key in the entries of fig.value

{"x": ..., "y": ..., "tooltip": ...}

Alternative

No response

Additional context

The user chose plotly (and was very happy to see it supported!) because it gives more flexibility than altair — they were plotting a graph with nodes and edges, which altair/vega does not support as far as I can tell.

Cell clock only increases when tab is active

Describe the bug

Its not necessarily a big issue, but I realized that the timer for a cells run time only increases when the tab/window is active. If I switch to another tab and then later return to the marimo tab, the clock continues at the previous earlier value and did not increase in the meantime.

Version

1.50

Code to reproduce

No response

mo.status.progress_bar: seconds/iteration, estimated time remaining

Description

Feature request on mo.status.progress_bar: It would be nice to be able to automatically display things like seconds/iteration and estimated time to completion (which are both automatically displayed in tqdm )

cc @bmeyers

Suggested solution

Both could be displayed on the right of the progress bar: Seconds/it could be a running average, and time to completion could be based on this average.

This might be awkward for very fast iterations, but tqdm has presumably designed a way to handle that, so we can study what they do.

Alternative

No response

Additional context

No response

Ploty figures can't be displayed

Describe the bug

Screenshot_20231025_195155

As the screenshot says.

Version

0.1.36

Code to reproduce

import marimo

__generated_with = "0.1.36"
app = marimo.App()


@app.cell
def __():
    import marimo as mo
    from plotly import express as px
    import numpy as np
    return mo, np, px


@app.cell
def __(np):
    x = np.linspace(0, 1, 50)
    return x,


@app.cell
def __(px, x):
    px.line(x, x)
    return


if __name__ == "__main__":
    app.run()

Reloading symbols imported with `from ... import ....`

We don't have a good way for users to reload names imported using from ... import .... We recommend that users reload modules using importlib.reload(), but that doesn't work for names.

In the interim, we could recommend

import mymodule
from mymodule import name

import importlib
importlib.reload(mymodule)

But I find that I need to run reload(mymodule) twice before name is updated with what's on disk; this is a bug, or at least very unintuitive.

Cached Virtual Files Should Not Be Optimistically Deleted

Describe the bug

Virtual Files are being optimistically deleted on cell re-run. This breaks if a user is caching HTML that used a virtual file created in a previous run of the cell.

This bug is very similar to the bug raised in #307 .

In the below video, notice how the plot doesn't update when the slider goes to the value $2$: this is because the virtual file for the quadratic plot was incorrectly deleted.

cached_virtual_files_bug.webm

Version

0.1.45

Code to reproduce

import marimo

__generated_with = "0.1.43"
app = marimo.App()


@app.cell
def __(exp):
    exp
    return


@app.cell
def __(altp, exp, mo, mplplot, plotlyplot, snsplot):
    mo.vstack(
        [
            mo.md(f"$$y=x^{exp.value}$$"),
            mo.tabs(
                {
                    "altair": mo.vstack([altp, altp.value]),
                    "plotly": plotlyplot(exp.value),
                    "seaborn": snsplot(exp.value),
                    "matplotlib": mplplot(exp.value),
                }
            ),
        ]
    )
    return


@app.cell
def __():
    import marimo as mo
    from plotly import express as px
    import altair as alt
    import numpy as np
    import pandas as pd
    import seaborn as sns
    from matplotlib import pyplot as plt
    from functools import cache
    return alt, cache, mo, np, pd, plt, px, sns


@app.cell
def __(mo):
    exp = mo.ui.slider(1, 8, 1, label="exp: ",value=8)
    return exp,


@app.cell
def __(cache, np):
    @cache
    def prep_xy(exp):
        x = np.linspace(0, 5, 100)
        return x, x**exp
    return prep_xy,


@app.cell
def __(alt, cache, mo, pd, prep_xy):
    @cache
    def altplot(exp):
        x, y = prep_xy(exp)
        data = pd.DataFrame({"x": x, "y": y})
        return mo.ui.altair_chart(
            alt.Chart(data).mark_line().encode(x="x", y="y"),
            chart_selection="interval",
        )
    return altplot,


@app.cell
def __(cache, prep_xy, px):
    @cache
    def plotlyplot(exp):
        x, y = prep_xy(exp)
        return px.line(x=x, y=y)
    return plotlyplot,


@app.cell
def __(cache, prep_xy, sns):
    @cache
    def snsplot(exp):
        x, y = prep_xy(exp)
        return sns.lineplot(x=x, y=y)
    return snsplot,


@app.cell
def __(cache, mo, plt, prep_xy):
    @cache
    def mplplot(exp):
        x, y = prep_xy(exp)
        plt.plot(x, y)
        return mo.mpl.interactive(plt.gcf())
    return mplplot,


@app.cell
def __(altplot, exp):
    altp = altplot(exp.value)
    return altp,


if __name__ == "__main__":
    app.run()

Marimo plot does not respect altair opacity parameter

Describe the bug

When plotting bar charts with Altair that have an opacity parameter, the altair_chart UI element seems to reset the opacity parameter.

Showing the Altair chart directly displays the correct figure.

chart = alt.Chart(data).mark_bar(opacity=0.5).encode(
    x='x', 
    y=alt.Y('value').stack(None), 
    color="distribution")
chart = mo.ui.altair_chart(chart)
chart

Version

0.1.39

Code to reproduce

No response

`mo.mpl.interactive` doesn't work

Describe the bug

It's just blank.
Screenshot_20231026_000211

Version

0.1.36

Code to reproduce

import marimo

__generated_with = "0.1.36"
app = marimo.App()


@app.cell
def __():
    import marimo as mo
    import numpy as np
    from matplotlib import pyplot as plt
    return mo, np, plt


@app.cell
def __(np):
    x=np.linspace(0,1,20)
    return x,


@app.cell
def __(plt, x):
    plt.plot(x,x)
    return


@app.cell
def __(mo, plt):
    mo.mpl.interactive(plt.gcf())
    return


if __name__ == "__main__":
    app.run()

Pyodide kernel support, for serverless operation

Description

Pyodide is python compiled into web assembly. This allows running the interpreter in a web worker within the browser.
JupyterLite is a modification that runs the entire jupyter IDE in the browser.
There are some limitations - e.g., file system access / storage is a mess and browser support varies.
Nevertheless, this allows for highly scalable solutions, as there are only static files to be served.

Suggested solution

Add a pyodide kernel as an alternative to allow serverless operation.

Alternative

No response

Additional context

No response

Raised exception after dragging the slider backwards

Describe the bug

Kooha-2023-11-06-19-40-20.webm

I found that exception only occurs when I drag the slider backwards.

When the slider starts at 8 (the right end), the same error will occur when I drag it back, towards right.

Version

0.1.43

Code to reproduce

the same plot.py

import marimo

__generated_with = "0.1.43"
app = marimo.App()


@app.cell
def __(exp):
    exp
    return


@app.cell
def __(altp, exp, mo, mplplot, plotlyplot, snsplot):
    mo.vstack(
        [
            mo.md(f"$$y=x^{exp.value}$$"),
            mo.tabs(
                {
                    "altair": mo.vstack([altp, altp.value]),
                    "plotly": plotlyplot(exp.value),
                    "seaborn": snsplot(exp.value),
                    "matplotlib": mplplot(exp.value),
                }
            ),
        ]
    )
    return


@app.cell
def __():
    import marimo as mo
    from plotly import express as px
    import altair as alt
    import numpy as np
    import pandas as pd
    import seaborn as sns
    from matplotlib import pyplot as plt
    from functools import cache
    return alt, cache, mo, np, pd, plt, px, sns


@app.cell
def __(mo):
    exp = mo.ui.slider(1, 8, 1, label="exp: ",value=8)
    return exp,


@app.cell
def __(cache, np):
    @cache
    def prep_xy(exp):
        x = np.linspace(0, 5, 100)
        return x, x**exp
    return prep_xy,


@app.cell
def __(alt, cache, mo, pd, prep_xy):
    @cache
    def altplot(exp):
        x, y = prep_xy(exp)
        data = pd.DataFrame({"x": x, "y": y})
        return mo.ui.altair_chart(
            alt.Chart(data).mark_line().encode(x="x", y="y"),
            chart_selection="interval",
        )
    return altplot,


@app.cell
def __(cache, prep_xy, px):
    @cache
    def plotlyplot(exp):
        x, y = prep_xy(exp)
        return px.line(x=x, y=y)
    return plotlyplot,


@app.cell
def __(cache, prep_xy, sns):
    @cache
    def snsplot(exp):
        x, y = prep_xy(exp)
        return sns.lineplot(x=x, y=y)
    return snsplot,


@app.cell
def __(cache, mo, plt, prep_xy):
    @cache
    def mplplot(exp):
        x, y = prep_xy(exp)
        plt.plot(x, y)
        return mo.mpl.interactive(plt.gcf())
    return mplplot,


@app.cell
def __(altplot, exp):
    altp = altplot(exp.value)
    return altp,


if __name__ == "__main__":
    app.run()

pip install error installing example dependencies

Describe the bug

I ran pip install -r requirements.txt in the examples folder and got the following error:

Collecting osqp>=0.6.2
Downloading osqp-0.6.3.tar.gz (228 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 228.4/228.4 KB 16.0 MB/s eta 0:00:00
Installing build dependencies ... error
error: subprocess-exited-with-error

× pip subprocess to install build dependencies did not run successfully.
│ exit code: 1
╰─> [113 lines of output]
Collecting oldest-supported-numpy
Downloading oldest_supported_numpy-2023.10.25-py3-none-any.whl (4.9 kB)
Collecting setuptools>=40.8.0
Downloading setuptools-69.0.2-py3-none-any.whl (819 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 819.5/819.5 KB 5.0 MB/s eta 0:00:00
Collecting wheel
Downloading wheel-0.42.0-py3-none-any.whl (65 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 65.4/65.4 KB 7.1 MB/s eta 0:00:00
Collecting setuptools_scm>=6.2
Downloading setuptools_scm-8.0.4-py3-none-any.whl (42 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 42.1/42.1 KB 5.8 MB/s eta 0:00:00
Collecting qdldl
Downloading qdldl-0.1.7.post0.tar.gz (70 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 71.0/71.0 KB 10.8 MB/s eta 0:00:00
Installing build dependencies: started
Installing build dependencies: finished with status 'done'
Getting requirements to build wheel: started
Getting requirements to build wheel: finished with status 'done'
Installing backend dependencies: started
Installing backend dependencies: finished with status 'done'
Preparing metadata (pyproject.toml): started
Preparing metadata (pyproject.toml): finished with status 'done'
Collecting numpy==1.21.6
Downloading numpy-1.21.6-cp310-cp310-macosx_11_0_arm64.whl (12.4 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 12.4/12.4 MB 38.6 MB/s eta 0:00:00
Collecting packaging>=20
Using cached packaging-23.2-py3-none-any.whl (53 kB)
Collecting tomli>=1
Using cached tomli-2.0.1-py3-none-any.whl (12 kB)
Collecting typing-extensions
Using cached typing_extensions-4.9.0-py3-none-any.whl (32 kB)
Collecting scipy>=0.13.2
Downloading scipy-1.11.4-cp310-cp310-macosx_12_0_arm64.whl (29.8 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 29.8/29.8 MB 48.6 MB/s eta 0:00:00
Building wheels for collected packages: qdldl
Building wheel for qdldl (pyproject.toml): started
Building wheel for qdldl (pyproject.toml): finished with status 'error'
error: subprocess-exited-with-error

    × Building wheel for qdldl (pyproject.toml) did not run successfully.
    │ exit code: 1
    ╰─> [65 lines of output]
        running bdist_wheel
        running build
        running build_ext
        Traceback (most recent call last):
          File "<string>", line 81, in build_extensions
          File "/Users/davidarbirk/miniforge3/lib/python3.10/subprocess.py", line 420, in check_output
            return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
          File "/Users/davidarbirk/miniforge3/lib/python3.10/subprocess.py", line 501, in run
            with Popen(*popenargs, **kwargs) as process:
          File "/Users/davidarbirk/miniforge3/lib/python3.10/subprocess.py", line 966, in __init__
            self._execute_child(args, executable, preexec_fn, close_fds,
          File "/Users/davidarbirk/miniforge3/lib/python3.10/subprocess.py", line 1842, in _execute_child
            raise child_exception_type(errno_num, err_msg, err_filename)
        FileNotFoundError: [Errno 2] No such file or directory: 'cmake'
  
        During handling of the above exception, another exception occurred:
  
        Traceback (most recent call last):
          File "/var/folders/xp/9tpdfsb14h19rmvd1prj9d9h0000gn/T/tmp_isdzniu_in_process.py", line 363, in <module>
            main()
          File "/var/folders/xp/9tpdfsb14h19rmvd1prj9d9h0000gn/T/tmp_isdzniu_in_process.py", line 345, in main
            json_out['return_val'] = hook(**hook_input['kwargs'])
          File "/var/folders/xp/9tpdfsb14h19rmvd1prj9d9h0000gn/T/tmp_isdzniu_in_process.py", line 261, in build_wheel
            return _build_backend().build_wheel(wheel_directory, config_settings,
          File "/private/var/folders/xp/9tpdfsb14h19rmvd1prj9d9h0000gn/T/pip-build-env-xs99b8zu/overlay/lib/python3.10/site-packages/setuptools/build_meta.py", line 404, in build_wheel
            return self._build_with_temp_dir(
          File "/private/var/folders/xp/9tpdfsb14h19rmvd1prj9d9h0000gn/T/pip-build-env-xs99b8zu/overlay/lib/python3.10/site-packages/setuptools/build_meta.py", line 389, in _build_with_temp_dir
            self.run_setup()
          File "/private/var/folders/xp/9tpdfsb14h19rmvd1prj9d9h0000gn/T/pip-build-env-xs99b8zu/overlay/lib/python3.10/site-packages/setuptools/build_meta.py", line 311, in run_setup
            exec(code, locals())
          File "<string>", line 113, in <module>
          File "/private/var/folders/xp/9tpdfsb14h19rmvd1prj9d9h0000gn/T/pip-build-env-xs99b8zu/overlay/lib/python3.10/site-packages/setuptools/__init__.py", line 103, in setup
            return distutils.core.setup(**attrs)
          File "/private/var/folders/xp/9tpdfsb14h19rmvd1prj9d9h0000gn/T/pip-build-env-xs99b8zu/overlay/lib/python3.10/site-packages/setuptools/_distutils/core.py", line 185, in setup
            return run_commands(dist)
          File "/private/var/folders/xp/9tpdfsb14h19rmvd1prj9d9h0000gn/T/pip-build-env-xs99b8zu/overlay/lib/python3.10/site-packages/setuptools/_distutils/core.py", line 201, in run_commands
            dist.run_commands()
          File "/private/var/folders/xp/9tpdfsb14h19rmvd1prj9d9h0000gn/T/pip-build-env-xs99b8zu/overlay/lib/python3.10/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands
            self.run_command(cmd)
          File "/private/var/folders/xp/9tpdfsb14h19rmvd1prj9d9h0000gn/T/pip-build-env-xs99b8zu/overlay/lib/python3.10/site-packages/setuptools/dist.py", line 963, in run_command
            super().run_command(command)
          File "/private/var/folders/xp/9tpdfsb14h19rmvd1prj9d9h0000gn/T/pip-build-env-xs99b8zu/overlay/lib/python3.10/site-packages/setuptools/_distutils/dist.py", line 988, in run_command
            cmd_obj.run()
          File "/private/var/folders/xp/9tpdfsb14h19rmvd1prj9d9h0000gn/T/pip-build-env-xs99b8zu/normal/lib/python3.10/site-packages/wheel/bdist_wheel.py", line 368, in run
            self.run_command("build")
          File "/private/var/folders/xp/9tpdfsb14h19rmvd1prj9d9h0000gn/T/pip-build-env-xs99b8zu/overlay/lib/python3.10/site-packages/setuptools/_distutils/cmd.py", line 318, in run_command
            self.distribution.run_command(command)
          File "/private/var/folders/xp/9tpdfsb14h19rmvd1prj9d9h0000gn/T/pip-build-env-xs99b8zu/overlay/lib/python3.10/site-packages/setuptools/dist.py", line 963, in run_command
            super().run_command(command)
          File "/private/var/folders/xp/9tpdfsb14h19rmvd1prj9d9h0000gn/T/pip-build-env-xs99b8zu/overlay/lib/python3.10/site-packages/setuptools/_distutils/dist.py", line 988, in run_command
            cmd_obj.run()
          File "/private/var/folders/xp/9tpdfsb14h19rmvd1prj9d9h0000gn/T/pip-build-env-xs99b8zu/overlay/lib/python3.10/site-packages/setuptools/_distutils/command/build.py", line 131, in run
            self.run_command(cmd_name)
          File "/private/var/folders/xp/9tpdfsb14h19rmvd1prj9d9h0000gn/T/pip-build-env-xs99b8zu/overlay/lib/python3.10/site-packages/setuptools/_distutils/cmd.py", line 318, in run_command
            self.distribution.run_command(command)
          File "/private/var/folders/xp/9tpdfsb14h19rmvd1prj9d9h0000gn/T/pip-build-env-xs99b8zu/overlay/lib/python3.10/site-packages/setuptools/dist.py", line 963, in run_command
            super().run_command(command)
          File "/private/var/folders/xp/9tpdfsb14h19rmvd1prj9d9h0000gn/T/pip-build-env-xs99b8zu/overlay/lib/python3.10/site-packages/setuptools/_distutils/dist.py", line 988, in run_command
            cmd_obj.run()
          File "/private/var/folders/xp/9tpdfsb14h19rmvd1prj9d9h0000gn/T/pip-build-env-xs99b8zu/overlay/lib/python3.10/site-packages/setuptools/command/build_ext.py", line 88, in run
            _build_ext.run(self)
          File "/private/var/folders/xp/9tpdfsb14h19rmvd1prj9d9h0000gn/T/pip-build-env-xs99b8zu/overlay/lib/python3.10/site-packages/setuptools/_distutils/command/build_ext.py", line 345, in run
            self.build_extensions()
          File "<string>", line 83, in build_extensions
        RuntimeError: CMake must be installed to build qdldl
        [end of output]
  
    note: This error originates from a subprocess, and is likely not a problem with pip.
    ERROR: Failed building wheel for qdldl
  Failed to build qdldl
  ERROR: Could not build wheels for qdldl, which is required to install pyproject.toml-based projects
  [end of output]

note: This error originates from a subprocess, and is likely not a problem with pip.
error: subprocess-exited-with-error

× pip subprocess to install build dependencies did not run successfully.
│ exit code: 1
╰─> See above for output.

note: This error originates from a subprocess, and is likely not a problem with pip.

Environment

(base) ➜ examples git:(main) marimo env
{
"marimo": "0.1.64",
"OS": "Darwin",
"OS Version": "23.1.0",
"Python Version": "3.10.4",
"Binaries": {
"Chrome": "120.0.6099.71",
"Node": "v18.7.0"
},
"Requirements": {
"black": "23.11.0",
"click": "8.1.7",
"jedi": "0.18.1",
"pymdown-extensions": "10.5",
"tomlkit": "0.12.3",
"tornado": "6.2",
"typing_extensions": "4.9.0"
}
}

Code to reproduce

pip install -r requirements.txt

Error converting from Jupyter notebooks

Describe the bug

When converting a Jupyter markdown cell that contains Latex math equations, any equation containing a single backslash results in an invalid mo.md string. Backslashes should be doubled up in order to prevent the python parser from capture the first letter and creating a non-ascii character.

Environment

{
"marimo": "0.1.58",
"OS": "Darwin",
"OS Version": "22.4.0",
"Python Version": "3.11.6",
"Binaries": {
"Chrome": "119.0.6045.199",
"Node": "v16.17.1"
},
"Requirements": {
"black": "23.10.1",
"click": "8.1.6",
"jedi": "0.19.0",
"pymdown-extensions": "10.3.1",
"tomlkit": "0.12.1",
"tornado": "6.3.2",
"typing_extensions": "4.8.0"
}
}

Code to reproduce

Notebook code:

{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "f1f39bf9-3f67-40f3-8e92-d386ed883fea",
   "metadata": {},
   "source": [
    "$a \\approx b$"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}

Marimo code:

import marimo

__generated_with = "0.1.58"
app = marimo.App()


@app.cell
def _(mo):
    mo.md(
        """
        $a \approx b$
        """
    )
    return


@app.cell
def _():
    import marimo as mo
    return mo,


if __name__ == "__main__":
    app.run()

Spurious cycle detection when classes are only used in annotations

Describe the bug

I was defining some classes that have methods that depend on each other, in different cells, and marimo claimed that there were cyclic dependencies between cells. This makes it somewhat less convenient than I'd like to use annotations.

It appears that the code is parsed with annotations as strings, so any value that's only used in annotations shouldn't factor into dependency ordering.

Environment

{
  "marimo": "0.1.58",
  "OS": "Linux",
  "OS Version": "5.15.0-89-generic",
  "Python Version": "3.12.0",
  "Binaries": {
    "Chrome": "--",
    "Node": "v19.8.1"
  },
  "Requirements": {
    "black": "23.11.0",
    "click": "8.1.7",
    "jedi": "0.19.1",
    "pymdown-extensions": "10.4",
    "tomlkit": "0.12.2",
    "tornado": "6.3.3",
    "typing_extensions": "4.8.0"
  }
}

Code to reproduce

import marimo

__generated_with = "0.1.58"
app = marimo.App()


@app.cell
def __(B):
    class A:
        def use_b(self, b: B) -> None:
            ...
    return A,


@app.cell
def __(A):
    class B:
        def use_a(self, a: A) -> None:
            ...
    return B,


@app.cell
def __():
    return


if __name__ == "__main__":
    app.run()

Blinking of `altair` plots when value changes

Describe the bug

plot.webm

There is unpleasant visual blinking for the altair plot, but not for matplotlib and seaborn plot.

Confirmed blinking using either plain altair chart and marimo.ui.altair_chart.

Version

0.1.36

Code to reproduce

No response

feature request: a variable table like Jupyter Variable Explorer

Description

Variable Explorer will be very helpful for debugging and improve UX.

It may visualize variables with their data graph dependencies as a further enhancement.

Suggested solution

provide a table for visualizing variables and/or data graph dependencies for better ux

Alternative

No response

Additional context

No response

Additional mapping support

Description

Hi

I work with geospatial data and find leafmap, geemap, etc. useful. Any integration would help!
There is also a nice demonstrator of different mapping libraries here for example.

Suggested solution

Deeper integration with mapping libraries. I personally have been using leafmap.

Alternative

No response

Additional context

No response

🙋 Have feedback? Get in touch!

Hi! 👋 Thanks for your interest in marimo. We're excited you're here as we discover and build the future of Python notebooks — made for humans like you.

We want to hear from you: from minor bug reports or usability issues, to your most hoped-for wishlist features, and everything in between. Here are some ways you can get in touch:

  1. 🔨 Bug reports/feature requests: Open a Github issue.
  2. 🙋 Help and free-flowing conversation: Hop into our Discord and chat with us in real-time.

Is it possible to recover overwritten marimo notebooks (`.py` files)?

Describe the bug

Is it possible to recover overwritten marimo notebooks (.py files)? I launched two different scripts in the same port and one overwrote the other, it seems.

Longer version/more details:
I was working in VS code (version 1.84.2) with a remote ssh connection. In the terminal of the ssh machine, I typed marimo edit remote_script.py which launched localhost:2718 (the default) in my local browser. I edited and saved there, with the "Notebook saved" notification on the bottom right corner popping up often.

I have, at the same time, another VS code window open that is local. When I typed marimo edit different_script.py in the terminal (of this local window) where different_script.py is a blank script, it launched to localhost:2718 in my local browser again by default, because I meant to but forgot to specify a port. Unfortunately, this action seemed to have overwritten the remote_scripty.py in my remote session.

I have tried a few different ways to recover the saving history, including looking at VS code Timeline/local history. The most recent save is my latest commit, ~2 days ago. I am able to see the edit history of my other scripts in the past two days though.

Thank you!

Version

0.1.43

Code to reproduce

No response

Rendering 10,000 accordions crashes the browser

Describe the bug

A user attempted to render 10,000 accordions in a single output. The marimo frontend took a long time attempting to show the output, Chrome said the page was unresponsive, and then the browser crashed, bringing down all open tabs. The server however was still running. The user can reproduce this reliably.

Probably not good practice to render such a large output. But is there anything we can do to prevent this from crashing the browser?

Version

0.1.41

Code to reproduce

import marimo

__generated_with = "0.1.47"
app = marimo.App()


@app.cell
def __():
    import marimo as mo
    return mo,


@app.cell
def __(mo):
    count = mo.ui.slider(0, 1000)
    count
    return count,


@app.cell
def __(count, mo):
    # render a count of accordions
    views = []
    for i in range(count.value):
        views.append(
            mo.accordion(
                {
                    "title": "Accordion {}".format(i),
                    "content": [
                        mo.ui.text("Accordion {}".format(i)),
                        mo.ui.text("Accordion {}".format(i)),
                        mo.ui.text("Accordion {}".format(i)),
                    ],
                }
            )
        )

    mo.vstack(views)
    return i, views


if __name__ == "__main__":
    app.run()

Embedded PDF viewer

Description

Would love a marimo.ui component which allows me to embed PDFs in a Marimo notebook, and ideally allows me to determine which part of the PDF to start at.

Suggested solution

Open to what you guys come up with.

Alternative

Have considered just printing plain text.

Additional context

Context is that I am building an LLM-enabled information retrieval app.

[Windows] mpl.interactive does not work

This issue was being discussed in #260, but is separate from the original issue in that thread. So creating a new issue to track.

A user said that on the latest version of chrome, marimo 0.1.39, the only plot that shows up for the below code is seaborn. I am unable to repro.

import marimo

__generated_with = "0.1.38"
app = marimo.App()


@app.cell
def __(exp):
    exp
    return


@app.cell
def __(altp, exp, mo, mplplot, plotlyplot, snsplot):
    mo.vstack(
        [
            mo.md(f"$$y=x^{exp.value}$$"),
            mo.tabs(
                {
                    "altair": mo.vstack([altp, altp.value]),
                    "plotly": plotlyplot(exp.value),
                    "seaborn": snsplot(exp.value),
                    "matplotlib": mplplot(exp.value),
                }
            ),
        ]
    )
    return


@app.cell
def __():
    import marimo as mo
    from plotly import express as px
    import altair as alt
    import numpy as np
    import pandas as pd
    import seaborn as sns
    from matplotlib import pyplot as plt
    from functools import cache
    return alt, cache, mo, np, pd, plt, px, sns


@app.cell
def __(mo):
    exp = mo.ui.slider(1, 8, 1, label="exp: ")
    return exp,


@app.cell
def __(cache, np):
    @cache
    def prep_xy(exp):
        x = np.linspace(0, 5, 100)
        return x, x**exp
    return prep_xy,


@app.cell
def __(alt, cache, mo, pd, prep_xy):
    @cache
    def altplot(exp):
        x, y = prep_xy(exp)
        data = pd.DataFrame({"x": x, "y": y})
        return mo.ui.altair_chart(
            alt.Chart(data).mark_line().encode(x="x", y="y"),
            chart_selection="interval",
        )
    return altplot,


@app.cell
def __(cache, prep_xy, px):
    @cache
    def plotlyplot(exp):
        x, y = prep_xy(exp)
        return px.line(x=x, y=y)
    return plotlyplot,


@app.cell
def __(cache, prep_xy, sns):
    @cache
    def snsplot(exp):
        x, y = prep_xy(exp)
        return sns.lineplot(x=x, y=y)
    return snsplot,


@app.cell
def __(cache, mo, plt, prep_xy):
    @cache
    def mplplot(exp):
        x, y = prep_xy(exp)
        plt.plot(x, y)
        return mo.mpl.interactive(plt.gcf())
    return mplplot,


@app.cell
def __(altplot, exp):
    altp = altplot(exp.value)
    return altp,


if __name__ == "__main__":
    app.run()

Asyncio error when hosting marimo behind google IAP

Describe the bug

Hey Marimo team,

We've been trying to host a Marimo notebook (using marimo run) in Google Cloud/Kubernetes, and have run into this issue which seems internal to Marimo. (see error log below). The template page loads, but none of the subsequent api calls to actually run the notebook code seem to work. For context, I've been able to successfully load this notebook locally, and have also successfully loaded it when port forwarding to the kubernetes service (the same one behind the public endpoint). But when we run it with our public endpoint, I get this error.

On a possibly related note, we have Google IAP handling auth for the public endpoint, which I think causes the websockets requests to fail (since they can't authenticate) and fallback to http requests. I see a lot of /api/kernel/instantiate/ requests failing with 404, for example (but some get 200).

Any ideas you might have here would be much appreciated. Thanks!

ERROR:asyncio:Exception in callback None() 
handle: <Handle cancelled>
Traceback (most recent call last):      
  File "/usr/lib/python3.10/asyncio/events.py", line 80, in _run         
    self._context.run(self._callback, *self._args)
  File "/.../python/.venv/lib/python3.10/site-packages/tornado/platform/asyncio.py", line 192, in _handle_events
    handler_func(fileobj, events)      
  File "/.../python/.venv/lib/python3.10/site-packages/marimo/server/sessions.py", line 207, in reader
    (op, data) = self.read_conn.recv() 
  File "/usr/lib/python3.10/multiprocessing/connection.py", line 250, in recv
    buf = self._recv_bytes()           
  File "/usr/lib/python3.10/multiprocessing/connection.py", line 421, in _recv_bytes             
    return self._recv(size)            
  File "/usr/lib/python3.10/multiprocessing/connection.py", line 379, in _recv
    chunk = read(handle, remaining)    
OSError: [Errno 9] Bad file descriptor 

Version

marimo-0.0.1a0-py3-none-any.whl

Code to reproduce

No response

mo.ui.multiselect results don't reflect the current textbox

Describe the bug

Screen.Recording.2023-12-11.at.6.08.36.PM.mov

When filtering in the multiselect, results don't show unless you explicitly delete the text contents -- if you select all text and type over it (without pushing delete), nothing shows up even if the text in the search box matches.

Environment

{
  "marimo": "0.1.64",
  "OS": "Darwin",
  "OS Version": "22.6.0",
  "Python Version": "3.11.4",
  "Binaries": {
    "Chrome": "120.0.6099.71",
    "Node": "v20.3.1"
  },
  "Requirements": {
    "black": "23.10.1",
    "click": "8.1.7",
    "jedi": "0.19.1",
    "pymdown-extensions": "10.3.1",
    "tomlkit": "0.12.1",
    "tornado": "6.3.3",
    "typing_extensions": "4.8.0"
  }
}

Code to reproduce

import marimo as mo
multiselect = mo.ui.multiselect(options=["A", "AA", "B"])
multiselect

Search for "A", then select all text and type "B"

Multiselect filter doesn't search consecutively

Describe the bug

Screen.Recording.2023-12-12.at.3.39.04.PM.mov

Not clear how the filtering works. I would expect it to search by substring, but searching foo also returns the result farboo.

Environment

{
"marimo": "0.1.65",
"OS": "Darwin",
"OS Version": "22.6.0",
"Processor": "arm",
"Python Version": "3.11.4",
"Binaries": {
"Chrome": "120.0.6099.71",
"Node": "v20.3.1"
},
"Requirements": {
"black": "23.10.1",
"click": "8.1.7",
"jedi": "0.19.1",
"pymdown-extensions": "10.3.1",
"tomlkit": "0.12.1",
"tornado": "6.3.3",
"typing_extensions": "4.8.0"
}
}

Code to reproduce

import marimo as mo
multiselect = mo.ui.multiselect(["foo", "farboo"])
multiselect

Mobile layout, full width, and hamburger menu issues

Describe the bug

A few things I've noticed when using marimo on mobile:

The hamburger/settings buttons overlap the title sometimes.
Tapping the hamburger menu doesn't keep it open, you have to long-press on it to get it to stay open when you lift your finger.

With full width off in portrait, the block is cut off to the right, but is roughly the full width of the screen:
image

When you fill the block with text, it scrolls the page to the right, but you cannot manually scroll right/left:
image

With full width on in portrait, the block gets tiny:
image

In landscape, full width on/off makes essentially no difference:
Screenshot_20231104_142110_Firefox
Screenshot_20231104_142132_Firefox

These are from Firefox, but the same behavior happens in Chrome, other than the hamburger menu long press issue.

Version

0.1.43

Code to reproduce

No response

Cells run infinitely when including import of mpi4py

Describe the bug

When a cell imports mpi4py or any library importing it, the cell will execute but infinitely run on. Interestingly this only happens when importing MPI from mpi4py, not when importing mpi4py alone. Also note that code after the import will still execute, but the cell never stops thus preventing later cells from executing at all.

Now, one might say that this should not be an issue since why would you use mpi with marimo anyways, but the issue is that many libraries offer support for mpi4py, often importing it as follows:

try:
    from mpi4py import MPI
except:
    MPI = None

and thereby making mpi optional. This works perfectly well outside of marimo, but even the import in the try statement will cause the cell to run forever when executed in marimo.

Version

1.50

Code to reproduce

from mpi4py import MPI 

Dark mode

Description

Add a dark mode to reduce eye fatigue, especially at night.

Suggested solution

Maybe adding a switch to toggle? I think it can be useful in both app and script mode.

Alternative

Maybe adding theme support in the long term?

Additional context

No response

Showing Pandas DataFrame crashes marimo

Describe the bug

When I display a DataFrame with a lot of rows, e.g. California housing dataset directly, marimo is getting really unresponsive.

I would expect to add a pagination or show the first and last few rows (like Jupyter does).

If you can point me in the right direction, I'm happy to help!

Version

0.1.47

Code to reproduce

import marimo
 
__generated_with = "0.1.47"
app = marimo.App()
 
 
@app.cell
def __():
    from sklearn.datasets import fetch_california_housing
    return fetch_california_housing,
 
 
@app.cell
def __(fetch_california_housing):
    data = fetch_california_housing(as_frame=True)
    return data,
 
 
@app.cell
def __(data):
    data.get("data")
    return

Progress bar cell marked stale in preview mode

Describe the bug

Screenshot 2023-12-11 at 6 04 51 PM

Progress bar is marked stale in preview mode when cell is running, but not in edit mode

Environment

{
"marimo": "0.1.64",
"OS": "Darwin",
"OS Version": "22.6.0",
"Python Version": "3.11.4",
"Binaries": {
"Chrome": "120.0.6099.71",
"Node": "v20.3.1"
},
"Requirements": {
"black": "23.10.1",
"click": "8.1.7",
"jedi": "0.19.1",
"pymdown-extensions": "10.3.1",
"tomlkit": "0.12.1",
"tornado": "6.3.3",
"typing_extensions": "4.8.0"
}
}

Code to reproduce

import marimo

__generated_with = "0.1.64"
app = marimo.App()


@app.cell
def __():
    import time
    return time,


@app.cell
def __():
    import marimo as mo
    return mo,


@app.cell
def __(mo, time):
    for i in mo.status.progress_bar(range(10)):
        time.sleep(1)
    return i,


if __name__ == "__main__":
    app.run()

ProgressBar has no attribute _virtual_filenames

Describe the bug

Exception ignored in: <function Html.del at 0x1036b5670>
Traceback (most recent call last):
File "/Users/akshay/envs/playground/lib/python3.9/site-packages/marimo/_output/hypertext.py", line 104, in del
for f in self._virtual_filenames:
AttributeError: 'ProgressBar' object has no attribute '_virtual_filenames'

Version

0.1.46

Code to reproduce

No response

Simple entry point for a group of "notebooks"

Description

I am hoping to get something in the spirit of JupyterBooks

Suggested solution

This could initially be a simple webpage with hyperlinks into the different notebooks

Alternative

No response

Additional context

No response

3.12 Type Parameter syntax fix only applies to class-level parameters, not function/method level

Describe the bug

This is basically an extension of #388. That PR correctly handles class Klass[T], but it doesn't handle def func[T]; such variables are still interpreted as refs.

Environment

{
  "marimo": "0.1.63",
  "OS": "Linux",
  "OS Version": "5.15.0-89-generic",
  "Python Version": "3.12.0",
  "Binaries": {
    "Chrome": "--",
    "Node": "v21.2.0"
  },
  "Requirements": {
    "black": "23.11.0",
    "click": "8.1.7",
    "jedi": "0.19.1",
    "pymdown-extensions": "10.4",
    "tomlkit": "0.12.2",
    "tornado": "6.3.3",
    "typing_extensions": "4.8.0"
  }
}

Code to reproduce

import marimo

__generated_with = "0.1.63"
app = marimo.App()


@app.cell
def __(T):
    class Test:
        def test[T](self, t: T) -> T:
            return t
    return Test,


@app.cell
def __(U):
    def test[U](u: U) -> U:
        return u
    return test,


@app.cell
def __():
    return


if __name__ == "__main__":
    app.run()

None of the cells should take arguments.

`from x import *` results in invalid Python file

Describe the bug

Using import * results in an invalid .py file: import * can only be used at module level, but marimo puts it in a function.

We may have to disallow * imports in marimo. They are not great practice anyway, since they add invisible names to globals that marimo cannot track

cc @bmeyers

Environment

{
  "marimo": "0.1.56",
  "OS": "Linux",
  "OS Version": "6.2.0-36-generic",
  "Python Version": "3.10.12",
  "Binaries": {
    "Chrome": "119.0.6045.159",
    "Node": "v18.13.0"
  },
  "Requirements": {
    "black": "23.3.0",
    "click": "8.1.3",
    "jedi": "0.19.0",
    "pymdown-extensions": "10.3",
    "tomlkit": "0.12.1",
    "tornado": "6.3.3",
    "typing_extensions": "4.8.0"
  }
}

Code to reproduce

No response

Automatically executing cells based on a timer

Description

I have a use case for a dashboard where I would like to fetch data through an API and have plots/cards displayed for various parameters, say weather, energy, etc.

PS: Loving the app!

Suggested solution

To implement this, it would be great if for some cells, we could specify a refresh rate so that they automatically get executed after a certain interval, thus updating data on the frontend.

Alternative

No response

Additional context

No response

VSCode extension should detect python project root

Describe the bug

I have a marimo notebook in a VSCode workspace where the python project root is not the directory root.
The marimo extension runs the marimo notebook in the directory root and thus fails to find any installed modules.

Environment

{
"marimo": "0.1.55",
"OS": "Darwin",
"OS Version": "23.1.0",
"Python Version": "3.11.5",
"Binaries": {
"Chrome": "119.0.6045.159",
"Node": "v18.18.2"
},
"Requirements": {
"black": "23.11.0",
"click": "8.1.7",
"jedi": "0.19.1",
"pymdown-extensions": "10.4",
"tomlkit": "0.12.3",
"tornado": "6.3.3",
"typing_extensions": "4.8.0"
}
}

Code to reproduce

No response

password required when logging in

Description

hi 👋, I just started trying marimo.

I deployed this as a public service on the server, considering that there might be some security risks. I'm hoping to restrict logins in some way.

Not sure if I've missed something, if marimo can do this please point it out.

Thank you for your great work!

Suggested solution

If a password is set in the configuration, you need to provide the password to enter marimo.

Alternative

No response

Additional context

No response

Use an elementary list of files in the current directory

Description

I want to jump between different *.py files on the fly without the need to restart the marimo server

Suggested solution

A little window on the left that may disappear and pop up whenever user is hovering over the left area of the screen

Alternative

No response

Additional context

No response

Confusing error related to UI element deletion

Describe the bug

Exception ignored in: <function UIElement.__del__ at 0x108939940>
Traceback (most recent call last):
  File "/Users/delenn/.pyenv/versions/notebook/lib/python3.11/site-packages/marimo/_plugins/ui/_core/ui_element.py", line 213, in __del__
    ctx.ui_element_registry.delete(self._id, id(self))
                                   ^^^^^^^^
AttributeError: 'table' object has no attribute '_id'

(Reported by a user)

Environment

{
"marimo": "0.1.65",
"OS": "Darwin",
"OS Version": "22.6.0",
"Processor": "arm",
"Python Version": "3.11.4",
"Binaries": {
"Chrome": "120.0.6099.71",
"Node": "v20.3.1"
},
"Requirements": {
"black": "23.10.1",
"click": "8.1.7",
"jedi": "0.19.1",
"pymdown-extensions": "10.3.1",
"tomlkit": "0.12.1",
"tornado": "6.3.3",
"typing_extensions": "4.8.0"
}
}

Code to reproduce

Difficult to reproduce ...

Reactive update issue in list comprehension

Describe the bug

I want to write a simple item counter, and to layout the buttons, I used batch with list comprehension, but it doesn't update properly.
Kooha-2023-11-28-15-23-35.webm

Environment

{
  "marimo": "0.1.60",
  "OS": "Linux",
  "OS Version": "6.1.62-1-MANJARO",
  "Python Version": "3.11.6",
  "Binaries": {
    "Chrome": "--",
    "Node": "v20.2.0"
  },
  "Requirements": {
    "black": "23.10.1",
    "click": "8.1.6",
    "jedi": "0.18.2",
    "pymdown-extensions": "10.3.1",
    "tomlkit": "0.12.1",
    "tornado": "6.3.2",
    "typing_extensions": "4.8.0"
  }
}

Code to reproduce

counter.py

Control+K on MacOS

Describe the bug

In a marimo notebook in the browser, the key sequence Control+K results in the same behavior as Command+K on MacOS. Namely, it opens the command palette. This behavior is undesirable because:

  1. Control+K is the MacOS keyboard shortcut for deleting the text from the cursor to the end of the line. Some users, like me, use this feature heavily and have a significantly degraded experience if it isn't available.
  2. The command palette is already accessible with Command+K, so using Control+K doesn't make the command palette any more accessible.

For these reasons, I would argue that the behavior should be changed so that Control+K is not intercepted by the application and Command+K retains its current behavior of opening the command palette.

Environment

marimo env threw an error so I can't put the output here, but the behavior mentioned above is completely in the frontend anyway.

Code to reproduce

No response

Plot blinking: matplotlib interactive

Describe the bug

I suspect that's very much the same as #251, but maybe not for mpl.interactive?

Besides blinking, mpl.interactive will also use a new port every time I drag the slider, and stop responding after a few changes.

Screenshot_20231026_154844

Version

0.1.38

Code to reproduce

import marimo

__generated_with = "0.1.38"
app = marimo.App()


@app.cell
def __(exp):
    exp
    return


@app.cell
def __(altp, exp, mo, mplplot, plotlyplot, snsplot):
    mo.vstack(
        [
            mo.md(f"$$y=x^{exp.value}$$"),
            mo.tabs(
                {
                    "altair": mo.vstack([altp, altp.value]),
                    "plotly": plotlyplot(exp.value),
                    "seaborn": snsplot(exp.value),
                    "matplotlib": mplplot(exp.value),
                }
            ),
        ]
    )
    return


@app.cell
def __():
    import marimo as mo
    from plotly import express as px
    import altair as alt
    import numpy as np
    import pandas as pd
    import seaborn as sns
    from matplotlib import pyplot as plt
    from functools import cache
    return alt, cache, mo, np, pd, plt, px, sns


@app.cell
def __(mo):
    exp = mo.ui.slider(1, 8, 1, label="exp: ")
    return exp,


@app.cell
def __(cache, np):
    @cache
    def prep_xy(exp):
        x = np.linspace(0, 5, 100)
        return x, x**exp
    return prep_xy,


@app.cell
def __(alt, cache, mo, pd, prep_xy):
    @cache
    def altplot(exp):
        x, y = prep_xy(exp)
        data = pd.DataFrame({"x": x, "y": y})
        return mo.ui.altair_chart(
            alt.Chart(data).mark_line().encode(x="x", y="y"),
            chart_selection="interval",
        )
    return altplot,


@app.cell
def __(cache, prep_xy, px):
    @cache
    def plotlyplot(exp):
        x, y = prep_xy(exp)
        return px.line(x=x, y=y)
    return plotlyplot,


@app.cell
def __(cache, prep_xy, sns):
    @cache
    def snsplot(exp):
        x, y = prep_xy(exp)
        return sns.lineplot(x=x, y=y)
    return snsplot,


@app.cell
def __(cache, mo, plt, prep_xy):
    @cache
    def mplplot(exp):
        x, y = prep_xy(exp)
        plt.plot(x, y)
        return mo.mpl.interactive(plt.gcf())
    return mplplot,


@app.cell
def __(altplot, exp):
    altp = altplot(exp.value)
    return altp,


if __name__ == "__main__":
    app.run()

Better keyboard shortcut for cell navigation & manipulation

Description

Currently, keyboard shortcuts in marimo is a bit cumbersome, with uncomfortable positioned keys for frequent things, and some keys missing.

Here are some keyboard shortcuts I find unsatisfying:

  • for focus up/down: ctrl+shift+9/0 I think it's used very often, thus shouldn't be this far from home row
  • for focus top/bottom: ctrl+shift+f/g It only move the focus to the first/last cell, but will not scroll the page to top/bottom
  • for delete cell, pause cell execution: missing

Suggested solution

I'm thinking about keymap of the jupyter plugin of vscode.

That is, like a modal editor, we can have normal mode and insert mode for cells. Quote from the jupyter plugin's doc:

a cell can be in three states: unselected, command mode, and edit mode.
...
In command mode, a solid vertical bar will appear to the left of the cell. The cell can be operated on and accepts keyboard commands.
In edit mode, a solid vertical bar is joined by a border around the cell editor. The cell's contents (code or Markdown) can be modified.

Then we can avoid that annoying ctrl+shift, and just use a in command mode to add new cell below, or directly use arrow keys/hjkl to navigate between cells in command mode, for example.

I think it will make code editing experience in marimo much better.

Alternative

Not sure how difficult to implement the things above, and I can think of two, maybe easier, alternatives.

Improve code editing experience in vscode plugin

I think currently, we are missing mainly the ability to auto fill boilerplate code, especially these global var dependencies and returns

@app.cell
def __(np):
    x=np.linspace(0,1,20)
    return x,

Additionally, it will be even better to have a jupyter-like cell view to edit code, even without all the reactivity.

Assign better (near homerow) shortcuts to most used actions

I'm mainly talking about focus up/down: ctrl+shift+9/0. I feel that it's used much more than move cells up/down: ctrl+shift+j/k, while the latter have a much better shortcut.

Additional context

Again, thanks for your awesome work! It makes my playing with data much more fun :)

Marimo doesn't show how long a cell was running for if it errors out

Describe the bug

If a cell errors out, there is no way to tell how long it was running for (whereas all other cells display runtime)

Environment

{
"marimo": "0.1.65",
"OS": "Darwin",
"OS Version": "22.6.0",
"Processor": "arm",
"Python Version": "3.11.4",
"Binaries": {
"Chrome": "120.0.6099.71",
"Node": "v20.3.1"
},
"Requirements": {
"black": "23.10.1",
"click": "8.1.7",
"jedi": "0.19.1",
"pymdown-extensions": "10.3.1",
"tomlkit": "0.12.1",
"tornado": "6.3.3",
"typing_extensions": "4.8.0"
}
}

Code to reproduce

import time
time.sleep(5)
raise ValueError()

Adding an extra suggestion to convert from the ipynb file to marimo file while running the `marimo edit sample.ipynb`

Description

When i tried to run the marimo file using the marimo edit sample.ipynb it showed me


Usage: marimo edit [OPTIONS] [NAME]

  Edit a new or existing notebook.

    * marimo edit:         Create a new notebook

    * marimo edit app.py:  Create or edit app.py

Options:
  -p, --port INTEGER  Port to attach to.
  --headless          Don't launch a browser.
  --help              Show this message and exit. 

Suggested solution

However we can also suggest user to convert the file from the ipynb to marimo file, something like this

Error: Invalid NAME - sample.ipynb is not a Python file

Usage: marimo edit [OPTIONS] [NAME]

  Edit a new or existing notebook.


    * marimo edit:         Create a new notebook
    * marimo convert your_notebook.ipynb > your_notebook.py: Convert your notebook
    * marimo edit app.py:  Create or edit app.py

Options:
  -p, --port INTEGER  Port to attach to.
  --headless          Don't launch a browser.
  --help              Show this message and exit. 

This extra comment will somehow help the enduser

Alternative

No response

Additional context

No response

marimo edit: Failed to Instantiate on Safari

Describe the bug

marimo edit on macOS, Safari 16.5.2. I see:

image

When I reload by clicking the button, it loads correctly. But when I refresh, the same error occurs.

Version

0.1.3

Code to reproduce

marimo edit at the command-line, open in safari. Running port 2719

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Awaiting Schedule

These updates are awaiting their schedule. Click on a checkbox to get an update now.

  • chore(deps): update all eslint dependencies (eslint-plugin-react-hooks, eslint-plugin-vitest)
  • chore(deps): update all storybook dependencies to ^8.0.9 (@storybook/addon-docs, @storybook/addon-essentials, @storybook/addon-interactions, @storybook/addon-links, @storybook/blocks, @storybook/react, @storybook/react-vite, storybook)
  • chore(deps): update dependency typescript to ^5.4.5
  • fix(deps): update dependency react-resizable-panels to v2.0.18
  • chore(deps): update all eslint dependencies (major) (@typescript-eslint/eslint-plugin, @typescript-eslint/parser, eslint, eslint-plugin-unicorn)
  • chore(deps): update codecov/codecov-action action to v4
  • chore(deps): update dependency tsup to v8
  • chore(deps): update github artifact actions to v4 (major) (actions/download-artifact, actions/upload-artifact)
  • chore(deps): update google-github-actions/auth action to v2
  • chore(deps): update google-github-actions/upload-cloud-storage action to v2
  • chore(deps): update tj-actions/branch-names action to v8
  • fix(deps): update dependency cmdk to v1
  • fix(deps): update dependency cssnano to v7
  • fix(deps): update dependency iconify-icon to v2
  • fix(deps): update dependency partysocket to v1

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

  • fix(deps): update all non-major dependencies (@codemirror/autocomplete, @codemirror/commands, @codemirror/lang-markdown, @codemirror/lang-python, @codemirror/language-data, @codemirror/view, @emotion/react, @playwright/test, @replit/codemirror-vim, @tanstack/react-table, @textea/json-viewer, @types/node, @types/react, @types/react-dom, @uiw/codemirror-extensions-langs, @uiw/react-codemirror, ai, autoprefixer, clsx, contributor-assistant/github-action, copilot-node-server, crate-ci/typos, cssnano, date-fns, html-react-parser, humanize-duration, jotai, katex, lucide-react, mermaid, plotly.js, postcss, pyodide, react, react-codemirror-merge, react-day-picker, react-dom, react-error-boundary, react-hook-form, reactflow, stylelint, swiper, tailwind-merge, tailwindcss, turbo, vega-lite, vite, vite-tsconfig-paths, vitest, zod)

Detected dependencies

github-actions
.github/workflows/cla.yml
  • contributor-assistant/github-action v2.3.1
.github/workflows/dev-release.yml
  • styfle/cancel-workflow-action 0.12.1
  • actions/checkout v4
  • actions/setup-node v4
  • actions/setup-python v5
  • yezz123/setup-uv v4
  • actions/github-script v7
.github/workflows/discord-release.yml
  • actions/checkout v4
  • SethCohen/github-releases-to-discord v1.15.0
.github/workflows/playwright.yml
  • styfle/cancel-workflow-action 0.12.1
  • actions/checkout v4
  • actions/setup-node v4
  • turbocache-build/turbocache-action v1
  • actions/setup-python v5
  • actions/cache v4
  • google-github-actions/auth v1
  • tj-actions/branch-names v7
  • google-github-actions/upload-cloud-storage v1
  • google-github-actions/upload-cloud-storage v1
  • actions/upload-artifact v3
.github/workflows/release.yml
  • styfle/cancel-workflow-action 0.12.1
  • actions/checkout v4
  • actions/setup-node v4
  • actions/setup-python v5
.github/workflows/test.yaml
  • styfle/cancel-workflow-action 0.12.1
  • actions/checkout v4
  • actions/setup-node v4
  • turbocache-build/turbocache-action v1
  • actions/checkout v4
  • actions/setup-python v5
  • yezz123/setup-uv v4
  • codecov/codecov-action v3
  • actions/checkout v4
  • crate-ci/typos v1.18.2
.github/workflows/test_cli.yaml
  • styfle/cancel-workflow-action 0.12.1
  • actions/checkout v4
  • actions/setup-node v4
  • turbocache-build/turbocache-action v1
  • actions/setup-python v5
  • yezz123/setup-uv v4
  • actions/upload-artifact v3
  • actions/checkout v4
  • actions/setup-python v5
  • actions/download-artifact v3
npm
frontend/package.json
  • @codemirror/autocomplete ^6.12.0
  • @codemirror/commands ^6.3.3
  • @codemirror/lang-markdown ^6.2.4
  • @codemirror/lang-python ^6.1.4
  • @codemirror/language ^6.10.1
  • @codemirror/language-data ^6.4.1
  • @codemirror/lint ^6.5.0
  • @codemirror/search ^6.5.6
  • @codemirror/state ^6.4.1
  • @codemirror/theme-one-dark ^6.1.2
  • @codemirror/view ^6.24.1
  • @dnd-kit/core ^6.1.0
  • @dnd-kit/modifiers ^7.0.0
  • @dnd-kit/sortable ^8.0.0
  • @dnd-kit/utilities ^3.2.2
  • @emotion/cache ^11.11.0
  • @emotion/react ^11.11.3
  • @hookform/resolvers ^3.3.4
  • @lezer/common ^1.2.1
  • @lezer/highlight ^1.2.0
  • @lezer/lr ^1.4.0
  • @open-rpc/client-js ^1.8.1
  • @paralleldrive/cuid2 ^2.2.2
  • @radix-ui/colors ^3.0.0
  • @radix-ui/primitive ^1.0.1
  • @radix-ui/react-accordion ^1.1.2
  • @radix-ui/react-alert-dialog ^1.0.5
  • @radix-ui/react-checkbox ^1.0.4
  • @radix-ui/react-compose-refs ^1.0.1
  • @radix-ui/react-context-menu ^2.1.5
  • @radix-ui/react-dialog ^1.0.5
  • @radix-ui/react-dropdown-menu ^2.0.6
  • @radix-ui/react-icons ^1.3.0
  • @radix-ui/react-label ^2.0.2
  • @radix-ui/react-popover ^1.0.7
  • @radix-ui/react-progress ^1.0.3
  • @radix-ui/react-radio-group ^1.1.3
  • @radix-ui/react-select ^2.0.0
  • @radix-ui/react-slider ^1.1.2
  • @radix-ui/react-slot ^1.0.2
  • @radix-ui/react-switch ^1.0.3
  • @radix-ui/react-tabs ^1.0.4
  • @radix-ui/react-toast ^1.1.5
  • @radix-ui/react-toggle ^1.0.3
  • @radix-ui/react-tooltip ^1.0.7
  • @radix-ui/react-use-callback-ref ^1.0.1
  • @radix-ui/react-use-controllable-state ^1.0.1
  • @react-aria/focus ^3.16.2
  • @replit/codemirror-vim ^6.2.0
  • @storybook/addon-styling ^1.3.7
  • @tanstack/react-table ^8.12.0
  • @textea/json-viewer ^3.4.0
  • @types/humanize-duration ^3.27.4
  • @types/js-cookie ^3.0.6
  • @types/jsdom ^21.1.6
  • @types/react-grid-layout ^1.3.5
  • @uidotdev/usehooks ^2.4.1
  • @uiw/codemirror-extensions-langs ^4.21.23
  • @uiw/react-codemirror ^4.21.23
  • ai ^3.0.17
  • ansi_up ^6.0.2
  • blob-polyfill ^7.0.20220408
  • class-variance-authority ^0.7.0
  • clsx ^2.1.0
  • cmdk ^0.2.1
  • codemirror-extension-inline-suggestion ^0.0.3
  • codemirror-languageserver ^1.11.0
  • compassql ^0.21.2
  • cssnano ^6.0.4
  • date-fns ^3.3.1
  • dequal ^2.0.3
  • eslint-plugin-header ^3.1.1
  • htm ^3.1.1
  • html-react-parser ^5.1.7
  • html-to-image ^1.11.11
  • humanize-duration ^3.31.0
  • iconify-icon ^1.0.8
  • jotai ^2.6.5
  • js-cookie ^3.0.5
  • katex ^0.16.9
  • lodash-es ^4.17.21
  • lucide-react ^0.338.0
  • lz-string ^1.5.0
  • mathjs ^12.4.2
  • mermaid ^10.8.0
  • partysocket 0.0.25
  • plotly.js ^2.29.1
  • pyodide ^0.25.0
  • react-arborist ^3.4.0
  • react-aria-components ^1.1.1
  • react-codemirror-merge ^4.21.24
  • react-day-picker ^8.10.0
  • react-dropzone ^14.2.3
  • react-error-boundary ^4.0.12
  • react-grid-layout ^1.4.4
  • react-hook-form ^7.50.1
  • react-plotly.js ^2.6.0
  • react-resizable-panels 2.0.16
  • react-use-event-hook ^0.9.6
  • react-vega ^7.6.0
  • reactflow ^11.10.4
  • rpc-anywhere ^1.7.0
  • string-dedent ^3.0.1
  • swiper ^11.0.7
  • tailwind-merge ^2.2.1
  • tailwindcss-animate ^1.0.7
  • timestring ^7.0.0
  • use-resize-observer ^9.1.0
  • vega-lite ^5.16.3
  • vega-loader ^4.5.1
  • vscode-languageserver-protocol ^3.17.5
  • web-vitals ^3.5.2
  • zod ^3.22.4
  • @playwright/test ^1.41.2
  • @storybook/addon-docs ^8.0.5
  • @storybook/addon-essentials ^8.0.5
  • @storybook/addon-interactions ^8.0.5
  • @storybook/addon-links ^8.0.5
  • @storybook/blocks ^8.0.8
  • @storybook/react ^8.0.5
  • @storybook/react-vite ^8.0.5
  • @storybook/testing-library ^0.2.2
  • @swc-jotai/react-refresh ^0.1.0
  • @types/emscripten ^1.39.10
  • @types/katex ^0.16.7
  • @types/lodash-es ^4.17.12
  • @types/react ^18.2.58
  • @types/react-dom ^18.2.19
  • @types/react-plotly.js ^2.6.3
  • @types/timestring ^6.0.5
  • @typescript-eslint/eslint-plugin ^6.21.0
  • @typescript-eslint/parser ^6.21.0
  • @vitejs/plugin-react-swc ^3.6.0
  • autoprefixer ^10.4.17
  • eslint ^8.57.0
  • eslint-config-prettier ^9.1.0
  • eslint-plugin-jsx-a11y ^6.8.0
  • eslint-plugin-react ^7.34.1
  • eslint-plugin-react-hooks ^4.6.0
  • eslint-plugin-ssr-friendly ^1.3.0
  • eslint-plugin-storybook ^0.8.0
  • eslint-plugin-unicorn ^50.0.1
  • eslint-plugin-vitest ^0.4.1
  • jsdom ^24.0.0
  • npm-run-all2 ^6.1.2
  • postcss ^8.4.35
  • postcss-plugin-namespace ^0.0.3
  • prettier ^3.2.5
  • react ^18.2.0
  • react-dom ^18.2.0
  • storybook ^8.0.5
  • stylelint ^16.2.1
  • stylelint-config-standard ^36.0.0
  • tailwindcss ^3.4.1
  • turbo ^1.12.4
  • typescript ^5.4.3
  • vite ^5.1.4
  • vite-tsconfig-paths ^4.3.1
  • vitest ^1.3.1
lsp/package.json
  • copilot-node-server 1.20.1
  • @sourcegraph/vscode-ws-jsonrpc 0.0.3-fork
  • @types/minimist ^1.2.5
  • @types/node ^20.11.20
  • @types/ws ^8.5.10
  • jsonrpc-ws-proxy ^0.0.5
  • minimist ^1.2.8
  • tsup ^7.2.0
  • typescript ^5.4.3
  • ws ^8.16.0

  • Check this box to trigger a request for Renovate to run again on this repository

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.